This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit fa672af7bab9a09124fec1955d68d2b4359e0f9c
Author: jsorel <[email protected]>
AuthorDate: Thu Sep 17 15:48:36 2026 +0200

    feat(Geometry): replace fixed length,area,volume by Quantity<?> to handle 
dimensionless and temporal geometries
---
 .../main/org/apache/sis/geometries/Curve.java      | 86 +++++++++++++++++-----
 .../main/org/apache/sis/geometries/Empty.java      |  9 ++-
 .../main/org/apache/sis/geometries/Geometries.java | 35 +++++++++
 .../main/org/apache/sis/geometries/Geometry.java   | 23 ++++--
 .../org/apache/sis/geometries/GeometryFactory.java |  4 +-
 .../main/org/apache/sis/geometries/Solid.java      | 13 +++-
 .../main/org/apache/sis/geometries/Surface.java    | 13 +++-
 .../geometries/cs/GeometricCoordinateSystem.java   |  4 +-
 .../apache/sis/geometries/curve/CompoundCurve.java | 13 ++--
 .../apache/sis/geometries/curve/LineString.java    |  4 +-
 .../apache/sis/geometries/curve/MultiCurve.java    | 13 ++--
 .../apache/sis/geometries/curve/OffsetCurve.java   |  4 +-
 .../internal/shared/DefaultBSplineSurface.java     |  4 +-
 .../internal/shared/DefaultBilinearGrid.java       |  4 +-
 .../internal/shared/DefaultCurvePolygon.java       |  4 +-
 .../internal/shared/DefaultNurbSurface.java        |  4 +-
 .../internal/shared/DefaultOffsetCurve.java        |  8 +-
 .../geometries/internal/shared/DefaultPolygon.java |  4 +-
 .../internal/shared/DefaultPolyhedron.java         |  7 +-
 .../internal/shared/DefaultReversedCurve.java      |  4 +-
 .../internal/shared/DefaultReversedSurface.java    |  4 +-
 .../geometries/operation/GeometryProcessor.java    | 15 +++-
 .../apache/sis/geometries/point/PointCloud.java    | 12 ++-
 .../org/apache/sis/geometries/solid/Sphere.java    |  4 +-
 .../sis/geometries/surface/MultiSurface.java       | 13 ++--
 .../sis/geometries/surface/PolyhedralSurface.java  | 13 ++--
 .../apache/sis/geometries/surface/Triangle.java    |  4 +-
 .../sis/geometries/operation/BufferTest.java       |  8 +-
 .../sis/geometries/operation/DistanceTest.java     | 10 +--
 .../geometries/operation/WithinDistanceTest.java   |  6 +-
 30 files changed, 234 insertions(+), 115 deletions(-)

diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Curve.java
index 82df3a4fb9..658a6570bf 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
@@ -17,7 +17,7 @@
 package org.apache.sis.geometries;
 
 import java.util.List;
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.curve.ArcByBulge;
 import org.apache.sis.geometries.curve.ArcByCenterPoint;
 import org.apache.sis.geometries.curve.CircularString;
@@ -111,7 +111,10 @@ public sealed interface Curve extends Orientable
      * The arc length parameterization of this curve therefore spans the [0 … 
length] interval.
      *
      * <p>Difference with OGC Simple Feature Access, which returns a {@code 
double}:
-     * the length is returned as a {@link Length} quantity in order to carry 
its unit of measurement.</p>
+     * the length is returned as a {@link Quantity} in order to carry its unit 
of measurement.</p>
+     *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
      *
      * @return length of the curve.
      *
@@ -119,7 +122,7 @@ public sealed interface Curve extends Orientable
      * @see ISO 19107:2019 - 6.4.18.9
      */
     @UML(identifier="length", specification=ISO_19107)
