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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new e6ea84055e feat(Geometry): add getDataPoints()on Geometry interface
e6ea84055e is described below

commit e6ea84055e2f239621566c547ad55554fd853305
Author: jsorel <[email protected]>
AuthorDate: Wed Oct 7 17:04:34 2026 +0200

    feat(Geometry): add getDataPoints()on Geometry interface
---
 .../main/org/apache/sis/geometries/BBox.java       | 107 +++++++++++-
 .../main/org/apache/sis/geometries/Curve.java      |   1 +
 .../main/org/apache/sis/geometries/Empty.java      |   9 +
 .../main/org/apache/sis/geometries/Geometry.java   |  20 +++
 .../apache/sis/geometries/GeometryCollection.java  |  19 +++
 .../main/org/apache/sis/geometries/OBBox.java      |  16 +-
 .../main/org/apache/sis/geometries/Point.java      |   3 +-
 .../main/org/apache/sis/geometries/Prism.java      |   9 +
 .../main/org/apache/sis/geometries/Solid.java      |   5 +-
 .../main/org/apache/sis/geometries/Surface.java    |   6 +-
 .../apache/sis/geometries/adapter/JTSAdapter.java  |   4 +-
 .../geometries/adapter/PathIteratorAdapter.java    |   2 +-
 .../geometries/csg/ConstructiveSolidGeometry.java  |  10 ++
 .../sis/geometries/curve/ArcByCenterPoint.java     |   4 +-
 .../apache/sis/geometries/curve/CompoundCurve.java |  18 ++
 .../apache/sis/geometries/curve/ProductCurve.java  |  13 ++
 .../internal/shared/ConcatenatedDataPoints.java    | 183 +++++++++++++++++++++
 .../internal/shared/DefaultArcByCenterPoint.java   |  10 ++
 .../internal/shared/DefaultCompoundCurve.java      |   5 -
 .../internal/shared/DefaultMultiPoint.java         |   2 +-
 .../geometries/internal/shared/DefaultPoint.java   |   2 +-
 .../internal/shared/DefaultPolyhedron.java         |   6 -
 .../internal/shared/DefaultProductCurve.java       |   6 -
 .../internal/shared/DefaultReversedSurface.java    |   6 +
 .../internal/shared/EmptyDataPoints.java           | 115 +++++++++++++
 .../internal/shared/SinglePositionDataPoints.java  | 139 ++++++++++++++++
 .../apache/sis/geometries/mesh/MeshPrimitive.java  |  28 ++--
 .../sis/geometries/mesh/MultiMeshPrimitive.java    |  17 ++
 .../org/apache/sis/geometries/operation/To3D.java  |   2 +-
 .../sis/geometries/operation/ToPrimitive.java      |   2 +-
 .../triangulate/delaunay/OrientedTriangle.java     |   6 +
 .../apache/sis/geometries/point/MultiPoint.java    |   3 +-
 .../org/apache/sis/geometries/solid/Frustrum.java  |  11 ++
 .../apache/sis/geometries/solid/Polyhedron.java    |  11 ++
 .../org/apache/sis/geometries/solid/Sphere.java    |  17 +-
 .../solid/polyhedron/AbstractPolyhedron.java       |  17 ++
 .../sis/geometries/surface/CurvePolygon.java       |  11 ++
 .../org/apache/sis/geometries/surface/Polygon.java |  11 ++
 .../sis/geometries/surface/PolyhedralSurface.java  |  17 ++
 .../main/org/apache/sis/gml/GML2Writer.java        |   2 +-
 .../test/org/apache/sis/geometries/PointTest.java  |   2 +-
 .../test/org/apache/sis/gml/GeometryAssert.java    |   2 +-
 42 files changed, 820 insertions(+), 59 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/BBox.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/BBox.java
index c5d8163ea3..c6f665b736 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/BBox.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/BBox.java
@@ -21,7 +21,10 @@ import java.util.Map;
 import org.opengis.coordinate.MismatchedDimensionException;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.internal.shared.IndexedPoint;
 import org.apache.sis.geometry.GeneralEnvelope;
+import org.apache.sis.maths.DataType;
+import org.apache.sis.maths.SampleSystem;
 import org.apache.sis.maths.Tuple;
 import org.apache.sis.maths.Vectors;
 
