-
Notifications
You must be signed in to change notification settings - Fork 431
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix LargestEmptyCircle to handle polygonal obstacles (#988)
- Loading branch information
Showing
5 changed files
with
222 additions
and
16 deletions.
There are no files selected for viewing
81 changes: 81 additions & 0 deletions
81
...s/core/src/main/java/org/locationtech/jts/algorithm/construct/IndexedDistanceToPoint.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,81 @@ | ||
/* | ||
* Copyright (c) 2023 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.algorithm.construct; | ||
|
||
import org.locationtech.jts.geom.Coordinate; | ||
import org.locationtech.jts.geom.Geometry; | ||
import org.locationtech.jts.geom.Location; | ||
import org.locationtech.jts.geom.Point; | ||
import org.locationtech.jts.operation.distance.IndexedFacetDistance; | ||
|
||
/** | ||
* Computes the distance between a point and a geometry | ||
* (which may be a collection containing any type of geometry). | ||
* Also computes the pair of points containing the input | ||
* point and the nearest point on the geometry. | ||
* | ||
* @author mdavis | ||
* | ||
*/ | ||
class IndexedDistanceToPoint { | ||
|
||
private Geometry targetGeometry; | ||
private IndexedFacetDistance facetDistance; | ||
private IndexedPointInPolygonsLocater ptLocater; | ||
|
||
public IndexedDistanceToPoint(Geometry geom) { | ||
this.targetGeometry = geom; | ||
} | ||
|
||
private void init() { | ||
if (facetDistance != null) | ||
return; | ||
facetDistance = new IndexedFacetDistance(targetGeometry); | ||
ptLocater = new IndexedPointInPolygonsLocater(targetGeometry); | ||
} | ||
|
||
/** | ||
* Computes the distance from a point to the geometry. | ||
* | ||
* @param pt the input point | ||
* @return the distance to the geometry | ||
*/ | ||
public double distance(Point pt) { | ||
init(); | ||
//-- distance is 0 if point is inside a target polygon | ||
if (isInArea(pt)) { | ||
return 0; | ||
} | ||
return facetDistance.distance(pt); | ||
} | ||
|
||
private boolean isInArea(Point pt) { | ||
return Location.EXTERIOR != ptLocater.locate(pt.getCoordinate()); | ||
} | ||
|
||
/** | ||
* Gets the nearest locations between the geometry and a point. | ||
* The first location lies on the geometry, | ||
* and the second location is the provided point. | ||
* | ||
* @param pt the point to compute the nearest location for | ||
* @return a pair of locations | ||
*/ | ||
public Coordinate[] nearestPoints(Point pt) { | ||
init(); | ||
if (isInArea(pt)) { | ||
Coordinate p = pt.getCoordinate(); | ||
return new Coordinate[] { p.copy(), p.copy() }; | ||
} | ||
return facetDistance.nearestPoints(pt); | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
...src/main/java/org/locationtech/jts/algorithm/construct/IndexedPointInPolygonsLocater.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,67 @@ | ||
/* | ||
* Copyright (c) 2023 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.algorithm.construct; | ||
|
||
import java.util.List; | ||
|
||
import org.locationtech.jts.algorithm.locate.IndexedPointInAreaLocator; | ||
import org.locationtech.jts.algorithm.locate.PointOnGeometryLocator; | ||
import org.locationtech.jts.geom.Coordinate; | ||
import org.locationtech.jts.geom.Envelope; | ||
import org.locationtech.jts.geom.Geometry; | ||
import org.locationtech.jts.geom.Location; | ||
import org.locationtech.jts.geom.util.PolygonalExtracter; | ||
import org.locationtech.jts.index.strtree.STRtree; | ||
|
||
/** | ||
* Determines the location of a point in the polygonal elements of a geometry. | ||
* Uses spatial indexing to provide efficient performance. | ||
* | ||
* @author mdavis | ||
* | ||
*/ | ||
class IndexedPointInPolygonsLocater implements PointOnGeometryLocator { | ||
|
||
private Geometry geom; | ||
private List<Geometry> polys; | ||
private STRtree index; | ||
|
||
public IndexedPointInPolygonsLocater(Geometry geom) { | ||
this.geom = geom; | ||
} | ||
|
||
private void init() { | ||
if (polys != null) | ||
return; | ||
polys = PolygonalExtracter.getPolygonals(geom); | ||
index = new STRtree(); | ||
for (int i = 0; i < polys.size(); i++) { | ||
Geometry poly = polys.get(i); | ||
index.insert(poly.getEnvelopeInternal(), new IndexedPointInAreaLocator(poly)); | ||
} | ||
} | ||
|
||
@Override | ||
public int locate(Coordinate p) { | ||
init(); | ||
|
||
List results = index.query(new Envelope(p)); | ||
for (int i = 0; i < results.size(); i++) { | ||
IndexedPointInAreaLocator ptLocater = (IndexedPointInAreaLocator) results.get(i); | ||
int loc = ptLocater.locate(p); | ||
if (loc != Location.EXTERIOR) | ||
return loc; | ||
} | ||
return Location.EXTERIOR; | ||
} | ||
|
||
} |
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
59 changes: 59 additions & 0 deletions
59
modules/core/src/main/java/org/locationtech/jts/geom/util/PolygonalExtracter.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,59 @@ | ||
/* | ||
* Copyright (c) 2023 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.geom.util; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.locationtech.jts.geom.Geometry; | ||
import org.locationtech.jts.geom.GeometryCollection; | ||
import org.locationtech.jts.geom.MultiPolygon; | ||
import org.locationtech.jts.geom.Polygon; | ||
|
||
/** | ||
* Extracts the {@link Polygon} and {@link MultiPolygon} elements from a {@link Geometry}. | ||
*/ | ||
public class PolygonalExtracter | ||
{ | ||
/** | ||
* Extracts the {@link Polygon} and {@link MultiPolygon} elements from a {@link Geometry} | ||
* and adds them to the provided list. | ||
* | ||
* @param geom the geometry from which to extract | ||
* @param list the list to add the extracted elements to | ||
*/ | ||
public static List<Geometry> getPolygonals(Geometry geom, List<Geometry> list) | ||
{ | ||
if (geom instanceof Polygon || geom instanceof MultiPolygon) { | ||
list.add(geom); | ||
} | ||
else if (geom instanceof GeometryCollection) { | ||
for (int i = 0; i < geom.getNumGeometries(); i++) { | ||
getPolygonals(geom.getGeometryN(i), list); | ||
} | ||
} | ||
// skip non-Polygonal elemental geometries | ||
return list; | ||
} | ||
|
||
/** | ||
* Extracts the {@link Polygon} and {@link MultiPolygon} elements from a {@link Geometry} | ||
* and returns them in a list. | ||
* | ||
* @param geom the geometry from which to extract | ||
*/ | ||
public static List<Geometry> getPolygonals(Geometry geom) | ||
{ | ||
return getPolygonals(geom, new ArrayList<Geometry>()); | ||
} | ||
|
||
} |
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