Select to view content in your preferred language

Incorrect geographic transformation from EPSG:31255 to WebMercator in ArcGIS JS API

267
3
3 weeks ago
QuentinDLV
New Contributor

Using EsriMap JS v4.34

I am projecting coordinates from EPSG:31255 (MGI / Austria GK West) to WebMercator (EPSG:3857).


Test coordinate:
X: 48402
Y: 335041

Expected result (EPSG.io / PROJ / pyproj):
1556587.0410259578, 6132161.572467429

ArcGIS JS result (ProjectOperator.execute without geographicTransformation):
1556143.0256220328, 6132152.124194294

This results in a horizontal offset of ~440 meters.

Even when trying several GeographicTransformation WKIDs, none match the correct result.

Is ArcGIS JS missing the correct transformation grid for this CRS?

My JS code test :

require([
"esri/geometry/operators/projectOperator",
"esri/geometry/Polyline",
"esri/geometry/SpatialReference"
], function (ProjectOperator, Polyline, SpatialReference) {

(async () => {

await ProjectOperator.load();

const sourceSR = new SpatialReference({ wkid: 31255 });
const targetSR = new SpatialReference({ wkid: 3857 });

let polyline = new Polyline({
paths: [[[48402, 335041]]],
spatialReference: sourceSR
});

let projected = ProjectOperator.execute(polyline, targetSR);

console.log(projected);

})();

});

0 Kudos
3 Replies
AndyGup
Esri Regular Contributor

> Is ArcGIS JS missing the correct transformation grid for this CRS?

@QuentinDLV this is likely because the JS SDK projectOperator currently doesn't have any support for grid transforms, so you are only getting a best-effort result through equation-based geographic transformations. See the known limitations section in the doc, here. Have you tried testing with geometryService?

0 Kudos
QuentinDLV
New Contributor

Thanks for your reply!

I’m not fully convinced that this is a grid-related issue in this specific case.

1) EPSG:31255 (MGI / Austria GK Central) is not a very recent CRS, but the transformation to WGS84 / WebMercator does not strictly require grid-based transformations to achieve a correct result. A standard Helmert / equation-based transformation should already give a much closer result than what I observe.

2) I tested the same coordinate using pyproj (default installation, without adding any external grid files), and I get the exact same result as EPSG.io:

Input (EPSG:31255):
X: 48402
Y: 335041

pyproj / EPSG.io result (EPSG:3857):
1556587.0410259578, 6132161.572467429

This suggests that an equation-based transformation is sufficient to reach the expected accuracy.

Given that:
- pyproj (no grids) = correct
- EPSG.io = correct
- ArcGIS JS = ~440m offset

it looks more like ArcGIS JS is selecting an incorrect geographic transformation for this CRS, rather than just lacking grid support.

I’ll try geometryService as you suggested, but I’m curious:
Is there a way to control or inspect which geographic transformation is actually being used internally by projectOperator?

Thanks again!

0 Kudos
AndyGup
Esri Regular Contributor

You're right, after double checking it's not a grid issue. It's also not a bug in the JS SDK. You will just need to set the areaOfInterestExtent in ProjectOptions*, or you can also set geographicTransformation. Once you do that you should get a result that is much more accurate.

My test app is showing a difference of 0.0035 meters between your expected result and the projectOperator, as well as geometryService.project():

projectOperator result 31255 => 3857 1556587.0407006142 6132161.568937744
projectOperator result distance to expected EPSG:3857 point (meters) 0.0035446469419314845

    const targetSR = new SpatialReference({ "wkid": 3857 });
    const point = new Point({
      "x": 48402,
      "y": 335041,
      "spatialReference": { "wkid": 31255 }
    }); 

    // Austria
    const testExtent = new Extent({
      "xmin": -292428.21,
      "ymin": 140068.94,
      "xmax": 295094.41,
      "ymax": 438461.34,
      "spatialReference": { "wkid": 31255 }
    });

    let projected = projectOperator.execute(point, targetSR, {
      areaOfInterestExtent: testExtent, // be sure to set this
    });

 

0 Kudos