How can I get x,y in dec degrees from a poly feat serv using arcade?

11610
35
Jump to solution
12-18-2017 03:37 PM
GusMonteverde1
New Contributor II

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!

35 Replies
StuartMoore
Occasional Contributor III

is there a way to simply convert meters in OSGB36 to WGS84

Stu

0 Kudos
XanderBakker
Esri Esteemed Contributor

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. 

0 Kudos
StuartMoore
Occasional Contributor III

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

0 Kudos
XanderBakker
Esri Esteemed Contributor

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...

0 Kudos
XanderBakker
Esri Esteemed Contributor

MKennedy-esristaff  any thoughts and/or recommendations?

0 Kudos
MelitaKennedy
Esri Notable Contributor

Are you converting the input coordinates to radians and converting to XYZ? The main equations look okay to me.

0 Kudos
XanderBakker
Esri Esteemed Contributor

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?

0 Kudos
MelitaKennedy
Esri Notable Contributor

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

0 Kudos
XanderBakker
Esri Esteemed Contributor

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";
0 Kudos
MelitaKennedy
Esri Notable Contributor

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