com.vividsolutions.jtstest.testbuilder.geom.GeometryPointLocater Maven / Gradle / Ivy
The newest version!
package com.vividsolutions.jtstest.testbuilder.geom;
import com.vividsolutions.jts.geom.*;
/**
* Finds a vertex or a point on a segment of a Geometry
* which lies within a tolerance of a given point.
*
* @author Martin Davis
*
*/
public class GeometryPointLocater
{
public static GeometryLocation locateNonVertexPoint(Geometry geom, Coordinate testPt, double tolerance)
{
GeometryPointLocater finder = new GeometryPointLocater(geom);
GeometryLocation geomLoc = finder.getLocation(testPt, false, tolerance);
if (geomLoc == null) return null;
if (geomLoc.isVertex()) return null;
return geomLoc;
}
public static GeometryLocation locateVertex(Geometry geom, Coordinate testPt, double tolerance)
{
GeometryPointLocater finder = new GeometryPointLocater(geom);
GeometryLocation geomLoc = finder.getLocation(testPt, true, tolerance);
if (geomLoc == null) return null;
if (geomLoc.isVertex()) return geomLoc;
return null;
}
private Geometry geom;
private Coordinate locationPt;
private int segIndex = -1;
private boolean isVertex = false;
public GeometryPointLocater(Geometry geom) {
this.geom = geom;
}
public GeometryLocation getLocation(Coordinate testPt, boolean vertexOnly, double tolerance)
{
NearestSegmentLocationFilter filter = new NearestSegmentLocationFilter(testPt, vertexOnly, tolerance);
geom.apply(filter);
locationPt = filter.getCoordinate();
segIndex = filter.getIndex();
isVertex = filter.isVertex();
if (locationPt == null)
return null;
return new GeometryLocation(geom,
filter.getComponent(),
filter.getIndex(),
filter.isVertex(),
filter.getCoordinate());
}
public int getIndex() { return segIndex; }
public boolean isVertex() { return isVertex; }
static class NearestSegmentLocationFilter implements GeometryComponentFilter
{
private double tolerance = 0.0;
private Coordinate testPt;
private boolean vertexOnly = false;
private Geometry component = null;
private int segIndex = -1;
private Coordinate nearestPt = null;
private boolean isVertex = false;
private LineSegment seg = new LineSegment();
public NearestSegmentLocationFilter(Coordinate testPt, boolean vertexOnly, double tolerance)
{
this.testPt = testPt;
this.tolerance = tolerance;
this.vertexOnly = vertexOnly;
}
public void filter(Geometry geom)
{
if (! (geom instanceof LineString)) return;
if (nearestPt != null)
return;
LineString lineStr = (LineString) geom;
CoordinateSequence seq = lineStr.getCoordinateSequence();
for (int i = 0; i < seq.size(); i++) {
if (i != seq.size() - 1)
checkSegment(lineStr, seq, i);
else
checkVertex(lineStr, seq, i);
// check if done
if (nearestPt != null) {
// found matching location!
component = lineStr;
break;
}
}
}
private void checkSegment(LineString lineStr, CoordinateSequence seq, int i)
{
Coordinate p0 = seq.getCoordinate(i);
Coordinate p1 = seq.getCoordinate(i+1);
// if point matches endpoint ==> vertex match
double dist0 = p0.distance(testPt);
double dist1 = p1.distance(testPt);
if (dist0 < tolerance) {
nearestPt = p0;
segIndex = i;
isVertex = true;
return;
}
else if (dist1 < tolerance) {
nearestPt = p1;
segIndex = i + 1;
isVertex = true;
return;
}
// check closeness to segment (if allowing segments)
if (vertexOnly) return;
seg.p0 = p0;
seg.p1 = p1;
double segDist = seg.distance(testPt);
if (segDist < tolerance) {
nearestPt = seg.closestPoint(testPt);
segIndex = i;
isVertex = false;
}
}
private void checkVertex(LineString lineStr, CoordinateSequence seq, int i)
{
Coordinate p0 = seq.getCoordinate(i);
double dist0 = p0.distance(testPt);
if (dist0 < tolerance) {
nearestPt = p0;
segIndex = i;
isVertex = true;
}
}
public Geometry getComponent()
{
return component;
}
public Coordinate getCoordinate()
{
return nearestPt;
}
public int getIndex() { return segIndex; }
public boolean isVertex() { return isVertex; }
public boolean isDone() { return nearestPt != null; }
public boolean isGeometryChanged() { return false; }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy