I am getting strange results with distance queries in PostGIS using geography types and ST_Distance. According to the docs, ST_Distance should return the distance in metres between two geography objects. However this query, between a polygon and a point that is two degrees south of the polygon, returns a distance of 0:

SELECT ST_Distance(
    ST_GeographyFromText('POINT(0 -82)'),
    ST_GeographyFromText('POLYGON((-90 -80, 90 -80, 90 10, -90 10, -90 -80))')

I've verified that the lat/lon order for the WKT strings is as expected (lon/lat order; x/y). The polygon is a valid geometry. Both ST_Touches and ST_Intersects return false between this point and polygon geographies, which suggests to me that the distance must be greater than 0. But the result is stubbornly 0...

That is until you change the polygon to not cross the equator (no, I don't mean the antimeridian). If you change the northern edge of the polygon to be south of the equator like below, the result of the ST_Distance query is 893,493.4 metres, when it shouldn't have changed at all.

SELECT ST_Distance(
    ST_GeographyFromText('POINT(0 -82)'),
    ST_GeographyFromText('POLYGON((-90 -80, 90 -80, 90 -10, -90 -10, -90 -80))')

In either case, if I cast to geometry, I get 2 (degrees).

This really stumps me. I can consistently reproduce this result in two different environments:

  • "POSTGIS="2.2.1 r14555" GEOS="3.5.1-CAPI-1.9.1 r4246" PROJ="Rel. 4.9.2, 08 September 2015" GDAL="GDAL 2.1.2, released 2016/10/24" LIBXML="2.9.3" LIBJSON="0.11.99" RASTER"
  • POSTGIS="2.3.0 r15146" GEOS="3.5.0-CAPI-1.9.0 r4084" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.11.4, released 2016/01/25" LIBXML="2.9.1" LIBJSON="0.11" TOPOLOGY RASTER

Let's break down your polygon, segment by segment:

POLYGON((-90 -80, 90 -80, 90 10, -90 10, -90 -80))
  • -90 -80, 90 -80 : this segment goes straight over the south pole
  • 90 -80, 90 10 : this segment goes directly north to just over the equator
  • 90 10, -90 10 : this segment goes directly over the north pole
  • -90 10, -90 -80 : this segment goes directly south to the initial point

Taken all together, this polygon covers exactly one half of the earth, and that half does in fact contain your point of interest, POINT(0 -82).

You have to think spherically, not rectangularly. Blue up a balloon and work the problem on there, connecting each point to the next using the shortest distance possible.

  • That makes a whole lot of sense. Tricky to remember though, I was just thinking in terms of rectangular bounding boxes. – alphabetasoup Feb 21 '17 at 3:52

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.