Skip to content

Commit

Permalink
Fix Douglas Peucker simplifier for XYZM coordinates (#1045)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsantosmerino-wkl authored Jan 3, 2025
1 parent b1313ad commit 658365a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public Coordinate[] simplify()
CoordinateList coordList = new CoordinateList();
for (int i = 0; i < pts.length; i++) {
if (usePt[i])
coordList.add(new Coordinate(pts[i]));
coordList.add(pts[i].copy());
}

if (! isPreserveEndpoint && CoordinateArrays.isRing(pts)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ public void testLineStringTiny() {
10,
"LINESTRING (0 5, 5 5)");
}

public void testLineStringWithFourDimensions() {
checkDPXYZM("LINESTRING ZM(0 5 114.6 1709024189000, 1 5 114.6 1709024190000, 2 5 114.5 1709024192000, 5 5 114.5 1709024196000)",
10,
"LINESTRING ZM(0 5 114.6 1709024189000, 5 5 114.5 1709024196000)");
}

public void testMultiPoint() {
checkDPNoChange("MULTIPOINT(80 200, 240 200, 240 60, 80 60, 80 200, 140 199, 120 120)",
Expand Down Expand Up @@ -166,7 +172,13 @@ private void checkDP(String wkt, double tolerance, String wktExpected) {
Geometry expected = read(wktExpected);
checkEqual(expected, result);
}

private void checkDPXYZM(String wkt, double tolerance, String wktExpected) {
Geometry geom = read(wkt);
Geometry result = DouglasPeuckerSimplifier.simplify(geom, tolerance);
Geometry expected = read(wktExpected);
checkEqualXYZM(expected, result);
}

private void checkDPNoChange(String wkt, double tolerance) {
checkDP(wkt, tolerance, wkt);
}
Expand Down
31 changes: 21 additions & 10 deletions modules/core/src/test/java/test/jts/GeometryTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,48 +126,60 @@ protected void checkEqual(Geometry expected, Geometry actual, double tolerance)
protected void checkEqualXYZ(Geometry expected, Geometry actual) {
Geometry actualNorm = actual.norm();
Geometry expectedNorm = expected.norm();
boolean equal = equalsExactXYZ(actualNorm, expectedNorm);
boolean equal = equalsExactMultipleDimension(actualNorm, expectedNorm, 3);
if (! equal) {
System.out.format(CHECK_EQUAL_FAIL,
writerZ.write(expectedNorm),
writerZ.write(actualNorm) );
}
assertTrue(equal);
}

protected void checkEqualXYZM(Geometry expected, Geometry actual) {
Geometry actualNorm = actual.norm();
Geometry expectedNorm = expected.norm();
boolean equal = equalsExactMultipleDimension(actualNorm, expectedNorm, 4);
if (! equal) {
System.out.format(CHECK_EQUAL_FAIL,
writerZ.write(expectedNorm),
writerZ.write(actualNorm) );
}
assertTrue(equal);
}

private boolean equalsExactXYZ(Geometry a, Geometry b) {
private boolean equalsExactMultipleDimension(Geometry a, Geometry b, int dimension) {
if (a.getClass() != b.getClass()) return false;
if (a.getNumGeometries() != b.getNumGeometries()) return false;
if (a instanceof Point) {
return isEqualDim(((Point) a).getCoordinateSequence(), ((Point) b).getCoordinateSequence(), 3);
return isEqualDim(((Point) a).getCoordinateSequence(), ((Point) b).getCoordinateSequence(), dimension);
}
else if (a instanceof LineString) {
return isEqualDim(((LineString) a).getCoordinateSequence(), ((LineString) b).getCoordinateSequence(), 3);
return isEqualDim(((LineString) a).getCoordinateSequence(), ((LineString) b).getCoordinateSequence(), dimension);
}
else if (a instanceof Polygon) {
return equalsExactXYZPolygon( (Polygon) a, (Polygon) b);
return equalsExactMultipleDimensionPolygon( (Polygon) a, (Polygon) b, dimension);
}
else if (a instanceof GeometryCollection) {
for (int i = 0; i < a.getNumGeometries(); i++) {
if (! equalsExactXYZ(a.getGeometryN(i), b.getGeometryN(i)))
if (! equalsExactMultipleDimension(a.getGeometryN(i), b.getGeometryN(i), dimension))
return false;
}
return true;
}
return false;
}

private boolean equalsExactXYZPolygon(Polygon a, Polygon b) {
private boolean equalsExactMultipleDimensionPolygon(Polygon a, Polygon b, int dimension) {
LinearRing aShell = a.getExteriorRing();
LinearRing bShell = b.getExteriorRing();
if (! isEqualDim(aShell.getCoordinateSequence(), bShell.getCoordinateSequence(), 3))
if (! isEqualDim(aShell.getCoordinateSequence(), bShell.getCoordinateSequence(), dimension))
return false;
if (a.getNumInteriorRing() != b.getNumInteriorRing())
return false;
for (int i = 0; i < a.getNumInteriorRing(); i++) {
LinearRing aHole = a.getInteriorRingN(i);
LinearRing bHole = b.getInteriorRingN(i);
if (! isEqualDim(aHole.getCoordinateSequence(), bHole.getCoordinateSequence(), 3))
if (! isEqualDim(aHole.getCoordinateSequence(), bHole.getCoordinateSequence(), dimension))
return false;
}
return true;
Expand Down Expand Up @@ -198,7 +210,6 @@ protected void checkEqualXYZ(Coordinate expected, Coordinate actual) {
assertEquals("Coordinate Y", expected.getY(), actual.getY() );
assertEquals("Coordinate Z", expected.getZ(), actual.getZ() );
}

protected void checkEqualXY(String message, Coordinate expected, Coordinate actual) {
assertEquals(message + " X", expected.getX(), actual.getX() );
assertEquals(message + " Y", expected.getY(), actual.getY() );
Expand Down

0 comments on commit 658365a

Please sign in to comment.