Better Distance Measurements in Web Mercator Projection

For short distances, you could multiply the calculated distance with cos(lat), since the scale of the mercator projection is proportional to the secant of the latitude (secant is 1/cos). Also see http://en.wikipedia.org/wiki/Mercator_projection#Mathematics_of_the_projection


Addendum thanks to @jeremiah-england: while the above correction would be correct when it comes to true Mercator projections, the Web Mercator (EPSG:3857) is not a Mercator. EPSG calls it a "Pseudo-Mercator." The problem is that it uses WGS84, an eliptical model, and projects it using spherical mercator calculations (which Google used because they are faster). If you scale your distances by 1/cos(phi) with the web Mercator, you'll be about 0.6% off at the equator. See Noel Zinn's presentation on Web Mercator for more details.

According to the above-mentioned presentation, the following method could be used to calculate more accurate distances from web mercator coordinates. Given dx — horizontal coordinate difference (W-E direction), and dy — vertical coordinate difference (S-N direction):

e = 0.081819191
adjustedX = dx * cos(lat) / sqrt(1 - e^2 * sin(lat)^2)
adjustedY = dy * cos(lat) * (1 - e^2) / pow(1 - e^2 * sin(lat)^2, 3/2)
adjustedDistance = hypot(adjustedX, adjustedY)

The ratio between this adjustment and cos(lat) is larger in the S-N direction, ranging from 0.9933 at the equator to 1.0034 at the poles. The W-E direction ratio starts with 1 at the equator and grows to 1.0034 at the poles.

Note that this correction still works reasonably well only for short distances, where planar geometry of the Earth's surface can be assumed.


I'd consider your second option of storing your data in the GEOGRAPHY format again if you are looking for accurate results on global data.

There is nothing stopping you from having two spatial fields in a table - one in Mercator as a GEOMETRY type and one in WGS84 as a GEOGRAPHY type (at least not in SQL Server, I am not sure about ArcSDE).

You should be able to create a simple geoprocessing script that will populate both fields with your original data. If there is editing and frequent updates going on then this may not be an option.

Once you have the two fields you can carry on using your Mercator for fast display, and convert user entered points to Lat/Lon for distances.

This has two major advantages:

  • you can also get more accurate areas and lengths of features based on user queries
  • you don't need to worry about forgetting to add custom code for each query which deals with measurements

The query speeds will be more complex, but it may be unnoticeable to a user. You may want to test with one feature class before deciding on a solution. You'll also have to convert the user entered points from Mercator (which should be trivial, and could be done in the browser).

Even with the geography type though there is still an error margin:

The error tolerance for the geography methods can be as large as 1.0e-7 * extents

From MSDN


An alternative suggestion from ESRI is to use a "Geometry service", which involves sending the geometries to an ArcGIS Server and having the result returned. If you don't expect any bottleneck issues by using a web service, this can be a very effective approach. I have used the same approach in a Silverlight application.

Here is an original blog entry from ESRI: http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2010/03/05/Measuring-distances-and-areas-when-your-map-uses-the-Mercator-projection.aspx

In the blog there is a simplified JavaScript example, and there is also a full example application here: http://serverapps.esri.com/javascript_examples/compare_measurements.htm