com.vividsolutions.jts.simplify.VWSimplifier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of JTSplus Show documentation
Show all versions of JTSplus Show documentation
JTS Topology Suite 1.14 with additional functions for GeoSpark
/*
* The JTS Topology Suite is a collection of Java classes that
* implement the fundamental operations required to validate a given
* geo-spatial data set to a known topological specification.
*
* Copyright (C) 2001 Vivid Solutions
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
package com.vividsolutions.jts.simplify;
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.geom.util.*;
/**
* Simplifies a {@link Geometry} using the Visvalingam-Whyatt area-based algorithm.
* Ensures that any polygonal geometries returned are valid. Simple lines are not
* guaranteed to remain simple after simplification. All geometry types are
* handled. Empty and point geometries are returned unchanged. Empty geometry
* components are deleted.
*
* The simplification tolerance is specified as a distance.
* This is converted to an area tolerance by squaring it.
*
* Note that in general this algorithm does not preserve topology - e.g. polygons can be split,
* collapse to lines or disappear holes can be created or disappear, and lines
* can cross.
*
*
Known Bugs
*
* - Not yet optimized for performance
*
- Does not simplify the endpoint of rings
*
* To Do
*
* - Allow specifying desired number of vertices in the output
*
*
* @version 1.7
*/
public class VWSimplifier
{
/**
* Simplifies a geometry using a given tolerance.
*
* @param geom geometry to simplify
* @param distanceTolerance the tolerance to use
* @return a simplified version of the geometry
*/
public static Geometry simplify(Geometry geom, double distanceTolerance)
{
VWSimplifier simp = new VWSimplifier(geom);
simp.setDistanceTolerance(distanceTolerance);
return simp.getResultGeometry();
}
private Geometry inputGeom;
private double distanceTolerance;
private boolean isEnsureValidTopology = true;
/**
* Creates a simplifier for a given geometry.
*
* @param inputGeom the geometry to simplify
*/
public VWSimplifier(Geometry inputGeom)
{
this.inputGeom = inputGeom;
}
/**
* Sets the distance tolerance for the simplification. All vertices in the
* simplified geometry will be within this distance of the original geometry.
* The tolerance value must be non-negative.
*
* @param distanceTolerance
* the approximation tolerance to use
*/
public void setDistanceTolerance(double distanceTolerance)
{
if (distanceTolerance < 0.0)
throw new IllegalArgumentException("Tolerance must be non-negative");
this.distanceTolerance = distanceTolerance;
}
/**
* Controls whether simplified polygons will be "fixed" to have valid
* topology. The caller may choose to disable this because:
*
* - valid topology is not required
*
- fixing topology is a relative expensive operation
*
- in some pathological cases the topology fixing operation may either
* fail or run for too long
*
*
* The default is to fix polygon topology.
*
* @param isEnsureValidTopology
*/
public void setEnsureValid(boolean isEnsureValidTopology)
{
this.isEnsureValidTopology = isEnsureValidTopology;
}
/**
* Gets the simplified geometry.
*
* @return the simplified geometry
*/
public Geometry getResultGeometry()
{
// empty input produces an empty result
if (inputGeom.isEmpty())
return (Geometry) inputGeom.clone();
return (new VWTransformer(isEnsureValidTopology)).transform(inputGeom);
}
class VWTransformer extends GeometryTransformer
{
private boolean isEnsureValidTopology = true;
public VWTransformer(boolean isEnsureValidTopology)
{
this.isEnsureValidTopology = isEnsureValidTopology;
}
protected CoordinateSequence transformCoordinates(CoordinateSequence coords, Geometry parent)
{
Coordinate[] inputPts = coords.toCoordinateArray();
Coordinate[] newPts = null;
if (inputPts.length == 0) {
newPts = new Coordinate[0];
}
else {
newPts = VWLineSimplifier.simplify(inputPts, distanceTolerance);
}
return factory.getCoordinateSequenceFactory().create(newPts);
}
/**
* Simplifies a polygon, fixing it if required.
*/
protected Geometry transformPolygon(Polygon geom, Geometry parent)
{
// empty geometries are simply removed
if (geom.isEmpty())
return null;
Geometry rawGeom = super.transformPolygon(geom, parent);
// don't try and correct if the parent is going to do this
if (parent instanceof MultiPolygon) {
return rawGeom;
}
return createValidArea(rawGeom);
}
/**
* Simplifies a LinearRing. If the simplification results in a degenerate
* ring, remove the component.
*
* @return null if the simplification results in a degenerate ring
*/
protected Geometry transformLinearRing(LinearRing geom, Geometry parent)
{
boolean removeDegenerateRings = parent instanceof Polygon;
Geometry simpResult = super.transformLinearRing(geom, parent);
if (removeDegenerateRings && !(simpResult instanceof LinearRing))
return null;
;
return simpResult;
}
/**
* Simplifies a MultiPolygon, fixing it if required.
*/
protected Geometry transformMultiPolygon(MultiPolygon geom, Geometry parent)
{
Geometry rawGeom = super.transformMultiPolygon(geom, parent);
return createValidArea(rawGeom);
}
/**
* Creates a valid area geometry from one that possibly has bad topology
* (i.e. self-intersections). Since buffer can handle invalid topology, but
* always returns valid geometry, constructing a 0-width buffer "corrects"
* the topology. Note this only works for area geometries, since buffer
* always returns areas. This also may return empty geometries, if the input
* has no actual area.
*
* @param rawAreaGeom
* an area geometry possibly containing self-intersections
* @return a valid area geometry
*/
private Geometry createValidArea(Geometry rawAreaGeom)
{
if (isEnsureValidTopology)
return rawAreaGeom.buffer(0.0);
return rawAreaGeom;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy