[postgis-users] st_intersects and st_disjoint inconsistent results

Emily Gouge egouge at refractions.net
Thu Feb 10 16:55:58 PST 2022


I have a linear dataset on which I was building a query to find edges 
that are “very close” but don’t touch. While working on this query I 
found some unexpected results with the st_intersects and st_disjoint 
functions. As outlined below, the query returned true for both 
st_instersects and st_disjoint for a few geometries comparisons, but 
ONLY when a where clause was used to filter the geometries spatially. 
When unique identifiers were used to filter geometries only st_disjoint 
returns true.

Versions:
Except where noted otherwise the results below reference testing on 
these versions:
POSTGIS="3.2.0 3.2.0" [EXTENSION] PGSQL="140" GEOS="3.10.1-CAPI-1.16.0" 
PROJ="7.2.1" LIBXML="2.9.9" LIBJSON="0.12" LIBPROTOBUF="1.2.1" 
WAGYU="0.5.0 (Internal)"
PostgreSQL 14.1, compiled by Visual C++ build 1914, 64-bit

When I run this query:
select a.id, b.id,
st_intersects(a.geometry, b.geometry),
st_intersects(b.geometry, a.geometry),
st_disjoint(a.geometry, b.geometry),
st_disjoint(b.geometry, a.geometry)
from test.eflowpath a, test.eflowpath b
where a.id != b.id
and st_dwithin(a.geometry, b.geometry, 0.00001)
and st_disjoint(a.geometry, b.geometry);

PostGIS 3.2: 50 rows were returned, but there are three rows that return 
true for both st_disjoint and st_intersects. Given the query this in 
itself is a bit odd as you'd expect reciprocal results for the pairs of 
the geometry (so at least 4 rows).
-------
889105be-5782-43f1-b50c-5a5825c83875
e5703673-a995-472e-b4b4-0280143eba0c
true
true
true
true
-------
0d05aabb-9ff3-4d8f-b6c7-b2b44b0868c8
3a09b2af-5932-4e36-9e3e-d8109e5463fa
true
true
true
true
-------
3a09b2af-5932-4e36-9e3e-d8109e5463fa
0d05aabb-9ff3-4d8f-b6c7-b2b44b0868c8
true
true
true
true
-------
...

Note: In PostGIS 3.1.2 50 rows were returned by only two rows returned 
true for both disjoint and intersects.

HOWEVER,
When I compare one pair of those edges specifically using the ids they 
are only disjoint (which is the result I would expect to see)

select a.id, b.id,
st_intersects(a.geometry, b.geometry),
st_intersects(b.geometry, a.geometry),
st_disjoint(a.geometry, b.geometry),
st_disjoint(b.geometry, a.geometry)
from test.eflowpath a, test.eflowpath b
where b.id = '889105be-5782-43f1-b50c-5a5825c83875' and a.id = 
'e5703673-a995-472e-b4b4-0280143eba0c'

Results:
-------
e5703673-a995-472e-b4b4-0280143eba0c
889105be-5782-43f1-b50c-5a5825c83875
false
false
true
true
-------

I thought perhaps this had something to do with the indexes so I removed 
all geometry indexes from the table and re-ran the initial query. In 
postgis 3.2 this returned the same results as the indexed query.
Note: In PostGIS 3.1.2 this also returned three rows with intersects and 
disjoint true. As noted above with indexes in 3.1.2 only 2 rows were 
returned where intersects and disjoint were true.

Similar results occurred if st_dwithin from the where statement was 
increased to 0.01.

Test Data: When I made a table with only the edges in question all 
queries returned expected results: st_intersects is false and 
st_disjoint is true. As a result providing a small test case for this 
issue doesn’t seem possible. But I am happy to provide all the data - 
there are 27,444 rows.

While this isn’t a problem for me, I find it unexpected that the results 
from st_intersects and st_disjoint of two geometries would be different 
based on the where clause in the query (and the data in the table).

Thoughts?

Thanks,
Emily


More information about the postgis-users mailing list