diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/Geometry.java b/modules/core/src/main/java/org/locationtech/jts/geom/Geometry.java index e6e434dc8e..b0dd119b96 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/Geometry.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/Geometry.java @@ -556,10 +556,27 @@ public Point getInteriorPoint() * For example, a 0-dimensional geometry (e.g. a Point) * may have a coordinate dimension of 3 (X,Y,Z). * - *@return the topological dimension of this geometry. + * @return the topological dimension of this geometry. + * + * @see #hasDimension(int) */ public abstract int getDimension(); + /** + * Tests whether an atomic geometry or any element of a collection + * has the specified dimension. + * In particular, this can be used with mixed-dimension {@link GeometryCollection}s + * to test if they contain an element of the specified dimension. + * + * @param dim the dimension to test + * @return true if the geometry has or contains an element with the dimension + * + * @see #getDimension() + */ + public boolean hasDimension(int dim) { + return dim == getDimension(); + } + /** * Returns the boundary, or an empty geometry of appropriate dimension * if this Geometry is empty. diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/GeometryCollection.java b/modules/core/src/main/java/org/locationtech/jts/geom/GeometryCollection.java index 4a72f0e416..42e0f8d1d5 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/GeometryCollection.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/GeometryCollection.java @@ -100,6 +100,14 @@ public int getDimension() { return dimension; } + public boolean hasDimension(int dim) { + for (int i = 0; i < geometries.length; i++) { + if (geometries[i].hasDimension(dim)) + return true; + } + return false; + } + public int getBoundaryDimension() { int dimension = Dimension.FALSE; for (int i = 0; i < geometries.length; i++) { diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/MultiLineString.java b/modules/core/src/main/java/org/locationtech/jts/geom/MultiLineString.java index d49f562234..418f688f04 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/MultiLineString.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/MultiLineString.java @@ -59,6 +59,10 @@ public int getDimension() { return 1; } + public boolean hasDimension(int dim) { + return dim == 1; + } + public int getBoundaryDimension() { if (isClosed()) { return Dimension.FALSE; diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/MultiPoint.java b/modules/core/src/main/java/org/locationtech/jts/geom/MultiPoint.java index ec14068170..c1d73a80d3 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/MultiPoint.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/MultiPoint.java @@ -54,6 +54,10 @@ public int getDimension() { return 0; } + public boolean hasDimension(int dim) { + return dim == 0; + } + public int getBoundaryDimension() { return Dimension.FALSE; } diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/MultiPolygon.java b/modules/core/src/main/java/org/locationtech/jts/geom/MultiPolygon.java index d795b4db7e..23284a6d82 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/MultiPolygon.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/MultiPolygon.java @@ -68,6 +68,10 @@ public int getDimension() { return 2; } + public boolean hasDimension(int dim) { + return dim == 2; + } + public int getBoundaryDimension() { return 1; } diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/prep/PreparedLineStringIntersects.java b/modules/core/src/main/java/org/locationtech/jts/geom/prep/PreparedLineStringIntersects.java index b0d3e435e1..2330a80c58 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/prep/PreparedLineStringIntersects.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/prep/PreparedLineStringIntersects.java @@ -78,10 +78,6 @@ public boolean intersects(Geometry geom) if (segsIntersect) return true; } - /** - * For L/L case we are done - */ - if (geom.getDimension() == 1) return false; /** * For L/A case, need to check for proper inclusion of the target in the test @@ -92,7 +88,7 @@ public boolean intersects(Geometry geom) /** * For L/P case, need to check if any points lie on line(s) */ - if (geom.getDimension() == 0) + if (geom.hasDimension(0)) return isAnyTestPointInTarget(geom); return false; diff --git a/modules/core/src/test/java/org/locationtech/jts/geom/GeometryCollectionImplTest.java b/modules/core/src/test/java/org/locationtech/jts/geom/GeometryCollectionImplTest.java index f1d1489931..65938239d7 100644 --- a/modules/core/src/test/java/org/locationtech/jts/geom/GeometryCollectionImplTest.java +++ b/modules/core/src/test/java/org/locationtech/jts/geom/GeometryCollectionImplTest.java @@ -19,6 +19,7 @@ import junit.framework.TestCase; import junit.framework.TestSuite; import junit.textui.TestRunner; +import test.jts.GeometryTestCase; /** @@ -26,7 +27,7 @@ * * @version 1.7 */ -public class GeometryCollectionImplTest extends TestCase { +public class GeometryCollectionImplTest extends GeometryTestCase { PrecisionModel precisionModel = new PrecisionModel(1000); GeometryFactory geometryFactory = new GeometryFactory(precisionModel, 0); @@ -44,6 +45,29 @@ public void testGetDimension() throws Exception { GeometryCollection g = (GeometryCollection) reader.read("GEOMETRYCOLLECTION (POINT (10 10), POINT (30 30), LINESTRING (15 15, 20 20))"); assertEquals(1, g.getDimension()); } + + public void testHasDimension() { + Geometry mixedGC = read("GEOMETRYCOLLECTION (POINT (10 10), LINESTRING (15 15, 20 20), POLYGON ((10 20, 20 20, 20 10, 10 10, 10 20)))"); + assertTrue(mixedGC.hasDimension(0)); + assertTrue(mixedGC.hasDimension(1)); + assertTrue(mixedGC.hasDimension(2)); + + Geometry mA = read("MULTIPOLYGON (((10 20, 20 20, 20 10, 10 10, 10 20)), ((30 30, 30 20, 20 20, 20 30, 30 30)))"); + assertFalse(mA.hasDimension(0)); + assertFalse(mA.hasDimension(1)); + assertTrue(mA.hasDimension(2)); + + Geometry mL = read("MULTILINESTRING ((5 5, 10 5), (15 5, 20 5))"); + assertFalse(mL.hasDimension(0)); + assertTrue(mL.hasDimension(1)); + assertFalse(mL.hasDimension(2)); + + Geometry mP = read("MULTIPOINT ((10 10), (20 20))"); + assertTrue(mP.hasDimension(0)); + assertFalse(mP.hasDimension(1)); + assertFalse(mP.hasDimension(2)); + + } public void testGetCoordinates() throws Exception { GeometryCollection g = (GeometryCollection) reader.read("GEOMETRYCOLLECTION (POINT (10 10), POINT (30 30), LINESTRING (15 15, 20 20))"); diff --git a/modules/tests/src/test/resources/testxml/general/TestPreparedPredicatesWithGeometryCollection.xml b/modules/tests/src/test/resources/testxml/general/TestPreparedPredicatesWithGeometryCollection.xml index 9ea3821932..284d20b341 100644 --- a/modules/tests/src/test/resources/testxml/general/TestPreparedPredicatesWithGeometryCollection.xml +++ b/modules/tests/src/test/resources/testxml/general/TestPreparedPredicatesWithGeometryCollection.xml @@ -76,6 +76,16 @@ true - + + LineString against GC, with point at endpoint + + + LINESTRING (0 0, 1 1) + + + GEOMETRYCOLLECTION (POINT (1 1), LINESTRING (2 2, 3 3)) + + true +