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