Greetings Dev Community-
I need help with an arcade expression. I am trying to generate x,y pairs from a tax lot polygon feature service. In my "custom" field I have used the following expression:
var pnt= Centroid(Geometry($feature));
return Text(pnt);
RESULT...
{"x":-13649119.198784793,"y":5696311.278630899,"spatialReference":{"latestWkid":3857,"wkid":102100}}
but, I need the x and y to be returned in dec degrees, and my results appear to be on UTM northing/easting
I also tried to call a member method X and Y but I am getting the following error...
Thanks!
Solved! Go to Solution.
is there a way to simply convert meters in OSGB36 to WGS84
Stu
Hi Stuart Moore ,
According to this site: Converting between osgb36 and wgs84 you should be able to use the Helmert transformation to convert between WGS84 and OSGB36 (Helmert transformation - Wikipedia ), which should provide results within 5 meter precision.
thanks Xander Bakker i had a look at the links but its over my head, maybe after a few more coffee's it will sink in
thanks again
Stu
Hi Stuart Moore ,
I also had a look yesterday and played with the expression below and 3 points of interest:
function WGS84toOSGB36(Xa, Ya, Za) {
// source: https://digimap.edina.ac.uk/webhelp/digimapgis/projections_and_transformations/converting_between_osgb36_and_wgs84.htm
// source: https://en.wikipedia.org/wiki/Helmert_transformation
// source: https://www.ordnancesurvey.co.uk/documents/resources/guide-coordinate-systems-great-britain.pdf
// parameters (from WGS84 to OSGB36):
var cx = -446.448;
var cy = 125.157;
var cz = -542.06;
var s = 20.4894 * Pow(10, -6); // (ppm)
var rx = -0.1502 * 4.84813681 * Pow(10, -6); // (arcsecond to radian)
var ry = -0.247 * 4.84813681 * Pow(10, -6); //(arcsecond to radian)
var rz = -0.8421 * 4.84813681 * Pow(10, -6); // (arcsecond to radian)
// Xb = cx + (1 + s * 10-6) * (Xa - rz * Ya + ry * Za)
// Yb = cy + (1 + s * 10-6) * (rz * Xa + Ya - rx * Za)
// Zb = cz + (1 + s * 10-6) * (-ry * Xa + rx * Ya + Za)
var Xb = cx + (1 + s) * (Xa - rz * Ya + ry * Za);
var Yb = cy + (1 + s) * (rz * Xa + Ya - rx * Za);
var Zb = cz + (1 + s) * (-ry * Xa + rx * Ya + Za);
return [Xb, Yb, Zb];
}
// example coords WGS84 in and OSGB36 A20H1 out
var coords = {"Edinburgh Castle": [-3.2004710, 55.9485273, -179913.35, 844672.45],
"Cardiff Castle": [-3.1820435, 51.4814364, -187026.17, 347567.19],
"Big Ben London": [-0.1245993, 51.5006821, 25274.73, 350718.17]};
for (var place in coords) {
Console("");
Console(place);
var crd = coords[place];
var Xa = crd[0];
var Ya = crd[1];
var Za = 0;
Console("Xa:" + Xa);
Console("Ya:" + Ya);
var osgb = WGS84toOSGB36(Xa, Ya, Za);
Console(osgb);
var Xb = osgb[0];
var Yb = osgb[1];
var Zb = osgb[2];
Console("Calculated Xb:" + Xb);
Console("Calculated Yb:" + Yb);
var realXb = crd[2];
var realYb = crd[3];
Console("Real Xb:" + realXb);
Console("Real Yb:" + realYb);
var deltaX = realXb - Xb;
var deltaY = realYb - Yb;
Console("delta X:" + deltaX);
Console("dalta Y:" + deltaY);
var dist = Sqrt(Pow(deltaX, 2) + Pow(deltaY, 2));
Console("Error dist:" + dist);
}
return "OK";
The results are however nowhere near to what they should be so I am sure I am doing something completely wrong...
MKennedy-esristaff any thoughts and/or recommendations?
Are you converting the input coordinates to radians and converting to XYZ? The main equations look okay to me.
Hi Melita Kennedy ,
Thanks for stepping in. Actually the source coordinates are expression in decimal degrees and I don't convert them in the process. Is that what is causing the huge errors that I am getting? Should I convert the input decimal degrees to radians?
Hi Xander,
Yes! And they need converted to XYZ. There is an abridged Molodensky method that uses decimal degrees directly--but accuracy is a little less. After converted through the conformal 3D equation, the output XYZ need to be converted back to lat-lnng-ellipsoid h. That conversion is usually iterative but I think there are some direct but less accurate conversions.
Melita
Hi MKennedy-esristaff ,
I tried to include the conversion(s) in the expression (see lines 35, 36 where I read the input coordinates and lines 42 to 44 where the resulting coordinates are returned). I am pretty sure I am doing something completely wrong, since the results are very far off from what they should be. The "coords" dictionary on line 26 contains the input long and lat and output X and Y for 3 given points.
You also mention an abridged Molodensky method. Would you have more info on that?
function WGS84toOSGB36(Xa, Ya, Za) {
// source: https://digimap.edina.ac.uk/webhelp/digimapgis/projections_and_transformations/converting_between_osgb36_and_wgs84.htm
// source: https://en.wikipedia.org/wiki/Helmert_transformation
// source: https://www.ordnancesurvey.co.uk/documents/resources/guide-coordinate-systems-great-britain.pdf
// parameters (from WGS84 to OSGB36):
var cx = -446.448;
var cy = 125.157;
var cz = -542.06;
var s = 20.4894 * Pow(10, -6); // (ppm)
var rx = -0.1502 * PI / (180 * 3600) * Pow(10, -6); // (arcsecond to radian)
var ry = -0.2470 * PI / (180 * 3600) * Pow(10, -6); // (arcsecond to radian)
var rz = -0.8421 * PI / (180 * 3600) * Pow(10, -6); // (arcsecond to radian)
// Xb = cx + (1 + s * 10-6) * (Xa - rz * Ya + ry * Za)
// Yb = cy + (1 + s * 10-6) * (rz * Xa + Ya - rx * Za)
// Zb = cz + (1 + s * 10-6) * (-ry * Xa + rx * Ya + Za)
var Xb = cx + (1 + s) * (Xa - rz * Ya + ry * Za);
var Yb = cy + (1 + s) * (rz * Xa + Ya - rx * Za);
var Zb = cz + (1 + s) * (-ry * Xa + rx * Ya + Za);
return [Xb, Yb, Zb];
}
// example coords WGS84 in and OSGB36 A20H1 out
var coords = {"Edinburgh Castle": [-3.2004710, 55.9485273, -179913.35, 844672.45],
"Cardiff Castle": [-3.1820435, 51.4814364, -187026.17, 347567.19],
"Big Ben London": [-0.1245993, 51.5006821, 25274.73, 350718.17]};
for (var place in coords) {
Console("");
Console(place);
var crd = coords[place];
var Xa = crd[1] * (PI / (180 * 3600));
var Ya = crd[0] * (PI / (180 * 3600));
var Za = 0;
Console("Xa:" + Xa);
Console("Ya:" + Ya);
var osgb = WGS84toOSGB36(Xa, Ya, Za);
Console(osgb);
var Xb = osgb[0] * ((180 * 3600) / PI);
var Yb = osgb[1] * ((180 * 3600) / PI);
var Zb = osgb[2] * ((180 * 3600) / PI);
Console("Calculated Xb:" + Xb);
Console("Calculated Yb:" + Yb);
var realXb = crd[2];
var realYb = crd[3];
Console("Real Xb:" + realXb);
Console("Real Yb:" + realYb);
var deltaX = realXb - Xb;
var deltaY = realYb - Yb;
Console("delta X:" + deltaX);
Console("dalta Y:" + deltaY);
var dist = Sqrt(Pow(deltaX, 2) + Pow(deltaY, 2));
Console("Error dist:" + dist);
}
return "OK";
You still need to convert between latitude-longitude and XYZ. See section 4.1.1 of IOGP / EPSG Guidance Note 7-2. It's available from https://www.epsg.org.