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 6b00476a2d48fa4123a971f5f02712c9b4d25260
Author: jsorel <[email protected]>
AuthorDate: Mon Sep 14 16:02:18 2026 +0200

    feat(Geometry): implement several small methods
---
 .../main/org/apache/sis/geometries/Curve.java      | 56 +++++++++++++++++-----
 .../main/org/apache/sis/geometries/Geometry.java   | 33 ++++++++++---
 .../main/org/apache/sis/geometries/Point.java      | 23 +++++++++
 .../main/org/apache/sis/geometries/Primitive.java  | 18 +++++++
 4 files changed, 112 insertions(+), 18 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java
index c120566a77..82df3a4fb9 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java
@@ -33,6 +33,8 @@ import org.apache.sis.geometries.curve.Spiral;
 import org.apache.sis.geometries.internal.shared.DefaultReversedCurve;
 import org.apache.sis.maths.Array;
 import org.apache.sis.maths.Vector;
+import org.apache.sis.measure.Quantities;
+import org.apache.sis.measure.Units;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
 import org.opengis.geometry.DirectPosition;
@@ -201,6 +203,24 @@ public sealed interface Curve extends Orientable
         return isCycle() && isSimple();
     }
 
+    /**
+     * Returns the two end points of this curve, or the empty geometry when 
this curve is
+     * {@linkplain #isClosed() closed} and therefore has no end.
+     *
+     * @return boundary of this curve.
+     *
+     * @see OGC Simple Feature Access 1.2.1 - 6.1.6.2
+     * @see ISO 19107:2019 - 6.4.4.7
+     */
+    @UML(identifier="boundary", specification=ISO_19107)
+    @Override
+    default Geometry boundary() {
+        if (isEmpty() || isClosed()) {
+            return GeometryFactory.createEmpty(getCoordinateReferenceSystem());
+        }
+        return GeometryFactory.createMultiPoint(getStartPoint(), 
getEndPoint());
+    }
+
     /**
      * Positions used to build the geometry of this curve, the way they are 
used depending on the interpolation.
      *
@@ -314,8 +334,12 @@ public sealed interface Curve extends Orientable
      */
     @UML(identifier="startParam", specification=ISO_19107)
     default Length getStartParam() {
-        //TODO
-        throw new UnsupportedOperationException();
+        /*
+         * Zero, since the arc length parameterization of a curve spans [0 … 
length] as stated by
+         * `getLength()`. A curve which is a segment of another one, and which 
therefore starts
+         * where the preceding segment ended, has to override.
+         */
+        return Quantities.create(0, Units.METRE);
     }
 
     /**
@@ -334,8 +358,14 @@ public sealed interface Curve extends Orientable
      */
     @UML(identifier="endParam", specification=ISO_19107)
     default Length getEndParam() {
-        //TODO
-        throw new UnsupportedOperationException();
+        /*
+         * The constraint above: the difference with the start parameter is 
the length of the
+         * curve. This holds whatever the start parameter, so a segment which 
overrides
+         * `getStartParam()` gets the right answer without overriding this 
method.
+         */
+        final Length start = getStartParam();
+        final Length length = getLength();
+        return Quantities.castOrCopy(start.add(length));
     }
 
     /**
@@ -349,8 +379,7 @@ public sealed interface Curve extends Orientable
      */
     @UML(identifier="numDerivativesInterior", specification=ISO_19107)
     default Integer getNumDerivativesInterior() {
-        //TODO
-        throw new UnsupportedOperationException();
+        return 0;       // C⁰, which a curve always is since it is connected.
     }
 
     /**
@@ -364,8 +393,7 @@ public sealed interface Curve extends Orientable
      */
     @UML(identifier="numDerivativesStart", specification=ISO_19107)
     default Integer getNumDerivativesStart() {
-        //TODO
-        throw new UnsupportedOperationException();
+        return 0;       // C⁰, the weakest continuity, which is what a 
junction guarantees.
     }
 
     /**
@@ -379,8 +407,7 @@ public sealed interface Curve extends Orientable
      */
     @UML(identifier="numDerivativesEnd", specification=ISO_19107)
     default Integer getNumDerivativesEnd() {
-        //TODO
-        throw new UnsupportedOperationException();
+        return 0;       // C⁰, the weakest continuity, which is what a 
junction guarantees.
     }
 
     /**
@@ -395,8 +422,13 @@ public sealed interface Curve extends Orientable
     @UML(identifier="reverse", specification=ISO_19107)
     @Override
     default Curve getReverse() {
-        //TODO
-        throw new UnsupportedOperationException();
+        /*
+         * A view of this curve carrying the opposite orientation sign. It is 
a view and not a copy
+         * because reversing changes no coordinate: which end is the start one 
is an orientation,
+         * not a geometry. `DefaultReversedCurve` returns this curve back from 
its own `getReverse()`,
+         * so wrapping never nests.
+         */
+        return GeometryFactory.createReversed(this);
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java
index bbcf9ae742..70e5938beb 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometry.java
@@ -125,13 +125,17 @@ public sealed interface Geometry
      * <p>Difference with ISO 19107: we return a single Metadata instead of a 
