Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable ring-endpoint-handling for LineString with isRing() == true #1033

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static Coordinate[] simplify(Coordinate[] pts, double distanceTolerance,
return simp.simplify();
}

private Coordinate[] pts;
private final Coordinate[] pts;
private boolean[] usePt;
private double distanceTolerance;
private boolean isPreserveEndpoint = false;
Expand All @@ -56,21 +56,21 @@ public void setDistanceTolerance(double distanceTolerance) {
private void setPreserveEndpoint(boolean isPreserveEndpoint) {
this.isPreserveEndpoint = isPreserveEndpoint;
}

public Coordinate[] simplify()
{
usePt = new boolean[pts.length];
for (int i = 0; i < pts.length; i++) {
usePt[i] = true;
}
simplifySection(0, pts.length - 1);

CoordinateList coordList = new CoordinateList();
for (int i = 0; i < pts.length; i++) {
if (usePt[i])
coordList.add(new Coordinate(pts[i]));
}

if (! isPreserveEndpoint && CoordinateArrays.isRing(pts)) {
simplifyRingEndpoint(coordList);
}
Expand All @@ -84,7 +84,7 @@ private void simplifyRingEndpoint(CoordinateList pts) {
return;
//-- base segment for endpoint
seg.p0 = pts.get(1);
seg.p1 = pts.get(pts.size() - 2);
seg.p1 = pts.get(pts.size() - 2);
double distance = seg.distance(pts.get(0));
if (distance <= distanceTolerance) {
pts.remove(0);
Expand All @@ -93,7 +93,7 @@ private void simplifyRingEndpoint(CoordinateList pts) {
}
}

private LineSegment seg = new LineSegment();
private final LineSegment seg = new LineSegment();

private void simplifySection(int i, int j)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* Simplifies a {@link Geometry} using the Douglas-Peucker algorithm.
* Ensures that any polygonal geometries returned are valid.
* Simple lines are not guaranteed to remain simple after simplification.
* All geometry types are handled.
* All geometry types are handled.
* Empty and point geometries are returned unchanged.
* Empty geometry components are deleted.
* <p>
Expand All @@ -49,7 +49,7 @@ public class DouglasPeuckerSimplifier

/**
* 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
Expand All @@ -61,13 +61,13 @@ public static Geometry simplify(Geometry geom, double distanceTolerance)
return tss.getResultGeometry();
}

private Geometry inputGeom;
private final Geometry inputGeom;
private double distanceTolerance;
private boolean isEnsureValidTopology = true;

/**
* Creates a simplifier for a given geometry.
*
*
* @param inputGeom the geometry to simplify
*/
public DouglasPeuckerSimplifier(Geometry inputGeom)
Expand All @@ -79,7 +79,7 @@ public DouglasPeuckerSimplifier(Geometry 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.
* The tolerance value must be non-negative.
*
* @param distanceTolerance the approximation tolerance to use
*/
Expand All @@ -98,46 +98,46 @@ public void setDistanceTolerance(double distanceTolerance) {
* <li>fixing topology is a relative expensive operation
* <li>in some pathological cases the topology fixing operation may either fail or run for too long
* </ul>
*
*
* 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 inputGeom.copy();

return (new DPTransformer(isEnsureValidTopology, distanceTolerance)).transform(inputGeom);
}

static class DPTransformer
extends GeometryTransformer
{
private boolean isEnsureValidTopology = true;
private double distanceTolerance;
private final boolean isEnsureValidTopology;
private final double distanceTolerance;

public DPTransformer(boolean isEnsureValidTopology, double distanceTolerance)
{
this.isEnsureValidTopology = isEnsureValidTopology;
this.distanceTolerance = distanceTolerance;
}

protected CoordinateSequence transformCoordinates(CoordinateSequence coords, Geometry parent)
{
boolean isPreserveEndpoint = ! (parent instanceof LinearRing);
Coordinate[] inputPts = coords.toCoordinateArray();
Coordinate[] newPts = null;
Coordinate[] newPts;
if (inputPts.length == 0) {
newPts = new Coordinate[0];
}
Expand All @@ -163,22 +163,20 @@ protected Geometry transformPolygon(Polygon geom, Geometry parent) {
}

/**
* Simplifies a LinearRing. If the simplification results
* 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)
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.
*/
Expand All @@ -195,8 +193,8 @@ protected Geometry transformMultiPolygon(MultiPolygon geom, Geometry parent) {
* 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.
* If the input is empty or is not polygonal,
* has no actual area.
* If the input is empty or is not polygonal,
* this ensures that POLYGON EMPTY is returned.
*
* @param rawAreaGeom an area geometry possibly containing self-intersections
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@
import org.locationtech.jts.geom.LinearRing;

/**
* Represents a {@link LineString} which can be modified to a simplified shape.
* Represents a {@link LineString} which can be modified to a simplified shape.
* This class provides an attribute which specifies the minimum allowable length
* for the modified result.
*
*
* @version 1.7
*/
class TaggedLineString
{

private LineString parentLine;
private final LineString parentLine;
private TaggedLineSegment[] segs;
private List<LineSegment> resultSegs = new ArrayList<LineSegment>();
private int minimumSize;
private boolean isRing = true;
private final List<LineSegment> resultSegs = new ArrayList<LineSegment>();
private final int minimumSize;
private final boolean isRing;

public TaggedLineString(LineString parentLine, int minimumSize, boolean isRing) {
this.parentLine = parentLine;
Expand All @@ -46,8 +46,8 @@ public TaggedLineString(LineString parentLine, int minimumSize, boolean isRing)
public boolean isRing() {
return isRing;
}
public int getMinimumSize() { return minimumSize; }

public int getMinimumSize() { return minimumSize; }
public LineString getParent() { return parentLine; }
public Coordinate[] getParentCoordinates() { return parentLine.getCoordinates(); }
public Coordinate[] getResultCoordinates() { return extractCoordinates(resultSegs); }
Expand All @@ -59,11 +59,11 @@ public Coordinate getCoordinate(int i) {
public int size() {
return parentLine.getNumPoints();
}

public Coordinate getComponentPoint() {
return getParentCoordinates()[1];
}

public int getResultSize()
{
int resultSegsSize = resultSegs.size();
Expand All @@ -78,12 +78,11 @@ public int getResultSize()
* @param i the segment index to retrieve
* @return the result segment
*/
public LineSegment getResultSegment(int i) {
int index = i;
public LineSegment getResultSegment(int i) {
if (i < 0) {
index = resultSegs.size() + i;
i = resultSegs.size() + i;
}
return (LineSegment) resultSegs.get(index);
return resultSegs.get(i);
}

private void init()
Expand All @@ -103,7 +102,7 @@ private void init()
* Add a simplified segment to the result.
* This assumes simplified segments are computed in the order
* they occur in the line.
*
*
* @param seg the result segment to add
*/
public void addToResult(LineSegment seg)
Expand All @@ -125,7 +124,7 @@ private static Coordinate[] extractCoordinates(List<LineSegment> segs)
Coordinate[] pts = new Coordinate[segs.size() + 1];
LineSegment seg = null;
for (int i = 0; i < segs.size(); i++) {
seg = (LineSegment) segs.get(i);
seg = segs.get(i);
pts[i] = seg.p0;
}
// add last point
Expand All @@ -135,8 +134,8 @@ private static Coordinate[] extractCoordinates(List<LineSegment> segs)

void removeRingEndpoint()
{
LineSegment firstSeg = (LineSegment) resultSegs.get(0);
LineSegment lastSeg = (LineSegment) resultSegs.get(resultSegs.size() - 1);
LineSegment firstSeg = resultSegs.get(0);
LineSegment lastSeg = resultSegs.get(resultSegs.size() - 1);

firstSeg.p0 = lastSeg.p0;
resultSegs.remove(resultSegs.size() - 1);
Expand Down
Loading
Loading