You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by js...@apache.org on 2026/10/12 19:28:06 UTC
(sis) 01/02: feat(Geometry): move MultiCurve and MultiSurface methods on GeometryCollection
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
commit 70c15a524c72f85db6fad7e6338173190d7be137
Author: jsorel <jo...@geomatys.com>
AuthorDate: Mon Oct 12 15:04:46 2026 +0200
feat(Geometry): move MultiCurve and MultiSurface methods on GeometryCollection
---
.../apache/sis/geometries/GeometryCollection.java | 95 ++++++++++++++++++++++
.../apache/sis/geometries/curve/MultiCurve.java | 40 +--------
.../apache/sis/geometries/curve/ProductCurve.java | 12 +++
.../internal/shared/DefaultProductCurve.java | 10 +++
.../sis/geometries/surface/MultiSurface.java | 47 +----------
5 files changed, 119 insertions(+), 85 deletions(-)
diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryCollection.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryCollection.java
index 55af9eb961..72125eedd1 100644
--- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryCollection.java
+++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryCollection.java
@@ -17,6 +17,7 @@
package org.apache.sis.geometries;
import java.util.Set;
+import javax.measure.Quantity;
import static org.opengis.annotation.Specification.ISO_19107;
import org.opengis.annotation.UML;
import org.opengis.geometry.Envelope;
@@ -30,6 +31,8 @@ import org.apache.sis.geometries.point.MultiPoint;
import org.apache.sis.geometries.solid.MultiPolyhedron;
import org.apache.sis.geometries.surface.MultiSurface;
import org.apache.sis.geometry.GeneralEnvelope;
+import org.apache.sis.measure.Quantities;
+import org.apache.sis.measure.Units;
/**
@@ -51,6 +54,17 @@ import org.apache.sis.geometry.GeneralEnvelope;
* implementation which needs a genuine set of sets should use a plain array of geometries instead
* of this interface.</p>
*
+ * Deviation from OGC-SFA :<br>
+ * <ul>
+ * <li>OGC-SFA defines several sub types of GeometryCollection, like MultiCurve, MultiSurface, MultiLineString, MultiPolygon, MultiPoint.
+ * The subtypes defined : getLength, isClosed(), getArea().
+ * Since ISO-19107:2019 covers a much larger scope of geometry, creating a subtype for each would duplicate the number of interfaces.
+ * ISO-19107:2019 decided instead to have a single GeometryCollection and add a getElementType restricting the possible content
+ * of the collection. The methods from OGC SFA are then moved on GeometryCollection but will raise an error if the collection element type
+ * is not applicable.
+ * </li>
+ * </ul>
+ *
* @param <T> type of the elements of this collection.
*
* @author Johann Sorel (Geomatys)
@@ -204,4 +218,85 @@ public sealed interface GeometryCollection<T extends Geometry> extends Geometry
return ConcatenatedDataPoints.of(elements);
}
+ /**
+ * Returns TRUE if this MultiCurve is closed [StartPoint () = EndPoint () for each Curve in this MultiCurve].
+ *
+ * Can be called only if collection element type is made of Curve.
+ *
+ * @see OGC Simple Feature Access 1.2.1 - 6.1.8.2
+ * @return true if multicurve is closed.
+ */
+ default boolean isClosed() {
+ assertElementType(GeometryType.CURVE);
+ for (int i = 0, n = getNumGeometries(); i < n; i++) {
+ if (!((Curve) getGeometryN(i)).isClosed()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * The Length of this MultiCurve which is equal to the sum of the lengths of the element Curves.
+ * The unit of measurement is the one of the first element,
+ * or dimensionless if this MultiCurve has no element.
+ *
+ * Can be called only if collection element type is made of Curve.
+ *
+ * @see OGC Simple Feature Access 1.2.1 - 6.1.8.2
+ * @return length of the multicurve.
+ */
+ default Quantity<?> getLength() {
+ assertElementType(GeometryType.CURVE);
+ final int n = getNumGeometries();
+ if (n == 0) {
+ return Quantities.create(0, Units.UNITY);
+ }
+ Quantity<?> length = ((Curve) getGeometryN(0)).getLength();
+ for (int i = 1; i < n; i++) {
+ length = Geometries.add(length, ((Curve)getGeometryN(i)).getLength());
+ }
+ return length;
+ }
+
+ /**
+ * The area of this MultiSurface, as measured in the spatial reference system of this MultiSurface.
+ * The unit of measurement is the one of the first element,
+ * or dimensionless if this MultiSurface has no element.
+ *
+ * Can be called only if collection element type is made of Surface.
+ *
+ * @see OGC Simple Feature Access 1.2.1 - 6.1.13.2
+ * @return area of the surface.
+ */
+ default Quantity<?> getArea() {
+ assertElementType(GeometryType.SURFACE);
+ final int n = getNumGeometries();
+ if (n == 0) {
+ return Quantities.create(0, Units.UNITY);
+ }
+ Quantity<?> area = ((Surface)getGeometryN(0)).getArea();
+ for (int i = 1; i < n; i++) {
+ area = Geometries.add(area, ((Surface)getGeometryN(i)).getArea());
+ }
+ return area;
+ }
+
+ /**
+ * A Point guaranteed to be on this MultiSurface.
+ *
+ * @see OGC Simple Feature Access 1.2.1 - 6.1.13.2
+ * @return point guaranteed to be on this MultiSurface.
+ */
+ default Point getPointOnSurface() {
+ throw new UnsupportedOperationException();
+ }
+
+ private void assertElementType(GeometryType type) {
+ for (GeometryType gt : getElementType()) {
+ if (!type.isAssignableFrom(gt)) {
+ throw new IllegalArgumentException("Collection must be composed of " + type + " to call this method.");
+ }
+ }
+ }
}
diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/MultiCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/MultiCurve.java
index c10246b978..30b64e6002 100644
--- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/MultiCurve.java
+++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/MultiCurve.java
@@ -17,14 +17,11 @@
package org.apache.sis.geometries.curve;
import java.util.Set;
-import javax.measure.Quantity;
+import javax.print.attribute.standard.MediaSize.ISO;
import org.apache.sis.geometries.Curve;
-import org.apache.sis.geometries.Geometries;
import org.apache.sis.geometries.GeometryCollection;
import org.apache.sis.geometries.GeometryType;
import org.apache.sis.geometries.internal.shared.DefaultMultiCurve;
-import org.apache.sis.measure.Quantities;
-import org.apache.sis.measure.Units;
/**
@@ -70,39 +67,4 @@ public sealed interface MultiCurve<T extends Curve> extends GeometryCollection<T
return Set.of(GeometryType.CURVE);
}
- /**
- * Returns TRUE if this MultiCurve is closed [StartPoint () = EndPoint () for each Curve in this MultiCurve].
- *
- * @see OGC Simple Feature Access 1.2.1 - 6.1.8.2
- * @return true if multicurve is closed.
- */
- default boolean isClosed() {
- for (int i = 0, n = getNumGeometries(); i < n; i++) {
- if (!getGeometryN(i).isClosed()) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * The Length of this MultiCurve which is equal to the sum of the lengths of the element Curves.
- * The unit of measurement is the one of the first element,
- * or dimensionless if this MultiCurve has no element.
- *
- * @see OGC Simple Feature Access 1.2.1 - 6.1.8.2
- * @return length of the multicurve.
- */
- default Quantity<?> getLength() {
- final int n = getNumGeometries();
- if (n == 0) {
- return Quantities.create(0, Units.UNITY);
- }
- Quantity<?> length = getGeometryN(0).getLength();
- for (int i = 1; i < n; i++) {
- length = Geometries.add(length, getGeometryN(i).getLength());
- }
- return length;
- }
-
}
diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ProductCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ProductCurve.java
index 085c4124fa..c7352ba201 100644
--- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ProductCurve.java
+++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ProductCurve.java
@@ -18,6 +18,7 @@ package org.apache.sis.geometries.curve;
import java.util.List;
import java.util.Set;
+import javax.measure.Quantity;
import static org.opengis.annotation.Specification.ISO_19107;
import org.opengis.annotation.UML;
import org.apache.sis.geometries.Curve;
@@ -146,4 +147,15 @@ public sealed interface ProductCurve extends Curve, GeometryCollection<Curve>
return GeometryCollection.super.getDataPoints();
}
+ @Override
+ default Quantity<?> getLength() {
+ return Curve.super.getLength();
+ }
+
+ @Override
+ default boolean isClosed() {
+ return Curve.super.isClosed();
+ }
+
+
}
diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultProductCurve.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultProductCurve.java
index 46edccafc8..ee1dd07d44 100644
--- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultProductCurve.java
+++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultProductCurve.java
@@ -17,6 +17,7 @@
package org.apache.sis.geometries.internal.shared;
import java.util.List;
+import javax.measure.Quantity;
import org.apache.sis.geometries.Curve;
import org.apache.sis.geometries.GeometryType;
import org.apache.sis.geometries.cs.Projection;
@@ -76,4 +77,13 @@ public non-sealed class DefaultProductCurve extends DefaultGeometryCollection<Cu
throw new UnsupportedOperationException("Not supported yet.");
}
+ @Override
+ public Quantity<?> getLength() {
+ return ProductCurve.super.getLength();
+ }
+
+ @Override
+ public boolean isClosed() {
+ return ProductCurve.super.isClosed();
+ }
}
diff --git a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/MultiSurface.java b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/MultiSurface.java
index f6fefe82ae..a37f71e1a2 100644
--- a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/MultiSurface.java
+++ b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/MultiSurface.java
@@ -17,15 +17,11 @@
package org.apache.sis.geometries.surface;
import java.util.Set;
-import javax.measure.Quantity;
-import org.apache.sis.geometries.Geometries;
+import javax.print.attribute.standard.MediaSize.ISO;
import org.apache.sis.geometries.GeometryCollection;
import org.apache.sis.geometries.GeometryType;
-import org.apache.sis.geometries.Point;
import org.apache.sis.geometries.Surface;
import org.apache.sis.geometries.internal.shared.DefaultMultiSurface;
-import org.apache.sis.measure.Quantities;
-import org.apache.sis.measure.Units;
/**
@@ -67,45 +63,4 @@ public sealed interface MultiSurface<T extends Surface> extends GeometryCollecti
return Set.of(GeometryType.SURFACE);
}
- /**
- * The area of this MultiSurface, as measured in the spatial reference system of this MultiSurface.
- * The unit of measurement is the one of the first element,
- * or dimensionless if this MultiSurface has no element.
- *
- * @see OGC Simple Feature Access 1.2.1 - 6.1.13.2
- * @return area of the surface.
- */
- default Quantity<?> getArea() {
- final int n = getNumGeometries();
- if (n == 0) {
- return Quantities.create(0, Units.UNITY);
- }
- Quantity<?> area = getGeometryN(0).getArea();
- for (int i = 1; i < n; i++) {
- area = Geometries.add(area, getGeometryN(i).getArea());
- }
- return area;
- }
-
- /**
- * The mathematical centroid for this MultiSurface.
- * The result is not guaranteed to be on this MultiSurface.
- *
- * @see OGC Simple Feature Access 1.2.1 - 6.1.13.2
- * @return centroid for this MultiSurface
- */
- @Override
- default Point getCentroid() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * A Point guaranteed to be on this MultiSurface.
- *
- * @see OGC Simple Feature Access 1.2.1 - 6.1.13.2
- * @return point guaranteed to be on this MultiSurface.
- */
- default Point getPointOnSurface() {
- throw new UnsupportedOperationException();
- }
}