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)

nei_test.sql (4.5 KB ) - added by robe 13 years ago.
nei_hole.png (5.7 KB ) - added by strk 13 years ago.
nei_hole_big.png (4.2 KB ) - added by strk 13 years ago.
bogussnap.png (2.4 KB ) - added by strk 13 years ago.

Download all attachments as: .zip

Change History (14)

by robe, 13 years ago

Attachment: nei_test.sql added

comment:1 by robe, 13 years ago

Seems to work fine if I don't create my topology with a tolerance. so i guess similar to pramsey's issue with tolerance.

comment:2 by strk, 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 strk, 13 years ago

Attachment: nei_hole.png added

by strk, 13 years ago

Attachment: nei_hole_big.png added

comment:3 by strk, 13 years ago

The damage occurs near a very tiny hole in your polygon:

The distance between the two closest red points there is around 1.6, which is bigger than your tolerance, so that doesn't need to be the reason...

comment:4 by strk, 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 strk, 13 years ago

Attachment: bogussnap.png added

comment:5 by strk, 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).

No image "bogus_snap.png" attached to Ticket #1714

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:6 by strk, 13 years ago

The image referred by the previous comment:

comment:7 by strk, 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 strk, 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 strk, 13 years ago

Summary: totopogeom - can't add multipolygototopogeom - 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 strk, 13 years ago

Resolution: fixed
Status: newclosed

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.

Note: See TracTickets for help on using tickets.