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 <[email protected]>
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();
-    }
 }

Reply via email to