From 978c64f0c6e3239e64e89d8bd4482274a3e1b0e8 Mon Sep 17 00:00:00 2001 From: Michael Barry Date: Wed, 10 Apr 2024 07:12:29 -0400 Subject: [PATCH] Add polygon index intersection utility (#866) --- .../planetiler/geo/PolygonIndex.java | 22 +++++++++++++++++-- .../planetiler/geo/PolygonIndexTest.java | 6 +++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/PolygonIndex.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/PolygonIndex.java index 0d06d903..8f79dff5 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/PolygonIndex.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/PolygonIndex.java @@ -57,11 +57,29 @@ public class PolygonIndex { return postFilterContaining(point, items); } + /** Returns the data associated with all polygons containing {@code point}. */ + public List getIntersecting(Geometry geom) { + build(); + List items = index.query(geom.getEnvelopeInternal()); + return postFilterIntersecting(geom, items); + } + private List postFilterContaining(Point point, List items) { List result = new ArrayList<>(items.size()); for (Object item : items) { - if (item instanceof GeomWithData value && value.poly.contains(point)) { - @SuppressWarnings("unchecked") T t = (T) value.data; + if (item instanceof GeomWithData(var poly,var data) && poly.contains(point)) { + @SuppressWarnings("unchecked") T t = (T) data; + result.add(t); + } + } + return result; + } + + private List postFilterIntersecting(Geometry geom, List items) { + List result = new ArrayList<>(items.size()); + for (Object item : items) { + if (item instanceof GeomWithData(var poly,var data) && poly.intersects(geom)) { + @SuppressWarnings("unchecked") T t = (T) data; result.add(t); } } diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/geo/PolygonIndexTest.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/geo/PolygonIndexTest.java index a959994b..27ace2ec 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/geo/PolygonIndexTest.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/geo/PolygonIndexTest.java @@ -21,10 +21,13 @@ class PolygonIndexTest { void testSingle() { index.put(rectangle(0, 1), 1); assertListsContainSameElements(List.of(1), index.getContaining(newPoint(0.5, 0.5))); + assertListsContainSameElements(List.of(1), index.getIntersecting(newPoint(0.5, 0.5))); + assertListsContainSameElements(List.of(1), index.getIntersecting(rectangle(1, 2))); assertListsContainSameElements(List.of(1), index.getContainingOrNearest(newPoint(0.5, 0.5))); assertListsContainSameElements(List.of(), index.getContaining(newPoint(1.5, 1.5))); assertListsContainSameElements(List.of(), index.getContainingOrNearest(newPoint(1.5, 1.5))); + assertListsContainSameElements(List.of(), index.getIntersecting(rectangle(2, 3))); } @Test @@ -33,6 +36,9 @@ class PolygonIndexTest { index.put(rectangle(0, 1), 2); assertListsContainSameElements(List.of(1, 2), index.getContaining(newPoint(0.5, 0.5))); assertListsContainSameElements(List.of(1, 2), index.getContainingOrNearest(newPoint(0.5, 0.5))); + assertListsContainSameElements(List.of(1, 2), index.getIntersecting(rectangle(0.5, 1.5))); + assertListsContainSameElements(List.of(1, 2), index.getIntersecting(rectangle(1, 2))); + assertListsContainSameElements(List.of(), index.getIntersecting(rectangle(2, 3))); } @Test