5

I'm developing a project using LeafleatJS and PostGIS. Currently I'm getting trouble while calculating distance between two coordinates. For example:

Point 1 - lat: -12.99835864475412, lng: -38.506194949150085

Point 2 - lat: -12.999215865191118, lng: -38.50590527057648

Leaflet calculates 99.906 m, while using the following SQL in PostGIS:

SELECT ST_Distance_Sphere(
ST_GeomFromText('POINT(-12.99835864475412 -38.506194949150085)', 4326),
ST_GeomFromText('POINT(-12.999215865191118 -38.50590527057648)', 4326));

I get 81.248 m.

Leafleat uses Haversine distance formula to calculate distance and I'm using its default CRS - EPSG3857 - while on PostGIS I'm storing data as a Geographic Point with SRID 4326.

I know, it seems confusing but I'm following the answer given on this link:

All of this further confused by that fact that often even though the map is in Web Mercator(EPSG: 3857), the actual coordinates used are in lat-long (EPSG: 4326). This convention is used in many places, such as:

  • In Most Mapping API,s You can give the coordinates in Lat-long, and the API automatically transforms it to the appropriate Web Mercator coordinates.

I'm new on GIS so... why there's a difference between the results (I know they use different formulas to calculate, but almost 20m difference is pretty considerable)? Am I storing and retrieving data in the wrong way? Which one is the most accurate (Leafleat or PostGIS)?

  • What's the result if you use PostGIS geographies instead? – IvanSanchez May 24 '16 at 13:11
  • 81.392m using geographies – M. Barreto May 24 '16 at 13:53
2

You have most probably inverted the Lat and Lng values in either Leaflet or PostGIS.

Let's have:

  • Point1: Lat: -12.99835864475412 / Lng: -38.506194949150085
  • Point2: Lat: -12.999215865191118 / Lng: -38.50590527057648
  • Point3: Lat: -38.506194949150085 / Lng: -12.99835864475412 (inverted from Point1)
  • Point4: Lat: -38.50590527057648 / Lng: -12.999215865191118 (inverted from Point2)

Then in Leaflet:

  • Point1.distanceTo(Point2) gives 100.3527621446386 m
  • Point3.distanceTo(Point4) gives 81.24853213830093 m

Live computation: http://jsfiddle.net/ve2huzxw/232/

Note that Leaflet API uses [Lat, Lng], whereas some other software and standards use [Lng, Lat] (e.g. GeoJSON).

  • 1
    Indeed - PostGIS uses Well-Known Text (WKT) format in ST_GeomFromText, which is x-y, which is lng-lat. See also macwright.org/lonlat. – IvanSanchez May 25 '16 at 8:20
  • Thank you, that was exactly what was happening, I inverted the values on my application and everything is fine now. – M. Barreto May 25 '16 at 12:38
2

The reason the Haversine equation is used for the 4326 calculation is that this is a geographic coordinate system. That means that the coordinates are still on a sphere, they are not mathematically transformed to a flat surface. A projected coordinate system would have this equation or some similar construct already "built-in", so to speak.

The Web Mercator (3857), on the other hand, is a projected coordinate system. It is, however, a cylindrical projection, which favors the accuracy of bearings over distances and areas. This is not an ideal (to put it mildly) projection when it comes to measuring distances. The Web mercator projection was essentially designed to make dealing with cached map tiles, which are square, easy.

This ESRI article covers this topic very well, and it has some suggestions on how to deal with the issue. It boils down to choosing a better coordinate system just for the measuring tasks, if it is not possible to use a different one alltogether (which is the case with web mapping, typically). From the article:

This begs the question, which coordinate system should you use for the measurement? There is no answer that fits every application. You should make your decision based on the general area covered by your application. If your application covers a small area, such as a city, county, or perhaps even a state or province, you can use a local coordinate system such as State Plane or UTM. As mentioned before, these are designed to minimize distortion for just the regions or zones that they cover. For example, UTM Zone 1 minimizes distortion between -180 and -174 degrees longitude.

0

Haversine distance formula calculates on a sphere, which is going to be a closer calculation than a straight line distance calculation that does not take into consideration the curvature of the Earth.

This Math SE Q&A may give you some additional insight. From link:

The Haversine formula gives the "as-the-crow-flies" distance, i.e., the great circle distance along the surface of the earth. If you take the Euclidean distance between two points in R3R3, you are finding the straight-line distance, which will cut through the earth. That being said, if the points are close together, the results should be very similar: the discrepancy in your case is due to another mistake you made, which is ignoring the zz-coordinate in the Euclidean calculation. The zz-coordinate doesn't correspond to the altitude; it's the altitude at the North Pole, but at the equator it's the north-south direction. Using

x=Rcos⁡θcos⁡ϕ

y=Rcos⁡θsin⁡ϕ

z=Rsin⁡θ

you find

(xA,yA,zA)(xB,yB,zB)==(4599.39264,1279.66103,4218.73156)(4599.33435,1279.57441,4218.82138);

(xA,yA,zA)=(4599.39264,1279.66103,4218.73156)(xB,yB,zB)=(4599.33435,1279.57441,4218.82138);

and the Euclidean distance between them is indeed 137.7137.7m.

To make things even more complex--I don't believe either of these take into account terrain features and the actual distances uphill and downhill, which will add some distance to your results as well ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.