diff --git a/modules/core/src/main/java/org/locationtech/jts/algorithm/RobustLineIntersector.java b/modules/core/src/main/java/org/locationtech/jts/algorithm/RobustLineIntersector.java index 21a5891773..92ed60715f 100644 --- a/modules/core/src/main/java/org/locationtech/jts/algorithm/RobustLineIntersector.java +++ b/modules/core/src/main/java/org/locationtech/jts/algorithm/RobustLineIntersector.java @@ -15,6 +15,10 @@ *@version 1.7 */ import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.CoordinateXY; +import org.locationtech.jts.geom.CoordinateXYM; +import org.locationtech.jts.geom.CoordinateXYZM; +import org.locationtech.jts.geom.Coordinates; import org.locationtech.jts.geom.Envelope; /** @@ -211,8 +215,8 @@ private static Coordinate copyWithZInterpolate(Coordinate p, Coordinate p1, Coor private static Coordinate copyWithZ(Coordinate p, double z) { Coordinate pCopy = copy(p); - if (! Double.isNaN(z)) { - pCopy.setZ( z ); + if (! Double.isNaN(z) && Coordinates.hasZ(pCopy)) { + pCopy.setZ(z); } return pCopy; } diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/Coordinates.java b/modules/core/src/main/java/org/locationtech/jts/geom/Coordinates.java index 71f5b186f9..a7e79628f0 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/Coordinates.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/Coordinates.java @@ -67,6 +67,26 @@ public static int dimension(Coordinate coordinate) return 3; } + /** + * Check if coordinate can store Z valye, based on subclass of {@link Coordinate}. + * + * @param coordinate supplied coordinate + * @return true if setZ is available + */ + public static boolean hasZ(Coordinate coordinate) + { + if (coordinate instanceof CoordinateXY) { + return false; + } else if (coordinate instanceof CoordinateXYM) { + return false; + } else if (coordinate instanceof CoordinateXYZM) { + return true; + } else if (coordinate instanceof Coordinate) { + return true; + } + return true; + } + /** * Determine number of measures based on subclass of {@link Coordinate}. * diff --git a/modules/core/src/test/java/org/locationtech/jts/algorithm/IntersectionTest.java b/modules/core/src/test/java/org/locationtech/jts/algorithm/IntersectionTest.java index c26af8b92f..4bd8aa02c9 100644 --- a/modules/core/src/test/java/org/locationtech/jts/algorithm/IntersectionTest.java +++ b/modules/core/src/test/java/org/locationtech/jts/algorithm/IntersectionTest.java @@ -4,6 +4,14 @@ import junit.framework.TestCase; import junit.textui.TestRunner; +import org.locationtech.jts.geom.CoordinateSequence; +import org.locationtech.jts.geom.CoordinateSequenceFactory; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryFactory; +import org.locationtech.jts.geom.LinearRing; +import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.geom.impl.CoordinateArraySequenceFactory; +import org.locationtech.jts.io.WKTReader; public class IntersectionTest extends TestCase { private static final double MAX_ABS_ERROR = 1e-5; @@ -71,6 +79,41 @@ public void testLineSegNone() { checkIntersectionLineSegmentNull( 0, 0, 0, 1, 2, 9, 1, 9 ); } + public void testIntersectionXY() throws Exception { + // intersection with dim 3 x dim3 + WKTReader reader = new WKTReader(); + Geometry poly1 = reader.read("POLYGON((0 0 0, 0 10000 2, 10000 10000 2, 10000 0 0, 0 0 0))"); + Geometry clipArea = reader.read("POLYGON((0 0, 0 2500, 2500 2500, 2500 0, 0 0))"); + Geometry clipped1 = poly1.intersection(clipArea); + + // intersection with dim 3 x dim 2 + GeometryFactory gf = poly1.getFactory(); + CoordinateSequenceFactory csf = gf.getCoordinateSequenceFactory(); + double xmin = 0.0; + double xmax = 2500.0; + double ymin = 0.0; + double ymax = 2500.0; + + CoordinateSequence cs = csf.create(5,2); + cs.setOrdinate(0, 0, xmin); + cs.setOrdinate(0, 1, ymin); + cs.setOrdinate(1, 0, xmin); + cs.setOrdinate(1, 1, ymax); + cs.setOrdinate(2, 0, xmax); + cs.setOrdinate(2, 1, ymax); + cs.setOrdinate(3, 0, xmax); + cs.setOrdinate(3, 1, ymin); + cs.setOrdinate(4, 0, xmin); + cs.setOrdinate(4, 1, ymin); + + LinearRing bounds = gf.createLinearRing(cs); + + Polygon fence = gf.createPolygon(bounds, null); + Geometry clipped2 = poly1.intersection(fence); + + assertTrue(clipped1.equals(clipped2)); + } + //================================================== private void checkIntersection(double p1x, double p1y, double p2x, double p2y,