-    default Length getLength() {
+    default Quantity<?> getLength() {
         throw new UnsupportedOperationException();
     }
 
@@ -322,24 +325,33 @@ public sealed interface Curve extends Orientable
      *
      * <p>Constraints:</p>
      * <ul>
-     *   <li>{@link #param(Length)} applied to this value gives the start 
point.</li>
+     *   <li>{@link #param(Quantity)} applied to this value gives the start 
point.</li>
      *   <li>For a curve which is not a segment of another curve, this value 
is usually zero.</li>
      *   <li>For a segment other than the first one, this value is the
      *       {@linkplain #getEndParam() end parameter} of the preceding 
segment.</li>
      * </ul>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @return arc length parameter of the start point.
      *
      * @see ISO 19107:2019 - 6.4.18.13
      */
     @UML(identifier="startParam", specification=ISO_19107)
-    default Length getStartParam() {
+    default Quantity<?> getStartParam() {
         /*
          * Zero, since the arc length parameterization of a curve spans [0 … 
length] as stated by
          * `getLength()`. A curve which is a segment of another one, and which 
therefore starts
          * where the preceding segment ended, has to override.
+         *
+         * The unit is dimensionless rather than metres: this default knows 
nothing of the curve,
+         * so it cannot know whether the arc length is a distance at all — a 
temporal or crs-less
+         * curve measures its length in something else. Zero being the neutral 
element of the
+         * addition, the unit does not matter here; `getEndParam()` takes care 
of not letting this
+         * dimensionless zero drag the unit of the length down with it.
          */
-        return Quantities.create(0, Units.METRE);
+        return Quantities.create(0, Units.UNITY);
     }
 
     /**
@@ -347,25 +359,38 @@ public sealed interface Curve extends Orientable
      *
      * <p>Constraints:</p>
      * <ul>
-     *   <li>{@link #param(Length)} applied to this value gives the end 
point.</li>
+     *   <li>{@link #param(Quantity)} applied to this value gives the end 
point.</li>
      *   <li>The difference with the {@linkplain #getStartParam() start 
parameter} is the
      *       {@linkplain #getLength() length} of this curve.</li>
      * </ul>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @return arc length parameter of the end point.
      *
      * @see ISO 19107:2019 - 6.4.18.13
      */
     @UML(identifier="endParam", specification=ISO_19107)
-    default Length getEndParam() {
+    default Quantity<?> getEndParam() {
         /*
          * The constraint above: the difference with the start parameter is 
the length of the
          * curve. This holds whatever the start parameter, so a segment which 
overrides
          * `getStartParam()` gets the right answer without overriding this 
method.
          */
-        final Length start = getStartParam();
-        final Length length = getLength();
-        return Quantities.castOrCopy(start.add(length));
+        final Quantity<?> start = getStartParam();
+        final Quantity<?> length = getLength();
+        if (start.getValue().doubleValue() == 0) {
+            /*
+             * The start parameter of a curve which is not a segment of 
another one is zero, and
+             * the default `getStartParam()` reports that zero as a 
dimensionless quantity since it
+             * cannot know the unit of the arc length. `Geometries.add(…)` 
would accept it and
+             * return a dimensionless sum, discarding the unit of the length; 
zero being the
+             * neutral element, the end parameter is the length itself, unit 
included.
+             */
+            return length;
+        }
+        return Geometries.add(start, length);
     }
 
     /**
@@ -454,10 +479,13 @@ public sealed interface Curve extends Orientable
      * @param  offset   maximal distance between this curve and the line, or 
zero for no limit.
      * @return a linear approximation of this curve.
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @see ISO 19107:2019 - 6.4.18.17
      */
     @UML(identifier="asLine", specification=ISO_19107)
-    default LineString asLine(Length spacing, Length offset) {
+    default LineString asLine(Quantity<?> spacing, Quantity<?> offset) {
         //TODO
         throw new UnsupportedOperationException();
     }
@@ -490,6 +518,9 @@ public sealed interface Curve extends Orientable
      *       the smallest length is returned.</li>
      * </ul>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  point1  first position, by default the {@linkplain 
#getStartPoint() start point}.
      * @param  point2  second position, by default the {@linkplain 
#getEndPoint() end point}.
      * @return length of this curve between the two given positions.
@@ -497,7 +528,7 @@ public sealed interface Curve extends Orientable
      * @see ISO 19107:2019 - 6.4.18.19
      */
     @UML(identifier="length", specification=ISO_19107)
-    default Length getLength(DirectPosition point1, DirectPosition point2) {
+    default Quantity<?> getLength(DirectPosition point1, DirectPosition 
point2) {
         //TODO
         throw new UnsupportedOperationException();
     }
@@ -507,6 +538,9 @@ public sealed interface Curve extends Orientable
      * This variant works directly in the construction parameter space, and 
therefore also
      * converts a construction parameter into an arc length parameter.
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  cparam1  first construction parameter, by default the 
{@linkplain #getStartConstrParam() start} one.
      * @param  cparam2  second construction parameter, by default the 
{@linkplain #getEndConstrParam() end} one.
      * @return length of this curve between the two given construction 
parameters.
@@ -514,7 +548,7 @@ public sealed interface Curve extends Orientable
      * @see ISO 19107:2019 - 6.4.18.19
      */
     @UML(identifier="length", specification=ISO_19107)
-    default Length getLength(double cparam1, double cparam2) {
+    default Quantity<?> getLength(double cparam1, double cparam2) {
         //TODO
         throw new UnsupportedOperationException();
     }
@@ -524,6 +558,9 @@ public sealed interface Curve extends Orientable
      * i.e. at the given distance measured along this curve from the
      * {@linkplain #getStartParam() start parameter}.
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  s  arc length parameter, between the {@linkplain 
#getStartParam() start}
      *            and the {@linkplain #getEndParam() end} parameters.
      * @return position on this curve at the given arc length parameter.
@@ -531,7 +568,7 @@ public sealed interface Curve extends Orientable
      * @see ISO 19107:2019 - 6.4.18.20
      */
     @UML(identifier="param", specification=ISO_19107)
-    default DirectPosition param(Length s) {
+    default DirectPosition param(Quantity<?> s) {
         //TODO
         throw new UnsupportedOperationException();
     }
@@ -542,20 +579,23 @@ public sealed interface Curve extends Orientable
      * <p>Constraints:</p>
      * <ul>
      *   <li>A position which is not on this curve is replaced by the nearest 
position on this curve.</li>
-     *   <li>For any returned value <var>d</var>, {@link #param(Length)} 
applied to <var>d</var>
+     *   <li>For any returned value <var>d</var>, {@link #param(Quantity)} 
applied to <var>d</var>
      *       gives the given position.</li>
      *   <li>More than one value is returned only if this curve is not 
simple.</li>
      *   <li>If several positions of this curve are at the same minimal 
distance from the given
      *       position, the choice among them is arbitrary.</li>
      * </ul>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  p  position for which to compute the arc length parameters.
      * @return arc length parameters of the given position, possibly empty.
      *
      * @see ISO 19107:2019 - 6.4.18.21
      */
     @UML(identifier="paramForPoint", specification=ISO_19107)
-    default List<Length> paramForPoint(DirectPosition p) {
+    default List<Quantity<?>> paramForPoint(DirectPosition p) {
         //TODO
         throw new UnsupportedOperationException();
     }
@@ -567,12 +607,15 @@ public sealed interface Curve extends Orientable
      *
      * @param  s  arc length parameter, between the {@linkplain 
#getStartParam() start}
      *            and the {@linkplain #getEndParam() end} parameters.
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @return unit tangent vector at the given arc length parameter.
      *
      * @see ISO 19107:2019 - 6.4.18.22
      */
     @UML(identifier="tangent", specification=ISO_19107)
-    default Vector tangent(Length s) {
+    default Vector tangent(Quantity<?> s) {
         //TODO
         throw new UnsupportedOperationException();
     }
@@ -581,7 +624,7 @@ public sealed interface Curve extends Orientable
      * Returns the tangent vector at the given construction parameter.
      * The vector coordinates are the differentials of the coordinates of the 
direct positions.
      * Its direction is the direction of this curve, but its magnitude depends 
on the construction
-     * parameterization; {@link #tangent(Length)} returns the collinear unit 
vector.
+     * parameterization; {@link #tangent(Quantity)} returns the collinear unit 
vector.
      *
      * @param  knotParameter  construction parameter, between the {@linkplain 
#getStartConstrParam() start}
      *                        and the {@linkplain #getEndConstrParam() end} 
construction parameters.
@@ -635,6 +678,9 @@ public sealed interface Curve extends Orientable
      * <p>Difference with ISO 19107: declared as a copy constructor in the 
standard,
      * which an interface cannot express in Java.</p>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  dist1  arc length parameter where the returned curve begins.
      * @param  dist2  arc length parameter where the returned curve ends.
      * @return the portion of this curve between the two given arc length 
parameters.
@@ -642,7 +688,7 @@ public sealed interface Curve extends Orientable
      * @see ISO 19107:2019 - 6.4.18.22
      */
     @UML(identifier="Curve", specification=ISO_19107)
-    default Curve subCurve(Length dist1, Length dist2) {
+    default Curve subCurve(Quantity<?> dist1, Quantity<?> dist2) {
         //TODO
         throw new UnsupportedOperationException();
     }
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 8d6631a3a2..589e7ae868 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
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometries;
 
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.internal.shared.DefaultEmpty;
 import org.apache.sis.measure.Quantities;
 import org.apache.sis.measure.Units;
@@ -174,7 +174,7 @@ public sealed interface Empty extends Geometry
      */
     @UML(identifier="buffer", specification=ISO_19107)
     @Override
-    default Geometry buffer(Length radius) {
+    default Geometry buffer(Quantity<?> radius) {
         return this;
     }
 
@@ -202,13 +202,14 @@ public sealed interface Empty extends Geometry
 
     /**
      * Returns an infinite distance: no position of this geometry can come 
close to another geometry.
+     * The returned quantity is dimensionless, the empty set having no 
measurement unit to report.
      *
      * @see ISO 19107:2019 - 6.4.4.26
      */
     @UML(identifier="distance", specification=ISO_19107)
     @Override
-    default Length distance(Geometry other) {
-        return Quantities.create(Double.POSITIVE_INFINITY, Units.METRE);
+    default Quantity<?> distance(Geometry other) {
+        return Quantities.create(Double.POSITIVE_INFINITY, Units.UNITY);
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometries.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometries.java
index 86236ba510..343a3caff7 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometries.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Geometries.java
@@ -29,6 +29,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
+import javax.measure.Quantity;
 import javax.measure.Unit;
 import org.apache.sis.geometries.adapter.JTSAdapter;
 import org.apache.sis.geometries.adapter.ShapeAdapter;
@@ -44,6 +45,7 @@ import org.apache.sis.maths.Tuple;
 import org.apache.sis.maths.Vector;
 import org.apache.sis.maths.Vector3D;
 import org.apache.sis.maths.Vectors;
+import org.apache.sis.measure.Quantities;
 import org.apache.sis.measure.Units;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.crs.DefaultEngineeringCRS;
@@ -695,6 +697,39 @@ public final class Geometries {
         return primitive;
     }
 
+    /**
+     * Returns the sum of the two given quantities, expressed in the unit of 
the first one,
+     * or dimensionless if either operand is dimensionless.
+     *
+     * @param  q1  the first quantity, whose unit is the unit of the result 
unless one operand is
+     *             dimensionless, in which case the result is dimensionless.
+     * @param  q2  the quantity to add to the first one.
+     * @return the sum of the two quantities.
+     * @throws ClassCastException if the two quantities have different 
dimensions, neither of them
+     *         being the dimensionless one.
+     */
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    public static Quantity<?> add(final Quantity<?> q1, final Quantity<?> q2) {
+        if (Units.isScale(q1.getUnit()) != Units.isScale(q2.getUnit())) {
+            return Quantities.create(toScalar(q1) + toScalar(q2), Units.UNITY);
+        }
+        return ((Quantity) q1).add(q2);
+    }
+
+    /**
+     * Returns the value of the given quantity as a plain number. A 
dimensionless quantity is first
+     * converted to {@link Units#UNITY}, so that a percentage counts for its 
fraction rather than
+     * for its numerator. Any other quantity is taken as-is, no conversion to 
unity existing.
+     */
+    private static double toScalar(final Quantity<?> q) {
+        final Unit<?> unit = q.getUnit();
+        final double value = q.getValue().doubleValue();
+        if (Units.isScale(unit)) {
+            return 
Units.ensureScale(unit).getConverterTo(Units.UNITY).convert(value);
+        }
+        return value;
+    }
+
     /**
      * Ensure two geometries declare the same attributes.
      */
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 3997f5d419..d17f5153fa 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
@@ -18,7 +18,7 @@ package org.apache.sis.geometries;
 
 import java.util.List;
 import java.util.Map;
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.adapter.WellKnownBinary;
 import org.apache.sis.geometries.adapter.WellKnownText;
 import org.apache.sis.geometries.internal.shared.AbstractGeometry;
@@ -580,7 +580,7 @@ public sealed interface Geometry
      * expressed in the units of the coordinate reference system.
      *
      * <p>Difference with ISO 19107, which takes a distance quantity:
-     * see {@link #buffer(Length)} for the standard operation.</p>
+     * see {@link #buffer(Quantity)} for the standard operation.</p>
      *
      * @param  distance  radius of the buffer.
      * @return buffer around this geometry.
@@ -606,16 +606,19 @@ public sealed interface Geometry
      *   <li>The buffer of an empty geometry is the empty geometry.</li>
      * </ul>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  radius  radius of the buffer.
      * @return buffer around this geometry.
      * @throws OperationException if the buffer cannot be computed.
      *
-     * @see GeometryProcessor#buffer(org.apache.sis.geometries.Geometry, 
javax.measure.quantity.Length)
+     * @see GeometryProcessor#buffer(org.apache.sis.geometries.Geometry, 
javax.measure.Quantity)
      * @see ISO 19107:2019 - 6.4.4.24, 6.4.8.3, 6.4.9
      */
     @UML(identifier="buffer", specification=ISO_19107)
     //@UML(identifier="3Dbuffer", specification=ISO_19107)
-    default Geometry buffer(Length radius) throws OperationException {
+    default Geometry buffer(Quantity<?> radius) throws OperationException {
         return new GeometryProcessor().buffer(this, radius);
     }
 
@@ -676,6 +679,9 @@ public sealed interface Geometry
      *   <li>Infinite if either geometry is empty.</li>
      * </ul>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  other  the geometry to measure the distance to.
      * @return distance between the two geometries.
      * @throws OperationException if the distance cannot be computed.
@@ -685,7 +691,7 @@ public sealed interface Geometry
      */
     @UML(identifier="distance", specification=ISO_19107)
     //@UML(identifier="3Ddistance", specification=ISO_19107)
-    default Length distance(Geometry other) throws OperationException {
+    default Quantity<?> distance(Geometry other) throws OperationException {
         return new GeometryProcessor().distance(this, other);
     }
 
@@ -1075,17 +1081,20 @@ public sealed interface Geometry
      *   <li>Equivalent to {@code buffer(distance).intersects(other)}.</li>
      * </ul>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  other     the geometry to test against.
      * @param  distance  maximal distance between the two geometries.
      * @return {@code true} if the two geometries are within the given 
distance.
      * @throws OperationException if the test cannot be performed.
      *
-     * @see 
GeometryProcessor#withinDistance(org.apache.sis.geometries.Geometry, 
org.apache.sis.geometries.Geometry, javax.measure.quantity.Length)
+     * @see 
GeometryProcessor#withinDistance(org.apache.sis.geometries.Geometry, 
org.apache.sis.geometries.Geometry, javax.measure.Quantity)
      * @see ISO 19107:2019 - 6.4.8.8, 6.4.9, 10.8.7
      */
     @UML(identifier="withinDistance", specification=ISO_19107)
     //@UML(identifier="3DwithinDistance", specification=ISO_19107)
-    default boolean withinDistance(Geometry other, Length distance) throws 
OperationException {
+    default boolean withinDistance(Geometry other, Quantity<?> distance) 
throws OperationException {
         return new GeometryProcessor().withinDistance(this, other, distance);
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
index cf42443272..1829edadcf 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/GeometryFactory.java
@@ -21,8 +21,8 @@ import java.nio.DoubleBuffer;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import javax.measure.Quantity;
 import javax.measure.Unit;
-import javax.measure.quantity.Length;
 import org.apache.sis.geometries.cs.Projection;
 import org.apache.sis.geometries.curve.Arc;
 import org.apache.sis.geometries.curve.ArcByBulge;
@@ -487,7 +487,7 @@ public final class GeometryFactory extends 
org.apache.sis.geometry.wrapper.Geome
      * @param  refDirection  reference direction of the offset in a 
3-dimensional coordinate system,
      *                       or {@code null} if the spatial dimension is 2.
      */
-    public static OffsetCurve createOffsetCurve(Curve baseCurve, Length 
distance, Bearing refDirection) {
+    public static OffsetCurve createOffsetCurve(Curve baseCurve, Quantity<?> 
distance, Bearing refDirection) {
         return new DefaultOffsetCurve(baseCurve, distance, refDirection);
     }
 
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 16c87596e9..a026d0e2e1 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
@@ -17,8 +17,7 @@
 package org.apache.sis.geometries;
 
 import java.util.List;
-import javax.measure.quantity.Area;
-import javax.measure.quantity.Volume;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.solid.ParametricCurveSolid;
 import org.apache.sis.geometries.solid.Polyhedron;
 import static org.opengis.annotation.Specification.ISO_19107;
@@ -108,12 +107,15 @@ public sealed interface Solid extends Primitive
     /**
      * Sum of the areas of all the boundary surfaces of this solid.
      *
+     * <p>Difference with ISO-19107, the Area type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @return area of the boundary of this solid.
      *
      * @see ISO 19107:2019 - 6.4.28.3
      */
     @UML(identifier="area", specification=ISO_19107)
-    default Area getArea() {
+    default Quantity<?> getArea() {
         throw new UnsupportedOperationException();
     }
 
@@ -121,12 +123,15 @@ public sealed interface Solid extends Primitive
      * Volume enclosed by this solid, that is the volume interior to the 
exterior shell
      * and exterior to any interior shell.
      *
+     * <p>Difference with ISO-19107, the Volume type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @return volume of this solid.
      *
      * @see ISO 19107:2019 - 6.4.28.4
      */
     @UML(identifier="volume", specification=ISO_19107)
-    default Volume getVolume() {
+    default Quantity<?> getVolume() {
         throw new UnsupportedOperationException();
     }
 
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 d725c2ca94..2b619df9c2 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
@@ -17,8 +17,7 @@
 package org.apache.sis.geometries;
 
 import java.util.List;
-import javax.measure.quantity.Area;
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.internal.shared.DefaultReversedSurface;
 import org.apache.sis.geometries.surface.CurvePolygon;
 import org.apache.sis.geometries.surface.ParametricCurveSurface;
@@ -93,13 +92,16 @@ public sealed interface Surface extends Orientable
      * metres. Computing a true area on the reference surface, as required by 
ISO 19107 REQ. 11,
      * remains to be done.</p>
      *
+     * <p>Difference with ISO-19107, the Area type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @return area of the surface.
      *
      * @see OGC Simple Feature Access 1.2.1 - 6.1.10.2
      * @see ISO 19107:2019 - 6.4.25.7
      */
     @UML(identifier="area", specification=ISO_19107)
-    Area getArea();
+    Quantity<?> getArea();
 
     /**
      * The mathematical centroid for this Surface as a Point.
@@ -209,12 +211,15 @@ public sealed interface Surface extends Orientable
     /**
      * Sum of the lengths of all the boundary curves of this surface.
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @return perimeter of this surface.
      *
      * @see ISO 19107:2019 - 6.4.25.6
      */
     @UML(identifier="perimeter", specification=ISO_19107)
-    default Length getPerimeter() {
+    default Quantity<?> getPerimeter() {
         //TODO
         throw new UnsupportedOperationException();
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/cs/GeometricCoordinateSystem.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/cs/GeometricCoordinateSystem.java
index de477134a0..93e309f147 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/cs/GeometricCoordinateSystem.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/cs/GeometricCoordinateSystem.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometries.cs;
 
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
 import org.opengis.geometry.DirectPosition;
@@ -56,7 +56,7 @@ public interface GeometricCoordinateSystem {
     Number csDistance(DirectPosition p1, DirectPosition p2);
 
     @UML(identifier="distance", specification=ISO_19107) // section 6.2.8.10
-    Length distance(DirectPosition p1, DirectPosition p2);
+    Quantity<?> distance(DirectPosition p1, DirectPosition p2);
 
     @UML(identifier="pointAtDistance", specification=ISO_19107) // section 
6.2.8.11
     DirectPosition pointAtDistance(DirectPosition center, Vector vector);
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 aae8df5e70..0423c28385 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
@@ -18,9 +18,10 @@ package org.apache.sis.geometries.curve;
 
 import java.util.ArrayList;
 import java.util.List;
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.CurveInterpolation;
+import org.apache.sis.geometries.Geometries;
 import org.apache.sis.geometries.Point;
 import org.apache.sis.geometries.internal.shared.DefaultCompoundCurve;
 import org.apache.sis.measure.Quantities;
@@ -103,17 +104,17 @@ public sealed interface CompoundCurve extends Curve
     /**
      * Returns the sum of the lengths of the components.
      * The unit of measurement is the one of the first component,
-     * or metres if this compound curve has no component.
+     * or dimensionless if this compound curve has no component.
      */
     @Override
-    default Length getLength() {
+    default Quantity<?> getLength() {
         final int n = getNumCurves();
         if (n == 0) {
-            return Quantities.create(0, Units.METRE);
+            return Quantities.create(0, Units.UNITY);
         }
-        Length length = getCurveN(0).getLength();
+        Quantity<?> length = getCurveN(0).getLength();
         for (int i = 1; i < n; i++) {
-            length = 
Quantities.castOrCopy(length.add(getCurveN(i).getLength()));
+            length = Geometries.add(length, getCurveN(i).getLength());
         }
         return length;
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/LineString.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/LineString.java
index fef79f59f4..758c4916df 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/LineString.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/LineString.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometries.curve;
 
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.CurveInterpolation;
@@ -94,7 +94,7 @@ public sealed interface LineString extends Curve
      * @see ISO 19107:2019 - 6.4.18.17
      */
     @Override
-    default LineString asLine(Length spacing, Length offset) {
+    default LineString asLine(Quantity<?> spacing, Quantity<?> offset) {
         return this;
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/MultiCurve.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/MultiCurve.java
index 98edf739d1..5e887cfbe8 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/MultiCurve.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/MultiCurve.java
@@ -17,8 +17,9 @@
 package org.apache.sis.geometries.curve;
 
 import java.util.Set;
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Curve;
+import org.apache.sis.geometries.Geometries;
 import org.apache.sis.geometries.GeometryCollection;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.internal.shared.DefaultMultiCurve;
@@ -87,19 +88,19 @@ public sealed interface MultiCurve<T extends Curve> extends 
GeometryCollection<T
     /**
      * The Length of this MultiCurve which is equal to the sum of the lengths 
of the element Curves.
      * The unit of measurement is the one of the first element,
-     * or metres if this MultiCurve has no element.
+     * or dimensionless if this MultiCurve has no element.
      *
      * @see OGC Simple Feature Access 1.2.1 - 6.1.8.2
      * @return length of the multicurve.
      */
-    default Length getLength() {
+    default Quantity<?> getLength() {
         final int n = getNumGeometries();
         if (n == 0) {
-            return Quantities.create(0, Units.METRE);
+            return Quantities.create(0, Units.UNITY);
         }
-        Length length = getGeometryN(0).getLength();
+        Quantity<?> length = getGeometryN(0).getLength();
         for (int i = 1; i < n; i++) {
-            length = 
Quantities.castOrCopy(length.add(getGeometryN(i).getLength()));
+            length = Geometries.add(length, getGeometryN(i).getLength());
         }
         return length;
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/OffsetCurve.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/OffsetCurve.java
index 5182e2b2c4..85dae6091f 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/OffsetCurve.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/curve/OffsetCurve.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometries.curve;
 
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Bearing;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.internal.shared.DefaultOffsetCurve;
@@ -77,7 +77,7 @@ public sealed interface OffsetCurve extends Curve
      * @see ISO 19107:2019 - 6.4.20.2
      */
     @UML(identifier="distance", specification=ISO_19107)
-    Length getDistance();
+    Quantity<?> getDistance();
 
     /**
      * Direction in which this curve is offset from the {@linkplain 
#getBaseCurve() base curve},
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java
index 2774c512ce..452e250e52 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBSplineSurface.java
@@ -18,7 +18,7 @@ package org.apache.sis.geometries.internal.shared;
 
 import java.util.List;
 import java.util.Objects;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.curve.KnotType;
@@ -178,7 +178,7 @@ public non-sealed class DefaultBSplineSurface extends 
AbstractGeometry implement
     }
 
     @Override
-    public Area getArea() {
+    public Quantity<?> getArea() {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java
index 41fe91c035..1ec023de7a 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultBilinearGrid.java
@@ -18,7 +18,7 @@ package org.apache.sis.geometries.internal.shared;
 
 import java.util.List;
 import java.util.Objects;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.DataPoints;
@@ -162,7 +162,7 @@ public non-sealed class DefaultBilinearGrid extends 
AbstractGeometry implements
     }
 
     @Override
-    public Area getArea() {
+    public Quantity<?> getArea() {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCurvePolygon.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCurvePolygon.java
index c86cc90970..558efc536c 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCurvePolygon.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultCurvePolygon.java
@@ -18,7 +18,7 @@ package org.apache.sis.geometries.internal.shared;
 
 import java.util.List;
 import java.util.Objects;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.Geometries;
 import org.apache.sis.geometries.surface.CurvePolygon;
@@ -83,7 +83,7 @@ public non-sealed class DefaultCurvePolygon extends 
AbstractGeometry implements
     }
 
     @Override
-    public Area getArea() {
+    public Quantity<?> getArea() {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultNurbSurface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultNurbSurface.java
index 60c1b45172..6e27f7759e 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultNurbSurface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultNurbSurface.java
@@ -18,7 +18,7 @@ package org.apache.sis.geometries.internal.shared;
 
 import java.util.Arrays;
 import java.util.List;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.BBox;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.DataPoints;
@@ -337,7 +337,7 @@ public non-sealed class DefaultNurbSurface extends 
AbstractGeometry implements N
     }
 
     @Override
-    public Area getArea() {
+    public Quantity<?> getArea() {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultOffsetCurve.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultOffsetCurve.java
index b89bf050c6..88c5b0afd7 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultOffsetCurve.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultOffsetCurve.java
@@ -17,7 +17,7 @@
 package org.apache.sis.geometries.internal.shared;
 
 import java.util.Objects;
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.Bearing;
 import org.apache.sis.geometries.Curve;
@@ -44,7 +44,7 @@ public non-sealed class DefaultOffsetCurve extends 
AbstractGeometry implements O
     /**
      * Distance at which this curve is generated from the base curve.
      */
-    protected final Length distance;
+    protected final Quantity<?> distance;
 
     /**
      * Direction in which this curve is offset, or {@code null} if the spatial 
dimension is 2.
@@ -63,7 +63,7 @@ public non-sealed class DefaultOffsetCurve extends 
AbstractGeometry implements O
      *                       of the base curve gives the offset direction in a 
3-dimensional
      *                       coordinate system, or {@code null} if the spatial 
dimension is 2.
      */
-    public DefaultOffsetCurve(final Curve baseCurve, final Length distance, 
final Bearing refDirection) {
+    public DefaultOffsetCurve(final Curve baseCurve, final Quantity<?> 
distance, final Bearing refDirection) {
         this.baseCurve    = Objects.requireNonNull(baseCurve);
         this.distance     = Objects.requireNonNull(distance);
         this.refDirection = refDirection;
@@ -75,7 +75,7 @@ public non-sealed class DefaultOffsetCurve extends 
AbstractGeometry implements O
     }
 
     @Override
-    public Length getDistance() {
+    public Quantity<?> getDistance() {
         return distance;
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolygon.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolygon.java
index 9530a19ebc..a8e3492e05 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolygon.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultPolygon.java
@@ -18,7 +18,7 @@ package org.apache.sis.geometries.internal.shared;
 
 import java.util.List;
 import java.util.Objects;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.Geometries;
 import org.apache.sis.geometries.curve.LinearRing;
@@ -87,7 +87,7 @@ public non-sealed class DefaultPolygon extends 
AbstractGeometry implements Polyg
     }
 
     @Override
-    public Area getArea() {
+    public Quantity<?> getArea() {
         //TODO : fallback on JTS until implemented
         return Quantities.create(Geometries.asJTS(this, false, new 
GeometryFactory()).getArea(), Units.SQUARE_METRE);
     }
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 b603651aca..d9019e4b27 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
@@ -18,8 +18,7 @@ package org.apache.sis.geometries.internal.shared;
 
 import java.util.List;
 import java.util.Objects;
-import javax.measure.quantity.Area;
-import javax.measure.quantity.Volume;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.DataPoints;
 import org.apache.sis.geometries.Geometry;
 import org.apache.sis.geometries.solid.Polyhedron;
@@ -91,12 +90,12 @@ public non-sealed class DefaultPolyhedron extends 
AbstractGeometry implements Po
     }
 
     @Override
-    public Area getArea() {
+    public Quantity<?> getArea() {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
     @Override
-    public Volume getVolume() {
+    public Quantity<?> getVolume() {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultReversedCurve.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultReversedCurve.java
index efcddf5bce..234d8bcdc6 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultReversedCurve.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/internal/shared/DefaultReversedCurve.java
@@ -17,7 +17,7 @@
 package org.apache.sis.geometries.internal.shared;
 
 import java.util.Objects;
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.Curve;
 import org.apache.sis.geometries.CurveInterpolation;
@@ -94,7 +94,7 @@ public non-sealed class DefaultReversedCurve extends 
AbstractGeometry implements
     }
 
     @Override
-    public Length getLength() {
+    public Quantity<?> getLength() {
         return base.getLength();
     }
 
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 fa6730f8c1..30588db837 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
@@ -17,7 +17,7 @@
 package org.apache.sis.geometries.internal.shared;
 
 import java.util.Objects;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.Orientable;
 import org.apache.sis.geometries.Primitive;
@@ -72,7 +72,7 @@ public non-sealed class DefaultReversedSurface extends 
AbstractGeometry implemen
      * Returns the area of the base surface. Area is unsigned, so the 
orientation does not affect it.
      */
     @Override
-    public Area getArea() {
+    public Quantity<?> getArea() {
         return base.getArea();
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/GeometryProcessor.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/GeometryProcessor.java
index 3fd2fa991d..3448540947 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/GeometryProcessor.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/GeometryProcessor.java
@@ -23,7 +23,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.function.Consumer;
 import java.util.function.Function;
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.Geometries;
 import org.apache.sis.geometries.Geometry;
@@ -85,7 +85,7 @@ public final class GeometryProcessor {
 
     @UML(identifier="buffer", specification=ISO_19107) // section 6.4.4.24 and 
6.4.8.3
     //@UML(identifier="3Dbuffer", specification=ISO_19107) // section 6.4.9
-    public Geometry buffer(Geometry geom, Length radius) throws 
OperationException {
+    public Geometry buffer(Geometry geom, Quantity<?> radius) throws 
OperationException {
         throw new UnsupportedOperationException();
     }
 
@@ -123,10 +123,13 @@ public final class GeometryProcessor {
      * coordinate reference system that magnitude is therefore an amount of 
degrees reported as
      * metres. Computing a true geodesic distance on the reference surface, as 
required by
      * ISO 19107 REQ. 11, remains to be done.</p>
+     *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
      */
     @UML(identifier="distance", specification=ISO_19107) // section 6.4.4.26 
and 6.4.8.2
     //@UML(identifier="3Ddistance", specification=ISO_19107) // section 6.4.9
-    public Length distance(Geometry geom1, Geometry geom2) throws 
OperationException {
+    public Quantity<?> distance(Geometry geom1, Geometry geom2) throws 
OperationException {
         if (geom1 instanceof Point pt1) {
             if (geom2 instanceof Point pt2) {
                 return Quantities.create(Distance.distance(pt1, pt2), 
Units.METRE);
@@ -309,9 +312,13 @@ public final class GeometryProcessor {
         return jts(geom1).within(jts(geom2));
     }
 
+    /**
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     */
     @UML(identifier="withinDistance", specification=ISO_19107) // section 
6.4.8.8
     //@UML(identifier="3DwithinDistance", specification=ISO_19107) // section 
6.4.9
-    public boolean withinDistance(Geometry geom1, Geometry geom2, Length 
distance) throws OperationException {
+    public boolean withinDistance(Geometry geom1, Geometry geom2, Quantity<?> 
distance) throws OperationException {
         throw new UnsupportedOperationException();
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/point/PointCloud.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/point/PointCloud.java
index 0c697f61a5..c5328d3875 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/point/PointCloud.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/point/PointCloud.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometries.point;
 
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Geometry;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
@@ -93,6 +93,9 @@ public interface PointCloud {
      * <p>Difference with ISO 19107, which also takes a list of {@code 
Constraint}: no such type is
      * defined by this implementation, so additional constraints cannot be 
expressed yet.</p>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  density  average distance between the points of the returned 
cloud.
      * @param  range    extent to which the returned cloud is limited.
      * @return a sub-cloud of this cloud.
@@ -100,7 +103,7 @@ public interface PointCloud {
      * @see ISO 19107:2019 - 11.2.2.4
      */
     @UML(identifier="SubCloud", specification=ISO_19107)
-    PointCloud subCloud(Length density, Envelope range);
+    PointCloud subCloud(Quantity<?> density, Envelope range);
 
     /**
      * Builds a simplicial complex from this cloud: a triangulated surface in 
2 dimensions,
@@ -110,6 +113,9 @@ public interface PointCloud {
      * of {@code Constraint}: neither type is defined by this implementation, 
so the result is
      * returned as a {@link Geometry} and additional constraints cannot be 
expressed yet.</p>
      *
+     * <p>Difference with ISO-19107, the Length type has been changed to 
Quantity to
+     * handle temporal geometries and crs-less geometries.</p>
+     *
      * @param  dimension  topological dimension of the simplices to build.
      * @param  density    average distance between the points to use.
      * @param  range      extent to which the computation is limited.
@@ -118,5 +124,5 @@ public interface PointCloud {
      * @see ISO 19107:2019 - 11.2.2.5
      */
     @UML(identifier="SimplicialComplex", specification=ISO_19107)
-    Geometry simplicialComplex(int dimension, Length density, Envelope range);
+    Geometry simplicialComplex(int dimension, Quantity<?> density, Envelope 
range);
 }
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 5cb802e25a..a4edc2804e 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
@@ -17,7 +17,7 @@
 package org.apache.sis.geometries.solid;
 
 import java.util.List;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.BBox;
 import org.apache.sis.geometries.Curve;
@@ -113,7 +113,7 @@ public final class Sphere extends AbstractGeometry 
implements ParametricCurveSur
     }
 
     @Override
-    public Area getArea() {
+    public Quantity<?> getArea() {
         throw new UnsupportedOperationException("Not supported.");
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/MultiSurface.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/MultiSurface.java
index 10dfba4767..dff56c9455 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/MultiSurface.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/MultiSurface.java
@@ -17,7 +17,8 @@
 package org.apache.sis.geometries.surface;
 
 import java.util.Set;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
+import org.apache.sis.geometries.Geometries;
 import org.apache.sis.geometries.GeometryCollection;
 import org.apache.sis.geometries.GeometryType;
 import org.apache.sis.geometries.Point;
@@ -68,18 +69,20 @@ public sealed interface MultiSurface<T extends Surface> 
extends GeometryCollecti
 
     /**
      * The area of this MultiSurface, as measured in the spatial reference 
system of this MultiSurface.
+     * The unit of measurement is the one of the first element,
+     * or dimensionless if this MultiSurface has no element.
      *
      * @see OGC Simple Feature Access 1.2.1 - 6.1.13.2
      * @return area of the surface.
      */
-    default Area getArea() {
+    default Quantity<?> getArea() {
         final int n = getNumGeometries();
         if (n == 0) {
-            return Quantities.create(0, Units.SQUARE_METRE);
+            return Quantities.create(0, Units.UNITY);
         }
-        Area area = getGeometryN(0).getArea();
+        Quantity<?> area = getGeometryN(0).getArea();
         for (int i = 1; i < n; i++) {
-            area = Quantities.castOrCopy(area.add(getGeometryN(i).getArea()));
+            area = Geometries.add(area, getGeometryN(i).getArea());
         }
         return area;
     }
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 cdb4d7d99e..13ab993c0d 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
@@ -17,7 +17,8 @@
 package org.apache.sis.geometries.surface;
 
 import java.util.List;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
+import org.apache.sis.geometries.Geometries;
 import org.apache.sis.geometries.Surface;
 import org.apache.sis.geometries.SurfaceInterpolation;
 import org.apache.sis.geometries.internal.shared.DefaultPolyhedralSurface;
@@ -125,19 +126,19 @@ public sealed interface PolyhedralSurface<T extends 
Polygon> extends /*GeometryC
     /**
      * Returns the sum of the areas of the patches.
      * The unit of measurement is the one of the first patch,
-     * or square metres if this surface has no patch.
+     * or dimensionless if this surface has no patch.
      *
      * @see ISO 19107:2019 - 6.4.25.7
      */
     @Override
-    default Area getArea() {
+    default Quantity<?> getArea() {
         final int n = getNumPatches();
         if (n == 0) {
-            return Quantities.create(0, Units.SQUARE_METRE);
+            return Quantities.create(0, Units.UNITY);
         }
-        Area area = getPatchN(0).getArea();
+        Quantity<?> area = getPatchN(0).getArea();
         for (int i = 1; i < n; i++) {
-            area = Quantities.castOrCopy(area.add(getPatchN(i).getArea()));
+            area = Geometries.add(area, getPatchN(i).getArea());
         }
         return area;
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Triangle.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Triangle.java
index d071af9728..5c380c2511 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Triangle.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/surface/Triangle.java
@@ -18,7 +18,7 @@ package org.apache.sis.geometries.surface;
 
 import java.util.Collections;
 import java.util.List;
-import javax.measure.quantity.Area;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.AttributesType;
 import org.apache.sis.geometries.BBox;
 import org.apache.sis.geometries.DataPoints;
@@ -126,7 +126,7 @@ public sealed interface Triangle extends Polygon
     }
 
     @Override
-    default Area getArea() {
+    default Quantity<?> getArea() {
         final DataPoints points = getExteriorRing().getDataPoints();
         final Tuple<?> a = points.getPosition(0);
         final Tuple<?> b = points.getPosition(1);
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/BufferTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/BufferTest.java
index cd1a78f099..3ca9c28d15 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/BufferTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/BufferTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometries.operation;
 
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
@@ -71,7 +71,7 @@ public class BufferTest {
     }
 
     /**
-     * The inputs and expected result of a single test of {@code 
buffer(Geometry, Length)}.
+     * The inputs and expected result of a single test of {@code 
buffer(Geometry, Quantity)}.
      *
      * @param input    the geometry on which the operation is invoked.
      * @param radius   the buffer radius.
@@ -79,14 +79,14 @@ public class BufferTest {
      * @param error    the type of the expected exception, or {@code null} if 
the operation should succeed.
      */
     private record RadiusEntry(Geometry input,
-                               Length radius,
+                               Quantity<?> radius,
                                Geometry expected,
                                Class<? extends Exception> error)
     {
     }
 
     /**
-     * All test cases of {@code buffer(Geometry, Length)}.
+     * All test cases of {@code buffer(Geometry, Quantity)}.
      */
     private static final RadiusEntry[] RADIUS_ENTRIES = {
     };
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DistanceTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DistanceTest.java
index 09cdd5c436..516ffe675f 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DistanceTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/DistanceTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometries.operation;
 
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Geometry;
 import org.apache.sis.geometries.GeometryFactory;
 import org.apache.sis.geometries.Point;
@@ -56,7 +56,7 @@ public class DistanceTest {
         { //at same position
             final Point point1 = GeometryFactory.createPoint(CRS2D, 10.0, 5.0);
             final Point point2 = GeometryFactory.createPoint(CRS2D, 10.0, 5.0);
-            final Length distance = new GeometryProcessor().distance(point1, 
point2);
+            final Quantity<?> distance = new 
GeometryProcessor().distance(point1, point2);
             assertEquals(Units.METRE, distance.getUnit());
             assertEquals(0.0, distance.getValue().doubleValue(), 0.0);
         }
@@ -64,7 +64,7 @@ public class DistanceTest {
         { //at 1.0 of distance
             final Point point1 = GeometryFactory.createPoint(CRS2D, 10, 5);
             final Point point2 = GeometryFactory.createPoint(CRS2D, 10, 6);
-            final Length distance = new GeometryProcessor().distance(point1, 
point2);
+            final Quantity<?> distance = new 
GeometryProcessor().distance(point1, point2);
             assertEquals(Units.METRE, distance.getUnit());
             assertEquals(1.0, distance.getValue().doubleValue(), 0.0);
         }
@@ -80,7 +80,7 @@ public class DistanceTest {
      */
     private record Entry(Geometry input,
                          Geometry other,
-                         Length expected,
+                         Quantity<?> expected,
                          Class<? extends Exception> error)
     {
     }
@@ -98,7 +98,7 @@ public class DistanceTest {
     public void testDistance() {
         for (final Entry entry : ENTRIES) {
             try {
-                final Length result = new 
GeometryProcessor().distance(entry.input(), entry.other());
+                final Quantity<?> result = new 
GeometryProcessor().distance(entry.input(), entry.other());
                 assertNull(entry.error(), "An exception was expected.");
                 assertEquals(entry.expected(), result);
             } catch (Exception ex) {
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinDistanceTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinDistanceTest.java
index a6b72e8c49..5de7a80cb2 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinDistanceTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/operation/WithinDistanceTest.java
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometries.operation;
 
-import javax.measure.quantity.Length;
+import javax.measure.Quantity;
 import org.apache.sis.geometries.Geometry;
 
 // Test dependencies
@@ -42,14 +42,14 @@ public class WithinDistanceTest {
      */
     private record Entry(Geometry input,
                          Geometry other,
-                         Length distance,
+                         Quantity<?> distance,
                          Boolean expected,
                          Class<? extends Exception> error)
     {
     }
 
     /**
-     * All test cases of {@code withinDistance(Geometry, Geometry, Length)}.
+     * All test cases of {@code withinDistance(Geometry, Geometry, Quantity)}.
      */
     private static final Entry[] ENTRIES = {
     };

Reply via email to