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 297c91c8d54cbcc81567bc5bcb22a8185a1289cd
Author: jsorel <[email protected]>
AuthorDate: Wed Oct 14 10:03:03 2026 +0200

    feat(Geometry): separate Ray as a Curve subtype, implement several small 
methods
---
 .../main/org/apache/sis/geometries/Curve.java      |   2 +
 .../org/apache/sis/geometries/GeometryFactory.java |   6 +-
 .../org/apache/sis/geometries/GeometryType.java    |   1 +
 .../main/org/apache/sis/geometries/curve/Ray.java  | 197 +++++++++++++++++++++
 .../internal/shared/DefaultBSplineSurface.java     |   8 -
 .../internal/shared/DefaultBilinearGrid.java       |   8 -
 .../internal/shared/DefaultNurbSurface.java        |   8 -
 .../{Ray.java => internal/shared/DefaultRay.java}  |  76 ++------
 .../org/apache/sis/geometries/solid/Frustrum.java  |   5 +-
 .../solid/polyhedron/AbstractPolyhedron.java       |  19 +-
 .../apache/sis/geometries/surface/Ellipsoid.java   |   8 -
 .../geometries/surface/ParametricCurveSurface.java |  14 ++
 .../org/apache/sis/geometries/surface/Sphere.java  |   8 -
 13 files changed, 252 insertions(+), 108 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 59693f4cc5..526b71a5fc 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
@@ -32,6 +32,7 @@ import org.apache.sis.geometries.curve.Line;
 import org.apache.sis.geometries.curve.LineString;
 import org.apache.sis.geometries.curve.OffsetCurve;
 import org.apache.sis.geometries.curve.ProductCurve;
+import org.apache.sis.geometries.curve.Ray;
 import org.apache.sis.geometries.curve.Rhumb;
 import org.apache.sis.geometries.curve.Spiral;
 import org.apache.sis.geometries.internal.shared.DefaultReversedCurve;
@@ -79,6 +80,7 @@ public sealed interface Curve extends Orientable
                 LineString,
                 OffsetCurve,
                 ProductCurve,
+                Ray,
                 Rhumb,
                 Spiral,
                 DefaultReversedCurve
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
index d92129f139..3b7cca3a4c 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
@@ -48,6 +48,7 @@ import org.apache.sis.geometries.curve.OffsetCurve;
 import org.apache.sis.geometries.curve.PolynomialSpline;
 import org.apache.sis.geometries.curve.ProductCurve;
 import org.apache.sis.geometries.curve.RealFunction;
+import org.apache.sis.geometries.curve.Ray;
 import org.apache.sis.geometries.curve.Rhumb;
 import org.apache.sis.geometries.curve.Spiral;
 import org.apache.sis.geometries.curve.SplineCurveForm;
@@ -84,6 +85,7 @@ import 
org.apache.sis.geometries.internal.shared.DefaultPolyhedron;
 import org.apache.sis.geometries.internal.shared.DefaultPolynomialSpline;
 import org.apache.sis.geometries.internal.shared.DefaultPrism;
 import org.apache.sis.geometries.internal.shared.DefaultProductCurve;
+import org.apache.sis.geometries.internal.shared.DefaultRay;
 import org.apache.sis.geometries.internal.shared.DefaultReversedCurve;
 import org.apache.sis.geometries.internal.shared.DefaultReversedSurface;
 import org.apache.sis.geometries.internal.shared.DefaultRhumb;
