From fa4e05b673d2ce86d0ac1c8bbeab6a89fa71e9f9 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Thu, 18 Jan 2024 17:36:52 -0800 Subject: [PATCH] Fix PointLocator with BoundaryNodeRule for lines (#1031) --- .../jts/algorithm/PointLocator.java | 8 +++---- .../jts/algorithm/PointLocatorTest.java | 22 ++++++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/modules/core/src/main/java/org/locationtech/jts/algorithm/PointLocator.java b/modules/core/src/main/java/org/locationtech/jts/algorithm/PointLocator.java index 0a08fad14a..31da848f5e 100644 --- a/modules/core/src/main/java/org/locationtech/jts/algorithm/PointLocator.java +++ b/modules/core/src/main/java/org/locationtech/jts/algorithm/PointLocator.java @@ -165,11 +165,11 @@ private int locateOnLineString(Coordinate p, LineString l) if (! l.getEnvelopeInternal().intersects(p)) return Location.EXTERIOR; CoordinateSequence seq = l.getCoordinateSequence(); - if (! l.isClosed()) { - if (p.equals(seq.getCoordinate(0)) + if (p.equals(seq.getCoordinate(0)) || p.equals(seq.getCoordinate(seq.size() - 1)) ) { - return Location.BOUNDARY; - } + int boundaryCount = l.isClosed() ? 2 : 1; + int loc = boundaryRule.isInBoundary(boundaryCount) ? Location.BOUNDARY : Location.INTERIOR; + return loc; } if (PointLocation.isOnLine(p, seq)) { return Location.INTERIOR; diff --git a/modules/core/src/test/java/org/locationtech/jts/algorithm/PointLocatorTest.java b/modules/core/src/test/java/org/locationtech/jts/algorithm/PointLocatorTest.java index 6cc0a501e8..8b3036473b 100644 --- a/modules/core/src/test/java/org/locationtech/jts/algorithm/PointLocatorTest.java +++ b/modules/core/src/test/java/org/locationtech/jts/algorithm/PointLocatorTest.java @@ -67,7 +67,17 @@ public void testPolygon() throws Exception { assertEquals(Location.INTERIOR, pointLocator.locate(new Coordinate(190, 150), polygon)); } - private void runPtLocator(int expected, Coordinate pt, String wkt) + public void testRingBoundaryNodeRule() throws Exception + { + String wkt = "LINEARRING(10 10, 10 20, 20 10, 10 10)"; + Coordinate pt = new Coordinate(10, 10); + runPtLocator(Location.INTERIOR, pt, wkt, BoundaryNodeRule.MOD2_BOUNDARY_RULE); + runPtLocator(Location.BOUNDARY, pt, wkt, BoundaryNodeRule.ENDPOINT_BOUNDARY_RULE); + runPtLocator(Location.INTERIOR, pt, wkt, BoundaryNodeRule.MONOVALENT_ENDPOINT_BOUNDARY_RULE); + runPtLocator(Location.BOUNDARY, pt, wkt, BoundaryNodeRule.MULTIVALENT_ENDPOINT_BOUNDARY_RULE); + } + + private void runPtLocator(int expected, Coordinate pt, String wkt) throws Exception { Geometry geom = reader.read(wkt); @@ -76,4 +86,14 @@ private void runPtLocator(int expected, Coordinate pt, String wkt) assertEquals(expected, loc); } + private void runPtLocator(int expected, Coordinate pt, String wkt, + BoundaryNodeRule bnr) + throws Exception + { + Geometry geom = reader.read(wkt); + PointLocator pointLocator = new PointLocator(bnr); + int loc = pointLocator.locate(pt, geom); + assertEquals(expected, loc); + } + }