libgeos / geos

Geometry Engine, Open Source
https://libgeos.org
GNU Lesser General Public License v2.1
1.19k stars 357 forks source link

GEOSTopologyPreserveSimplify returns invalid geometry (47 examples provided) #1180

Open jmealo opened 1 week ago

jmealo commented 1 week ago

GEOSTopologyPreserveSimplify can return invalid geometry (see attached 47 test cases). Our current fix is to check if the value returned is valid, if not, we re-run with tolerance / 10 until we get a valid shape. Our default tolerance is 0.01 if that's of relevance.

47 Test fixtures in .geojson files that cause GEOSTopologyPreserveSimplify to return invalid geometry: https://github.com/user-attachments/files/17261209/network_as_polygon_edgecase.zip

tree -sh output of the zip:

[ 192]  .
├── [1.3K]  geojson
│   ├── [2.0M]  network-as-polygon-edgecase-1.geojson
│   ├── [983K]  network-as-polygon-edgecase-10.geojson
│   ├── [1.8M]  network-as-polygon-edgecase-11.geojson
│   ├── [1.0M]  network-as-polygon-edgecase-12.geojson
│   ├── [2.3M]  network-as-polygon-edgecase-13.geojson
│   ├── [2.1M]  network-as-polygon-edgecase-14.geojson
│   ├── [3.1M]  network-as-polygon-edgecase-15.geojson
│   ├── [1.4M]  network-as-polygon-edgecase-16.geojson
│   ├── [1.7M]  network-as-polygon-edgecase-17.geojson
│   ├── [1.1M]  network-as-polygon-edgecase-18.geojson
│   ├── [2.1M]  network-as-polygon-edgecase-19.geojson
│   ├── [2.8M]  network-as-polygon-edgecase-20.geojson
│   ├── [1.2M]  network-as-polygon-edgecase-21.geojson
│   ├── [1.1M]  network-as-polygon-edgecase-22.geojson
│   ├── [1007K]  network-as-polygon-edgecase-23.geojson
│   ├── [992K]  network-as-polygon-edgecase-24.geojson
│   ├── [1.2M]  network-as-polygon-edgecase-25.geojson
│   ├── [1.2M]  network-as-polygon-edgecase-26.geojson
│   ├── [1.4M]  network-as-polygon-edgecase-27.geojson
│   ├── [2.8M]  network-as-polygon-edgecase-28.geojson
│   ├── [1010K]  network-as-polygon-edgecase-29.geojson
│   ├── [1.2M]  network-as-polygon-edgecase-30.geojson
│   ├── [1.6M]  network-as-polygon-edgecase-31.geojson
│   ├── [1.1M]  network-as-polygon-edgecase-32.geojson
│   ├── [1.1M]  network-as-polygon-edgecase-33.geojson
│   ├── [2.8M]  network-as-polygon-edgecase-34.geojson
│   ├── [1.5M]  network-as-polygon-edgecase-35.geojson
│   ├── [3.9M]  network-as-polygon-edgecase-36.geojson
│   ├── [1.3M]  network-as-polygon-edgecase-37.geojson
│   ├── [1.0M]  network-as-polygon-edgecase-38.geojson
│   ├── [1.2M]  network-as-polygon-edgecase-39.geojson
│   ├── [2.3M]  network-as-polygon-edgecase-40.geojson
│   ├── [1.9M]  network-as-polygon-edgecase-41.geojson
│   ├── [2.8M]  network-as-polygon-edgecase-42.geojson
│   ├── [2.7M]  network-as-polygon-edgecase-43.geojson
│   ├── [1.8M]  network-as-polygon-edgecase-44.geojson
│   ├── [1.8M]  network-as-polygon-edgecase-45.geojson
│   ├── [2.5M]  network-as-polygon-edgecase-46.geojson
│   └── [1.1M]  network-as-polygon-edgecase-47.geojson
└── [ 17M]  network_as_polygon_edgecase.zip

A test harness with pytest testing this functionality via Shapely is available here: https://github.com/shapely/shapely/issues/2165

Related to: https://github.com/shapely/shapely/issues/2165

dr-jts commented 1 week ago

Which version of GEOS is causing this issue?

There were fixes to TopologyPreservingSimplifier in 3.13 (#986 and #1110).