@@ -773,7 +775,7 @@ public final class GeometryFactory {
      * @return the ray starting from the given position.
      */
     public Ray createRay(Vector<?> position, Vector<?> direction) {
-        return new Ray(position, direction);
+        return new DefaultRay(position, direction);
     }
 
     /**
@@ -786,7 +788,7 @@ public final class GeometryFactory {
      * @throws IllegalArgumentException if the given {@code DataPoints} does 
not hold exactly one position.
      */
     public Ray createRay(DataPoints points, Vector<?> direction) {
-        return new Ray(points, direction);
+        return new DefaultRay(points, direction);
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryType.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryType.java
index 36601c3aa3..952396a479 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryType.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryType.java
@@ -37,6 +37,7 @@ import org.apache.sis.geometries.curve.NurbCurve;
 import org.apache.sis.geometries.curve.OffsetCurve;
 import org.apache.sis.geometries.curve.PolynomialSpline;
 import org.apache.sis.geometries.curve.ProductCurve;
+import org.apache.sis.geometries.curve.Ray;
 import org.apache.sis.geometries.curve.Rhumb;
 import org.apache.sis.geometries.curve.Spiral;
 import org.apache.sis.geometries.curve.SplineCurve;
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Ray.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Ray.java
new file mode 100644
index 0000000000..7412d9ff32
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/Ray.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.geometries.curve;
+
+import javax.measure.Quantity;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.BBox;
+import org.apache.sis.geometries.Curve;
+import org.apache.sis.geometries.CurveInterpolation;
+import org.apache.sis.geometries.DataPointsType;
+import org.apache.sis.geometries.Geometries;
+import org.apache.sis.geometries.GeometryType;
+import org.apache.sis.geometries.Point;
+import org.apache.sis.geometries.internal.shared.DefaultRay;
+import org.apache.sis.maths.Array;
+import org.apache.sis.maths.ReadOnly;
+import org.apache.sis.measure.Quantities;
+
+
+/**
+ * A ray is a one direction infinite line.
+ * It is build from a position and a direction.
+ *
+ * <p>Constraints:</p>
+ * <ul>
+ *   <li>The {@linkplain #getDataPoints() data points} hold exactly one 
position,
+ *       the {@linkplain #getStartPoint() start point} of the ray.</li>
+ *   <li>The ray has no end point and its length is infinite.</li>
+ * </ul>
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public sealed interface Ray extends Curve
+        permits DefaultRay
+{
+
+    /**
+     * Returns {@link GeometryType#RAY}.
+     */
+    @Override
+    default GeometryType getGeometryType() {
+        return GeometryType.RAY;
+    }
+
+    /**
+     * Returns the position the ray starts from.
+     *
+     * @return the start position of this ray.
+     */
+    ReadOnly.Vector<?> getPosition();
+
+    /**
+     * Sets the position the ray starts from.
+     *
+     * @param  position  the new start position, not null.
+     */
+    void setPosition(ReadOnly.Vector<?> position);
+
+    /**
+     * Returns the direction the ray extends toward.
+     *
+     * @return the direction of this ray.
+     */
+    ReadOnly.Vector<?> getDirection();
+
+    /**
+     * Sets the direction the ray extends toward.
+     *
+     * @param  direction  the new direction, not null.
+     */
+    void setDirection(ReadOnly.Vector<?> direction);
+
+    /**
+     * Returns {@code false}: a ray always has a start position.
+     */
+    @Override
+    default boolean isEmpty() {
+        return false;
+    }
+
+    /**
+     * Returns {@link CurveInterpolation#LINEAR}.
+     */
+    @Override
+    default CurveInterpolation getInterpolation() {
+        return CurveInterpolation.LINEAR;
+    }
+
+    /**
+     * Returns null, a ray has no control points.
+     */
+    @Override
+    default Array getControlPoints() {
+        return null;
+    }
+
+    /**
+     * Returns an infinite length, in the linear unit of the reference system 
of this ray.
+     */
+    @Override
+    default Quantity<?> getLength() {
+        return Quantities.create(Double.POSITIVE_INFINITY, 
Geometries.getLinearUnit(this));
+    }
+
+    /**
+     * Returns {@code null}: the ray extends to infinity, it has no end point.
+     */
+    @Override
+    default Point getEndPoint() {
+        return null;
+    }
+
+    /**
+     * Returns the {@linkplain #getStartPoint() start point}, which lies on 
the ray.
+     */
+    @Override
+    default Point getRepresentativePoint() {
+        return getStartPoint();
+    }
+
+    /**
+     * Returns {@code false}: the ray extends to infinity and never comes back 
to its start point.
+     */
+    @Override
+    default boolean isClosed() {
+        return false;
+    }
+
+    /**
+     * Returns {@code true}: a straight half-line never crosses itself.
+     */
+    @Override
+    default boolean isSimple() {
+        return true;
+    }
+
+    /**
+     * Returns the position the ray starts from: the ray extends to infinity
+     * in its direction, so its origin is its only end.
+     */
+    @Override
+    default Point getBoundary() {
+        return getStartPoint();
+    }
+
+    /**
+     * Returns the envelope of this ray, infinite on each axis where the 
direction is not zero.
+     */
+    @Override
+    default BBox getEnvelope() {
+        final ReadOnly.Vector<?> position = getPosition();
+        final ReadOnly.Vector<?> direction = getDirection();
+        final int dim = direction.getDimension();
+        final BBox bbox = new BBox(dim);
+        for (int i=0;i<dim;i++){
+            double d = direction.get(i);
+            if (d<0){
+                bbox.setRange(i, Double.NEGATIVE_INFINITY, position.get(i));
+            } else if (d>0){
+                bbox.setRange(i, position.get(i), Double.POSITIVE_INFINITY);
+            } else {
+                bbox.setRange(i, position.get(i), position.get(i));
+            }
+        }
+        return bbox;
+    }
+
+    @Override
+    default CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return getDataPoints().getCoordinateReferenceSystem();
+    }
+
+    @Override
+    default void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) 
throws IllegalArgumentException {
+        getDataPoints().setCoordinateReferenceSystem(crs);
+    }
+
+    @Override
+    default DataPointsType getDataPointsType() {
+        return getDataPoints().getType();
+    }
+
+}
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java
index 1d3cf43978..943d4c8207 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java
@@ -28,9 +28,6 @@ import org.apache.sis.geometries.curve.KnotType;
 import org.apache.sis.geometries.surface.BSplineSurface;
 import org.apache.sis.geometries.surface.BSplineSurfaceForm;
 
