Lat/Long unit conversion with Arcade

4446
10
Jump to solution
10-11-2018 01:10 PM
AhjungKim4
Occasional Contributor II

I am adding geometry fields using Arcade Geometry($feature).x and Geometry($feature).y.  Since my target feature layer is in Web Mercator projection, my custom lat & long fields are displaying the values in meter.  Is there a way to convert this to decimal degrees with arcade function? 

1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

Yes you can. If you use the function below you will be able to convert the Web Mercator Auxiliary Sphere coordinates into Lat and Long (WGS 1984):

function MetersToLatLon(x, y) {
    // Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum
    // Fuente: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
    var originShift = 2.0 * PI * 6378137.0 / 2.0;

    var lon = (x / originShift) * 180.0;
    var lat = (y / originShift) * 180.0;

    lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
    return [lat, lon];
}

Below you can see it in action:

function MetersToLatLon(x, y) {
    // Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum
     // Fuente: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
    var originShift = 2.0 * PI * 6378137.0 / 2.0;

    var lon = (x / originShift) * 180.0;
    var lat = (y / originShift) * 180.0;

    lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
    return [lat, lon];
}

function CreateWazeURL(lat, lon) {
    return "https://waze.com/ul?ll=" + lat + "," + lon + "&navigate=yes"
}

var latlon = MetersToLatLon(Geometry($feature).X, Geometry($feature).Y);
var url = CreateWazeURL(latlon[0], latlon[1]);
return url;

In this case you have two functions: MetersToLatLon (lines 1 - 11) for converting web merc into lat lon, the CreateWazeURL function (lines 13 to 15) for creating a navigation URL based on lat and lon.

The actual code starts on line 17 where a list is created containing the lat and lon converted from the X and Y extracted from the geometry.

On line 18 the lat and lon values are passed to the CreateWazeURL function and the URL that is returned from the function is returned as result.

Some images to explain the result can be found here: https://community.esri.com/docs/DOC-11541-crear-un-enlace-para-navegar-con-waze-en-la-ventana-emerge... (Spanish content)

View solution in original post

10 Replies
XanderBakker
Esri Esteemed Contributor

Yes you can. If you use the function below you will be able to convert the Web Mercator Auxiliary Sphere coordinates into Lat and Long (WGS 1984):

function MetersToLatLon(x, y) {
    // Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum
    // Fuente: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
    var originShift = 2.0 * PI * 6378137.0 / 2.0;

    var lon = (x / originShift) * 180.0;
    var lat = (y / originShift) * 180.0;

    lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
    return [lat, lon];
}

Below you can see it in action:

function MetersToLatLon(x, y) {
    // Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum
     // Fuente: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
    var originShift = 2.0 * PI * 6378137.0 / 2.0;

    var lon = (x / originShift) * 180.0;
    var lat = (y / originShift) * 180.0;

    lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
    return [lat, lon];
}

function CreateWazeURL(lat, lon) {
    return "https://waze.com/ul?ll=" + lat + "," + lon + "&navigate=yes"
}

var latlon = MetersToLatLon(Geometry($feature).X, Geometry($feature).Y);
var url = CreateWazeURL(latlon[0], latlon[1]);
return url;

In this case you have two functions: MetersToLatLon (lines 1 - 11) for converting web merc into lat lon, the CreateWazeURL function (lines 13 to 15) for creating a navigation URL based on lat and lon.

The actual code starts on line 17 where a list is created containing the lat and lon converted from the X and Y extracted from the geometry.

On line 18 the lat and lon values are passed to the CreateWazeURL function and the URL that is returned from the function is returned as result.

Some images to explain the result can be found here: https://community.esri.com/docs/DOC-11541-crear-un-enlace-para-navegar-con-waze-en-la-ventana-emerge... (Spanish content)

View solution in original post

AhjungKim4
Occasional Contributor II

This works beautifully, thank you!

XanderBakker
Esri Esteemed Contributor

Glad it worked!

0 Kudos
by Anonymous User
Not applicable

Hi Xander, thank you for your post this is very useful!!

Also - I was wondering if you had some ideas on how we could run a similar conversion to get USNG coordinates instead?

Thanks again,

Alix

0 Kudos
XanderBakker
Esri Esteemed Contributor

Unfortunately I don't. If you have access to the formula required I guess it would be possible to implement it in a similar way. I guess we have to wait until the projection engine is supported and available in Arcade to do this kind of transformation.

by Anonymous User
Not applicable

Thank you Xander. Do you know where it would be possible to find a list of the projection engines supported and available in Arcade? I'm wondering if maybe MGRS may be in there instead...

0 Kudos
XanderBakker
Esri Esteemed Contributor

The point is there there is no support for projecting data inside an Arcade expression at this moment. Hopefully it will come soon. The only "projections" that you can currently do are the ones that you have a formula for and can translate to Arcade. 

RaúlJiménez_Ortega
Esri Contributor

Thanks Xander Bakker‌, I have used your code to create a Google Street View link:

var p = Centroid( $feature )

function MetersToLatLon(x, y) {
// Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum
// Fuente: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/
var originShift = 2.0 * PI * 6378137.0 / 2.0;

var lon = (x / originShift) * 180.0;
var lat = (y / originShift) * 180.0;

lat = 180.0 / PI * (2.0 * Atan( Exp( lat * PI / 180.0)) - PI / 2.0);
return [lat, lon];
}

function CreateGoogleStreetView(lat, lon) {
return "https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=" + lat + "," + lon;

}

var latlon = MetersToLatLon(p.x, p.y)
var url = CreateGoogleStreetView(latlon[0],latlon[1])
return url

Thanks!

XanderBakker
Esri Esteemed Contributor

Hola Raúl Jiménez Ortega ,

I have a related document here in Spanish about creating a Street View link:

https://community.esri.com/docs/DOC-10883-crear-un-enlace-a-streetview-en-la-ventana-emergente-con-a...

More on Arcade in our GeoDev section that we are starting to build:

https://community.esri.com/groups/esricol-community/content?filterID=contentstatus%5Bpublished%5D~ca...