forked from locationtech/jts
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Handle point location on GC adjacent edges
- Loading branch information
Showing
7 changed files
with
196 additions
and
10 deletions.
There are no files selected for viewing
106 changes: 106 additions & 0 deletions
106
modules/core/src/main/java/org/locationtech/jts/operation/relateng/AdjacentEdgeLocator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
/* | ||
* Copyright (c) 2024 Martin Davis. | ||
* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License 2.0 | ||
* and Eclipse Distribution License v. 1.0 which accompanies this distribution. | ||
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html | ||
* and the Eclipse Distribution License is available at | ||
* | ||
* http://www.eclipse.org/org/documents/edl-v10.php. | ||
*/ | ||
package org.locationtech.jts.operation.relateng; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.locationtech.jts.algorithm.Orientation; | ||
import org.locationtech.jts.geom.Coordinate; | ||
import org.locationtech.jts.geom.Dimension; | ||
import org.locationtech.jts.geom.Geometry; | ||
import org.locationtech.jts.geom.GeometryCollection; | ||
import org.locationtech.jts.geom.LineSegment; | ||
import org.locationtech.jts.geom.LinearRing; | ||
import org.locationtech.jts.geom.Location; | ||
import org.locationtech.jts.geom.Polygon; | ||
import org.locationtech.jts.util.Assert; | ||
|
||
public class AdjacentEdgeLocator { | ||
|
||
private List<Coordinate[]> ringList;; | ||
|
||
public AdjacentEdgeLocator(Geometry geom) { | ||
init(geom); | ||
} | ||
|
||
public int locate(Coordinate p) { | ||
NodeSections sections = new NodeSections(p); | ||
for (Coordinate[] ring : ringList) { | ||
addIfOnSegment(p, ring, sections); | ||
} | ||
RelateNode node = sections.createNode(); | ||
//node.finish(false, false); | ||
return node.hasExteriorEdge(true) ? Location.BOUNDARY : Location.INTERIOR; | ||
} | ||
|
||
private void addIfOnSegment(Coordinate p, Coordinate[] ring, NodeSections sections) { | ||
for (int i = 0; i < ring.length - 1; i++) { | ||
Coordinate p0 = ring[i]; | ||
Coordinate pnext = ring[i + 1]; | ||
|
||
if (p.equals2D(p0)) { | ||
int iprev = i > 0 ? i - 1 : ring.length - 2; | ||
Coordinate pprev = ring[iprev]; | ||
sections.addNodeSection(createSection(p, pprev, pnext)); | ||
} | ||
else if (p.equals2D(pnext)) { | ||
//-- segment to point is assigned to next segment | ||
continue; | ||
} | ||
else { | ||
LineSegment seg = new LineSegment(p0, pnext); | ||
if (Orientation.COLLINEAR == seg.orientationIndex(p)) { | ||
sections.addNodeSection(createSection(p, p0, pnext)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private NodeSection createSection(Coordinate p, Coordinate prev, Coordinate next) { | ||
if (prev.distance(p) == 0 || next.distance(p) == 0) { | ||
System.out.println("Found zero-length section segment"); | ||
}; | ||
NodeSection ns = new NodeSection(true, Dimension.A, 1, 0, false, prev, p, next); | ||
return ns; | ||
} | ||
|
||
private void init(Geometry geom) { | ||
if (geom.isEmpty()) | ||
return; | ||
ringList = new ArrayList<Coordinate[]>(); | ||
addRings(geom); | ||
} | ||
|
||
private void addRings(Geometry geom) { | ||
if (geom instanceof Polygon) { | ||
Polygon poly = (Polygon) geom; | ||
LinearRing shell = poly.getExteriorRing(); | ||
addRing(shell, true); | ||
for (int i = 0; i < poly.getNumInteriorRing(); i++) { | ||
LinearRing hole = poly.getInteriorRingN(i); | ||
addRing(hole, false); | ||
} | ||
} | ||
else if (geom instanceof GeometryCollection) { | ||
for (int i = 0; i < geom.getNumGeometries(); i++) { | ||
addRings(geom.getGeometryN(i)); | ||
} | ||
} | ||
} | ||
|
||
private void addRing(LinearRing ring, boolean requireCW) { | ||
Coordinate[] pts = RelateGeometry.orient(ring.getCoordinates(), requireCW); | ||
ringList.add(pts); | ||
} | ||
|
||
} |
2 changes: 1 addition & 1 deletion
2
modules/core/src/main/java/org/locationtech/jts/operation/relateng/NodeSections.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
...s/core/src/test/java/org/locationtech/jts/operation/relateng/AdjacentEdgeLocatorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package org.locationtech.jts.operation.relateng; | ||
|
||
import org.locationtech.jts.geom.Coordinate; | ||
import org.locationtech.jts.geom.Geometry; | ||
import org.locationtech.jts.geom.Location; | ||
|
||
import junit.textui.TestRunner; | ||
import test.jts.GeometryTestCase; | ||
|
||
public class AdjacentEdgeLocatorTest extends GeometryTestCase { | ||
|
||
public static void main(String args[]) { | ||
TestRunner.run(AdjacentEdgeLocatorTest.class); | ||
} | ||
|
||
public AdjacentEdgeLocatorTest(String name) { | ||
super(name); | ||
} | ||
|
||
public void testAdjacent2() { | ||
checkLocation( | ||
"GEOMETRYCOLLECTION (POLYGON ((1 9, 5 9, 5 1, 1 1, 1 9)), POLYGON ((9 9, 9 1, 5 1, 5 9, 9 9)))", | ||
5, 5, Location.INTERIOR | ||
); | ||
} | ||
|
||
public void testNonAdjacent() { | ||
checkLocation( | ||
"GEOMETRYCOLLECTION (POLYGON ((1 9, 4 9, 5 1, 1 1, 1 9)), POLYGON ((9 9, 9 1, 5 1, 5 9, 9 9)))", | ||
5, 5, Location.BOUNDARY | ||
); | ||
} | ||
|
||
private void checkLocation(String wkt, int x, int y, int expectedLoc) { | ||
Geometry geom = read(wkt); | ||
AdjacentEdgeLocator ael = new AdjacentEdgeLocator(geom); | ||
int loc = ael.locate(new Coordinate(x, y)); | ||
assertEquals(expectedLoc, loc); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters