Opened 12 years ago
Last modified 7 months ago
#2038 assigned defect
Exception of topogeo_AddLineString() of a line string with a part colinear with an existing one.
Reported by: | wimned | Owned by: | strk |
---|---|---|---|
Priority: | medium | Milestone: | PostGIS Fund Me |
Component: | topology | Version: | master |
Keywords: | robustness | Cc: |
Description
version: POSTGIS="2.1.0SVN r10365" GEOS="3.3.4-CAPI-1.7.3" PROJ="Rel. 4.7.1, 23 September 2009" LIBXML="2.7.8" TOPOLOGY
the message:
ERROR: SQL/MM Spatial exception - geometry crosses edge 2 CONTEXT: PL/pgSQL function "topogeo_addlinestring" line 124 at assignment SQL statement "SELECT topogeo_AddLineString('wimpy', line1)
The code:
CREATE OR REPLACE FUNCTION test_AddLineString2() returns void as $$ declare line0 geometry; declare line1 geometry; BEGIN raise notice 'version: %', postgis_full_version(); perform CreateTopology('wimpy', 4326); line0 = ST_GeometryFromText( 'LINESTRING( 72.91981 20.95009,72.91082 20.95759)',4326); line1 = ST_GeometryFromText( 'LINESTRING(72.9123215921439 20.9563372813038,72.9122229474764 20.9564195766326, 72.9130010661966 20.9562352183313,72.9123215921439 20.9563372813038)', 4326); perform topogeo_AddLineString('wimpy', line0); perform topogeo_AddLineString('wimpy', line1); END $$ LANGUAGE plpgsql;
Attachments (1)
Change History (26)
comment:1 by , 12 years ago
Milestone: | PostGIS 2.1.0 → PostGIS 2.0.2 |
---|---|
Status: | new → assigned |
comment:2 by , 12 years ago
Well, my attempt at quoting the image attach syntax clearly didn't work, but you can use the Mona Lisa icon :)
by , 12 years ago
Attachment: | colinearity_exception.jpg added |
---|
comment:3 by , 12 years ago
comment:4 by , 12 years ago
Yeah QGis is very unhelpful with these kind of problems. See http://hub.qgis.org/issues/1337 -- would be nice to see that fixed. How did you produce the above image ?
It would be helpful to know which line is the first linestring and which one is the second, and which edges get which identifiers...
comment:5 by , 12 years ago
Simplest testcase, to put in regression testsuite:
SELECT CreateTopology('t2038'); SELECT TopoGeo_addLineString('t2038', 'LINESTRING( 72.91981 20.95009,72.91082 20.95759)'); SELECT TopoGeo_addLineString('t2038', 'LINESTRING(72.9123215921439 20.9563372813038,72.9122229474764 20.9564195766326, 72.9130010661966 20.9562352183313,72.9123215921439 20.9563372813038)');
There's a single edge and two nodes after first addition, so edge2 comes out from splitting the second line, which is simple in itself.
comment:6 by , 12 years ago
The two lines are DISJOINT, according to ST_Relate. When it comes to adding the first point of the new line, the code computes its own tolerance based on what's the minimum drift representable with floating points at point ordinate distance from origin. In this case the number comes out as ~ 2e-13:
DEBUG: Tolerance for snapping to point POINT(72.9123215921439 20.9563372813038) = 2.62484357731718e-13
This will basically split the first edge. You can obtain the same result by running:
SELECT TopoGeo_addPoint('t2038', ST_StartPoint('LINESTRING(72.9123215921439 20.9563372813038,72.9122229474764 20.9564195766326, 72.9130010661966 20.9562352183313,72.9123215921439 20.9563372813038)'));
BUT if you do, then adding the linestring _will_work_ ! So I guess this is about a missing re-snap after the splitting
comment:7 by , 12 years ago
Another interesting number is the distance between the two lines, according to ST_Distance:
3.5527136788005e-15
Which is two orders of magnitude smaller than the computed tolerance, btw, proving the tolerance computer badly wrong...
comment:8 by , 12 years ago
So to recap:
1: the first geometry creates the straight edge on the left 2: the second geometry is DISJOINT from the first, but its starting node (the bottom one on the left) is found to be within the min tolerance from the first edge, thus splitting it 3: the upper portion of former first edge, as split by the new node, results as having an interior-interior intersection with the second geometry
I guess we could re-iterate over AddLineString after the split. Would be a recursive call, until there's no more edge splitting...
comment:9 by , 12 years ago
I confirm that a recursion would fix, as shown by the TopoGeo_addPoint(ST_StartPoint()) trick shown above.
comment:10 by , 12 years ago
More possibly interesting numbers about the outcome of ST_ClosestPoint
NOTICE: ClosestPoint is at distance 3.5527136788005e-15 from line and 2.86428933843956e-14 from point (which is at distance 2.86428933843956e-14 from the line)
comment:11 by , 12 years ago
Seems like a rare situation. I can make a list of patch points. When they match the input I'll do a topogeo_AddPoint before adding linestrings, until this is repaired.
comment:12 by , 12 years ago
Yes, the suggested workaround could work.
This case falls in the general problem of adding a node to edge without moving the edge.
It's clearly impossible NOT to move the edge, due to the finite nature of the numbers being used to represent points. But it should theoretically be possible to ensure that such a drift never introduces further intersections. Only pretty hard to do in practice (and we know topology building is already being very slow..)
comment:13 by , 12 years ago
Since we're at it, the test with one vertex removed (so we have 5 vertices in total). Can still reproduce the issue:
SELECT CreateTopology('t2038'); SELECT TopoGeo_addLineString('t2038', 'LINESTRING( 72.91981 20.95009,72.91082 20.95759)'); SELECT TopoGeo_addLineString('t2038', 'LINESTRING(72.9123215921439 20.9563372813038,72.9122229474764 20.9564195766326, 72.9130010661966 20.9562352183313)');
comment:14 by , 12 years ago
Milestone: | PostGIS 2.0.2 → PostGIS 2.0.3 |
---|
comment:15 by , 11 years ago
Milestone: | PostGIS 2.0.4 → PostGIS 2.0.5 |
---|
comment:16 by , 11 years ago
Milestone: | PostGIS 2.0.5 → PostGIS 2.0.6 |
---|
comment:17 by , 9 years ago
Milestone: | PostGIS 2.0.7 → PostGIS 2.0.8 |
---|
comment:18 by , 7 years ago
Milestone: | PostGIS 2.0.8 → PostGIS 2.2.6 |
---|
comment:19 by , 7 years ago
Milestone: | PostGIS 2.2.6 → PostGIS 2.2.7 |
---|
comment:20 by , 7 years ago
Milestone: | PostGIS 2.2.7 → PostGIS 2.5.0 |
---|
comment:21 by , 6 years ago
Milestone: | PostGIS 2.5.0 → PostGIS next |
---|
comment:23 by , 5 years ago
Milestone: | PostGIS 3.0.0 → PostGIS Fund Me |
---|
comment:24 by , 7 months ago
Keywords: | robustness added |
---|
comment:25 by , 7 months ago
For the record: this problem persists as of current master branch ( [ff91a5acd205638bf6230c02391048883e0a4a35/git] 3.5.0dev )
See also #5699 for a similar case
Do you feel like attaching and putting inline an small image showing the lines ? You can use the {{ }} syntax for inlining an image