Opened 13 years ago
Closed 13 years ago
#1714 closed defect (fixed)
totopogeom - can't add multipolygon
Reported by: | robe | Owned by: | strk |
---|---|---|---|
Priority: | medium | Milestone: | PostGIS 2.0.1 |
Component: | topology | Version: | master |
Keywords: | Cc: |
Description
strk - not sure what to make of this. In adding my representative neighborhoods to a blank topology. Many went in fine, but for some, I got a
ERROR: SQL/MM Spatial exception - curve not simple CONTEXT: PL/pgSQL function "topogeo_addlinestring" line 179 at assignment SQL statement "SELECT array_cat(edges, array_agg(x)) FROM ( select topology.TopoGeo_addLinestring(atopology, rec.geom, tol) as x ) as foo" PL/pgSQL function "topogeo_addpolygon" line 27 at assignment
Here is my smallest workflow that triggers the error
SELECT topology.CreateTopology('topo_boston_test', 2249, 0.25); CREATE TABLE nei_topo(gid serial primary key, nei varchar(30)); SELECT topology.AddTopoGeometryColumn('topo_boston_test', 'public', 'nei_topo', 'topo', 'MULTIPOLYGON') As new_layer_id; INSERT INTO nei_topo(nei, topo) SELECT nei, topology.toTopoGeom(geom, 'topo_boston_test', 1,0.0) FROM nei_test;
I have attached to sql to build the nei_test table.
This was testing with beta4, geos 3.3.3dev
I tried with latest trunk and get same issue.
Attachments (4)
Change History (14)
by , 13 years ago
Attachment: | nei_test.sql added |
---|
comment:1 by , 13 years ago
comment:2 by , 13 years ago
It seems to be snapping to nodes that makes it become non-simple:
DEBUG: Unioned: MULTILINESTRING((765795.233731932 2949559.16014178,765795.233731932 2949558.8354405,765795.071381291 2949559.16014178),(765795.071381291 2949559.16014178,765795.233731932 2949559.16014178)) DEBUG: Intersecting nodes: MULTIPOINT(765795.071381291 2949559.16014178) DEBUG: Snapped to nodes: MULTILINESTRING((765795.071381291 2949559.16014178,765795.233731932 2949558.8354405,765795.071381291 2949559.16014178),(765795.071381291 2949559.16014178,765795.071381291 2949559.16014178))
Snap input is simple, snap output isn't:
strk=# select st_issimple( 'MULTILINESTRING((765795.233731932 2949559.16014178,765795.233731932 2949558.8354405,765795.071381291 2949559.16014178),(765795.071381291 2949559.16014178,765795.233731932 2949559.16014178))' ); st_issimple ------------- t (1 row) strk=# select st_issimple( 'MULTILINESTRING((765795.071381291 2949559.16014178,765795.233731932 2949558.8354405,765795.071381291 2949559.16014178),(765795.071381291 2949559.16014178,765795.071381291 2949559.16014178))' ); st_issimple ------------- f (1 row)
by , 13 years ago
Attachment: | nei_hole.png added |
---|
by , 13 years ago
Attachment: | nei_hole_big.png added |
---|
comment:3 by , 13 years ago
comment:4 by , 13 years ago
Simplified offending input:
LINESTRING(765795.1 2949559.2,765794.9 2949559.2,765795.2 2949558.8,765795.1 2949559.2) LINESTRING(765795.1 2949559.2,765795.2 2949559.2,765794.9 2949559.5,765795.1 2949559.2)
Add with TopoGeo_addLineString, in any order, using 0.25 tollerance.
by , 13 years ago
Attachment: | bogussnap.png added |
---|
comment:5 by , 13 years ago
See the bogus snapping here. The green line with an arrow is one of the linestrings being inserted (an edge). The triangle on the top-right is the other line which we try to add (vertices shown in red). The triangle on the left is the result of snapping the top-right line to the bottom line.
It looks like the bottom-right vertex of the line was snapped to the top-left vertex of the existing edge. It is surprising because the distance between those two vertices is ~ 0.3 (higher than the tolerance).
To isolate the case, these are the ST_Snap inputs:
A: LINESTRING(765795.1 2949559.2,765795.2 2949559.2,765794.9 2949559.5,765795.1 2949559.2) B: LINESTRING(765795.1 2949559.2,765794.9 2949559.2,765795.2 2949558.8,765795.1 2949559.2) tolerance: 0.25
I've filed #1767 for that one.
Here we might still want to succeed after that snapping. Note that at this point the snapped line is still simple, so let's see what happens afterwards.
comment:7 by , 13 years ago
NOTE: both horizontal distances between the top 2 vertices of the existing edge and the bottom 2 vertices of the line being added are less than 0.25
comment:8 by , 13 years ago
Alright so going on what happens is that the result of snapping is noded again with the existing edge so that the line being inserted becomes 2 lines (one matching the top-segment of the existing edge and another one describing the other two sides of the triangle) and then a new snap happens, to the now intersecting _nodes_.
We have a single node here so far, which is the top-right vertex of the existing edge (where the arrow ends).
As expected, given the distances between the horizontal vertices, snapping of both segments to the existing node results in two collapses: the horizontal line becomes a point (the node) and the triangle portion becomes a single line going back and forward.
The current code fails to re-node the result of snapping. It should.
comment:9 by , 13 years ago
Summary: | totopogeom - can't add multipolygo → totopogeom - can't add multipolygon |
---|
Final reduction of the case:
CreateTopology('bug1714'); SELECT AddNode('bug1714', 'POINT(10 0)'); SELECT TopoGeo_addLinestring('bug1714', 'LINESTRING(10 0, 0 20, 0 0, 10 0)', 12);
The second geometry, snapped against existing node (10,0) becomes non-simple.
Working on testcase and fix
comment:10 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Ok, this is fixed as of r9625 — you'll notice that one of the tiny holes in your input polygons will be collapsed in the output topology, so that you'll only have 2 faces rather than 3.
strk=# select topologysummary('topo_boston_test'); topologysummary ----------------------------------------------------------- Topology topo_boston_test (96), SRID 2249, precision 0.25 3 nodes, 3 edges, 2 faces, 1 topogeoms in 1 layers Layer 1, type Polygonal (3), 1 topogeoms Deploy: public.nei_topo.topo (1 row)
It is expected behavior due to the tolerance you specified.
Seems to work fine if I don't create my topology with a tolerance. so i guess similar to pramsey's issue with tolerance.