# Find a suitable distance function with PostGIS

I want to reach the nearest neighbour's problem and want to understand the projections. My data is stored as "geometry 4326" thus degrees. I "almost" rewrote this query to evaluate what is the distance in meters of 1 deg long at the equator compared to 1 deg long at the latitude of 80 deg. The result should be the same in degrees, ok, 1, but not when I transform to meters. In both cases, the output is 111,3 km, obviously wrong, but what is wrong?

``````SELECT ST_Distance(
ST_Transform('SRID=4326;POINT(-1 80)'::geometry,3857),
ST_Transform('SRID=4326;LINESTRING(0 0, 0 80)'::geometry, 3857)
);

SELECT ST_Distance(
ST_Transform('SRID=4326;POINT(-1 0)'::geometry,3857),
ST_Transform('SRID=4326;LINESTRING(0 0, 0 80)'::geometry, 3857)
);
``````
``````    st_distance
--------------------
111319.49079327357
``````
• Web Mercator isn't accurate for distance calculation anywhere, much less at 80N. It should not be used for this purpose. Sep 20, 2022 at 15:48
• ok, maybe was extreme, so which conversion should I use instead? I need [-50,50] in latitude.
– NevD
Sep 20, 2022 at 15:49
• Could you try to edit the title of your question to describe better what was your problem? I think that PostGIS did the coordinate transformation as it should. Sep 20, 2022 at 18:23
• I changed, hope this is more clear. Maybe the 3857 should also be renamed cylindrical projection, more clear too.
– NevD
Sep 20, 2022 at 19:57
• Sep 20, 2022 at 20:01

It doesn't work because `3857` highly distorts ground distances as you move away from the equator. In fact, you just illustrated that using this projection the ground length of a degree of longitude is constant at both latitudes, which is obviously wrong.

To get a meaningful distance, you can either use a suitable local projection such as UTM or use `st_distanceSphere` or use `st_distance` on `geography`. In both case the great circle is used, not a straight line.

`````` SELECT ST_DistanceSphere(
'SRID=4326;POINT(-1 80)'::geometry,
'SRID=4326;LINESTRING(0 0, 0 80)'::geometry);
st_distancesphere
-------------------
19308.58527687

SELECT ST_Distance(
'SRID=4326;POINT(-1 80)'::geography,
'SRID=4326;LINESTRING(0 0, 0 80)'::geography,
true);
st_distance
----------------
19393.24680139
``````