Select to view content in your preferred language

Automatically Calculate Geometry of Points in Web Mercator

144
1
03-25-2025 02:48 PM
BenWagner3
Occasional Contributor

I'm working in an Enterprise Geodatabase (Enterprise Version 11.3), and I have a point feature class that is in Iowa State Plane North. I currently have attribute rules that run on Insert and Update to calculate the Northing and Easting of the points. I have been asked to also include attribute fields called Latitude and Longitude and have those fields automatically calculate the Y & X values in Web Mercator. I don't believe that Arcade in an attribute rule can handle that process. I have tried creating a scheduled process to calculate the geometry, but so far my Python scripts have been generating values that aren't remotely close to being correct.

I would prefer not to have to manually run the Calculate Geometry tool, like I have the past couple of days.

Does anyone have pointers on how to write a Python script that would calculate the X & Y in Web Mercator?

Thanks!

-Ben
0 Kudos
1 Reply
CameronRex1
Occasional Contributor

@BenWagner3 You can try the following (I am not entirely sure what Iowa State Plane North you are using, so I have assumed WKID: 3417). I have tested something similar in another state plane and was able to get correct results. (If you are using a different WKID, let me know and I can change it up.)

// === Projection parameters for NAD83 StatePlane Iowa North FIPS 1401 (US Feet) ===
var lat0 = 41.5;
var lon0 = -93.5;
var phi1 = 43.2666666666667;
var phi2 = 42.0666666666667;
var E0 = 4921250.0; // False easting (ft)
var N0 = 3280833.3333; // False northing (ft)

// GRS80 ellipsoid
var a = 6378137.0;
var f = 1 / 298.257222101;
var e = sqrt(2 * f - f * f);

// === Helper functions ===
function rad(d) { return d * PI / 180; }
function deg(r) { return r * 180 / PI; }
function m(phi) {
return cos(phi) / sqrt(1 - pow(e, 2) * pow(sin(phi), 2));
}
function t(phi) {
return tan(PI / 4 - phi / 2) / pow((1 - e * sin(phi)) / (1 + e * sin(phi)), e / 2);
}
function inverseLCC(x, y) {
var phi1_rad = rad(phi1);
var phi2_rad = rad(phi2);
var lat0_rad = rad(lat0);
var lon0_rad = rad(lon0);

var m1 = m(phi1_rad);
var m2 = m(phi2_rad);
var t0 = t(lat0_rad);
var t1 = t(phi1_rad);
var t2 = t(phi2_rad);

var n = (log(m1) - log(m2)) / (log(t1) - log(t2));
var F = m1 / (n * pow(t1, n));
var r0 = a * F * pow(t0, n);

var r = sqrt(pow(x - E0, 2) + pow(r0 - (y - N0), 2));
var t_p = pow(r / (a * F), 1 / n);

var chi = PI / 2 - 2 * atan(t_p);
var lat_rad = chi + (e*e/2 + 5*pow(e,4)/24 + pow(e,6)/12) * sin(2*chi)
+ (7*pow(e,4)/48 + 29*pow(e,6)/240) * sin(4*chi)
+ (7*pow(e,6)/120) * sin(6*chi);
var lat = deg(lat_rad);

var theta = atan((x - E0) / (r0 - (y - N0)));
var lon = lon0 + deg(theta / n);

return [lat, lon];
}

// === Get point coordinates from the feature ===
var x = $feature.x;
var y = $feature.y;

// === Convert to Lat/Lon
var latlon = inverseLCC(x, y);

// === Format output
"Lat: " + Text(latlon[0], "#.######") + ", Lon: " + Text(latlon[1], "#.######")

0 Kudos