From a3d190e4a1492d127addf42dea914e858f9d8c59 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Fri, 3 Jan 2025 16:45:17 -0800 Subject: [PATCH] Fix VWSimplifier coordinate aliasing --- .../jts/simplify/VWLineSimplifier.java | 5 +++-- .../jts/simplify/VWSimplifierTest.java | 11 +++++++++-- .../test/java/test/jts/GeometryTestCase.java | 17 +++++++++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/modules/core/src/main/java/org/locationtech/jts/simplify/VWLineSimplifier.java b/modules/core/src/main/java/org/locationtech/jts/simplify/VWLineSimplifier.java index c5f974b8c8..2126e17e4f 100644 --- a/modules/core/src/main/java/org/locationtech/jts/simplify/VWLineSimplifier.java +++ b/modules/core/src/main/java/org/locationtech/jts/simplify/VWLineSimplifier.java @@ -13,6 +13,7 @@ package org.locationtech.jts.simplify; import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.CoordinateArrays; import org.locationtech.jts.geom.CoordinateList; import org.locationtech.jts.geom.Triangle; @@ -51,9 +52,9 @@ public Coordinate[] simplify() Coordinate[] simp = vwLine.getCoordinates(); // ensure computed value is a valid line if (simp.length < 2) { - return new Coordinate[] { simp[0], new Coordinate(simp[0]) }; + return new Coordinate[] { simp[0].copy(), simp[0].copy() }; } - return simp; + return CoordinateArrays.copyDeep(simp); } private double simplifyVertex(VWLineSimplifier.VWVertex vwLine) diff --git a/modules/core/src/test/java/org/locationtech/jts/simplify/VWSimplifierTest.java b/modules/core/src/test/java/org/locationtech/jts/simplify/VWSimplifierTest.java index 28e3a427dc..32b2c0079e 100644 --- a/modules/core/src/test/java/org/locationtech/jts/simplify/VWSimplifierTest.java +++ b/modules/core/src/test/java/org/locationtech/jts/simplify/VWSimplifierTest.java @@ -12,18 +12,20 @@ package org.locationtech.jts.simplify; +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.CoordinateFilter; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.io.ParseException; import org.locationtech.jts.io.WKTReader; -import junit.framework.TestCase; +import test.jts.GeometryTestCase; /** * @version 1.7 */ public class VWSimplifierTest - extends TestCase + extends GeometryTestCase { public VWSimplifierTest(String name) { super(name); @@ -67,6 +69,11 @@ public void testPolygonSpikeInHole() throws Exception { .test(); } + public void testNoAlias() { + Geometry geom = read("LINESTRING (1 1, 3 6, 6 5, 8 6, 9 1)"); + Geometry result = VWSimplifier.simplify(geom, 2); + checkNoAlias(geom, result); + } } diff --git a/modules/core/src/test/java/test/jts/GeometryTestCase.java b/modules/core/src/test/java/test/jts/GeometryTestCase.java index 8b308719a5..8b51fd91f9 100644 --- a/modules/core/src/test/java/test/jts/GeometryTestCase.java +++ b/modules/core/src/test/java/test/jts/GeometryTestCase.java @@ -38,6 +38,7 @@ public abstract class GeometryTestCase extends TestCase{ private static final String CHECK_EQUAL_FAIL = "FAIL - Expected = %s -- Actual = %s\n"; private static final String CHECK_EQUAL_FAIL_MSG = "FAIL - %s: Expected = %s -- Actual = %s\n"; + private static final String CHECK_NO_AlIAS_FAIL = "FAIL - geometries have aliased coordinates\n"; final GeometryFactory geomFactory; @@ -225,6 +226,22 @@ protected void checkEqualXY(String message, Coordinate expected, Coordinate actu assertEquals(message + " Y", expected.getY(), actual.getY(), tolerance); } + protected void checkNoAlias(Geometry geom, Geometry geom2) { + Geometry geom2Copy = geom2.copy(); + geom.apply(new CoordinateFilter() { + + @Override + public void filter(Coordinate coord) { + coord.x = coord.x + 1; + } + + }); + boolean equal = geom2.equalsExact(geom2Copy); + if (! equal) { + System.out.println(CHECK_NO_AlIAS_FAIL); + fail(); + } + } /** * Reads a {@link Geometry} from a WKT string using a custom {@link GeometryFactory}.