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

jsorel 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 4ac0d9f4bb Tuple interface do not inherit DirecPosition anymore
4ac0d9f4bb is described below

commit 4ac0d9f4bbb37715347684d088e4c23597b66332
Author: jsorel <[email protected]>
AuthorDate: Thu Jul 10 14:52:44 2025 +0200

    Tuple interface do not inherit DirecPosition anymore
---
 .../main/org/apache/sis/geometries/BBox.java       |  19 +++-
 .../main/org/apache/sis/geometries/LineString.java |   9 +-
 .../main/org/apache/sis/geometries/OBBox.java      |   2 +-
 .../main/org/apache/sis/geometries/Point.java      |   2 +-
 .../org/apache/sis/geometries/PointSequence.java   |  32 +++---
 .../org/apache/sis/geometries/PreparedTIN.java     |  11 +-
 .../main/org/apache/sis/geometries/Sphere.java     |   2 +-
 .../main/org/apache/sis/geometries/Triangle.java   |  21 ++--
 .../sis/geometries/math/AbstractTupleArray.java    |  37 -------
 .../main/org/apache/sis/geometries/math/Tuple.java |  46 ++++-----
 .../org/apache/sis/geometries/math/TupleArray.java |   2 +-
 .../apache/sis/geometries/math/TupleArrays.java    |  95 +++++++++++++++++-
 .../sis/geometries/math/TupleUnmodifiable.java     |  15 ---
 .../org/apache/sis/geometries/math/Vectors.java    | 111 +++++++++++++++++++--
 .../apache/sis/geometries/mesh/MeshPrimitive.java  |  20 ++--
 .../operation/spatialanalysis2d/ISOBand.java       |  12 +--
 .../operation/spatialanalysis2d/ISOLine.java       |   6 +-
 .../apache/sis/geometries/privy/ArraySequence.java |   8 ++
 .../processor/spatialedition/Transform.java        |   2 +-
 .../sis/geometries/math/AbstractTupleTest.java     |  38 -------
 .../apache/sis/geometries/math/VectorsTest.java    |   8 +-
 21 files changed, 306 insertions(+), 192 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 3abb5e3f5d..4c019c55e7 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,6 +21,7 @@ import java.util.Map;
 import org.apache.sis.geometries.math.Tuple;
 import org.apache.sis.geometries.math.Vectors;
 import org.apache.sis.geometry.GeneralEnvelope;
+import org.opengis.coordinate.MismatchedDimensionException;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 
@@ -50,6 +51,14 @@ public final class BBox extends GeneralEnvelope implements 
Geometry {
         setEnvelope(corners);
     }
 
+    /**
+     * @param lower lower corner
+     * @param upper upper corner
+     */
+    public BBox(Tuple lower, Tuple upper) {
+        super(Vectors.asDirectPostion(lower), Vectors.asDirectPostion(upper));
+    }
+
     /**
      * @param crs sphere coordinate system, not null.
      */
@@ -78,19 +87,21 @@ public final class BBox extends GeneralEnvelope implements 
Geometry {
         return "POLYGON"; //TODO not in OGC SFA.
     }
 
+    public void add(Tuple<?> position) throws MismatchedDimensionException {
+        add(Vectors.asDirectPostion(position));
+    }
+
     /**
      * {@inheritDoc }
      */
