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(); - } }
