I'm trying to find overlapping polygons with ST_Overlaps function. Everything works fine but there are cases when ST_Overlaps returns TRUE for adjacent polygons.


POLYGON((145053.95 167055.18,145054.85 167047.42,145058.81 167047.84,145059.07 167045.82,145059.91 167045.93,145060.01 167045.13,145062.05 167045.42,145074.27 167047.52,145061.74 167118.48,145060.33 167127.09,145034.52 167123.21,145031.66 167122.69,145032.15 167119.98,145022.81 167118.28,145028.33 167087.92,145048.3 167091.55,145049.01 167087.67,145053.95 167055.18))

POLYGON((145024.07 167111.35,145028.33 167087.92,145048.3 167091.55,145049.01 167087.67,145053.95 167055.18,145050.8 167054.73,145031.31 167067.47,145028.87 167084.01,145018.97 167082.72,145014.59 167109.69,145024.07 167111.35))

adjacent polygons with ST_Overlaps = true

I tested this polygons with ST_Intersection - result is a MULTILINESTRING.

enter image description here

But as far as I understand if ST_Overlaps returns TRUE that means ST_Intersection should return POLYGON.

So the question - is this an issue with PostGIS or I just misunderstood the way ST_Overlaps works.

PostGIS version: postgis 3.1 for docker (postgis/postgis image)

  • 3
    This may be floating point rounding/precision error; check if ST_Relate(a.geom, b.geom, '2*T***T**') is falsey. If not then you may need to ST_SnapToGrid with a tiny tolerance, or ST_QuantizeCoordinates - anything, really, to reduce precision to guaranteed 0s, which may or may not help... – geozelot Jan 10 at 19:16
  • You could use also use ST_Buffer with a very small negative radius to shrink your polygons slightly and avoid overlaps due to floating point imprecision. – amball Jan 10 at 20:43

Resolving spatial relationships between adjacent geometries which do not share exactly same vertices tends to be a bit unreliable because of inaccuracy of floating point computing. In this case the first polygon (on the right) does not have a vertex around the top-right corner of the second polygon.

enter image description here

The ST_Overlaps and ST_Intersection must create an additional virtual vertex to the first polygon.

However, the MultiLinestring geometry that PostGIS returns is odd. The real vertices of the both polygons are exactly same and I think that the lower part of the intersection geometry is any way wrong. There should be no intersection there.

The overlap segments that OpenJUMP shows make more sense even also OpenJUMP reports that the overlap geometry does not have any area.

enter image description here

There is overlap only around the virtual vertex.

By adding the "missing" vertex into the first polygon at coordinates (145024.07 167111.35) the overlap disappears.

select ST_Overlaps(
'POLYGON (( 145053.95 167055.18, 145054.85 167047.42, 145058.81 167047.84, 145059.07 167045.82, 145059.91 167045.93, 145060.01 167045.13, 145062.05 167045.42, 145074.27 167047.52, 145061.74 167118.48, 145060.33 167127.09, 145034.52 167123.21, 145031.66 167122.69, 145032.15 167119.98, 145022.81 167118.28, 145024.07 167111.35, 145028.33 167087.92, 145048.3 167091.55, 145049.01 167087.67, 145053.95 167055.18 ))'),
'POLYGON((145024.07 167111.35,145028.33 167087.92,145048.3 167091.55,145049.01 167087.67,145053.95 167055.18,145050.8 167054.73,145031.31 167067.47,145028.87 167084.01,145018.97 167082.72,145014.59 167109.69,145024.07 167111.35))')

This is a classic example revealing the (slight) inconsistency of the spatial predicates compared to the spatial overlay operations (in PostGIS, and the underlying GEOS and JTS geometry libraries). The reason for this is due to numerical precision issues with finite floating-point representation of real numbers. Because the spatial predicates return boolean values, they can be evaluated more accurately than overlay operations, which require some snapping heuristics in order to avoid robustness failures.

In cases like this where two line segments are "co-incident", but one line contains a vertex not on the other, it is almost never the case that the vertex lies exactly on the other line. In this case we can see that the vertex actually lies inside the other polygon, and hence ST_Overlaps = true. (Diagram below from the JTS TestBuilder Reveal Topology mode).

Polygon B overlaps Polygon A

However, the line segments are so close that ST_Intersection snaps them together, to ensure numerical robustness, and thus produces a linear result.

It sounds like from your use case that you should trust the ST_Overlaps result to correctly report overlapping polygons.

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.