com.vividsolutions.jtstest.testbuilder.geom.GeometryBoxDeleter Maven / Gradle / Ivy
The newest version!
package com.vividsolutions.jtstest.testbuilder.geom;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateArrays;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.util.GeometryEditor;
/**
* Deletes vertices or components from a geometry
* which lie inside a given box.
* If the box completely contains one or more components
* (including polygon holes), those components are deleted
* and the operation stops.
* Otherwise if the box contains a subset of vertices
* from a component, those vertices are deleted.
* When deleting vertices only one component of the geometry
* is modified (the first one found which has vertices in the box).
*
* @author Martin Davis
*
*/
public class GeometryBoxDeleter
{
public static Geometry delete(Geometry geom,
Envelope env)
{
Geometry gComp = deleteComponents(geom, env);
if (gComp != null) return gComp;
// otherwise, try and edit vertices
Geometry gVert = deleteVertices(geom, env);
if (gVert != null) return gVert;
// no edits - return original
return geom;
}
private static Geometry deleteComponents(Geometry geom, Envelope env)
{
GeometryEditor editor = new GeometryEditor();
BoxDeleteComponentOperation compOp = new BoxDeleteComponentOperation(env);
Geometry compEditGeom = editor.edit(geom, compOp);
if (compOp.isEdited()) return compEditGeom;
return null;
}
private static Geometry deleteVertices(Geometry geom, Envelope env)
{
GeometryEditor editor = new GeometryEditor();
BoxDeleteVertexOperation vertexOp = new BoxDeleteVertexOperation(env);
Geometry vertexEditGeom = editor.edit(geom, vertexOp);
if (vertexOp.isEdited()) return vertexEditGeom;
return null;
}
private static class BoxDeleteComponentOperation
implements GeometryEditor.GeometryEditorOperation
{
private Envelope env;
private boolean isEdited = false;
public BoxDeleteComponentOperation(Envelope env)
{
this.env = env;
}
public boolean isEdited() { return isEdited; }
public Geometry edit(Geometry geometry, GeometryFactory factory)
{
// Allow any number of components to be deleted
//if (isEdited) return geometry;
if (env.contains(geometry.getEnvelopeInternal())) {
isEdited = true;
return null;
}
return geometry;
}
}
private static class BoxDeleteVertexOperation
extends GeometryEditor.CoordinateOperation
{
private Envelope env;
private boolean isEdited = false;
public BoxDeleteVertexOperation(Envelope env)
{
this.env = env;
}
public boolean isEdited() { return isEdited; }
public Coordinate[] edit(Coordinate[] coords,
Geometry geometry)
{
if (isEdited) return coords;
if (! hasVertexInBox(coords))
return coords;
// only delete vertices of first component found
int minLen = 2;
if (geometry instanceof LinearRing) minLen = 4;
Coordinate[] newPts = new Coordinate[coords.length];
int newIndex = 0;
for (int i = 0; i < coords.length; i++) {
if (! env.contains(coords[i])) {
newPts[newIndex++] = coords[i];
}
}
Coordinate[] nonNullPts = CoordinateArrays.removeNull(newPts);
Coordinate[] finalPts = nonNullPts;
// close ring if required
if (geometry instanceof LinearRing) {
if (nonNullPts.length > 1 && ! nonNullPts[nonNullPts.length - 1].equals2D(nonNullPts[0])) {
Coordinate[] ringPts = new Coordinate[nonNullPts.length + 1];
CoordinateArrays.copyDeep(nonNullPts, 0, ringPts, 0, nonNullPts.length);
ringPts[ringPts.length-1] = new Coordinate(ringPts[0]);
finalPts = ringPts;
}
}
// don't change if would make geometry invalid
if (finalPts.length < minLen)
return coords;
isEdited = true;
return finalPts;
}
private boolean hasVertexInBox(Coordinate[] coords)
{
for (int i = 0; i < coords.length; i++) {
if (env.contains(coords[i])) {
return true;
}
}
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy