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

Fix Densifier for segs with length equal to distance tol #676

Merged
merged 1 commit into from
Jan 29, 2021
Merged
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 @@ -25,9 +25,10 @@
/**
* Densifies a {@link Geometry} by inserting extra vertices along the line segments
* contained in the geometry.
* All segments in the created densified geometry will be no longer than
* than the given distance tolerance.
* Densified polygonal geometries are guaranteed to be topologically correct.
* All segments in the created densified geometry will be <b>no longer</b>
* than the given distance tolerance
* (that is, all segments in the output will have length less than or equal to
* the distance tolerance).
* The coordinates created during densification respect the input geometry's
* {@link PrecisionModel}.
* <p>
Expand Down Expand Up @@ -56,10 +57,10 @@ public static Geometry densify(Geometry geom, double distanceTolerance) {
}

/**
* Densifies a coordinate sequence.
* Densifies a list of coordinates.
*
* @param pts
* @param distanceTolerance
* @param pts the coordinate list
* @param distanceTolerance the densify tolerance
* @return the densified coordinate sequence
*/
private static Coordinate[] densifyPoints(Coordinate[] pts,
Expand All @@ -71,18 +72,24 @@ private static Coordinate[] densifyPoints(Coordinate[] pts,
seg.p1 = pts[i + 1];
coordList.add(seg.p0, false);
double len = seg.getLength();

// check if no densification is required
if (len <= distanceTolerance)
continue;

// densify the segment
int densifiedSegCount = (int) (len / distanceTolerance) + 1;
if (densifiedSegCount > 1) {
double densifiedSegLen = len / densifiedSegCount;
for (int j = 1; j < densifiedSegCount; j++) {
double segFract = (j * densifiedSegLen) / len;
Coordinate p = seg.pointAlong(segFract);
precModel.makePrecise(p);
coordList.add(p, false);
}
double densifiedSegLen = len / densifiedSegCount;
for (int j = 1; j < densifiedSegCount; j++) {
double segFract = (j * densifiedSegLen) / len;
Coordinate p = seg.pointAlong(segFract);
precModel.makePrecise(p);
coordList.add(p, false);
}
}
coordList.add(pts[pts.length - 1], false);
// this check handles empty sequences
if (pts.length > 0)
coordList.add(pts[pts.length - 1], false);
return coordList.toCoordinateArray();
}

Expand All @@ -107,7 +114,6 @@ public Densifier(Geometry inputGeom) {
/**
* Sets the distance tolerance for the densification. All line segments
* in the densified geometry will be no longer than the distance tolerance.
* simplified geometry will be within this distance of the original geometry.
* The distance tolerance must be positive.
*
* @param distanceTolerance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,13 @@ protected Geometry transformPolygon(Polygon geom, Geometry parent) {
boolean isAllValidLinearRings = true;
Geometry shell = transformLinearRing(geom.getExteriorRing(), geom);

if (shell == null
|| ! (shell instanceof LinearRing)
|| shell.isEmpty() )
// handle empty inputs, or inputs which are made empty
boolean shellIsNullOrEmpty = shell == null || shell.isEmpty();
if (geom.isEmpty() && shellIsNullOrEmpty ) {
return factory.createPolygon();
}

if (shellIsNullOrEmpty || ! (shell instanceof LinearRing))
isAllValidLinearRings = false;

ArrayList holes = new ArrayList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,31 @@ public void testLine() {
10, "LINESTRING (0 0, 5 6.666666666666668, 10 13.333333333333336, 15 20, 20 26.66666666666667, 25 33.33333333333334, 30 40, 35 35)");
}

public void testLineOfToleranceLength() {
checkDensify("LINESTRING (0 0, 10 0)",
10, "LINESTRING (0 0, 10 0)");
}

public void testLineWithToleranceLengthSeg() {
checkDensify("LINESTRING (0 0, 12 0, 22 0, 34 0)",
10, "LINESTRING (0 0, 6 0, 12 0, 22 0, 28 0, 34 0)");
}

public void testLineEmpty() {
checkDensify("LINESTRING EMPTY",
10, "LINESTRING EMPTY");
}

public void testPointUnchanged() {
checkDensify("POINT (0 0)",
10, "POINT (0 0)");
}

public void testPolygonEmpty() {
checkDensify("POLYGON EMPTY",
10, "POLYGON EMPTY");
}

public void testBox() {
checkDensify("POLYGON ((10 30, 30 30, 30 10, 10 10, 10 30))",
10, "POLYGON ((10 30, 16.666666666666668 30, 23.333333333333336 30, 30 30, 30 23.333333333333332, 30 16.666666666666664, 30 10, 23.333333333333332 10, 16.666666666666664 10, 10 10, 10 16.666666666666668, 10 23.333333333333336, 10 30))");
Expand Down