clarisma / geodesk

Fast and storage-efficient spatial database engine for OpenStreetMap data
https://docs.geodesk.com/java
Apache License 2.0
137 stars 4 forks source link

IntersectsFilter fails with NPE for geometry collection with empty polygons #52

Open clarisma opened 1 year ago

clarisma commented 1 year ago

relation/2668952 (European Union) is incomplete in germany.gol. Missing relation members are turned into empty geometries. This apparently causes problems for JTS.

An -a query for r fails with NPE thrown by JTS:

java.lang.NullPointerException: Cannot read field "y" because "p" is null
        at org.locationtech.jts.algorithm.locate.IndexedPointInAreaLocator.locate(IndexedPointInAreaLocator.java:88)
        at org.locationtech.jts.geom.prep.PreparedPolygonPredicate.isAnyTestComponentInTarget(PreparedPolygonPredicate.java:102)
        at org.locationtech.jts.geom.prep.PreparedPolygonIntersects.intersects(PreparedPolygonIntersects.java:68)
        at org.locationtech.jts.geom.prep.PreparedPolygonIntersects.intersects(PreparedPolygonIntersects.java:41)
        at org.locationtech.jts.geom.prep.PreparedPolygon.intersects(PreparedPolygon.java:87)
        at com.geodesk.feature.filter.IntersectsFilter.acceptGeometry(IntersectsFilter.java:34)
        at com.geodesk.feature.filter.SpatialFilter.accept(SpatialFilter.java:17)
        at com.geodesk.feature.filter.IntersectsFilter.accept(IntersectsFilter.java:42)
        at com.geodesk.feature.query.RTreeQueryTask.searchLeaf(RTreeQueryTask.java:179)
        at com.geodesk.feature.query.RTreeQueryTask.searchTrunk(RTreeQueryTask.java:86)
        at com.geodesk.feature.query.RTreeQueryTask.exec(RTreeQueryTask.java:56)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
        at java.base/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:436)
        at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:670)
        at com.geodesk.feature.query.TileQueryTask.exec(TileQueryTask.java:138)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
clarisma commented 1 year ago

Polygon isn't actually empty, but an invalid geometry made from purgatory ways. PolygonBuilder should not produce such geometries. The core issue appears that these polygons have 3 vertexes, which means they are clearly degenerate. Check if turning polygons with <4 vertexes into empty polygons avoids this issue.