Skip to content

Commit

Permalink
Line endings
Browse files Browse the repository at this point in the history
  • Loading branch information
FObermaier committed Jan 25, 2024
1 parent 7cc545b commit da65acd
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 @@ -64,10 +64,10 @@ public static Geometry simplify(Geometry geom, double distanceTolerance)
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,26 +98,26 @@ 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);
}

Expand All @@ -132,12 +132,12 @@ 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,10 +21,10 @@
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
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 Down Expand Up @@ -102,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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class TaggedLineStringSimplifier
private Coordinate[] linePts;

public TaggedLineStringSimplifier(LineSegmentIndex inputIndex,
LineSegmentIndex outputIndex,
LineSegmentIndex outputIndex,
ComponentJumpChecker crossChecker)
{
this.inputIndex = inputIndex;
Expand All @@ -51,7 +51,7 @@ public TaggedLineStringSimplifier(LineSegmentIndex inputIndex,
/**
* Simplifies the given {@link TaggedLineString}
* using the distance tolerance specified.
*
*
* @param line the linestring to simplify
* @param distanceTolerance the simplification distance tolerance
*/
Expand All @@ -60,7 +60,7 @@ void simplify(TaggedLineString line, double distanceTolerance)
this.line = line;
linePts = line.getParentCoordinates();
simplifySection(0, linePts.length - 1, 0, distanceTolerance);

if (line.isRing() && CoordinateArrays.isRing(linePts)) {
simplifyRingEndpoint(distanceTolerance);
}
Expand Down Expand Up @@ -94,20 +94,20 @@ private void simplifySection(int i, int j, int depth, double distanceTolerance)

double[] distance = new double[1];
int furthestPtIndex = findFurthestPoint(linePts, i, j, distance);

// flattening must be less than distanceTolerance
if (distance[0] > distanceTolerance) {
isValidToSimplify = false;
}

if (isValidToSimplify) {
// test if flattened section would cause intersection or jump
LineSegment flatSeg = new LineSegment();
flatSeg.p0 = linePts[i];
flatSeg.p1 = linePts[j];
isValidToSimplify = isTopologyValid(line, i, j, flatSeg);
}

if (isValidToSimplify) {
LineSegment newSeg = flatten(i, j);
line.addToResult(newSeg);
Expand Down Expand Up @@ -163,7 +163,7 @@ private int findFurthestPoint(Coordinate[] pts, int i, int j, double[] maxDistan
* replacing them with a line between the endpoints.
* The input and output indexes are updated
* to reflect this.
*
*
* @param start the start index of the flattened section
* @param end the end index of the flattened section
* @return the new segment created
Expand All @@ -177,16 +177,16 @@ private LineSegment flatten(int start, int end)
// update the input and output indexes
outputIndex.add(newSeg);
remove(line, start, end);

return newSeg;
}

/**
* Tests if line topology remains valid after flattening a section of the line.
* The flattened section is being replaced by the flattening segment,
* so there is no need to test it
* The flattened section is being replaced by the flattening segment,
* so there is no need to test it
* (and it may well intersect the segment).
*
*
* @param line
* @param sectionStart
* @param sectionEnd
Expand All @@ -197,11 +197,11 @@ private boolean isTopologyValid(TaggedLineString line,
int sectionStart, int sectionEnd,
LineSegment flatSeg)
{
if (hasOutputIntersection(flatSeg))
if (hasOutputIntersection(flatSeg))
return false;
if (hasInputIntersection(line, sectionStart, sectionEnd, flatSeg))
if (hasInputIntersection(line, sectionStart, sectionEnd, flatSeg))
return false;
if (jumpChecker.hasJump(line, sectionStart, sectionEnd, flatSeg))
if (jumpChecker.hasJump(line, sectionStart, sectionEnd, flatSeg))
return false;
return true;
}
Expand All @@ -210,17 +210,17 @@ private boolean isTopologyValid(TaggedLineString line, LineSegment seg1, LineSeg
LineSegment flatSeg) {
//-- if segments are already flat, topology is unchanged and so is valid
//-- (otherwise, output and/or input intersection test would report false positive)
if (isCollinear(seg1.p0, flatSeg))
if (isCollinear(seg1.p0, flatSeg))
return true;
if (hasOutputIntersection(flatSeg))
if (hasOutputIntersection(flatSeg))
return false;
if (hasInputIntersection(flatSeg))
if (hasInputIntersection(flatSeg))
return false;
if (jumpChecker.hasJump(line, seg1, seg2, flatSeg))
if (jumpChecker.hasJump(line, seg1, seg2, flatSeg))
return false;
return true;
}

private boolean isCollinear(Coordinate pt, LineSegment seg) {
return Orientation.COLLINEAR == seg.orientationIndex(pt);
}
Expand All @@ -241,7 +241,7 @@ private boolean hasInputIntersection(LineSegment flatSeg)
{
return hasInputIntersection(null, -1, -1, flatSeg);
}

private boolean hasInputIntersection(TaggedLineString line,
int excludeStart, int excludeEnd,
LineSegment flatSeg)
Expand All @@ -250,11 +250,11 @@ private boolean hasInputIntersection(TaggedLineString line,
for (Iterator i = querySegs.iterator(); i.hasNext(); ) {
TaggedLineSegment querySeg = (TaggedLineSegment) i.next();
if (hasInvalidIntersection(querySeg, flatSeg)) {
/**
/*
* Ignore the intersection if the intersecting segment is part of the section being collapsed
* to the candidate segment
*/
if (line != null
if (line != null
&& isInLineSection(line, excludeStart, excludeEnd, querySeg))
continue;
return true;
Expand All @@ -265,12 +265,12 @@ && isInLineSection(line, excludeStart, excludeEnd, querySeg))

/**
* Tests whether a segment is in a section of a TaggedLineString.
* Sections may wrap around the endpoint of the line,
* Sections may wrap around the endpoint of the line,
* to support ring endpoint simplification.
* This is indicated by excludedStart > excludedEnd
*
*
* @param line the TaggedLineString containing the section segments
* @param excludeStart the index of the first segment in the excluded section
* @param excludeStart the index of the first segment in the excluded section
* @param excludeEnd the index of the last segment in the excluded section
* @param seg the segment to test
* @return true if the test segment intersects some segment in the line not in the excluded section
Expand All @@ -292,7 +292,7 @@ private static boolean isInLineSection(
else {
//-- section wraps around the end of a ring
if (segIndex >= excludeStart || segIndex <= excludeEnd)
return true;
return true;
}
return false;
}
Expand Down
Loading

0 comments on commit da65acd

Please sign in to comment.