-// Specific to the geoapi-4.0 branch:
-import org.opengis.metadata.Identifier;
-
 
 /**
  * A rational or polynomial parametric surface represented by control points, 
b-spline basis
@@ -195,9 +192,4 @@ public non-sealed class DefaultBSplineSurface extends 
AbstractGeometry implement
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
-    public Identifier getName() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java
index d94593c97d..92dedded85 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java
@@ -29,9 +29,6 @@ import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.DataPointsType;
 import org.apache.sis.geometries.surface.BilinearGrid;
 
-// Specific to the geoapi-4.0 branch:
-import org.opengis.metadata.Identifier;
-
 
 /**
  * A parametric curve surface using polylines as both horizontal and vertical 
curves, each cell of
@@ -179,9 +176,4 @@ public non-sealed class DefaultBilinearGrid extends 
AbstractGeometry implements
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
-    public Identifier getName() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultNurbSurface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultNurbSurface.java
index 28f5d14b89..eeb5736e90 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultNurbSurface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultNurbSurface.java
@@ -32,9 +32,6 @@ import org.apache.sis.maths.NDArrays;
 import org.apache.sis.maths.Vector;
 import org.apache.sis.maths.Vectors;
 
-// Specific to the geoapi-4.0 branch:
-import org.opengis.metadata.Identifier;
-
 
 /**
  * NURBS surface: tensor product of two directions (u, v), each one with its 
own degree and its own knot vector.
@@ -385,9 +382,4 @@ public non-sealed class DefaultNurbSurface extends 
AbstractGeometry implements N
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
-    public Identifier getName() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Ray.java 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultRay.java
similarity index 65%
rename from 
incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Ray.java
rename to 
incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultRay.java
index 129ba74266..ea76a5c8b9 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Ray.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultRay.java
@@ -14,23 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.geometries;
+package org.apache.sis.geometries.internal.shared;
 
 import java.util.Objects;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.geometries.internal.shared.AbstractGeometry;
+import org.apache.sis.geometries.DataPoints;
+import org.apache.sis.geometries.GeometryFactory;
+import org.apache.sis.geometries.curve.Ray;
 import org.apache.sis.maths.NDArrays;
 import org.apache.sis.maths.ReadOnly;
 import org.apache.sis.maths.Vector;
 
 
 /**
- * A ray is a one direction infinite line.
- * It is build from a position and a direction.
+ * Default implementation of a ray, storing its start position in a {@code 
DataPoints}.
  *
- * @author Johann Sorel
+ * @author Johann Sorel (Geomatys)
  */
