Opened 5 days ago
Last modified 4 days ago
#5859 new defect
Postgis Topology err Programmatic error ? Geometry of face 1098 is empty!
Reported by: | Lars Aksel Opsahl | Owned by: | strk |
---|---|---|---|
Priority: | medium | Milestone: | PostGIS 3.6.0 |
Component: | topology | Version: | master |
Keywords: | robustness | Cc: | Lars Aksel Opsahl |
Description ¶
Run the file ar50_test_03_topo_1449_test.sql.gz
The topology is valid add this line
SELECT ARRAY(SELECT abs(topogeo_addlinestring) FROM topology.TopoGeo_addLinestring('ar50_test_03_topo_1449','0102000020A210000005000000DCFB152B90082740A1CB42146B814D40AC9DD8F2A6082740D604853B6B814D405E6CD922A8082740AE95904B68814D40CAB06C5B91082740795C4E2468814D40DCFB152B90082740A1CB42146B814D40', 0) ) ;
and we see this in the log
DEBUG: 00000: rehashing catalog cache id 44 for pg_proc; 33 lists, 16 buckets LINE 1: ...lumn_default, POSITION('(' IN column_default)+2, (POSITION('... ^ QUERY: SELECT nextval(SUBSTRING(column_default, POSITION('(' IN column_default)+2, (POSITION(':' IN column_default)-POSITION('(' IN column_default)-3))) FROM information_schema.columns WHERE table_schema = 'ar50_test_03_topo_1449' AND table_name='edge_data' AND column_name = 'edge_id' LOCATION: RehashCatCacheLists, catcache.c:926 DEBUG: 00000: rehashing catalog cache id 7 for pg_attribute; 257 tups, 128 buckets LOCATION: RehashCatCache, catcache.c:888 DEBUG: 00000: rehashing catalog cache id 36 for pg_namespace; 33 tups, 16 buckets LOCATION: RehashCatCache, catcache.c:888 NOTICE: 00000: Corrupted topology: face 1098 could not be constructed only from edges knowing about it (like edge 2978). LOCATION: pg_notice, lwgeom_pg.c:389 ERROR: XX000: Programmatic error ? Geometry of face 1098 is empty! LOCATION: pg_error, lwgeom_pg.c:363
This is tested on
POSTGIS="3.6.0dev 3.5.0-191-g09b3419dc" [EXTENSION] PGSQL="160" GEOS="3.13.0-CAPI-1.19.0" PROJ="9.5.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/Users/lop/Library/Application Support/proj DATABASE_PATH=/opt/homebrew/Cellar/proj/9.5.1/share/proj/proj.db" (compiled against PROJ 9.5.1) LIBXML="2.13.0" LIBJSON="0.18" TOPOLOGY
Change History (12)
by , 5 days ago
Attachment: | ar50_test_03_topo_1449_test.sql.gz added |
---|
comment:1 by , 5 days ago
Does ValidateTopology not report an error ? I'll try myself but I'd expect an "empty face" to be reported as a topology invalidity, or that'd be the first bug (not reporting it)
comment:2 by , 5 days ago
Ok I can reproduce with:
NOTICE: Corrupted topology: face 1098 could not be constructed only from edges knowing about it (like edge 2978). ERROR: Programmatic error ? Geometry of face 1098 is empty!
A NOTICE message indeed reports an invalid topology:
NOTICE: Corrupted topology: face 1098 could not be constructed only from edges knowing about it (like edge 2978). ERROR: Programmatic error ? Geometry of face 1098 is empty!
So we probably have a bug in ValidateTopology which indeed does not report any error about having an empty face.
comment:3 by , 5 days ago
Another interesting observation is that face 1098 is NOT empty before the exception-throwing attempt at adding a line:
# select ST_Area(ST_GetFaceGeometry('ar50_test_03_topo_1449', 1098)); st_area ------------------------ 1.5621632099928084e-08 (1 row)
So it might become empty during the introduction of the new line. Digging further…
by , 4 days ago
comment:4 by , 4 days ago
comment:5 by , 4 days ago
I guess edge 2 entered the topology AFTER edge 1 and thus missed to have edge 1 (pre-existing) SNAP to the very-close vertex of edge 2. This is the mother of all robustness bugs in PostGIS Topology. The experimental code handling edge merges now exists in the codebase but it is still only ever used when adding new NODES so this case doesn't trigger that code because no new node is considered to be needed by the preparation step.
Maybe by using fixed-precision GEOS (available since GEOS-3.9) we'd get more nodes, this could be the road ahead…
comment:7 by , 4 days ago
Keywords: | robustness added |
---|
comment:8 by , 4 days ago
The problem is that no matter tolerance you would still NOT snap an incoming vertex to a pre-existing segment. At the moment we always ever snap incoming SEGMENTS to pre-existing VERTEXES. Except when a new intersection point is detected (as it is likely the case with #5862)
comment:9 by , 4 days ago
Running with a tolerance off 1e-07 and do simplify input by find missing edge parts when topo error on second gives us a much better result as it seems. Number of topo errors are reduced from around 600 to less than 200.
Related to gaps (missing areas) it's much better also. We had around 60 areas that got lost, we are now down to one single polygon and that polygon is also a problem with zero tolerance. We may now have result that we actually can use.
I will try create test case for that missing area later, but I have to work with other stuff now for days.
testfile