diff --git a/modules/core/src/main/java/org/locationtech/jts/algorithm/ConvexHull.java b/modules/core/src/main/java/org/locationtech/jts/algorithm/ConvexHull.java index 973ed20d0c..40d04a8ed6 100644 --- a/modules/core/src/main/java/org/locationtech/jts/algorithm/ConvexHull.java +++ b/modules/core/src/main/java/org/locationtech/jts/algorithm/ConvexHull.java @@ -205,8 +205,9 @@ private Coordinate[] reduce(Coordinate[] inputPts) Coordinate[] innerPolyPts = computeInnerOctolateralRing(inputPts); // unable to compute interior polygon for some reason + // Copy the input array, since it will be sorted later if (innerPolyPts == null) - return inputPts; + return inputPts.clone(); // LinearRing ring = geomFactory.createLinearRing(polyPts); // System.out.println(ring); diff --git a/modules/core/src/test/java/org/locationtech/jts/algorithm/ConvexHullTest.java b/modules/core/src/test/java/org/locationtech/jts/algorithm/ConvexHullTest.java index 44cca5496a..b85a366efa 100644 --- a/modules/core/src/test/java/org/locationtech/jts/algorithm/ConvexHullTest.java +++ b/modules/core/src/test/java/org/locationtech/jts/algorithm/ConvexHullTest.java @@ -19,6 +19,7 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.PrecisionModel; +import org.locationtech.jts.io.ParseException; import org.locationtech.jts.io.WKTReader; import junit.framework.Test; @@ -148,6 +149,22 @@ public void testGEOSSortFailure() { "POLYGON ((100 260, 140 350, 300 370, 450 310, 510 140, 380 80, 250 50, 110 140, 100 260))"); } + /** + * Tests a bug which modified the input point array in some cases + * (larger geometries which are nearly linear). + * + * See https://github.com/locationtech/jts/discussions/1082 + */ + public void testInputUnmodified() { + //-- test case is a large nearly-linear geometry + String line = "LINESTRING (74.20888 -245.64678, 16.0148 -54.30037, 15.9566 -54.10903, 15.86931 -53.82201, 15.81112 -53.63066, 15.75292 -53.43931, 15.69473 -53.24797, 15.63654 -53.05662, 15.57834 -52.86528, 15.52015 -52.67393, 15.46195 -52.48258, 15.40376 -52.29124, 15.34557 -52.09989, 15.28737 -51.90854, 15.22918 -51.7172, 15.17098 -51.52585, 15.11279 -51.3345, 15.05459 -51.14316, 14.9964 -50.95181, 14.93821 -50.76046, 14.88001 -50.56912, 14.82182 -50.37777, 14.76362 -50.18643, 14.70543 -49.99508, 14.64724 -49.80373, 14.58904 -49.61239, 14.53085 -49.42104, 14.47265 -49.22969, 14.41446 -49.03835, 14.35627 -48.847, 14.29807 -48.65565, 14.23988 -48.46431, 14.18168 -48.27296, 14.12349 -48.08161, 14.0653 -47.89027, 14.0071 -47.69892, 13.94891 -47.50758, 13.89071 -47.31623, 13.83252 -47.12488, 13.77432 -46.93354, 13.71613 -46.74219, 13.65794 -46.55084, 13.59974 -46.3595, 13.54155 -46.16815, -63.14605 260.17393, -63.18794 260.3695, -63.22983 260.56506, -63.27173 260.76062, -63.31362 260.95619, -63.35551 261.15175, -63.39741 261.34731, -63.4393 261.54288, -63.4812 261.73844, -63.52309 261.934, -63.56498 262.12956, -63.60688 262.32513, -63.64877 262.52069, -63.69067 262.71625, -63.73256 262.91182, -63.77445 263.10738, -63.81635 263.30294, -63.85824 263.49851, -63.90014 263.69407, -63.94203 263.88963, -63.98392 264.0852, -64.02582 264.28076, -64.06771 264.47632, -64.10961 264.67188, -64.1515 264.86745, -64.19339 265.06301, -64.23529 265.25857, -64.27718 265.45414, -64.31907 265.6497, -64.36097 265.84526, -64.40286 266.04083, -64.44476 266.23639, -64.48665 266.43195, -64.52854 266.62751, -64.57044 266.82308, -110.60097 481.69601)"; + Geometry geom = read(line); + Geometry geomCopy = geom.copy(); + geom.convexHull(); + boolean isUnmodified = geomCopy.equalsExact(geom); + assertTrue("Input geometry has been modified", isUnmodified); + } + //========================================================== private void checkConvexHull(String wkt, String wktExpected) {