-public final class Ray extends AbstractGeometry{
+public non-sealed class DefaultRay extends AbstractGeometry implements Ray {
 
     /**
      * Must contain a single point.
@@ -46,7 +46,7 @@ public final class Ray extends AbstractGeometry{
      * @param  position   the position the ray starts from, not null.
      * @param  direction  the direction the ray extends toward, not null.
      */
-    public Ray(Vector<?> position, Vector<?> direction) {
+    public DefaultRay(Vector<?> position, Vector<?> direction) {
         points = 
GeometryFactory.DEFAULT.createDataPoints(NDArrays.of(position.getSampleSystem(),
 position.getDataType(), 1));
         points.setPosition(0, position);
         this.direction = direction;
@@ -61,7 +61,7 @@ public final class Ray extends AbstractGeometry{
      * @param  direction  the direction the ray extends toward, not null.
      * @throws IllegalArgumentException if the given {@code DataPoints} does 
not hold exactly one position.
      */
-    public Ray(DataPoints points, Vector<?> direction) {
+    public DefaultRay(DataPoints points, Vector<?> direction) {
         if (points.size() != 1) {
             throw new IllegalArgumentException("Ray sequence must contain one 
point");
         }
@@ -70,78 +70,30 @@ public final class Ray extends AbstractGeometry{
     }
 
     @Override
-    public GeometryType getGeometryType() {
-        return GeometryType.RAY;
-    }
-
-    @Override
-    public int getTopologicDimension() {
-        return 1;
-    }
-
     public DataPoints getDataPoints() {
         return points;
     }
 
+    @Override
     public ReadOnly.Vector<?> getPosition() {
         return points.getPosition(0);
     }
 
+    @Override
     public void setPosition(ReadOnly.Vector<?> position) {
         points.setPosition(0, position);
     }
 
+    @Override
     public ReadOnly.Vector<?> getDirection() {
         return direction;
     }
 
+    @Override
     public void setDirection(ReadOnly.Vector<?> direction) {
         this.direction = direction.copy();
     }
 
-    @Override
-    public BBox getEnvelope() {
-        final ReadOnly.Vector<?> position = getPosition();
-        final int dim = direction.getDimension();
-        final BBox bbox = new BBox(dim);
-        for (int i=0;i<dim;i++){
-            double d = direction.get(i);
-            if (d<0){
-                bbox.setRange(i, Double.NEGATIVE_INFINITY, position.get(i));
-            } else if (d>0){
-                bbox.setRange(i, position.get(i), Double.POSITIVE_INFINITY);
-            } else {
-                bbox.setRange(i, position.get(i), position.get(i));
-            }
-        }
-        return bbox;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return false;
-    }
-
-    @Override
-    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
-        return points.getCoordinateReferenceSystem();
-    }
-
-    @Override
-    public Geometry getBoundary() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    @Override
-    public void setCoordinateReferenceSystem(CoordinateReferenceSystem crs) 
throws IllegalArgumentException {
-        points.setCoordinateReferenceSystem(crs);
-    }
-
-    @Override
-    public DataPointsType getDataPointsType() {
-        return points.getType();
-    }
-
     @Override
     public boolean equals(Object obj) {
         if (obj == null) {
@@ -150,7 +102,7 @@ public final class Ray extends AbstractGeometry{
         if (getClass() != obj.getClass()) {
             return false;
         }
-        final Ray other = (Ray) obj;
+        final DefaultRay other = (DefaultRay) obj;
         if (!Objects.equals(this.points, other.points)) {
             return false;
         }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Frustrum.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Frustrum.java
index 3e3c59861b..da5c29511c 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Frustrum.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Frustrum.java
@@ -89,9 +89,12 @@ public final class Frustrum extends AbstractGeometry {
         return ConcatenatedDataPoints.of(planes);
     }
 
+    /**
+     * Returns 3: a frustum is the volume enclosed by its planes.
+     */
     @Override
     public int getTopologicDimension() {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return 3;
     }
 
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/polyhedron/AbstractPolyhedron.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/polyhedron/AbstractPolyhedron.java
index 39fde90bd4..5f87692628 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/polyhedron/AbstractPolyhedron.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/polyhedron/AbstractPolyhedron.java
@@ -103,19 +103,32 @@ public abstract sealed class AbstractPolyhedron extends 
AbstractGeometry impleme
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    /**
+     * Returns {@code false}: a regular polyhedron always has faces.
+     */
     @Override
     public boolean isEmpty() {
-        throw new UnsupportedOperationException("Not supported yet."); // 
Generated from 
nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
+        return false;
     }
 
+    /**
+     * Returns the faces of this polyhedron, in the order of their indices.
+     */
     @Override
     public GeometryCollection<Polygon> getExteriorShell() {
-        throw new UnsupportedOperationException("Not supported yet."); // 
Generated from 
nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
+        final Polygon[] faces = new Polygon[getFaceCount()];
+        for (int i = 0; i < faces.length; i++) {
+            faces[i] = getFace(i);
+        }
+        return GeometryFactory.DEFAULT.createMultiPolygon(faces);
     }
 
+    /**
+     * Returns an empty list: a regular polyhedron has no void.
+     */
     @Override
     public List<GeometryCollection<Polygon>> getInteriorShells() {
-        throw new UnsupportedOperationException("Not supported yet."); // 
Generated from 
nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
+        return List.of();
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Ellipsoid.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Ellipsoid.java
index c7b6f91670..2583f181c5 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Ellipsoid.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Ellipsoid.java
@@ -42,9 +42,6 @@ import org.apache.sis.maths.SampleSystem;
 import org.apache.sis.maths.Vector;
 import org.apache.sis.util.ArgumentChecks;
 
-// Specific to the geoapi-4.0 branch:
-import org.opengis.metadata.Identifier;
-
 
 /**
  * An ellipsoid geometry defined by a center and one semi-axis length per axis 
of the coordinate
@@ -355,11 +352,6 @@ public final class Ellipsoid extends AbstractGeometry 
implements ParametricCurve
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
-    public Identifier getName() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
     /**
      * Returns the center of this ellipsoid, as a {@code DataPoints} of one 
position. An ellipsoid is defined
      * by that position and by its semi-axes, so the center is the only 
position it holds.
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/ParametricCurveSurface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/ParametricCurveSurface.java
index 5f7489dd08..6e61608751 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/ParametricCurveSurface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/ParametricCurveSurface.java
@@ -21,12 +21,16 @@ import static 
org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.ReferenceSystem;
+import org.apache.sis.referencing.NamedIdentifier;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.Surface;
 import org.apache.sis.geometries.SurfaceInterpolation;
 
+// Specific to the geoapi-4.0 branch:
+import org.opengis.metadata.Identifier;
+
 
 /**
  * A surface given by a family of continuous curves,
@@ -229,5 +233,15 @@ public sealed interface ParametricCurveSurface extends 
Surface, ReferenceSystem
     @UML(identifier="surface", specification=ISO_19107)
     DirectPosition getSurface(double u, double v);
 
+    /**
+     * Returns the name of this surface used as a reference system for its 
parameter space.
+     * The default implementation returns the name of the {@linkplain 
#getGeometryType() geometry type}.
+     *
+     * @return name of the parameter space of this surface.
+     */
+    @Override
+    default Identifier getName() {
+        return new NamedIdentifier(null, getGeometryType().name());
+    }
 
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Sphere.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Sphere.java
index 3497d9f022..81ecd4f55c 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Sphere.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Sphere.java
@@ -41,9 +41,6 @@ import org.apache.sis.maths.SampleSystem;
 import org.apache.sis.maths.Vector;
 import org.apache.sis.util.ArgumentChecks;
 
-// Specific to the geoapi-4.0 branch:
-import org.opengis.metadata.Identifier;
-
 
 /**
  * A sphere geometry defined by a center and a radius.
@@ -283,11 +280,6 @@ public final class Sphere extends AbstractGeometry 
implements ParametricCurveSur
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
-    public Identifier getName() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
     /**
      * Returns the center of this sphere, as a {@code DataPoints} of one 
position. A sphere is defined by
      * that position and by its radius, so the center is the only position it 
holds.

Reply via email to