<div dir="ltr">It seems to be predicate robustness failure week!  The geometries in this recent post show the same problem (in JTS, and probably GEOS too).<div><br></div><div><a href="https://lists.osgeo.org/pipermail/postgis-users/2022-February/045255.html">https://lists.osgeo.org/pipermail/postgis-users/2022-February/045255.html</a><br></div><br>A: LINESTRING (-29796.696826656284 138522.76848210802, -29804.3911369969 138519.3504205817)<br>B: LINESTRING (-29802.795222153436 138520.05937757515, -29802.23305474065 138518.7938969792)<div><br></div><div>A.disjoint(B) = TRUE</div><div>A.preparedIntersects(B) = TRUE</div><div><br></div><div>(Note: the post issue is slightly different - it just happens that the data shows this problem)</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Feb 11, 2022 at 2:19 PM Paul Ramsey <<a href="mailto:pramsey@cleverelephant.ca">pramsey@cleverelephant.ca</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This issue has been confirmed on both GEOS and JTS. You have magic geometry that breaks the consistency between prepared and standard results.<br>
<br>
<a href="https://github.com/libgeos/geos/pull/566" rel="noreferrer" target="_blank">https://github.com/libgeos/geos/pull/566</a><br>
<br>
P.<br>
<br>
> On Feb 10, 2022, at 6:43 PM, Emily Gouge <<a href="mailto:egouge@refractions.net" target="_blank">egouge@refractions.net</a>> wrote:<br>
> <br>
> Here you go.  Thanks!<br>
> <br>
> <br>
> SELECT ST_AsHEXEWKB (geometry) FROM test.eflowpath WHERE id = '889105be-5782-43f1-b50c-5a5825c83875'<br>
> <br>
> 01020000200912000007000000642F25DC75A24CC0E4DE5740FCB34840A7CEFE9B72A24CC09DA85B2CFBB34840B5519D0E64A24CC091FAA188FBB34840FA449E245DA24CC054C2137AFDB34840F4ACFFCE51A24CC09FEB562A03B448405328C1D144A24CC09A3DD00A0CB44840404C10C03CA24CC0EA07FE6910B44840<br>
> <br>
> SELECT ST_AsHEXEWKB (geometry) FROM test.eflowpath WHERE id = 'e5703673-a995-472e-b4b4-0280143eba0c'<br>
> <br>
> 0102000020091200000E00000004BE47A23CA24CC098A1F14410B448409871AEBC3FA24CC078341F2114B448400858AB764DA24CC09D0546031DB448406BFD3E2D50A24CC0BEDDEDD522B4484004824AA654A24CC02DC9A60128B44840EE377FB850A24CC0FA18BD642DB44840CCAF8B474EA24CC02CCCE78134B44840D7158E7B4EA24CC01D7C17A53AB44840ACFA01B452A24CC02688BA0F40B44840DB508C8752A24CC006CDF80846B44840A1F31ABB44A24CC0C891730756B44840009AF7EE45A24CC06B7649415CB448408C2ECAC749A24CC0CE57248161B44840A74302A150A24CC07DD00E1368B44840<br>
> <br>
> On 2022-02-10 5:57 p.m., Paul Ramsey wrote:<br>
>>> On Feb 10, 2022, at 4:55 PM, Emily Gouge <<a href="mailto:egouge@refractions.net" target="_blank">egouge@refractions.net</a>> wrote:<br>
>>> <br>
>>> 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.<br>
>>> <br>
>>> Versions:<br>
>>> Except where noted otherwise the results below reference testing on these versions:<br>
>>> 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)"<br>
>>> PostgreSQL 14.1, compiled by Visual C++ build 1914, 64-bit<br>
>>> <br>
>>> When I run this query:<br>
>>> select <a href="http://a.id" rel="noreferrer" target="_blank">a.id</a>, <a href="http://b.id" rel="noreferrer" target="_blank">b.id</a>,<br>
>>> st_intersects(a.geometry, b.geometry),<br>
>>> st_intersects(b.geometry, a.geometry),<br>
>>> st_disjoint(a.geometry, b.geometry),<br>
>>> st_disjoint(b.geometry, a.geometry)<br>
>>> from test.eflowpath a, test.eflowpath b<br>
>>> where <a href="http://a.id" rel="noreferrer" target="_blank">a.id</a> != <a href="http://b.id" rel="noreferrer" target="_blank">b.id</a><br>
>>> and st_dwithin(a.geometry, b.geometry, 0.00001)<br>
>>> and st_disjoint(a.geometry, b.geometry);<br>
>>> <br>
>>> 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).<br>
>>> -------<br>
>>> 889105be-5782-43f1-b50c-5a5825c83875<br>
>>> e5703673-a995-472e-b4b4-0280143eba0c<br>
>>> true<br>
>>> true<br>
>>> true<br>
>>> true<br>
>>> -------<br>
>>> 0d05aabb-9ff3-4d8f-b6c7-b2b44b0868c8<br>
>>> 3a09b2af-5932-4e36-9e3e-d8109e5463fa<br>
>>> true<br>
>>> true<br>
>>> true<br>
>>> true<br>
>>> -------<br>
>>> 3a09b2af-5932-4e36-9e3e-d8109e5463fa<br>
>>> 0d05aabb-9ff3-4d8f-b6c7-b2b44b0868c8<br>
>>> true<br>
>>> true<br>
>>> true<br>
>>> true<br>
>>> -------<br>
>>> ...<br>
>>> <br>
>>> Note: In PostGIS 3.1.2 50 rows were returned by only two rows returned true for both disjoint and intersects.<br>
>>> <br>
>>> HOWEVER,<br>
>>> 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)<br>
>>> <br>
>>> select <a href="http://a.id" rel="noreferrer" target="_blank">a.id</a>, <a href="http://b.id" rel="noreferrer" target="_blank">b.id</a>,<br>
>>> st_intersects(a.geometry, b.geometry),<br>
>>> st_intersects(b.geometry, a.geometry),<br>
>>> st_disjoint(a.geometry, b.geometry),<br>
>>> st_disjoint(b.geometry, a.geometry)<br>
>>> from test.eflowpath a, test.eflowpath b<br>
>>> where <a href="http://b.id" rel="noreferrer" target="_blank">b.id</a> = '889105be-5782-43f1-b50c-5a5825c83875' and <a href="http://a.id" rel="noreferrer" target="_blank">a.id</a> = 'e5703673-a995-472e-b4b4-0280143eba0c'<br>
>>> <br>
>>> Results:<br>
>>> -------<br>
>>> e5703673-a995-472e-b4b4-0280143eba0c<br>
>>> 889105be-5782-43f1-b50c-5a5825c83875<br>
>>> false<br>
>>> false<br>
>>> true<br>
>>> true<br>
>>> -------<br>
>>> <br>
>>> 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.<br>
>>> 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.<br>
>>> <br>
>>> Similar results occurred if st_dwithin from the where statement was increased to 0.01.<br>
>>> <br>
>>> 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.<br>
>>> <br>
>>> 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).<br>
>>> <br>
>>> Thoughts?<br>
>> The fact that a single test case returns one result, but results in a larger set returns another says to me that likely the issue in different code lines because of different cache behaviour. When you do the single test case you get a brute force intersects. When you do several in a batch, you get prepared geometry (at least, for the cases that happen after caching).<br>
>> If you can provide the HEXWKB of the two geometries that showed disagreement (where <a href="http://b.id" rel="noreferrer" target="_blank">b.id</a> = '889105be-5782-43f1-b50c-5a5825c83875' and <a href="http://a.id" rel="noreferrer" target="_blank">a.id</a> = 'e5703673-a995-472e-b4b4-0280143eba0c') we can set up a test case in GEOS that compares the normal and prepared geometry calls and see if that's the problem.<br>
>> P.<br>
>>> <br>
>>> Thanks,<br>
>>> Emily<br>
>>> _______________________________________________<br>
>>> postgis-users mailing list<br>
>>> <a href="mailto:postgis-users@lists.osgeo.org" target="_blank">postgis-users@lists.osgeo.org</a><br>
>>> <a href="https://lists.osgeo.org/mailman/listinfo/postgis-users" rel="noreferrer" target="_blank">https://lists.osgeo.org/mailman/listinfo/postgis-users</a><br>
>> _______________________________________________<br>
>> postgis-users mailing list<br>
>> <a href="mailto:postgis-users@lists.osgeo.org" target="_blank">postgis-users@lists.osgeo.org</a><br>
>> <a href="https://lists.osgeo.org/mailman/listinfo/postgis-users" rel="noreferrer" target="_blank">https://lists.osgeo.org/mailman/listinfo/postgis-users</a><br>
> _______________________________________________<br>
> postgis-users mailing list<br>
> <a href="mailto:postgis-users@lists.osgeo.org" target="_blank">postgis-users@lists.osgeo.org</a><br>
> <a href="https://lists.osgeo.org/mailman/listinfo/postgis-users" rel="noreferrer" target="_blank">https://lists.osgeo.org/mailman/listinfo/postgis-users</a><br>
<br>
_______________________________________________<br>
postgis-users mailing list<br>
<a href="mailto:postgis-users@lists.osgeo.org" target="_blank">postgis-users@lists.osgeo.org</a><br>
<a href="https://lists.osgeo.org/mailman/listinfo/postgis-users" rel="noreferrer" target="_blank">https://lists.osgeo.org/mailman/listinfo/postgis-users</a><br>
</blockquote></div>