Opened 11 years ago

Last modified 6 years ago

#668 reopened enhancement

Inconsistent ST_Intersection and ST_Intersects results

Reported by: sdebionne Owned by: geos-devel@…
Priority: minor Milestone: GEOS Fund Me
Component: Core Version: 3.4.2
Severity: Feature Request Keywords: ST_Intersects
Cc: pepijnve

Description

When intersecting two linestrings l1 and l2 with ST_Intersection resulting in an intersection point p, the expected results of ST_Intersects(l1, p) or ST_Intersects(l2, p) is TRUE.

The following test cases shows that it's hardly the case.

First a working test case

In this (very simple) case we effectively get a reasonable result; both segments do intersect at Point(5,5) as expected, and this point intersects both segments.

SELECT ST_AsText(p), ST_Intersects(p, l1), ST_Intersects(p, l2), 
CASE WHEN ST_Distance(p, l1) = 0.0 THEN 'dist1 is ZERO' 
     WHEN ST_Distance(p, l1) <> 0.0 THEN 'dist1 is not ZERO' END, 
CASE WHEN ST_Distance(p, l2) = 0.0 THEN 'dist2 is ZERO' 
     WHEN ST_Distance(p, l2) <> 0.0 THEN 'dist2 is not ZERO' END 
FROM (SELECT *, ST_Intersection(l1, l2) as p  FROM 
     (SELECT ST_LineStringFromText('LINESTRING(0 10, 10.00000 0)') AS l1), 
     (SELECT ST_LineStringFromText('LINESTRING(0 0, 10.00000 10)') AS l2));

A broken test case

One extreme point is shifted by a very small amount. Now the intersection Point(5.000002 5.000002) is reported to intersect only one segment and we have an unexpected distance (an incredibly small one, of course) separating this point and the other segment.

SELECT ST_AsText(p), 
ST_Intersects(p, l1), ST_Intersects(p, l2), 
CASE WHEN ST_Distance(p, l1) = 0.0 THEN 'dist1 is ZERO' 
      WHEN ST_Distance(p, l1) <> 0.0 THEN 'dist1 is not ZERO' END, 
CASE WHEN ST_Distance(p, l2) = 0.0 THEN 'dist2 is ZERO' 
      WHEN ST_Distance(p, l2) <> 0.0 THEN 'dist2 is not ZERO' END 
FROM (SELECT *, ST_Intersection(l1, l2) as p  FROM 
     (SELECT ST_LineStringFromText('LINESTRING(0 10, 10.00001 0)') AS l1), 
     (SELECT ST_LineStringFromText('LINESTRING(0 0, 10.00000 10)') AS l2));

An other broken test case

Just a further slight shift factor applied to another end-point; and this time we still continue to get back an intersection Point(5.000007 4.999998), this Point doesn't overlaps at all none of the two segments due to some ultra-minimal distance.

SELECT ST_AsText(p), 
ST_Intersects(p, l1), ST_Intersects(p, l2), 
CASE WHEN ST_Distance(p, l1) = 0.0 THEN 'dist1 is ZERO' 
      WHEN ST_Distance(p, l1) <> 0.0 THEN 'dist1 is not ZERO' END, 
CASE WHEN ST_Distance(p, l2) = 0.0 THEN 'dist2 is ZERO' 
      WHEN ST_Distance(p, l2) <> 0.0 THEN 'dist2 is not ZERO' END 
FROM (SELECT *, ST_Intersection(l1, l2) as p  FROM 
     (SELECT ST_LineStringFromText('LINESTRING(0 10, 10.00001 0)') AS l1), 
     (SELECT ST_LineStringFromText('LINESTRING(0 0, 10.00002 10)') AS l2));

This is probably a rounding/precision issue.

See this thread on spatialite users mailing list for more info : https://groups.google.com/forum/#!topic/spatialite-users/jlxEL6x0tZs

Change History (5)

comment:1 by pepijnve, 11 years ago

Cc: pepijnve added

comment:2 by strk, 11 years ago

Resolution: invalid
Status: newclosed

This is a known design limitation. ST_Intersects is exact, but constructive operation cannot be due to lack of infinite precision.

comment:3 by sdebionne, 11 years ago

Allright but, by marking the issue invalid, shall we understand that there is no plan to solve these precision issues (say with arbitrary precision or homogeneous coordinates) even in the long term ?

comment:4 by strk, 11 years ago

Component: DefaultCore
Milestone: 3.4.3GEOS Future
Priority: majorminor
Resolution: invalid
Severity: UnassignedFeature Request
Status: closedreopened
Type: defectenhancement

There's currently no plan. There could be one in the future. I'm reopening and tagging as "Feature Request", with no milestone.

comment:5 by robe, 6 years ago

Milestone: GEOS FutureGEOS Fund Me

Milestone renamed

Note: See TracTickets for help on using tickets.