#3463 closed defect (fixed)
Crash loading polygons in topology
Reported by: | strk | Owned by: | strk |
---|---|---|---|
Priority: | blocker | Milestone: | PostGIS 2.2.2 |
Component: | topology | Version: | 2.2.x |
Keywords: | Cc: | esseffe |
Description
The attached shapefile, loaded in a topology, triggers a backend crash. Steps to reproduce:
unzip sezioni.zip shp2pgsql -S sezionicrash.shp | psql psql -c "select topogeo_addpolygon('sezionicrash', geom) from sezionicrash"
Attachments (1)
Change History (16)
by , 9 years ago
Attachment: | sezioni.zip added |
---|
comment:1 by , 9 years ago
Cc: | added |
---|
comment:2 by , 9 years ago
The bug is in unhandled NULL return from lwt_GetFaceGeometry within lwt_ChangeEdgeGeom:
/* -- Update faces MBR of left and right faces -- TODO: think about ways to optimize this part, like see if -- the old edge geometry partecipated in the definition -- of the current MBR (for shrinking) or the new edge MBR -- would be larger than the old face MBR... -- */ int facestoupdate = 0; LWT_ISO_FACE faces[2]; LWGEOM *nface1 = NULL; LWGEOM *nface2 = NULL; if ( oldedge->face_left != 0 ) { nface1 = lwt_GetFaceGeometry(topo, oldedge->face_left); lwgeom_add_bbox(nface1); /// <--- nface1 is NULL here
comment:3 by , 9 years ago
Adding handling for the case prints:
ERROR: Corrupted topology: edges of face 37 (5 edges) do not form a polygon
Face 37 is fine before starting the new load, but it is very narrow. With an area of 0.0186 units and 2 almost parallel bounding edges with an angle on the shared starting node of < 0.0002 degrees.
comment:4 by , 9 years ago
BuildArea algorithm is used to build the area out of the edges, and is the one returning NULL. Should come straight from the GEOS polygonizer. I guess there's a full collapse somewhere, thus the edge changing attempt should be invalid, and reported as such.
comment:5 by , 9 years ago
This is the set of edges that BuildArea is incapable of getting an area from (will get the HEXWKB form in a subsequent comment):
NOTICE: Could not build an area with edges: MULTILINESTRING((634451.780306051602 4829559.16259394772,634451.780323039857 4829559.16248522233,634469.462315359502 4829541.48048062716),(634451.780306051602 4829559.16259394772,634485.780000000261 4829525.16290000081,634488.637000000104 4829521.20830000006,634506.460690993699 4829496.52791544143),(634469.462315359502 4829541.48048062716,634485.780000000261 4829525.16269999929,634485.781473573064 4829525.16065966897,634506.460690993699 4829496.52791544143),(634451.780299999751 4829559.16259999946,634469.462315359502 4829541.48048062716),(634451.780299999751 4829559.16259999946,634451.780306051602 4829559.16259394772))
comment:6 by , 9 years ago
The edge collection HEXWKB:
0105000000050000000102000000030000005946848FA75C234172F067CA5D6C52416180868FA75C23416B2866CA5D6C52414B99B4ECCA5C2341D131C05E596C52410102000000040000005946848FA75C234172F067CA5D6C5241F8285C8FEB5C234120F46C4A556C524130DD2446F15C234186C9544D546C52419FB0DFEB145D2341D95DC9214E6C52410102000000040000004B99B4ECCA5C2341D131C05E596C5241F8285C8FEB5C234142AD694A556C5241DE4D1D90EB5C23417E3F484A556C52419FB0DFEB145D2341D95DC9214E6C5241010200000002000000487B838FA75C2341D40968CA5D6C52414B99B4ECCA5C2341D131C05E596C5241010200000002000000487B838FA75C2341D40968CA5D6C52415946848FA75C234172F067CA5D6C5241
I confirm ST_BuildArea returns NULL with that input, while ST_BuildArea(ST_Node(x)) returns an area.
comment:7 by , 9 years ago
For the record: topology in 2.1 branch does not crash nor does it throw an exception, ValidateTopology returns no errors after load (but we know it doesn't check edge linking) and the resulting topology has 500 nodes, 992 edges, 492 faces.
comment:8 by , 9 years ago
min/max/avg area of the topology faces as loaded in 2.1 branch:
min | 3.18838413098732e-09 max | 8731603.80629115 avg | 49514.481442308
There are 4 faces with area < 1e-8, 13 with area < 1e-5
comment:9 by , 9 years ago
Simplified test, self-contained:
SELECT DropTopology('bug3463'); SELECT CreateTopology('bug3463'); SELECT TopoGeo_AddLinestring('bug3463', g) FROM ( VALUES ('LINESTRING(634451.7803 4829559.1626,634485.78 4829525.1627,634506.460690994 4829496.52791544)'::geometry), ('LINESTRING(634447.034152733 4829589.53826525,634451.7794 4829559.1635,634451.7803 4829559.1626)'), ('LINESTRING(634506.460690994 4829496.52791544,634511.7798 4829489.163,634516.720831369 4829468.57536243)'), ('LINESTRING(634451.7803 4829559.1626,634485.78 4829525.1629,634488.637 4829521.2083,634506.460690994 4829496.52791544)'), ('LINESTRING(634506.460690994 4829496.52791544,634511.7792 4829489.1634,634516.720831369 4829468.57536243)') ) foo (g); SELECT TopoGeo_AddLinestring('bug3463', 'LINESTRING(634452.780338203 4829623.16197433,634446.780374345 4829591.16223176,634451.78032304 4829559.16248522,634485.780040461 4829525.1627442,634488.530017153 4829521.16277512,634511.779820754 4829489.16302201,634523.779707286 4829439.16341655,632187.797669813 4827723.17794488,631718.05142978 4827788.42759019,631718.05144314 4827826.17728887,632759.754208638 4830776.16598454)' ::geometry);
comment:10 by , 9 years ago
The self-contained test also fails with pg21, but there it correctly throws an exception: SQL/MM Spatial exception - geometry crosses edge 4
comment:14 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
r14667 backports the crash fix to 2.2 branch (2.2.2). I'm closing this as the crash is fixed. Will file a followup for the exception being thrown.
Valgrind report from an equivalent spatialite run (by Alessandro Furieri):