Select to view content in your preferred language

# Calculate USNG Coordinates in Arcade

977
5
04-15-2020 10:17 AM
by
New Contributor III

I'm trying to write an attribute rule to automatically input the USNG coordinates for address points when they're created or modified.  Does anyone know if it's possible, or how to calculate USNG coordinates in Arcade?

Tags (4)
1 Solution

Accepted Solutions
New Contributor II

Great news! Someone from the Esri Defense Team shared the Arcade needed to do this. I just tested in Smart Forms and it works perfectly.

var x = Geometry(\$feature).x;
var y = Geometry(\$feature).y;
var originShift = 2.0 * PI * 6378137.0 / 2.0;
var lat = (y / originShift) * 180.0;
lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
var lon = (x / originShift) * 180.0;
function pad (val) {if (val < 10) {val = '0000' + val} else if (val < 100) {val = '000' + val} else if (val < 1000) {val = '00' + val} else if (val < 10000) {val = '0' + val};return val};
if (Lat < -80) return 'Too far South' ; if (Lat > 84) return 'Too far North' ;
var c = 1 + Floor((Long+180)/6);
var e = c*6 - 183 ;
var k = Lat*PI/180;
var l = Long*PI/180;
var m = e*PI/180;
var n = Cos(k);
var o = 0.006739496819936062*Pow(n,2);
var p = 40680631590769/(6356752.314*Sqrt(1 + o));
var q = Tan(k);
var r = q*q;
var s = (r*r*r) - Pow (q,6);
var t = l - m;
var u = 1.0 - r + o;
var v = 5.0 - r + 9*o + 4.0*(o*o);
var w = 5.0 - 18.0*r + (r*r) + 14.0*o - 58.0*r*o;
var x = 61.0 - 58.0*r + (r*r) + 270.0*o - 330.0*r*o;
var y = 61.0 - 479.0*r + 179.0*(r*r) - (r*r*r);
var z = 1385.0 - 3111.0*r + 543.0*(r*r) - (r*r*r);
var aa = p*n*t + (p/6.0*Pow (n,3)*u*Pow (t,3)) + (p/120.0*Pow (n,5)*w*Pow (t,5)) + (p/5040.0*Pow (n,7)*y*Pow (t,7));
var ab = 6367449.14570093*(k - (0.00251882794504*Sin (2*k)) + (0.00000264354112*Sin (4*k)) - (0.00000000345262*Sin (6*k)) + (0.000000000004892*Sin (8*k))) + (q/2.0*p*Pow (n,2)*Pow (t,2)) + (q/24.0*p*Pow (n,4)*v*Pow (t,4)) + (q/720.0*p*Pow (n,6)*x*Pow (t,6)) + (q/40320.0*p*Pow (n,8)*z*Pow (t,8));
aa = aa*0.9996 + 500000.0;
ab = ab*0.9996; if (ab < 0.0) ab += 10000000.0;
var split1 = Split('CDEFGHJKLMNPQRSTUVWXX', '');
var ad = split1[Floor(Lat/8 + 10)];
var ae = Floor (aa/100000);
var split2 = Split('ABCDEFGH', '');
var split3 = Split('JKLMNPQR', '');
var split4 = Split('STUVWXYZ', '');
var combinedSplit = [split2, split3, split4];
var af = combinedSplit[(c-1)%3][ae-1];
var ag = Floor (ab/100000)%20;
var split5 = Split('ABCDEFGHJKLMNPQRSTUV', '');
var split6 = Split('FGHJKLMNPQRSTUVABCDE', '');
var combinedSplit2 = [split5, split6];
var ah = combinedSplit2[(c-1)%2][ag];
return [Floor(aa%100000), Floor(ab%100000), c, ad, af, ah]
};
var formatted = MGRS[2] + MGRS[3] + MGRS[4] + MGRS[5] + aa + ab;
return formatted;

5 Replies
Occasional Contributor III

I am also interested in doing this use ArcGIS Field Maps smartforms. @PaulBarker any ideas?

New Contributor II

