Opened 7 weeks ago

Closed 5 weeks ago

#5788 closed defect (fixed)

ERROR: XX000: GEOSIntersects: TopologyException: side location conflict at

Reported by: Lars Aksel Opsahl Owned by: pramsey
Priority: medium Milestone: PostGIS GEOS
Component: postgis Version: 3.4.x
Keywords: Cc:

Description

On

POSTGIS="3.4.2 c19ce56" [EXTENSION] PGSQL="160" GEOS="3.12.1-CAPI-1.18.1" (compiled against GEOS 3.10.2) SFCGAL="SFCGAL 1.4.1, CGAL 5.3.1, BOOST 1.74.0" PROJ="8.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/proj.db" GDAL="GDAL 3.4.1, released 2021/12/27" LIBXML="2.9.13" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY RASTER

When uploading files and run this below sql

SELECT ST_area(ST_Union(ST_Intersection(mt.geo,f.geo)),true)
          FROM
          free_area_geo_before_must_overlap f,
          must_overlap_area_used_list_soknad_and_tiltak mt
          WHERE mt.geo && f.geo AND ST_Intersects(mt.geo,f.geo)
          AND ST_IsValid(mt.geo) AND ST_IsValid(f.geo);


I get this error

ERROR:  XX000: GEOSIntersects: TopologyException: side location conflict at 5.993730927467122 59.273001457529752. This can occur if the input geometry is invalid.
LOCATION:  pg_error, lwgeom_pg.c:332

With a the new SQL below it works where I use st_dump it works

SELECT ST_area(ST_Union(ST_Intersection(mt.geo,f.geo)),true)
          FROM
          (SELECT (ST_Dump(ff.geo)).geom geo FROM free_area_geo_before_must_overlap ff) f,
          (SELECT (ST_Dump(mt1.geo)).geom geo FROM must_overlap_area_used_list_soknad_and_tiltak mt1) mt
          WHERE mt.geo && f.geo AND ST_Intersects(mt.geo,f.geo)
          AND ST_IsValid(mt.geo) AND ST_IsValid(f.geo);
     st_area     
-----------------
 0.1568622817327
(1 row)

And the sql below also works but gives a different result as you see

SELECT ST_area(ST_Union(ST_Intersection(mt.geo,f.geo)),true)
          FROM
          free_area_geo_before_must_overlap f,
          (SELECT ST_collect(mt1.geo) geo FROM must_overlap_area_used_list_soknad_and_tiltak mt1) mt
          WHERE mt.geo && f.geo AND ST_Intersects(mt.geo,f.geo)
          AND ST_IsValid(mt.geo) AND ST_IsValid(f.geo);
 st_area 
---------
       0
(1 row)

On latest postgis all 3 sql's works but they give different result

POSTGIS="3.6.0dev 3.5.0-13-g290fffd11" [EXTENSION] PGSQL="160" GEOS="3.13.0beta2-CAPI-1.19.0" PROJ="9.3.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ 9.13.0) LIBXML="2.9.13" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY

As you see here

           SELECT ST_area(ST_Union(ST_Intersection(mt.geo,f.geo)),true)
          FROM
          free_area_geo_before_must_overlap f,
          must_overlap_area_used_list_soknad_and_tiltak mt
          WHERE mt.geo && f.geo AND ST_Intersects(mt.geo,f.geo)
          AND ST_IsValid(mt.geo) AND ST_IsValid(f.geo);
          
          SELECT ST_area(ST_Union(ST_Intersection(mt.geo,f.geo)),true)
          FROM
          (SELECT (ST_Dump(ff.geo)).geom geo FROM free_area_geo_before_must_overlap ff) f,
          (SELECT (ST_Dump(mt1.geo)).geom geo FROM must_overlap_area_used_list_soknad_and_tiltak mt1) mt
          WHERE mt.geo && f.geo AND ST_Intersects(mt.geo,f.geo)
          AND ST_IsValid(mt.geo) AND ST_IsValid(f.geo);
                    
                    
          SELECT ST_area(ST_Union(ST_Intersection(mt.geo,f.geo)),true)
          FROM
          free_area_geo_before_must_overlap f,
          (SELECT ST_collect(mt1.geo) geo FROM must_overlap_area_used_list_soknad_and_tiltak mt1) mt
          WHERE mt.geo && f.geo AND ST_Intersects(mt.geo,f.geo)
          AND ST_IsValid(mt.geo) AND ST_IsValid(f.geo);
       st_area       
---------------------
 0.12751095705231963
(1 row)

      st_area       
--------------------
 0.1569281251764355
(1 row)

 st_area 
---------
       0

Attachments (2)

free_area_geo_before_must_overlap.sql (68.1 KB ) - added by Lars Aksel Opsahl 7 weeks ago.
Table free_area_geo_before_must_overlap
must_overlap_area_used_list_soknad_and_tiltak.sql (41.7 KB ) - added by Lars Aksel Opsahl 7 weeks ago.
Table must_overlap_area_used_list_soknad_and_tiltak

Download all attachments as: .zip

Change History (7)

by Lars Aksel Opsahl, 7 weeks ago

Table free_area_geo_before_must_overlap

by Lars Aksel Opsahl, 7 weeks ago

Table must_overlap_area_used_list_soknad_and_tiltak

comment:1 by mdavis, 7 weeks ago

The reason ST_Intersects works with the latest PostGIS but not with the older version is that GEOS 3.13 uses the new RelateNG algorithm, which handles GeometryCollections correctly.

The difference in computed areas is caused by slight differences in the resultant geometries computed by ST_Intersection. The results of the pairwise intersections produce some narrow sliver polygons (which have some small area), whereas the full-geometry intersection produces only a LineString result (with zero area, of course).

I suspect the reason for the difference in intersection results is that the full intersection triggers some snapping due to robustness handling, whereas the pairwise ones don't in all cases. Note that the geometry in the free_area_geo_before_must_overlap table contains numerous very narrow slivers, in addition to some larger polygon elements. This kind of situation is likely to require internal snapping.

Also note that the computed area (0.1569281251764355) is much smaller than the area of the free_area_geo_before_must_overlap input (25159.949244602714). So, it's effectively zero, just like the snapped result.

This is yet another lesson about working with double-precision geometry - geometric operations are not precise, and not commutative. Different sequences of geometric operations on identical inputs may not produce exactly identical results, due to internal rounding. Workflows need to incorporate some error tolerances to allow for this. (This is exactly analogous to the situation when doing sequences of numerical operations on floating-point numbers. Exact answers cannot be expected.)

in reply to:  1 comment:2 by Lars Aksel Opsahl, 7 weeks ago

Replying to mdavis:

The reason ST_Intersects works with the latest PostGIS but not with the older version is that GEOS 3.13 uses the new RelateNG algorithm, which handles GeometryCollections correctly.

Thank's for the info.

Is it a problem to upgrade geos only to 3.13 and keep postgis on 3.4 ?

comment:3 by strk, 7 weeks ago

Upgrading GEOS is never a problem for already built PostGIS

comment:4 by robe, 5 weeks ago

Shouldn't this ticket be moved to GEOS and closed as it's already fixed in GEOS? or do we plan to do something about this in PostGIS?

comment:5 by mdavis, 5 weeks ago

Milestone: PostGIS 3.4.4PostGIS GEOS
Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.