list of URI,
      * whose first element would point to the normative document describing 
this geometry.</p>
      *
-     * @return metadata about this geometry.
+     * @return metadata about this geometry, or {@code null} if none.
      *
      * @see ISO 19107:2019 - 6.4.4.18
      */
     @UML(identifier="metadata", specification=ISO_19107)
     default Metadata getMetadata() {
-        throw new UnsupportedOperationException();
+        /*
+         * Absent, which the standard defines as meaning that ISO 19107 itself 
is the applicable
+         * documentation. Implementations departing from the standard should 
say so here.
+         */
+        return null;
     }
 
     /**
@@ -176,6 +180,15 @@ public sealed interface Geometry
      */
     @UML(identifier="dimension", specification=ISO_19107)
     default int getDimension(DirectPosition point) {
+        if (point == null) {
+            /*
+             * The dimension of the whole geometry, which is what 
`getTopologicDimension()` returns.
+             * A position is needed only because an aggregate may mix 
components of different
+             * dimensions; every homogeneous geometry answers the same at 
every interior position,
+             * which is what `Primitive` relies on.
+             */
+            return getTopologicDimension();
+        }
         throw new UnsupportedOperationException();
     }
 
@@ -354,8 +367,12 @@ public sealed interface Geometry
      */
     @UML(identifier="closure", specification=ISO_19107)
     default Geometry getClosure() {
-        //TODO remove this method default when all classes implement it.
-        throw new UnsupportedOperationException();
+        /*
+         * Every geometry of this package is metrically closed, as stated in 
the constraints of
+         * this interface: a curve contains its end points, a surface its 
boundary curves and a
+         * solid its boundary surfaces. A geometry is therefore its own 
closure.
+         */
+        return this;
     }
 
     /**
@@ -375,8 +392,12 @@ public sealed interface Geometry
      */
     @UML(identifier="maximalComplex", specification=ISO_19107)
     default Geometry getMaximalComplex() {
-        //TODO remove this method default when all classes implement it.
-        throw new UnsupportedOperationException();
+        /*
+         * This package has no notion of complex: it declares no type for a 
set of geometries
+         * closed under the boundary operation, which is what ISO 19107 calls 
a complex.
+         * The standard defines null as the answer in that case.
+         */
+        return null;
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Point.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Point.java
index 444fb9c3af..57f9f103f5 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Point.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Point.java
@@ -202,6 +202,29 @@ public sealed interface Point extends Primitive
         return true;
     }
 
+    /**
+     * Returns {@code true}: a single location satisfies every constraint a 
point can have.
+     *
+     * @see ISO 19107:2019 - 6.4.4.16
+     */
+    @UML(identifier="isValid", specification=ISO_19107)
+    @Override
+    default boolean isValid() {
+        return true;
+    }
+
+    /**
+     * Returns the empty geometry: the boundary of a point is the empty set.
+     *
+     * @see OGC Simple Feature Access 1.2.1 - 6.1.2.2
+     * @see ISO 19107:2019 - 6.4.4.7
+     */
+    @UML(identifier="boundary", specification=ISO_19107)
+    @Override
+    default Geometry boundary() {
+        return GeometryFactory.createEmpty(getCoordinateReferenceSystem());
+    }
+
     /**
      * Returns {@code this}: a point is its own centroid.
      *
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Primitive.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Primitive.java
index 750cbde8d5..b4bac83149 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Primitive.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Primitive.java
@@ -19,6 +19,7 @@ package org.apache.sis.geometries;
 import java.util.List;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
+import org.opengis.geometry.DirectPosition;
 
 
 /**
@@ -65,6 +66,23 @@ public sealed interface Primitive extends Geometry
         return BoundaryType.METRIC;
     }
 
+    /**
+     * Returns the {@linkplain #getTopologicDimension() topological dimension} 
of this primitive,
+     * whatever the given position: a primitive has a uniform dimension at 
each of its interior
+     * points, which is what makes it a primitive. Only an aggregate needs the 
position, because
+     * it may mix components of different dimensions.
+     *
+     * @param  point  ignored, since the answer is the same everywhere.
+     * @return topological dimension of this primitive.
+     *
+     * @see ISO 19107:2019 - 6.4.4.25
+     */
+    @UML(identifier="dimension", specification=ISO_19107)
+    @Override
+    default int getDimension(DirectPosition point) {
+        return getTopologicDimension();
+    }
+
     /**
      * Smaller primitives of the same dimension contained in this primitive,
      * each of them defining a portion of it.

Reply via email to