@JeffShaner any updates on this? It looks like this topic was tagged as an ArcGIS Pro question but I'd like to have USNG/MGRS added to a field upon entry in Field Maps and Smart Forms, similar to the way it works in QuickCapture as a device variable OR via an Arcade calculation (whatever works). I figured out how to apply lat/long in decimal degrees...

...but USNG is a requirement as per FEMAD092-5_dated.pdf (usngi.org)

So I really need to figure this out ASAP as we roll out Field Maps for additional field data collection / editing.

New Contributor II

Another example where USNG/MGRS "stamping" has worked in the past is in Web AppBuilder Smart Editor attribute actions Smart Editor widget—ArcGIS Web AppBuilder | Documentation. As we make the transition to Experience Builder, we are also looking for this functionality, but I am guessing it has to be implemented by the ArcGIS Online Team for Smart Forms first? @Jianxia

New Contributor II

Great news! Someone from the Esri Defense Team shared the Arcade needed to do this. I just tested in Smart Forms and it works perfectly.

var x = Geometry(\$feature).x;
var y = Geometry(\$feature).y;
var originShift = 2.0 * PI * 6378137.0 / 2.0;
var lat = (y / originShift) * 180.0;
lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
var lon = (x / originShift) * 180.0;
function pad (val) {if (val < 10) {val = '0000' + val} else if (val < 100) {val = '000' + val} else if (val < 1000) {val = '00' + val} else if (val < 10000) {val = '0' + val};return val};
if (Lat < -80) return 'Too far South' ; if (Lat > 84) return 'Too far North' ;
var c = 1 + Floor((Long+180)/6);
var e = c*6 - 183 ;
var k = Lat*PI/180;
var l = Long*PI/180;
var m = e*PI/180;
var n = Cos(k);
var o = 0.006739496819936062*Pow(n,2);
var p = 40680631590769/(6356752.314*Sqrt(1 + o));
var q = Tan(k);
var r = q*q;
var s = (r*r*r) - Pow (q,6);
var t = l - m;
var u = 1.0 - r + o;
var v = 5.0 - r + 9*o + 4.0*(o*o);
var w = 5.0 - 18.0*r + (r*r) + 14.0*o - 58.0*r*o;
var x = 61.0 - 58.0*r + (r*r) + 270.0*o - 330.0*r*o;
var y = 61.0 - 479.0*r + 179.0*(r*r) - (r*r*r);
var z = 1385.0 - 3111.0*r + 543.0*(r*r) - (r*r*r);
var aa = p*n*t + (p/6.0*Pow (n,3)*u*Pow (t,3)) + (p/120.0*Pow (n,5)*w*Pow (t,5)) + (p/5040.0*Pow (n,7)*y*Pow (t,7));
var ab = 6367449.14570093*(k - (0.00251882794504*Sin (2*k)) + (0.00000264354112*Sin (4*k)) - (0.00000000345262*Sin (6*k)) + (0.000000000004892*Sin (8*k))) + (q/2.0*p*Pow (n,2)*Pow (t,2)) + (q/24.0*p*Pow (n,4)*v*Pow (t,4)) + (q/720.0*p*Pow (n,6)*x*Pow (t,6)) + (q/40320.0*p*Pow (n,8)*z*Pow (t,8));
aa = aa*0.9996 + 500000.0;
ab = ab*0.9996; if (ab < 0.0) ab += 10000000.0;
var split1 = Split('CDEFGHJKLMNPQRSTUVWXX', '');
var ad = split1[Floor(Lat/8 + 10)];
var ae = Floor (aa/100000);
var split2 = Split('ABCDEFGH', '');
var split3 = Split('JKLMNPQR', '');
var split4 = Split('STUVWXYZ', '');
var combinedSplit = [split2, split3, split4];
var af = combinedSplit[(c-1)%3][ae-1];
var ag = Floor (ab/100000)%20;
var split5 = Split('ABCDEFGHJKLMNPQRSTUV', '');
var split6 = Split('FGHJKLMNPQRSTUVABCDE', '');
var combinedSplit2 = [split5, split6];
var ah = combinedSplit2[(c-1)%2][ag];
return [Floor(aa%100000), Floor(ab%100000), c, ad, af, ah]
};