Arcade Script For Converting From State Plane to Decimal Degrees

630
4
01-30-2025 02:30 PM
Labels (2)
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

Hi,

I found this code that I copied from copilot and modified for my specific needs and works somewhat but needs some major corrections.

 

 

// Constants for NAD83 Georgia West (FIPS 1002)
var A = 6378137.0; // Semi-major axis for NAD83
var F = 1 / 298.257222101; // Flattening for NAD83
var E2 = (2 * F) - (F * F); // Eccentricity squared
var centralMeridian = -84.16666666666667 * (PI / 180); // Central meridian for Georgia West (degrees to radians)
var latitudeOfOrigin = 30.0 // Latitude of origin (degrees to radians)
var scaleFactor = 0.9999; // Scale factor
var falseEasting = 2296583.333333 * 0.3048006096012192; // False easting in meters (1 US foot = 0.3048006096012192 meters)
var falseNorthing = 0.0; // False northing in meters

// Function to convert State Plane (NAD83) to Latitude and Longitude
function statePlaneToLatLong(x, y) {
    x *= 0.3048006096012192; // Convert x from US Feet to meters
    y *= 0.3048006096012192; // Convert y from US Feet to meters
    x -= falseEasting;
    y -= falseNorthing;

    var m = y / scaleFactor;
    var mu = m / (A * (1 - (E2 / 4) - (3 * E2 * E2 / 64) - (5 * E2 * E2 * E2 / 256)));

    var e1 = (1 - sqrt(1 - E2)) / (1 + sqrt(1 - E2));
    
    var phi1 = mu + (3 * e1 / 2 - 27 * pow(e1, 3) / 32) * sin(2 * mu)
        + (21 * pow(e1, 2) / 16 - 55 * pow(e1, 4) / 32) * sin(4 * mu)
        + (151 * pow(e1, 3) / 96) * sin(6 * mu)
        + (1097 * pow(e1, 4) / 512) * sin(8 * mu);

    var sinPhi1 = sin(phi1);
    var cosPhi1 = cos(phi1);
    var t1 = tan(phi1) * tan(phi1);
    var c1 = E2 * cosPhi1 * cosPhi1 / (1 - E2);
    var r1 = A * (1 - E2) / pow(1 - E2 * sinPhi1 * sinPhi1, 1.5);
    var n1 = A / sqrt(1 - E2 * sinPhi1 * sinPhi1);
    var d = x / (n1 * scaleFactor);

    // Calculate latitude and longitude in radians
    var latitude = phi1 - (n1 * tan(phi1) / r1)
        * (d * d / 2 - (5 + 3 * t1 + 10 * c1 - 4 * c1 * c1 - 9 * E2) * pow(d, 4) / 24
        + (61 + 90 * t1 + 298 * c1 + 45 * t1 * t1 - 252 * E2 - 3 * c1 * c1) * pow(d, 6) / 720);

    var longitude = centralMeridian + (d - (1 + 2 * t1 + c1) * pow(d, 3) / 6
        + (5 - 2 * c1 + 28 * t1 - 3 * c1 * c1 + 8 * E2 + 24 * t1 * t1) * pow(d, 5) / 120) / cosPhi1;

    // Convert latitude and longitude to degrees
    var latitudeDeg = latitude * (180 / PI)*10;
    var longitudeDeg = longitude * (180 / PI);

    // Format results as degrees North and degrees West
    return {
        latitude: round( abs(latitudeDeg) , 6),
        longitude: round( abs(longitudeDeg) , 6)
    };
}

// Example usage with provided coordinates
var x = Geometry($feature).x; // X coordinate in US feet
var y = Geometry($feature).y; // Y coordinate in US feet

var result = statePlaneToLatLong(x, y);
console(result); // Output: {latitude: "xy.xyzxyz° N", longitude: "xy.xyzxyz° W"}
return result.latitude

 

 

 

4 Replies
LindsayRaabe_FPCWA
MVP Regular Contributor

Can I suggest adding the purpose of the code to the post heading to make it more searchable? I believe it's a Lat/Long conversion code, which I know a lot of people would be looking for. Also maybe add some tags to improve search results. 

Lindsay Raabe
GIS Officer
Forest Products Commission WA
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

Thanks @LindsayRaabe_FPCWA for the suggestion. I went ahead and made the changes, and I am hoping that this can be used to create a function for attribute rules. I think there might be something simpler than this, but I will need to explore further.

DavidColey
MVP Regular Contributor

Hello @RPGIS  - would you be able to share how you used copilot to derive your expression?  I ask because when I try to parametrize for Florida State Plane West HARN, the only differences are the centralMeridian, latitutudeOfOrigin and the scale factor.  

var centralMeridian = -82.0 * (PI / 180); // Central meridian for NAD83 HARN Florida State Plane West (degrees to radians)
var latitudeOfOrigin = 24.33333333333333 // Latitude of origin (degrees to radians)
var scaleFactor = 0.9999411764705882; // Scale factor

Other than the scale factor for HARN carrying more precision than the NAD 83 above I cannot seem to find where HARN would cause my conversions to have a 0.1 degree shift north in latitude and 0.05 shift east in longitude.

For example, when I plug in the expressions for my respective lat and lon attributes:

Pro: 27.078110470, -82.43048022

Arcade: 27.505790, -82.383999

Its interesting too because the console returns different values from the actual calculation:

{"latitude":27.851679,"longitude":-82.409632}

Any insights you can provide are appreciated, (I just don't have the trig to keep up) -

Thanks,

David

Link to a similar post with an Arcade expression that works for State Plane North / South coordinate systems (Lambert Conformal Conic)

https://community.esri.com/t5/arcgis-pro-ideas/arcade-projectas-geometry-function/idi-p/1171382/page...

@TomNeer 

 

 

 

0 Kudos
RPGIS
by MVP Regular Contributor
MVP Regular Contributor

I noticed that there some issues with the console values as well that I am trying to breakdown the math but this code was copied, like you said, using copilot but it is incorrect.

When I ran some tests it worked in some instances and not in others. I also noticed that sometimes it would be off by 4 degrees in some spots but I am trying to figure out where that issue is in the code.

0 Kudos