@@ -124,7 +127,109 @@ public final class BBox extends GeneralEnvelope 
implements Geometry {
 
     @Override
     public DataPointsType getDataPointsType() {
-        return DataPointsType.EMPTY;
+        return getDataPoints().getType();
+    }
+
+    /**
+     * Returns the two corners of this box, the lower one first, as a sequence 
of two positions.
+     * Those corners are what this box is made of, so writing a position 
through the returned
+     * sequence moves the corresponding corner.
+     */
+    @Override
+    public DataPoints getDataPoints() {
+        return new Corners();
+    }
+
+    /**
+     * The two corners of the enclosing box, seen as a sequence of two 
positions.
+     * This class holds no coordinate of its own: it reads and writes the box.
+     */
+    private final class Corners implements DataPoints {
+
+        @Override
+        public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+            return BBox.this.getCoordinateReferenceSystem();
+        }
+
+        @Override
+        public void setCoordinateReferenceSystem(CoordinateReferenceSystem cs) 
throws IllegalArgumentException {
+            BBox.this.setCoordinateReferenceSystem(cs);
+        }
+
+        @Override
+        public DataPointsType getType() {
+            final DataPointsType.Template type = new DataPointsType.Template();
+            type.addOrReplaceAttribute(DataPointsType.ATT_POSITION,
+                    SampleSystem.of(BBox.this.getCoordinateReferenceSystem()), 
DataType.DOUBLE);
+            return type;
+        }
+
+        @Override
+        public int size() {
+            return 2;
+        }
+
+        @Override
+        public Point getPoint(int index) {
+            ensureValid(index);
+            return new IndexedPoint(this, index);
+        }
+
+        @Override
+        public Tuple<?> getPosition(int index) {
+            ensureValid(index);
+            final int dim = getDimension();
+            final Tuple<?> position = 
Vectors.create(BBox.this.getCoordinateReferenceSystem(), DataType.DOUBLE);
+            for (int i = 0; i < dim; i++) {
+                position.set(i, (index == 0) ? getMinimum(i) : getMaximum(i));
+            }
+            return position;
+        }
+
+        @Override
+        public void setPosition(int index, Tuple<?> value) {
+            ensureValid(index);
+            final int dim = getDimension();
+            for (int i = 0; i < dim; i++) {
+                if (index == 0) {
+                    setRange(i, value.get(i), getMaximum(i));
+                } else {
+                    setRange(i, getMinimum(i), value.get(i));
+                }
+            }
+        }
+
+        @Override
+        public Tuple<?> getAttribute(int index, String name) {
+            return DataPointsType.ATT_POSITION.equals(name) ? 
getPosition(index) : null;
+        }
+
+        @Override
+        public void setAttribute(int index, String name, Tuple<?> value) {
+            if (!DataPointsType.ATT_POSITION.equals(name)) {
+                throw new IllegalArgumentException("A box holds no \"" + name 
+ "\" attribute.");
+            }
+            setPosition(index, value);
+        }
+
+        /**
+         * Verifies that the given index is one of the two corners.
+         */
+        private void ensureValid(final int index) {
+            if (index != 0 && index != 1) {
+                throw new IndexOutOfBoundsException("A box has two corners, at 
index 0 and 1.");
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return DataPoints.hashCode(this);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return DataPoints.equals(this, obj);
+        }
     }
 
 }
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 09112d85eb..4c41dca8a0 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
@@ -104,6 +104,7 @@ public sealed interface Curve extends Orientable
      * @see ISO 19107:2019 - 6.4.18.3
      */
     @UML(identifier="dataPoint", specification=ISO_19107)
+    @Override
     DataPoints getDataPoints();
 
     /**
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Empty.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Empty.java
index 8a9141960e..a7c2dccbe4 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Empty.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Empty.java
@@ -19,6 +19,7 @@ package org.apache.sis.geometries;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
 import org.apache.sis.geometries.internal.shared.DefaultEmpty;
+import org.apache.sis.geometries.internal.shared.EmptyDataPoints;
 
 
 /**
@@ -164,4 +165,12 @@ public sealed interface Empty extends Geometry
         return null;
     }
 
+    /**
+     * Returns an empty sequence: the empty set holds no position.
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        return new EmptyDataPoints(getCoordinateReferenceSystem(), 
getDataPointsType());
+    }
+
 }
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 1c440d52d2..2205ac54d9 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
@@ -155,6 +155,26 @@ public sealed interface Geometry
      */
     DataPointsType getDataPointsType();
 
+    /**
+     * Positions this geometry is made of.
+     *
+     * <p>The returned sequence is the one this geometry holds, or a view onto 
it: writing a
+     * position through it moves this geometry. A geometry built on other 
geometries, such as a
+     * surface on its rings or a collection on its elements, returns a view 
concatenating their
+     * sequences in the order it holds them, so a position shared by two 
elements appears as many
+     * times as it is held. A geometry which has no position of its own 
returns an empty sequence.</p>
+     *
+     * <p>Difference with ISO 19107: the type has been changed from a list of 
direct positions
+     * to {@link DataPoints}, in order to accommodate additional attributes 
like in GLTF or
+     * GPU models.</p>
+     *
+     * @return positions of this geometry, never null.
+     *
+     * @see ISO 19107:2019 - 6.4.18.3, 6.4.25.8, 6.4.28.5
+     */
+    @UML(identifier="dataPoint", specification=ISO_19107)
+    DataPoints getDataPoints();
+
     /**
      * Number of axes in the coordinate reference system of this geometry.
      *
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 edc47d2c26..b58e611cb4 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
@@ -22,7 +22,9 @@ import org.opengis.annotation.UML;
 import org.opengis.geometry.Envelope;
 import org.apache.sis.geometries.curve.MultiCurve;
 import org.apache.sis.geometries.curve.ProductCurve;
+import org.apache.sis.geometries.internal.shared.ConcatenatedDataPoints;
 import org.apache.sis.geometries.internal.shared.DefaultGeometryCollection;
+import org.apache.sis.geometries.internal.shared.EmptyDataPoints;
 import org.apache.sis.geometries.mesh.MultiMeshPrimitive;
 import org.apache.sis.geometries.point.MultiPoint;
 import org.apache.sis.geometries.solid.MultiPolyhedron;
@@ -188,4 +190,21 @@ public sealed interface GeometryCollection<T extends 
Geometry> extends Geometry
         return getGeometryN(0).getDataPointsType();
     }
 
+    /**
+     * Returns the positions of the elements of this collection, in the order 
this collection
+     * holds them. A position held by two elements appears as many times as it 
is held.
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        final int n = getNumGeometries();
+        if (n == 0) {
+            return new EmptyDataPoints(getCoordinateReferenceSystem());
+        }
+        final Geometry[] elements = new Geometry[n];
+        for (int i = 0; i < n; i++) {
+            elements[i] = getGeometryN(i);
+        }
+        return ConcatenatedDataPoints.of(elements);
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/OBBox.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/OBBox.java
index c4be2ca624..259c5573db 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/OBBox.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/OBBox.java
@@ -18,7 +18,9 @@ package org.apache.sis.geometries;
 
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.internal.shared.AbstractGeometry;
+import org.apache.sis.geometries.internal.shared.SinglePositionDataPoints;
 import org.apache.sis.maths.Tuple;
 import org.apache.sis.maths.Vector;
 import org.apache.sis.maths.Vectors;
@@ -84,13 +86,13 @@ public final class OBBox extends AbstractGeometry {
 
     @Override
     public DataPointsType getDataPointsType() {
-        return DataPointsType.EMPTY;
+        return getDataPoints().getType();
     }
 
     /**
      * @return center of the bounding box.
      */
-    public Tuple getCenter() {
+    public Tuple<?> getCenter() {
         return center;
     }
 
@@ -152,4 +154,14 @@ public final class OBBox extends AbstractGeometry {
         yAxis.set(1, env.getSpan(1) / 2.0);
         zAxis.set(2, env.getSpan(2) / 2.0);
     }
+
+    /**
+     * Returns the center of this box, as a sequence of one position. The 
corners of the box are
+     * derived from that position and from its axes, so the center is the only 
position it holds.
+     */
+    @Override
+    public DataPoints getDataPoints() {
+        return new SinglePositionDataPoints(this::getCenter);
+    }
+
 }
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 b6e6115936..a7a4f19444 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
@@ -102,7 +102,8 @@ public sealed interface Point extends Primitive
      *
      * @return this point as a sequence of one data point.
      */
-    default DataPoints asDataPoint() {
+    @Override
+    default DataPoints getDataPoints() {
         return new DataPoints() {
             @Override
             public CoordinateReferenceSystem getCoordinateReferenceSystem() {
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Prism.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Prism.java
index 5a5a8e14dd..af1c3a47d5 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Prism.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Prism.java
@@ -42,6 +42,15 @@ public sealed interface Prism extends Geometry
         return getBase().getDataPointsType();
     }
 
+    /**
+     * Returns the positions of the geometry this prism is the extrusion of. 
The positions the
+     * extrusion adds are not materialized, so they are not part of the 
returned sequence.
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        return getBase().getDataPoints();
+    }
+
     /**
      * @return base shape of the prism.
      */
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Solid.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Solid.java
index d0e319c8e4..02ed7c68a8 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Solid.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Solid.java
@@ -125,9 +125,8 @@ public sealed interface Solid extends Primitive
      * @see ISO 19107:2019 - 6.4.28.5
      */
     @UML(identifier="dataPoint", specification=ISO_19107)
-    default DataPoints getDataPoints() {
-        throw new UnsupportedOperationException();
-    }
+    @Override
+    DataPoints getDataPoints();
 
     /**
      * Positions used to build the geometry of this solid, the way they are 
used depending on the interpolation.
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Surface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Surface.java
index 6c67c842cd..5752c7279b 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Surface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Surface.java
@@ -213,10 +213,8 @@ public sealed interface Surface extends Orientable
      * @see ISO 19107:2019 - 6.4.25.8
      */
     @UML(identifier="dataPoint", specification=ISO_19107)
-    default DataPoints getDataPoints() {
-        //TODO
-        throw new UnsupportedOperationException();
-    }
+    @Override
+    DataPoints getDataPoints();
 
     /**
      * Positions used to build the geometry of this surface, the way they are 
used depending on the interpolation.
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/JTSAdapter.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/JTSAdapter.java
index 94dc342d9f..409ca14d08 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/JTSAdapter.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/JTSAdapter.java
@@ -136,10 +136,10 @@ public final class JTSAdapter {
         if (geom == null) {
             return null;
         } else if (geom instanceof Point cdt) {
-            final CoordinateSequence cs = 
toCoordinateSequence(cdt.asDataPoint(), copy, gf);
+            final CoordinateSequence cs = 
toCoordinateSequence(cdt.getDataPoints(), copy, gf);
             jts = new org.locationtech.jts.geom.Point(cs, gf);
         } else if (geom instanceof MultiPoint cdt) {
-            final CoordinateSequence cs = 
toCoordinateSequence(cdt.asDataPoints(), copy, gf);
+            final CoordinateSequence cs = 
toCoordinateSequence(cdt.getDataPoints(), copy, gf);
             jts = gf.createMultiPoint(cs);
         } else if (geom instanceof LinearRing cdt) {
             final CoordinateSequence cs = 
toCoordinateSequence(cdt.getDataPoints(), copy, gf);
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/PathIteratorAdapter.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/PathIteratorAdapter.java
index 9c08d863d3..6959bc29d7 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/PathIteratorAdapter.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/adapter/PathIteratorAdapter.java
@@ -180,7 +180,7 @@ final class PathIteratorAdapter implements PathIterator {
         if (geometry instanceof LineString) {
             sequences = List.of(((LineString) geometry).getDataPoints());
         } else if (geometry instanceof Point) {
-            sequences = List.of(((Point) geometry).asDataPoint());
+            sequences = List.of(((Point) geometry).getDataPoints());
         } else if (geometry instanceof Polygon) {
             return new RingIterator((Polygon) geometry);
         } else if (geometry instanceof GeometryCollection) {
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/csg/ConstructiveSolidGeometry.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/csg/ConstructiveSolidGeometry.java
index 1f27802e5e..01785d4258 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/csg/ConstructiveSolidGeometry.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/csg/ConstructiveSolidGeometry.java
@@ -18,9 +18,11 @@ package org.apache.sis.geometries.csg;
 
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.DataPointsType;
 import org.apache.sis.geometries.internal.shared.AbstractGeometry;
+import org.apache.sis.geometries.internal.shared.EmptyDataPoints;
 
 
 /**
@@ -62,4 +64,12 @@ public final class ConstructiveSolidGeometry extends 
AbstractGeometry {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    /**
+     * Returns an empty sequence: this geometry is a placeholder and holds no 
position yet.
+     */
+    @Override
+    public DataPoints getDataPoints() {
+        return new EmptyDataPoints(getCoordinateReferenceSystem());
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ArcByCenterPoint.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ArcByCenterPoint.java
index 19545e8df1..5781955ad5 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ArcByCenterPoint.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/ArcByCenterPoint.java
@@ -108,9 +108,7 @@ public sealed interface ArcByCenterPoint extends Curve
     }
 
     @Override
-    default DataPoints getDataPoints() {
-        throw new UnsupportedOperationException("Not supported yet");
-    }
+    DataPoints getDataPoints();
 
     /**
      * @return null, a ArcByCenterPoint has no control points
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/CompoundCurve.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/CompoundCurve.java
index 188a027452..1a0ec466fa 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/CompoundCurve.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/CompoundCurve.java
@@ -21,9 +21,12 @@ import java.util.List;
 import javax.measure.Quantity;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.CurveInterpolation;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.Geometries;
+import org.apache.sis.geometries.Geometry;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.Point;
+import org.apache.sis.geometries.internal.shared.ConcatenatedDataPoints;
 import org.apache.sis.geometries.internal.shared.DefaultCompoundCurve;
 import org.apache.sis.measure.Quantities;
 import org.apache.sis.measure.Units;
@@ -133,4 +136,19 @@ public sealed interface CompoundCurve extends Curve
         }
         return 
getStartPoint().getPosition().equals(getEndPoint().getPosition(), 0);
     }
+
+    /**
+     * Returns the positions of the curves this one is made of, in the order 
they are traversed.
+     * Two consecutive curves share an end position, which therefore appears 
twice.
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        final int n = getNumCurves();
+        final Geometry[] curves = new Geometry[n];
+        for (int i = 0; i < n; i++) {
+            curves[i] = getCurveN(i);
+        }
+        return ConcatenatedDataPoints.of(curves);
+    }
+
 }
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 215402d3d4..085c4124fa 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
@@ -22,6 +22,7 @@ import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.CurveInterpolation;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.GeometryCollection;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.cs.Projection;
@@ -133,4 +134,16 @@ public sealed interface ProductCurve extends Curve, 
GeometryCollection<Curve>
      */
     @UML(identifier="projection", specification=ISO_19107)
     List<Projection> getProjection();
+    /**
+     * Returns the positions of the curves this product is built on, in the 
order it holds them.
+     *
+     * <p>This method resolves the two declarations this interface inherits: 
{@link Curve} leaves
+     * it abstract while {@link GeometryCollection} answers it from the 
elements, and a product
+     * curve is a collection of curves.</p>
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        return GeometryCollection.super.getDataPoints();
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/ConcatenatedDataPoints.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/ConcatenatedDataPoints.java
new file mode 100644
index 0000000000..c1d6057af5
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/ConcatenatedDataPoints.java
@@ -0,0 +1,183 @@
+/*
+ * 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.internal.shared;
+
+import java.util.Arrays;
+import java.util.List;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.DataPoints;
+import org.apache.sis.geometries.DataPointsType;
+import org.apache.sis.geometries.Geometries;
+import org.apache.sis.geometries.Geometry;
+import org.apache.sis.geometries.Point;
+import org.apache.sis.maths.Tuple;
+
+
+/**
+ * Several sequences of positions seen as a single one, in the order they are 
given.
+ * This is the sequence of an aggregate geometry: the rings of a surface, the 
elements of a
+ * collection, the segments of a compound curve. The positions a geometry 
holds several times,
+ * such as the end position two consecutive segments have in common, appear as 
many times.
+ *
+ * <p>The sequences must all declare the same attributes, which {@link 
#ConcatenatedDataPoints}
+ * verifies.</p>
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class ConcatenatedDataPoints implements DataPoints {
+
+    /**
+     * The sequences this view concatenates, never empty.
+     */
+    private final DataPoints[] sources;
+
+    /**
+     * Index at which each source starts in this view, plus the total size at 
the last position.
+     * {@code offsets[i]} is the index of the first position of {@code 
sources[i]}, so the size
+     * of this view is {@code offsets[sources.length]}.
+     */
+    private final int[] offsets;
+
+    /**
+     * Creates a view over the given sequences.
+     *
+     * @param  sources  the sequences to concatenate, at least one.
+     * @throws IllegalArgumentException if no sequence is given,
+     *         or if the sequences do not declare the same attributes.
+     */
+    public ConcatenatedDataPoints(final DataPoints... sources) {
+        if (sources.length == 0) {
+            throw new IllegalArgumentException("At least one sequence of 
positions is required");
+        }
+        this.sources = sources;
+        this.offsets = new int[sources.length + 1];
+        final DataPointsType type = sources[0].getType();
+        for (int i = 0; i < sources.length; i++) {
+            if (i != 0) {
+                Geometries.ensureSameAttributes(type, sources[i].getType());
+            }
+            offsets[i+1] = offsets[i] + sources[i].size();
+        }
+    }
+
+    /**
+     * Creates a view over the sequences of the given geometries.
+     *
+     * @param  geometries  the geometries whose sequences to concatenate, at 
least one.
+     * @return the positions of the given geometries, as a single sequence.
+     * @throws IllegalArgumentException if no geometry is given,
+     *         or if they do not declare the same attributes.
+     */
+    public static DataPoints of(final Geometry... geometries) {
+        final DataPoints[] sources = new DataPoints[geometries.length];
+        for (int i = 0; i < sources.length; i++) {
+            sources[i] = geometries[i].getDataPoints();
+        }
+        return new ConcatenatedDataPoints(sources);
+    }
+
+    /**
+     * Creates a view over the sequences of the given geometries.
+     *
+     * @param  first  the geometry whose sequence comes first, not null.
+     * @param  others the geometries whose sequences follow, possibly empty.
+     * @return the positions of the given geometries, as a single sequence.
+     */
+    public static DataPoints of(final Geometry first, final List<? extends 
Geometry> others) {
+        final DataPoints[] sources = new DataPoints[others.size() + 1];
+        sources[0] = first.getDataPoints();
+        for (int i = 1; i < sources.length; i++) {
+            sources[i] = others.get(i-1).getDataPoints();
+        }
+        return new ConcatenatedDataPoints(sources);
+    }
+
+    /**
+     * Returns the index of the source holding the given position of this view.
+     */
+    private int sourceOf(final int index) {
+        if (index < 0 || index >= offsets[sources.length]) {
+            throw new IndexOutOfBoundsException("Index " + index + " is 
outside the [0 … "
+                    + offsets[sources.length] + "[ range of this sequence");
+        }
+        final int i = Arrays.binarySearch(offsets, 0, sources.length, index);
+        // A negative result is the insertion point: the source is the one 
starting before the index.
+        return (i >= 0) ? i : ~i - 1;
+    }
+
+    @Override
+    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return sources[0].getCoordinateReferenceSystem();
+    }
+
+    @Override
+    public void setCoordinateReferenceSystem(CoordinateReferenceSystem cs) 
throws IllegalArgumentException {
+        for (final DataPoints source : sources) {
+            source.setCoordinateReferenceSystem(cs);
+        }
+    }
+
+    @Override
+    public DataPointsType getType() {
+        return sources[0].getType();
+    }
+
+    @Override
+    public int size() {
+        return offsets[sources.length];
+    }
+
+    @Override
+    public Point getPoint(int index) {
+        final int i = sourceOf(index);
+        return sources[i].getPoint(index - offsets[i]);
+    }
+
+    @Override
+    public Tuple<?> getPosition(int index) {
+        final int i = sourceOf(index);
+        return sources[i].getPosition(index - offsets[i]);
+    }
+
+    @Override
+    public void setPosition(int index, Tuple<?> value) {
+        final int i = sourceOf(index);
+        sources[i].setPosition(index - offsets[i], value);
+    }
+
+    @Override
+    public Tuple<?> getAttribute(int index, String name) {
+        final int i = sourceOf(index);
+        return sources[i].getAttribute(index - offsets[i], name);
+    }
+
+    @Override
+    public void setAttribute(int index, String name, Tuple<?> value) {
+        final int i = sourceOf(index);
+        sources[i].setAttribute(index - offsets[i], name, value);
+    }
+
+    @Override
+    public int hashCode() {
+        return DataPoints.hashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return DataPoints.equals(this, obj);
+    }
+}
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultArcByCenterPoint.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultArcByCenterPoint.java
index be699a4640..45b77d0f04 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultArcByCenterPoint.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultArcByCenterPoint.java
@@ -18,6 +18,7 @@ package org.apache.sis.geometries.internal.shared;
 
 import javax.measure.Unit;
 import org.opengis.geometry.Envelope;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.Point;
 import org.apache.sis.geometries.curve.ArcByCenterPoint;
 
@@ -97,4 +98,13 @@ public non-sealed class DefaultArcByCenterPoint extends 
AbstractGeometry impleme
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    /**
+     * Returns the center of this arc, as a sequence of one position. An arc 
by center point is
+     * defined by that position and by angles, so the center is the only 
position it holds.
+     */
+    @Override
+    public DataPoints getDataPoints() {
+        return center.getDataPoints();
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCompoundCurve.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCompoundCurve.java
index 525c1c10f6..5bab80f024 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCompoundCurve.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCompoundCurve.java
@@ -19,7 +19,6 @@ package org.apache.sis.geometries.internal.shared;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.geometries.Curve;
-import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.DataPointsType;
 import org.apache.sis.geometries.curve.CompoundCurve;
 import org.apache.sis.maths.Array;
@@ -101,8 +100,4 @@ public non-sealed class DefaultCompoundCurve extends 
AbstractGeometry implements
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
-    public DataPoints getDataPoints() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultMultiPoint.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultMultiPoint.java
index fc5ac4f8a9..4d82331193 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultMultiPoint.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultMultiPoint.java
@@ -70,7 +70,7 @@ public non-sealed class DefaultMultiPoint extends 
AbstractGeometry implements Mu
     }
 
     @Override
-    public DataPoints asDataPoints() {
+    public DataPoints getDataPoints() {
         return points;
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPoint.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPoint.java
index 532675eee1..6889c1543b 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPoint.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPoint.java
@@ -64,7 +64,7 @@ public non-sealed class DefaultPoint extends AbstractGeometry 
implements Point {
     }
 
     @Override
-    public DataPoints asDataPoint() {
+    public DataPoints getDataPoints() {
         return points;
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolyhedron.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolyhedron.java
index c05b495c13..37dee66304 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolyhedron.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolyhedron.java
@@ -22,7 +22,6 @@ import javax.measure.Quantity;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.Geometry;
 import org.apache.sis.geometries.solid.Polyhedron;
 import org.apache.sis.geometries.surface.MultiPolygon;
@@ -99,11 +98,6 @@ public non-sealed class DefaultPolyhedron extends 
AbstractGeometry implements Po
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
-    public DataPoints getDataPoints() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
     @Override
     public List<DirectPosition> getControlPoints() {
         throw new UnsupportedOperationException("Not supported yet.");
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 6be8db6890..94827b9490 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
@@ -18,7 +18,6 @@ package org.apache.sis.geometries.internal.shared;
 
 import java.util.List;
 import org.apache.sis.geometries.Curve;
-import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.cs.Projection;
 import org.apache.sis.geometries.curve.ProductCurve;
 import org.apache.sis.maths.Array;
@@ -71,11 +70,6 @@ public non-sealed class DefaultProductCurve extends 
DefaultGeometryCollection<Cu
         return projections;
     }
 
-    @Override
-    public DataPoints getDataPoints() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
     @Override
     public Array getControlPoints() {
         throw new UnsupportedOperationException("Not supported yet.");
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultReversedSurface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultReversedSurface.java
index b9c1281d3f..37532bdfde 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultReversedSurface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultReversedSurface.java
@@ -20,6 +20,7 @@ import java.util.Objects;
 import javax.measure.Quantity;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.Orientable;
 import org.apache.sis.geometries.Primitive;
@@ -102,4 +103,9 @@ public non-sealed class DefaultReversedSurface extends 
AbstractGeometry implemen
         return base.getEnvelope();
     }
 
+    @Override
+    public DataPoints getDataPoints() {
+        return base.getDataPoints();
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/EmptyDataPoints.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/EmptyDataPoints.java
new file mode 100644
index 0000000000..2d4ec34b51
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/EmptyDataPoints.java
@@ -0,0 +1,115 @@
+/*
+ * 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.internal.shared;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.DataPoints;
+import org.apache.sis.geometries.DataPointsType;
+import org.apache.sis.geometries.Point;
+import org.apache.sis.maths.Tuple;
+
+
+/**
+ * A sequence holding no position. This is what a geometry which has no 
position of its own
+ * returns, so that asking any geometry for its positions answers an empty 
sequence rather
+ * than failing.
+ *
+ * <p>Every accessor reports the sequence as empty: there is no index to read 
from or to write
+ * to, so this class is modifiable in the same way an empty list is.</p>
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class EmptyDataPoints implements DataPoints {
+
+    private final CoordinateReferenceSystem crs;
+    private final DataPointsType type;
+
+    /**
+     * Creates an empty sequence described by the given attributes.
+     *
+     * @param  crs   the reference system the absent positions would be 
expressed in, not null.
+     * @param  type  the attributes the absent positions would carry, not null.
+     */
+    public EmptyDataPoints(final CoordinateReferenceSystem crs, final 
DataPointsType type) {
+        this.crs = crs;
+        this.type = type;
+    }
+
+    /**
+     * Creates an empty sequence in the given reference system, carrying no 
attribute.
+     *
+     * @param  crs  the reference system the absent positions would be 
expressed in, not null.
+     */
+    public EmptyDataPoints(final CoordinateReferenceSystem crs) {
+        this(crs, DataPointsType.EMPTY);
+    }
+
+    @Override
+    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return crs;
+    }
+
+    @Override
+    public void setCoordinateReferenceSystem(CoordinateReferenceSystem cs) 
throws IllegalArgumentException {
+        throw new UnsupportedOperationException("The reference system of an 
empty sequence cannot be changed.");
+    }
+
+    @Override
+    public DataPointsType getType() {
+        return type;
+    }
+
+    @Override
+    public int size() {
+        return 0;
+    }
+
+    @Override
+    public Point getPoint(int index) {
+        throw new IndexOutOfBoundsException("This sequence holds no 
position.");
+    }
+
+    @Override
+    public Tuple<?> getPosition(int index) {
+        throw new IndexOutOfBoundsException("This sequence holds no 
position.");
+    }
+
+    @Override
+    public void setPosition(int index, Tuple<?> value) {
+        throw new IndexOutOfBoundsException("This sequence holds no 
position.");
+    }
+
+    @Override
+    public Tuple<?> getAttribute(int index, String name) {
+        throw new IndexOutOfBoundsException("This sequence holds no 
position.");
+    }
+
+    @Override
+    public void setAttribute(int index, String name, Tuple<?> value) {
+        throw new IndexOutOfBoundsException("This sequence holds no 
position.");
+    }
+
+    @Override
+    public int hashCode() {
+        return DataPoints.hashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return DataPoints.equals(this, obj);
+    }
+}
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/SinglePositionDataPoints.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/SinglePositionDataPoints.java
new file mode 100644
index 0000000000..f0b5f262a2
--- /dev/null
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/SinglePositionDataPoints.java
@@ -0,0 +1,139 @@
+/*
+ * 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.internal.shared;
+
+import java.util.function.Supplier;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.DataPoints;
+import org.apache.sis.geometries.DataPointsType;
+import org.apache.sis.geometries.Point;
+import org.apache.sis.maths.DataType;
+import org.apache.sis.maths.SampleSystem;
+import org.apache.sis.maths.Tuple;
+
+
+/**
+ * The single position a geometry is placed by, seen as a sequence of one 
position. This is the
+ * sequence of a shape which is defined by one position and by parameters 
rather than by a list
+ * of coordinates: the center of a sphere, the center of an oriented box.
+ *
+ * <p>This class holds no position of its own. The position is read from the 
geometry each time
+ * it is asked for, so this view follows a geometry which replaces its 
position, and writing
+ * through it moves the geometry.</p>
+ *
+ * @author Johann Sorel (Geomatys)
+ */
+public final class SinglePositionDataPoints implements DataPoints {
+
+    /**
+     * How to reach the position of the geometry this view is built on. It is 
read on each call
+     * rather than kept, so that replacing the position of the geometry is 
seen through this view.
+     */
+    private final Supplier<Tuple<?>> position;
+
+    /**
+     * Creates a view over the position the given supplier reads.
+     *
+     * @param  position  how to read the position of the geometry, not null.
+     */
+    public SinglePositionDataPoints(final Supplier<Tuple<?>> position) {
+        this.position = position;
+    }
+
+    @Override
+    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return position.get().getSampleSystem().getCoordinateReferenceSystem();
+    }
+
+    @Override
+    public void setCoordinateReferenceSystem(CoordinateReferenceSystem cs) 
throws IllegalArgumentException {
+        throw new UnsupportedOperationException("The reference system shall be 
set on the geometry itself.");
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>The type is derived from the position, which carries its own sample 
system and data
+     * type, so that this sequence describes the single attribute it holds.</p>
+     */
+    @Override
+    public DataPointsType getType() {
+        final Tuple<?> p = position.get();
+        final SampleSystem ss = p.getSampleSystem();
+        final DataType dt = p.getDataType();
+        final DataPointsType.Template type = new DataPointsType.Template();
+        type.addOrReplaceAttribute(DataPointsType.ATT_POSITION, ss, dt);
+        return type;
+    }
+
+    @Override
+    public int size() {
+        return 1;
+    }
+
+    @Override
+    public Point getPoint(int index) {
+        ensureValid(index);
+        return new IndexedPoint(this, index);
+    }
+
+    @Override
+    public Tuple<?> getPosition(int index) {
+        ensureValid(index);
+        return position.get();
+    }
+
+    @Override
+    public void setPosition(int index, Tuple<?> value) {
+        ensureValid(index);
+        position.get().set(value);
+    }
+
+    @Override
+    public Tuple<?> getAttribute(int index, String name) {
+        ensureValid(index);
+        return DataPointsType.ATT_POSITION.equals(name) ? position.get() : 
null;
+    }
+
+    @Override
+    public void setAttribute(int index, String name, Tuple<?> value) {
+        ensureValid(index);
+        if (!DataPointsType.ATT_POSITION.equals(name)) {
+            throw new IllegalArgumentException("This sequence holds no \"" + 
name + "\" attribute.");
+        }
+        position.get().set(value);
+    }
+
+    /**
+     * Verifies that the given index is the only one this sequence has.
+     */
+    private static void ensureValid(final int index) {
+        if (index != 0) {
+            throw new IndexOutOfBoundsException("This sequence holds a single 
position, at index 0.");
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return DataPoints.hashCode(this);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return DataPoints.equals(this, obj);
+    }
+}
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/mesh/MeshPrimitive.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/mesh/MeshPrimitive.java
index 994ab99976..20500e9a78 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/mesh/MeshPrimitive.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/mesh/MeshPrimitive.java
@@ -487,6 +487,23 @@ public sealed interface MeshPrimitive extends Geometry
             return positions;
         }
 
+        /**
+         * Returns the positions this primitive draws, in the order it draws 
them. When the
+         * primitive carries an index, the positions appear in the order that 
index names them,
+         * and a position the index names several times appears as many times.
+         */
+        @Override
+        public DataPoints getDataPoints() {
+            final int[] indices;
+            if (index == null) {
+                indices = new int[Math.toIntExact(getPositions().getLength())];
+                for (int i = 0; i < indices.length; i++) indices[i] = i;
+            } else {
+                indices = index.toArrayInt();
+            }
+            return new Sequence(this, indices);
+        }
+
         /**
          * Change positions.
          * Caution : changing the positions will change the primitive CRS,
@@ -1191,17 +1208,6 @@ public sealed interface MeshPrimitive extends Geometry
             super(Type.LINE_STRIP);
         }
 
-        @Override
-        public DataPoints getDataPoints() {
-            final int[] indices;
-            if (index == null) {
-                indices = new int[Math.toIntExact(getPositions().getLength())];
-                for (int i = 0; i < indices.length; i++) indices[i] = i;
-            } else {
-                indices = index.toArrayInt();
-            }
-            return new Sequence(this, indices);
-        }
     }
 
     public static final class Triangles extends Abs implements TIN {
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/mesh/MultiMeshPrimitive.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/mesh/MultiMeshPrimitive.java
index 77b5e75ca8..7b8c651723 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/mesh/MultiMeshPrimitive.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/mesh/MultiMeshPrimitive.java
@@ -26,9 +26,13 @@ import java.util.Map;
 import java.util.Objects;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.Geometries;
+import org.apache.sis.geometries.Geometry;
 import org.apache.sis.geometries.GeometryCollection;
 import org.apache.sis.geometries.internal.shared.AbstractGeometry;
+import org.apache.sis.geometries.internal.shared.ConcatenatedDataPoints;
+import org.apache.sis.geometries.internal.shared.EmptyDataPoints;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.util.ArgumentChecks;
 
@@ -195,4 +199,17 @@ public final class MultiMeshPrimitive<T extends 
MeshPrimitive> extends AbstractG
         return Objects.equals(this.getCoordinateReferenceSystem(), 
other.getCoordinateReferenceSystem());
     }
 
+
+    /**
+     * Returns the positions of the primitives of this set, in the order this 
set holds them.
+     */
+    @Override
+    public DataPoints getDataPoints() {
+        final List<T> components = getComponents();
+        if (components.isEmpty()) {
+            return new EmptyDataPoints(getCoordinateReferenceSystem());
+        }
+        return ConcatenatedDataPoints.of(components.toArray(Geometry[]::new));
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/To3D.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/To3D.java
index 837c1984e1..30a25fed0b 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/To3D.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/To3D.java
@@ -119,7 +119,7 @@ public final class To3D {
      * Add Z axis to Point.
      */
     public static Point to3D(Point base, CoordinateReferenceSystem crs3d, 
Consumer<Tuple> zeditor) {
-        final DataPoints copy3d = to3d(base.asDataPoint(), crs3d, zeditor);
+        final DataPoints copy3d = to3d(base.getDataPoints(), crs3d, zeditor);
         return GeometryFactory.createPoint(copy3d);
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/ToPrimitive.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/ToPrimitive.java
index 03641c19d0..3ab9a00a74 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/ToPrimitive.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/ToPrimitive.java
@@ -90,7 +90,7 @@ public final class ToPrimitive {
      * Transform MultiPoint to Primitive.
      */
     public static MeshPrimitive.Points toPrimitive(MultiPoint geometry) throws 
OperationException {
-        final ArrayDataPoints array = toArraySequence(geometry.asDataPoints());
+        final ArrayDataPoints array = 
toArraySequence(geometry.getDataPoints());
         final MeshPrimitive.Points primitive = new MeshPrimitive.Points();
         for (String name : array.getAttributeNames()) {
             primitive.setAttribute(name, array.getAttribute(name));
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/triangulate/delaunay/OrientedTriangle.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/triangulate/delaunay/OrientedTriangle.java
index 38aa79b01c..ca29c55cc0 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/triangulate/delaunay/OrientedTriangle.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/triangulate/delaunay/OrientedTriangle.java
@@ -313,4 +313,10 @@ public final class OrientedTriangle extends 
AbstractGeometry implements Triangle
         return (int) result;
     }
 
+
+    @Override
+    public DataPoints getDataPoints() {
+        return this;
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/point/MultiPoint.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/point/MultiPoint.java
index f80db68bb2..6a497a130b 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/point/MultiPoint.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/point/MultiPoint.java
@@ -65,7 +65,8 @@ public sealed interface MultiPoint<T extends Point> extends 
GeometryCollection<T
     /**
      * View this multipoint as a point sequence
      */
-    default DataPoints asDataPoints() {
+    @Override
+    default DataPoints getDataPoints() {
         return new DataPoints() {
             @Override
             public CoordinateReferenceSystem getCoordinateReferenceSystem() {
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 323c030c77..b497470e36 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
@@ -18,10 +18,12 @@ package org.apache.sis.geometries.solid;
 
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.Plane;
 import org.apache.sis.geometries.DataPointsType;
 import org.apache.sis.geometries.internal.shared.AbstractGeometry;
+import org.apache.sis.geometries.internal.shared.ConcatenatedDataPoints;
 
 
 /**
@@ -72,4 +74,13 @@ public final class Frustrum extends AbstractGeometry {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    /**
+     * Returns the positions of the planes delimiting this frustum,
+     * in the order this frustum holds them.
+     */
+    @Override
+    public DataPoints getDataPoints() {
+        return ConcatenatedDataPoints.of(planes);
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Polyhedron.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Polyhedron.java
index 8328354349..2838f076dd 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Polyhedron.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Polyhedron.java
@@ -17,10 +17,12 @@
 package org.apache.sis.geometries.solid;
 
 import java.util.List;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.SolidInterpolation;
 import org.apache.sis.geometries.Solid;
 import org.apache.sis.geometries.DataPointsType;
+import org.apache.sis.geometries.internal.shared.ConcatenatedDataPoints;
 import org.apache.sis.geometries.internal.shared.DefaultPolyhedron;
 import org.apache.sis.geometries.solid.polyhedron.AbstractPolyhedron;
 import org.apache.sis.geometries.surface.MultiPolygon;
@@ -57,6 +59,15 @@ public sealed interface Polyhedron extends Solid
         return getExteriorShell().getDataPointsType();
     }
 
+    /**
+     * Returns the positions of the shells bounding this solid, the exterior 
one first,
+     * then the interior ones in the order this solid holds them.
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        return ConcatenatedDataPoints.of(getExteriorShell(), 
getInteriorShells());
+    }
+
     /**
      * Returns {@link SolidInterpolation#NONE}: a polyhedron is defined by its 
boundary shells,
      * which leaves its interior unspecified.
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Sphere.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Sphere.java
index b76d1b0819..e6179b6b98 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Sphere.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/solid/Sphere.java
@@ -31,6 +31,7 @@ import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.SurfaceInterpolation;
 import org.apache.sis.geometries.DataPointsType;
 import org.apache.sis.geometries.internal.shared.AbstractGeometry;
+import org.apache.sis.geometries.internal.shared.SinglePositionDataPoints;
 import org.apache.sis.geometries.surface.ParametricCurveSurface;
 import org.apache.sis.maths.Tuple;
 import org.apache.sis.maths.Vector;
@@ -136,7 +137,7 @@ public final class Sphere extends AbstractGeometry 
implements ParametricCurveSur
 
     @Override
     public DataPointsType getDataPointsType() {
-        return DataPointsType.EMPTY;
+        return getDataPoints().getType();
     }
 
     /**
@@ -206,11 +207,6 @@ public final class Sphere extends AbstractGeometry 
implements ParametricCurveSur
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
-    public DataPoints getDataPoints() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
     @Override
     public GeometryType getHorizontalCurveType() {
         throw new UnsupportedOperationException("Not supported yet.");
@@ -246,4 +242,13 @@ public final class Sphere extends AbstractGeometry 
implements ParametricCurveSur
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
+    /**
+     * Returns the center of this sphere, as a sequence of one position. A 
sphere is defined by
+     * that position and by its radius, so the center is the only position it 
holds.
+     */
+    @Override
+    public DataPoints getDataPoints() {
+        return new SinglePositionDataPoints(this::getCenter);
+    }
+
 }
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 ec97f6c857..4f6c95e638 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
@@ -19,6 +19,7 @@ package org.apache.sis.geometries.solid.polyhedron;
 import java.util.List;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.GeometryFactory;
 import org.apache.sis.geometries.curve.LinearRing;
 import org.apache.sis.geometries.internal.shared.AbstractGeometry;
@@ -196,4 +197,20 @@ public abstract sealed class AbstractPolyhedron extends 
AbstractGeometry impleme
         return GeometryFactory.createPolygon(ring, null);
     }
 
+
+    /**
+     * Unsupported: the vertices of these shapes are a constant shared by 
every instance, not
+     * state of one of them. Returning them would either let one instance move 
the vertices of
+     * all the others, or hand out a sequence which refuses every write, so 
neither answers the
+     * contract of {@link org.apache.sis.geometries.Geometry#getDataPoints()}.
+     *
+     * @return never returns.
+     * @throws UnsupportedOperationException always.
+     */
+    @Override
+    public DataPoints getDataPoints() {
+        throw new UnsupportedOperationException("The vertices of a " + 
getClass().getSimpleName()
+                + " are a shared constant, not positions of this instance.");
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/CurvePolygon.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/CurvePolygon.java
index efa49f1404..8f6dda385d 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/CurvePolygon.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/CurvePolygon.java
@@ -21,9 +21,11 @@ import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
 import org.opengis.geometry.coordinate.GriddedSurface;
 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.DataPointsType;
+import org.apache.sis.geometries.internal.shared.ConcatenatedDataPoints;
 import org.apache.sis.geometries.internal.shared.DefaultCurvePolygon;
 
 
@@ -79,6 +81,15 @@ public sealed interface CurvePolygon extends Surface
         return getExteriorRing().getDataPointsType();
     }
 
+    /**
+     * Returns the positions of the curves bounding this surface, the exterior 
one first,
+     * then the interior ones in the order this surface holds them.
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        return ConcatenatedDataPoints.of(getExteriorRing(), 
getInteriorRings());
+    }
+
     /**
      * Rings bounding the holes of this surface, each of them oriented 
clockwise
      * when viewed from the <cite>top</cite> of this surface.
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Polygon.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Polygon.java
index d11a9f4c58..f186c22436 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Polygon.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Polygon.java
@@ -19,11 +19,13 @@ package org.apache.sis.geometries.surface;
 import java.util.List;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.Surface;
 import org.apache.sis.geometries.SurfaceInterpolation;
 import org.apache.sis.geometries.DataPointsType;
 import org.apache.sis.geometries.curve.LinearRing;
+import org.apache.sis.geometries.internal.shared.ConcatenatedDataPoints;
 import org.apache.sis.geometries.internal.shared.DefaultPolygon;
 
 
@@ -88,6 +90,15 @@ public sealed interface Polygon extends Surface
         return getExteriorRing().getDataPointsType();
     }
 
+    /**
+     * Returns the positions of the rings bounding this surface, the exterior 
ring first,
+     * then the interior ones in the order this surface holds them.
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        return ConcatenatedDataPoints.of(getExteriorRing(), 
getInteriorRings());
+    }
+
     /**
      * Returns {@link SurfaceInterpolation#PLANAR}: a polygon and its boundary 
lie in a single plane.
      *
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/PolyhedralSurface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/PolyhedralSurface.java
index c0f3009c10..95dbce3346 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/PolyhedralSurface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/PolyhedralSurface.java
@@ -20,10 +20,13 @@ import java.util.List;
 import javax.measure.Quantity;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
+import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.Geometries;
+import org.apache.sis.geometries.Geometry;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.Surface;
 import org.apache.sis.geometries.SurfaceInterpolation;
+import org.apache.sis.geometries.internal.shared.ConcatenatedDataPoints;
 import org.apache.sis.geometries.internal.shared.DefaultPolyhedralSurface;
 import org.apache.sis.measure.Quantities;
 import org.apache.sis.measure.Units;
@@ -165,4 +168,18 @@ public sealed interface PolyhedralSurface<T extends 
Polygon> extends /*GeometryC
         throw new UnsupportedOperationException();
     }
 
+    /**
+     * Returns the positions of the patches of this surface, in the order this 
surface holds
+     * them. A position shared by two patches appears as many times as it is 
held.
+     */
+    @Override
+    default DataPoints getDataPoints() {
+        final int n = getNumPatches();
+        final Geometry[] patches = new Geometry[n];
+        for (int i = 0; i < n; i++) {
+            patches[i] = getPatchN(i);
+        }
+        return ConcatenatedDataPoints.of(patches);
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/gml/GML2Writer.java 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/gml/GML2Writer.java
index cb25167d11..15fbe2755f 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/gml/GML2Writer.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/gml/GML2Writer.java
@@ -88,7 +88,7 @@ public final class GML2Writer extends AbstractGMLWriter {
     @Override
     protected void writePoint(final Point g, final String srsName, final 
boolean declareNamespace) throws XMLStreamException {
         writeStart(GML2Tags.POINT, srsName, declareNamespace);
-        writeCoordinates(g.asDataPoint());
+        writeCoordinates(g.getDataPoints());
         writer.writeEndElement();
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/PointTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/PointTest.java
index 1ed325da5f..9d1379547a 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/PointTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/PointTest.java
@@ -99,7 +99,7 @@ public abstract class PointTest extends GeometryTest {
     @Test
     public void testAsDataPoint() {
         final Point point = createPoint2D();
-        final DataPoints points = point.asDataPoint();
+        final DataPoints points = point.getDataPoints();
         assertNotNull(points);
         assertEquals(1, points.size(), "A point is a sequence of a single 
position.");
         assertFalse(points.isEmpty());
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/gml/GeometryAssert.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/gml/GeometryAssert.java
index a0eb410e0d..5e710f6599 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/gml/GeometryAssert.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/gml/GeometryAssert.java
@@ -82,7 +82,7 @@ final class GeometryAssert {
 
         if (expected instanceof Point e) {
             final Point a = (Point) actual;
-            assertSequenceEquals(e.asDataPoint(), a.asDataPoint(), tolerance);
+            assertSequenceEquals(e.getDataPoints(), a.getDataPoints(), 
tolerance);
         } else if (expected instanceof LineString e) {                  // 
Also covers LinearRing.
             final LineString a = (LineString) actual;
             assertSequenceEquals(e.getDataPoints(), a.getDataPoints(), 
tolerance);

Reply via email to