-    @Override
-    public Tuple getLowerCorner() {
+    public Tuple<?> getLower() {
         return Vectors.castOrWrap(super.getLowerCorner());
     }
 
     /**
      * {@inheritDoc }
      */
-    @Override
-    public Tuple getUpperCorner() {
+    public Tuple<?> getUpper() {
         return Vectors.castOrWrap(super.getUpperCorner());
     }
 
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/LineString.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/LineString.java
index 3ae78a34da..0059fda299 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/LineString.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/LineString.java
@@ -106,14 +106,7 @@ public interface LineString extends Curve {
         if (points.isEmpty()) {
             return null;
         }
-
-        final Tuple start = points.getPosition(0);
-        final GeneralEnvelope env = new GeneralEnvelope(start, start);
-        for (int i = 1, n = points.size(); i < n; i++) {
-            env.add(points.getPosition(i));
-        }
-        env.setCoordinateReferenceSystem(getCoordinateReferenceSystem());
-        return env;
+        return points.getEnvelope();
     }
 
     @Override
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 3f835f3da0..6eb2031672 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
@@ -123,7 +123,7 @@ public final class OBBox extends AbstractGeometry {
         final Tuple<?> nxAxis = xAxis.copy().scale(-1);
         final Tuple<?> nyAxis = yAxis.copy().scale(-1);
         final Tuple<?> nzAxis = zAxis.copy().scale(-1);
-        final GeneralEnvelope env = new GeneralEnvelope(center,center);
+        final BBox env = new BBox(center,center);
         final Vector<?> corner = center.copy();
         env.add(corner.set(center).add( xAxis).add( yAxis).add( zAxis));
         env.add(corner.set(center).add( xAxis).add( yAxis).add(nzAxis));
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 50c732d480..ec139bd97f 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
@@ -119,7 +119,7 @@ public interface Point extends Primitive {
     @Override
     default Envelope getEnvelope() {
         final Tuple first = getPosition();
-        final GeneralEnvelope env = new GeneralEnvelope(first, first);
+        final BBox env = new BBox(first, first);
         env.setCoordinateReferenceSystem(getCoordinateReferenceSystem());
         return env;
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/PointSequence.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/PointSequence.java
index cc4c233ef6..f15c3b76bc 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/PointSequence.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/PointSequence.java
@@ -68,18 +68,7 @@ public interface PointSequence {
      * @return Envelope in geometry coordinate reference system.
      */
     default Envelope getEnvelope() {
-        final int size = size();
-        if (size == 0) {
-            return null;
-        }
-
-        final Tuple start = getPosition(0);
-        final GeneralEnvelope env = new GeneralEnvelope(start, start);
-        for (int i = 1; i < size; i++) {
-            env.add(getPosition(i));
-        }
-        env.setCoordinateReferenceSystem(getCoordinateReferenceSystem());
-        return env;
+        return getAttributeRange(AttributesType.ATT_POSITION);
     }
 
     default boolean isEmpty() {
@@ -141,4 +130,23 @@ public interface PointSequence {
         }
         return ta;
     }
+
+    /**
+     * Get attribute values range
+     *
+     * @return BBox in attribute sample system
+     */
+    default BBox getAttributeRange(String name) {
+        if (isEmpty()) {
+            return null;
+        }
+        final Tuple<?> start = getAttribute(0, name);
+        final BBox env = new BBox(start, start);
+        for (int i = 1, n = size(); i < n; i++) {
+            env.add(getAttribute(i, name));
+        }
+        env.setCoordinateReferenceSystem(getCoordinateReferenceSystem());
+        return env;
+    }
+
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/PreparedTIN.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/PreparedTIN.java
index baa69449df..7d9d288f2f 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/PreparedTIN.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/PreparedTIN.java
@@ -272,7 +272,7 @@ public interface PreparedTIN extends TIN {
         //cache last position crs
         private CoordinateReferenceSystem lastCrs;
         private MathTransform lastTransform;
-        private final Vector target;
+        private final Vector<?> target;
         private final Vector2D.Double p = new Vector2D.Double();
         private final GeneralEnvelope env;
 
@@ -291,7 +291,7 @@ public interface PreparedTIN extends TIN {
             this.epsilon = epsilon;
         }
 
-        public Optional<Point> evaluate(DirectPosition dp) throws 
CannotEvaluateException {
+        public Optional<Point> evaluate(Tuple<?> dp) throws 
CannotEvaluateException {
             final CoordinateReferenceSystem dpCrs = 
dp.getCoordinateReferenceSystem();
             final MathTransform transform;
             if (dpCrs == null) {
@@ -319,13 +319,14 @@ public interface PreparedTIN extends TIN {
 
             if (transform != null) {
                 try {
-                    dp = transform.transform(dp, target);
+                    dp.transformTo(transform, target);
+                    dp = target;
                 } catch (TransformException ex) {
                     throw new CannotEvaluateException(ex.getMessage(), ex);
                 }
             }
-            p.x = dp.getCoordinate(0);
-            p.y = dp.getCoordinate(1);
+            p.x = dp.get(0);
+            p.y = dp.get(1);
 
             //use a local coordinate epsilon if undefined
             double epsilon = this.epsilon;
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Sphere.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Sphere.java
index 5d09027804..eaafc7b462 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Sphere.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Sphere.java
@@ -108,7 +108,7 @@ public final class Sphere extends AbstractGeometry {
     @Override
     public Envelope getEnvelope() {
         final Tuple center = getCenter();
-        final GeneralEnvelope env = new GeneralEnvelope(center, center);
+        final BBox env = new BBox(center, center);
         env.setCoordinateReferenceSystem(getCoordinateReferenceSystem());
         if (radius > 0) {
             for (int i = 0, n = getDimension(); i < n; i++) {
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Triangle.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Triangle.java
index c16bd6caf1..46add7381d 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Triangle.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/Triangle.java
@@ -25,7 +25,6 @@ import org.apache.sis.geometries.math.Vector;
 import org.apache.sis.geometries.math.Vector2D;
 import org.apache.sis.geometries.math.Vector3D;
 import org.apache.sis.geometries.math.Vectors;
-import org.apache.sis.geometry.GeneralEnvelope;
 import static org.opengis.annotation.Specification.ISO_19107;
 import org.opengis.annotation.UML;
 import org.opengis.geometry.Envelope;
@@ -58,7 +57,7 @@ public interface Triangle extends Polygon {
 
     @Override
     default List<Curve> getInteriorRings() {
-        return Collections.EMPTY_LIST;
+        return Collections.emptyList();
     }
 
     @Override
@@ -74,8 +73,8 @@ public interface Triangle extends Polygon {
     @Override
     default Envelope getEnvelope() {
         final PointSequence exterior = getExteriorRing().getPoints();
-        final Tuple first = exterior.getPosition(0);
-        final GeneralEnvelope env = new GeneralEnvelope(first, first);
+        final Tuple<?> first = exterior.getPosition(0);
+        final BBox env = new BBox(first, first);
         env.add(exterior.getPosition(1));
         env.add(exterior.getPosition(2));
         env.setCoordinateReferenceSystem(getCoordinateReferenceSystem());
@@ -85,9 +84,9 @@ public interface Triangle extends Polygon {
     @Override
     default double getArea() {
         final PointSequence points = getExteriorRing().getPoints();
-        final Tuple a = points.getPosition(0);
-        final Tuple b = points.getPosition(1);
-        final Tuple c = points.getPosition(2);
+        final Tuple<?> a = points.getPosition(0);
+        final Tuple<?> b = points.getPosition(1);
+        final Tuple<?> c = points.getPosition(2);
         final double area = (
                       a.get(0) * (b.get(1) - c.get(1))
                     + b.get(0) * (c.get(1) - a.get(1))
@@ -103,10 +102,10 @@ public interface Triangle extends Polygon {
      */
     default double distance(Tuple pt) {
         final PointSequence exterior = getExteriorRing().getPoints();
-        final Tuple p0 = exterior.getPosition(0);
-        final Tuple p1 = exterior.getPosition(1);
-        final Tuple p2 = exterior.getPosition(2);
-        Vector normal = Maths.calculateNormal(p0, p1, p2);
+        final Tuple<?> p0 = exterior.getPosition(0);
+        final Tuple<?> p1 = exterior.getPosition(1);
+        final Tuple<?> p2 = exterior.getPosition(2);
+        Vector<?> normal = Maths.calculateNormal(p0, p1, p2);
         double planD = normal.dot(p0);
         return Maths.distance(pt, normal, planD);
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/AbstractTupleArray.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/AbstractTupleArray.java
index 58ac1ee177..e7920c9b3c 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/AbstractTupleArray.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/AbstractTupleArray.java
@@ -39,11 +39,6 @@ public abstract class AbstractTupleArray implements 
TupleArray {
         return resize(getLength());
     }
 
-    @Override
-    public TupleArrayCursor cursor() {
-        return new Cursor();
-    }
-
     @Override
     public boolean equals(Object obj) {
         if (this == obj) {
@@ -80,36 +75,4 @@ public abstract class AbstractTupleArray implements 
TupleArray {
     public int hashCode() {
         return getDataType().hashCode() | (getDimension() * 21) | (getLength() 
* 7);
     }
-
-    private final class Cursor implements TupleArrayCursor {
-        private final int length = getLength();
-        private int coordinate = -1;
-        private final Tuple buffer = 
Vectors.create(AbstractTupleArray.this.getSampleSystem(), 
AbstractTupleArray.this.getDataType());
-
-        @Override
-        public Tuple samples() {
-            get(length, buffer);
-            return buffer;
-        }
-
-        @Override
-        public int coordinate() {
-            return coordinate;
-        }
-
-        @Override
-        public void moveTo(int coordinate) {
-            this.coordinate = coordinate;
-        }
-
-        @Override
-        public boolean next() {
-            if (coordinate + 1 >= length) {
-                return false;
-            } else {
-                this.coordinate++;
-                return true;
-            }
-        }
-    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Tuple.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Tuple.java
index 94824db4bf..6baa7c1da0 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Tuple.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Tuple.java
@@ -19,16 +19,15 @@ package org.apache.sis.geometries.math;
 import org.apache.sis.util.Utilities;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
 
 /**
  * A tuple is an array of values.
- * For interoperability with MathTransform operations a Tuple implements 
DirectPosition.
  *
  * @author Johann Sorel (Geomatys)
- *
- * @todo Remove the {@code extends DirectPosition} part. A tuple is not a 
direct position.
  */
-public interface Tuple<T extends Tuple <T>> extends DirectPosition {
+public interface Tuple<T extends Tuple <T>> {
 
     /**
      * @return sample system, never null.
@@ -38,7 +37,6 @@ public interface Tuple<T extends Tuple <T>> extends 
DirectPosition {
     /**
      * @return sample system size.
      */
-    @Override
     default int getDimension() {
         return getSampleSystem().getSize();
     }
@@ -46,7 +44,6 @@ public interface Tuple<T extends Tuple <T>> extends 
DirectPosition {
     /**
      * @return sample system CRS, may be null.
      */
-    @Override
     default CoordinateReferenceSystem getCoordinateReferenceSystem() {
         return getSampleSystem().getCoordinateReferenceSystem();
     }
@@ -156,7 +153,7 @@ public interface Tuple<T extends Tuple <T>> extends 
DirectPosition {
      */
     default T setAll(double value) {
         for (int i = 0, n = getDimension(); i < n; i++) {
-            setCoordinate(i, value);
+            set(i, value);
         }
         return (T) this;
     }
@@ -277,27 +274,30 @@ public interface Tuple<T extends Tuple <T>> extends 
DirectPosition {
     }
 
     /**
-     * {@inheritDoc }
-     */
-    @Override
-    default double getCoordinate(int dimension) throws 
IndexOutOfBoundsException {
-        return get(dimension);
-    }
-
-    /**
-     * {@inheritDoc }
+     * Apply given transform on this tuple.
+     *
+     * @param trs not null
+     * @return this tuple
+     * @throws TransformException
      */
-    @Override
-    default void setCoordinate(int dimension, double value) throws 
IndexOutOfBoundsException, UnsupportedOperationException {
-        set(dimension,value);
+    default T transform(MathTransform trs) throws TransformException {
+        final double[] array = toArrayDouble();
+        trs.transform(array, 0, array, 0, 1);
+        return set(array);
     }
 
     /**
-     * {@inheritDoc }
+     * Transform this tuple and store the result in given tuple.
+     *
+     * @param trs not null
+     * @param target not null to store transform result
+     * @return this tuple
+     * @throws TransformException
      */
-    @Override
-    default double[] getCoordinates() {
-        return toArrayDouble();
+    default void transformTo(MathTransform trs, Tuple<?> target) throws 
TransformException {
+        final double[] array = toArrayDouble();
+        trs.transform(array, 0, array, 0, 1);
+        target.set(array);
     }
 
     /**
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleArray.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleArray.java
index f0a8c1f454..694b91a98c 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleArray.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleArray.java
@@ -269,7 +269,7 @@ public interface TupleArray {
         final Vector v = Vectors.createDouble(getDimension());
         for (int i=0,n=getLength();i<n;i++) {
             get(i, v);
-            trs.transform(v, v);
+            v.transform(trs);
             set(i,v);
         }
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleArrays.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleArrays.java
index e718d49233..93e6c3c147 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleArrays.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleArrays.java
@@ -25,6 +25,7 @@ import java.util.concurrent.RecursiveAction;
 import org.apache.sis.coverage.SampleDimension;
 import org.apache.sis.geometries.BBox;
 import org.apache.sis.geometries.Geometries;
+import org.apache.sis.geometry.GeneralDirectPosition;
 import org.apache.sis.measure.NumberRange;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.util.ArgumentChecks;
@@ -203,8 +204,8 @@ public final class TupleArrays extends Static {
         while (cursor.next()) {
             final Tuple samples = cursor.samples();
             if (first) {
-                bbox.getLowerCorner().set(samples);
-                bbox.getUpperCorner().set(samples);
+                bbox.getLower().set(samples);
+                bbox.getUpper().set(samples);
                 first = false;
             } else {
                 bbox.add(samples);
@@ -327,7 +328,7 @@ public final class TupleArrays extends Static {
                 Tuple source = cursor.samples();
                 Tuple target = resultCursor.samples();
                 for (int s = 0; s < dim; s++) {
-                    target.setCoordinate(s+offset, source.get(s));
+                    target.set(s+offset, source.get(s));
                 }
             }
             offset += dim;
@@ -335,6 +336,13 @@ public final class TupleArrays extends Static {
         return result;
     }
 
+    /**
+     * Create a view of only the given selected index tuples in the array.
+     */
+    public static TupleArray subset(TupleArray array, int ... selection) {
+        return new Subset(array, selection);
+    }
+
     /**
      * View TupleArray as a list.
      */
@@ -477,4 +485,85 @@ public final class TupleArrays extends Static {
 
     private TupleArrays(){}
 
+    private static class Subset extends AbstractTupleArray {
+
+        private final TupleArray base;
+        private final int[] index;
+
+        public Subset(TupleArray base, int[] index) {
+            this.base = base;
+            this.index = index;
+        }
+
+        @Override
+        public int getLength() {
+            return index.length;
+        }
+
+        @Override
+        public SampleSystem getSampleSystem() {
+            return base.getSampleSystem();
+        }
+
+        @Override
+        public void setSampleSystem(SampleSystem type) {
+            base.setSampleSystem(type);
+        }
+
+        @Override
+        public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+            return base.getCoordinateReferenceSystem();
+        }
+
+        @Override
+        public int getDimension() {
+            return base.getDimension();
+        }
+
+        @Override
+        public DataType getDataType() {
+            return base.getDataType();
+        }
+
+        @Override
+        public void get(int index, Tuple buffer) {
+            base.get(this.index[index], buffer);
+        }
+
+        @Override
+        public void set(int index, Tuple buffer) {
+            base.set(this.index[index], buffer);
+        }
+
+        @Override
+        public TupleArrayCursor cursor() {
+            final TupleArrayCursor bc = base.cursor();
+            return new TupleArrayCursor() {
+                private int coordinate = -1;
+                @Override
+                public Tuple<?> samples() {
+                    bc.moveTo(index[coordinate]);
+                    return bc.samples();
+                }
+
+                @Override
+                public int coordinate() {
+                    return coordinate;
+                }
+
+                @Override
+                public void moveTo(int coordinate) {
+                    this.coordinate = coordinate;
+                }
+
+                @Override
+                public boolean next() {
+                    if (coordinate >= index.length-1) return false;
+                    coordinate++;
+                    return true;
+                }
+            };
+        }
+
+    }
 }
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleUnmodifiable.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleUnmodifiable.java
index db59ee3244..de90f8e181 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleUnmodifiable.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/TupleUnmodifiable.java
@@ -145,21 +145,6 @@ final class TupleUnmodifiable extends AbstractTuple {
         parent.toArrayDouble(buffer, offset);
     }
 
-    @Override
-    public double getCoordinate(int dimension) throws 
IndexOutOfBoundsException {
-        return parent.getCoordinate(dimension);
-    }
-
-    @Override
-    public void setCoordinate(int dimension, double value) throws 
IndexOutOfBoundsException, UnsupportedOperationException {
-        throw new UnsupportedOperationException("This implementation is 
unmodifiable");
-    }
-
-    @Override
-    public double[] getCoordinates() {
-        return parent.getCoordinates();
-    }
-
     @Override
     public Tuple copy() {
         return parent.copy();
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Vectors.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Vectors.java
index 43cdd0bcde..8bcd5385f8 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Vectors.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/math/Vectors.java
@@ -218,15 +218,40 @@ public final class Vectors extends Static {
         }
     }
 
-    public static Vector<?> castOrWrap(DirectPosition tuple) {
+    public static Vector<?> castOrCopy(Tuple pos) {
+        if (pos instanceof Vector) {
+            return (Vector) pos;
+        } else {
+            final SampleSystem type = pos.getSampleSystem();
+            final DataType dt = pos.getDataType();
+            final Vector v = create(type, dt);
+            v.set(pos);
+            return v;
+        }
+    }
+
+    public static Vector<?> castOrWrap(DirectPosition pos) {
+        if (pos instanceof Vector) {
+            return (Vector) pos;
+        } else if (pos instanceof Tuple) {
+            return new WrapTuple((Tuple) pos);
+        } else {
+            CoordinateReferenceSystem crs = pos.getCoordinateReferenceSystem();
+            return crs == null ? new WrapDirectPostion(pos, 
pos.getDimension()) : new WrapDirectPostion(pos);
+        }
+    }
+
+    public static Vector<?> castOrWrap(Tuple tuple) {
         if (tuple instanceof Vector) {
             return (Vector) tuple;
         } else {
-            CoordinateReferenceSystem crs = 
tuple.getCoordinateReferenceSystem();
-            return crs == null ? new WrapVector(tuple, tuple.getDimension()) : 
new WrapVector(tuple);
+            return new WrapTuple(tuple);
         }
     }
 
+    public static DirectPosition asDirectPostion(Tuple tuple) {
+        return new AsDirectPosition(tuple);
+    }
     /**
      * Create an unmodifiable view of the given tuple.
      *
@@ -237,16 +262,51 @@ public final class Vectors extends Static {
         return new TupleUnmodifiable(tuple);
     }
 
-    private static class WrapVector extends AbstractTuple<WrapVector> 
implements Vector<WrapVector> {
+    private static class WrapTuple extends AbstractTuple<WrapTuple> implements 
Vector<WrapTuple> {
+
+        private final Tuple pos;
+
+        public WrapTuple(Tuple pos, int size) {
+            super(size);
+            this.pos = pos;
+        }
+
+        public WrapTuple(Tuple pos) {
+            super(pos.getSampleSystem());
+            this.pos = pos;
+        }
+
+        @Override
+        public DataType getDataType() {
+            return pos.getDataType();
+        }
+
+        @Override
+        public double get(int indice) {
+            return pos.get(indice);
+        }
+
+        @Override
+        public void set(int indice, double value) {
+            pos.set(indice, value);
+        }
+
+        @Override
+        public int getDimension() {
+            return pos.getDimension();
+        }
+    }
+
+    private static class WrapDirectPostion extends 
AbstractTuple<WrapDirectPostion> implements Vector<WrapDirectPostion> {
 
         private final DirectPosition pos;
 
-        public WrapVector(DirectPosition pos, int size) {
+        public WrapDirectPostion(DirectPosition pos, int size) {
             super(size);
             this.pos = pos;
         }
 
-        public WrapVector(DirectPosition pos) {
+        public WrapDirectPostion(DirectPosition pos) {
             super(pos.getCoordinateReferenceSystem());
             this.pos = pos;
         }
@@ -272,6 +332,41 @@ public final class Vectors extends Static {
         }
     }
 
+    private static class AsDirectPosition implements DirectPosition {
+
+        private final Tuple tuple;
+
+        public AsDirectPosition(Tuple tuple) {
+            this.tuple = tuple;
+        }
+
+        @Override
+        public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+            return tuple.getCoordinateReferenceSystem();
+        }
+
+        @Override
+        public int getDimension() {
+            return tuple.getDimension();
+        }
+
+        @Override
+        public double[] getCoordinates() {
+            return tuple.toArrayDouble();
+        }
+
+        @Override
+        public double getCoordinate(int i) {
+            return tuple.get(i);
+        }
+
+        @Override
+        public void setCoordinate(int i, double d) {
+            tuple.set(i,d);
+        }
+
+    }
+
     /**
      * Computes the vector's length.
      *
@@ -1748,7 +1843,9 @@ public final class Vectors extends Static {
             final DataType dt = DataType.forRange(NumberRange.create(0, true, 
quantizeRange, true), true);
             buffer = (R) Vectors.create(tuple.getDimension(), dt);
         }
-        trs.transform(tuple, buffer);
+        double[] array = buffer.toArrayDouble();
+        trs.transform(tuple.toArrayDouble(), 0, array, 0, 1);
+        buffer.set(array);
         return buffer;
     }
 
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 1f53ff0270..747eda5a0a 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
@@ -31,6 +31,7 @@ import java.util.TreeSet;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.apache.sis.geometries.AttributesType;
+import org.apache.sis.geometries.BBox;
 import org.apache.sis.geometries.Geometries;
 import org.apache.sis.geometries.Geometry;
 import org.apache.sis.geometries.GeometryFactory;
@@ -41,6 +42,7 @@ import org.apache.sis.geometries.Point;
 import org.apache.sis.geometries.PointSequence;
 import org.apache.sis.geometries.TIN;
 import org.apache.sis.geometries.Triangle;
+import org.apache.sis.geometries.math.AbstractTupleArray;
 import org.apache.sis.geometries.math.DataType;
 import org.apache.sis.geometries.math.Maths;
 import org.apache.sis.geometries.math.SampleSystem;
@@ -52,6 +54,7 @@ import org.apache.sis.geometries.math.Vector;
 import org.apache.sis.geometries.math.Vector1D;
 import org.apache.sis.geometries.math.Vector3D;
 import org.apache.sis.geometries.math.Vectors;
+import org.apache.sis.geometry.GeneralDirectPosition;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.privy.UnmodifiableArrayList;
@@ -341,23 +344,13 @@ public interface MeshPrimitive extends Geometry {
          */
         @Override
         public Envelope getEnvelope() {
-
             final TupleArray positions = getAttribute(ATT_POSITION);
             if (positions.isEmpty()) {
                 final GeneralEnvelope env = new 
GeneralEnvelope(getCoordinateReferenceSystem());
                 env.setToNaN();
                 return env;
             }
-
-            final Vector tuple = Vectors.create(positions.getSampleSystem(), 
DataType.FLOAT);
-            positions.get(0, tuple);
-            final GeneralEnvelope env = new GeneralEnvelope(tuple, tuple);
-
-            for (int i = 1, n = positions.getLength(); i < n; i++) {
-                positions.get(i, tuple);
-                env.add(tuple);
-            }
-            return env;
+            return TupleArrays.computeRange(positions);
         }
 
         public List<Geometry> getComponents() {
@@ -1113,6 +1106,11 @@ public interface MeshPrimitive extends Geometry {
         public void setAttribute(int index, String name, Tuple value) {
             primitive.getAttribute(name).set(this.index[index], value);
         }
+
+        @Override
+        public BBox getAttributeRange(String name) {
+            return 
TupleArrays.computeRange(TupleArrays.subset(primitive.getAttribute(name),index));
+        }
     }
 
     public static class Points extends Abs implements MultiPoint<Point>{
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/spatialanalysis2d/ISOBand.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/spatialanalysis2d/ISOBand.java
index 3c18d9f37e..2901e12fd1 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/spatialanalysis2d/ISOBand.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/spatialanalysis2d/ISOBand.java
@@ -83,25 +83,25 @@ public final class ISOBand {
                 Tuple t1 = points.getPosition(1);
                 Tuple t2 = points.getPosition(2);
                 //sort points by Z, the point ordering to not matter for the 
algo
-                if (t0.getCoordinate(Z) < t1.getCoordinate(Z)) {
+                if (t0.get(Z) < t1.get(Z)) {
                     Tuple t = t0;
                     t0 = t1;
                     t1 = t;
                 }
-                if (t1.getCoordinate(Z) < t2.getCoordinate(Z)) {
+                if (t1.get(Z) < t2.get(Z)) {
                     Tuple t = t1;
                     t1 = t2;
                     t2 = t;
-                    if (t0.getCoordinate(Z) < t1.getCoordinate(Z)) {
+                    if (t0.get(Z) < t1.get(Z)) {
                         t = t0;
                         t0 = t1;
                         t1 = t;
                     }
                 }
 
-                final double[] p0 = t0.getCoordinates();
-                final double[] p1 = t1.getCoordinates();
-                final double[] p2 = t2.getCoordinates();
+                final double[] p0 = t0.toArrayDouble();
+                final double[] p1 = t1.toArrayDouble();
+                final double[] p2 = t2.toArrayDouble();
 
                 for (NumberRange range : levels.keySet()) {
                     final double min = range.getMinDouble(true);
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/spatialanalysis2d/ISOLine.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/spatialanalysis2d/ISOLine.java
index dce2039fd2..0426464c2e 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/spatialanalysis2d/ISOLine.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/operation/spatialanalysis2d/ISOLine.java
@@ -55,9 +55,9 @@ public final class ISOLine {
             @Override
             protected void visit(Triangle candidate) {
                 final PointSequence points = 
candidate.getExteriorRing().getPoints();
-                final double[] p0 = points.getPosition(0).getCoordinates();
-                final double[] p1 = points.getPosition(1).getCoordinates();
-                final double[] p2 = points.getPosition(2).getCoordinates();
+                final double[] p0 = points.getPosition(0).toArrayDouble();
+                final double[] p1 = points.getPosition(1).toArrayDouble();
+                final double[] p2 = points.getPosition(2).toArrayDouble();
 
                 for (double step : steps) {
                     final boolean p0a = p0[Z] >= step;
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/privy/ArraySequence.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/privy/ArraySequence.java
index 0f3d630acd..ea18626fde 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/privy/ArraySequence.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/privy/ArraySequence.java
@@ -27,9 +27,12 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.sis.geometries.AttributesType;
+import org.apache.sis.geometries.BBox;
 import org.apache.sis.geometries.Point;
 import org.apache.sis.geometries.PointSequence;
+import org.apache.sis.geometries.math.TupleArrays;
 import org.apache.sis.util.ArgumentChecks;
+import org.opengis.geometry.Envelope;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 
 /**
@@ -153,6 +156,11 @@ public final class ArraySequence implements PointSequence, 
AttributesType {
         return attributes.get(name).copy();
     }
 
+    @Override
+    public BBox getAttributeRange(String name) {
+        return TupleArrays.computeRange(attributes.get(name));
+    }
+
     /**
      * An indexed point in the point sequence
      */
diff --git 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialedition/Transform.java
 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialedition/Transform.java
index 3d6461afa4..eb613fbf8b 100644
--- 
a/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialedition/Transform.java
+++ 
b/incubator/src/org.apache.sis.geometry/main/org/apache/sis/geometries/processor/spatialedition/Transform.java
@@ -202,7 +202,7 @@ public final class Transform {
                         final Vector tag = (tangents == null) ? null : 
Vectors.create(tangents.getSampleSystem(), tangents.getDataType());
                         for (int i = 0, n = positions.getLength(); i < n; i++) 
{
                             positions.get(i, pos);
-                            final MatrixSIS matrix = 
MatrixSIS.castOrCopy(operation.transform.derivative(pos));
+                            final MatrixSIS matrix = 
MatrixSIS.castOrCopy(operation.transform.derivative(Vectors.asDirectPostion(pos)));
                             if (nor != null) {
                                 cpn.get(i, nor);
                                 nor.set(matrix.multiply(nor.toArrayDouble()));
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/math/AbstractTupleTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/math/AbstractTupleTest.java
index e783d57d98..5293797ba3 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/math/AbstractTupleTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/math/AbstractTupleTest.java
@@ -64,7 +64,6 @@ public abstract class AbstractTupleTest {
         assertTrue(tuple.isAll(0.0));
         testCellGetSet(tuple);
         testToArray(tuple);
-        testDirectPosition(tuple);
         testEquality(tuple);
 
         switch (tuple.getDataType()) {
@@ -137,40 +136,6 @@ public abstract class AbstractTupleTest {
 
     }
 
-    /**
-     * Test methods inherited from DirectPosition.
-     */
-    private void testDirectPosition(Tuple<?> tuple) {
-        final int dim = tuple.getDimension();
-
-        for (int i = 0; i < dim; i++) {
-            tuple.setCoordinate(i, i+1);
-            assertEquals(i+1, tuple.getCoordinate(i), TOLERANCE);
-        }
-
-        //test out of range
-        try {
-            tuple.setCoordinate(-1, 10);
-            fail(UNVALID_INDEX_EXPECTED);
-        } catch (IndexOutOfBoundsException ex) {
-            //ok
-        }
-        try {
-            tuple.setCoordinate(dim, 10);
-            fail(UNVALID_INDEX_EXPECTED);
-        } catch (IndexOutOfBoundsException ex) {
-            //ok
-        }
-
-        {//test getCoordinate
-            final double[] values = tuple.getCoordinates();
-            assertEquals(dim, values.length);
-            for (int i = 0; i < dim; i++) {
-                assertEquals(i+1, values[i], TOLERANCE);
-            }
-        }
-    }
-
     /**
      * Test tuple value to array methods.
      */
@@ -275,7 +240,6 @@ public abstract class AbstractTupleTest {
             //test get set
             tuple.set(i, value);
             assertEquals(value, tuple.get(i), 0.0);
-            assertEquals(value, tuple.getCoordinate(i), 0.0);
             tuple.set(i, 0);
 
             //test copy
@@ -288,8 +252,6 @@ public abstract class AbstractTupleTest {
             tuple.set(i, value);
             double[] array = tuple.toArrayDouble();
             assertEquals(value, array[i], 0.0);
-            array = tuple.getCoordinates();
-            assertEquals(value, array[i], 0.0);
             tuple.set(0, 0);
         }
     }
diff --git 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/math/VectorsTest.java
 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/math/VectorsTest.java
index a54352158e..6031af1fb4 100644
--- 
a/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/math/VectorsTest.java
+++ 
b/incubator/src/org.apache.sis.geometry/test/org/apache/sis/geometries/math/VectorsTest.java
@@ -114,11 +114,11 @@ public class VectorsTest {
         final Vector3D.Double coord1 = new Vector3D.Double(0,100,-300);
         final Vector3D.Double coord2 = new Vector3D.Double(100,300,-100);
 
-        trs.transform(coord1, coord1);
-        trs.transform(coord2, coord2);
+        coord1.transform(trs);
+        coord2.transform(trs);
 
-        assertArrayEquals(new double[] {0, 0, 0}, coord1.getCoordinates(), 
DELTA);
-        assertArrayEquals(new double[] {32767, 32767, 32767}, 
coord2.getCoordinates(), DELTA);
+        assertArrayEquals(new double[] {0, 0, 0}, coord1.toArrayDouble(), 
DELTA);
+        assertArrayEquals(new double[] {32767, 32767, 32767}, 
coord2.toArrayDouble(), DELTA);
 
     }
 }


Reply via email to