sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Add a MathTransforms.linear(MathTransform, DirectPosition) convenience method.
Date Sat, 24 Nov 2018 22:10:14 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux 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 278310d  Add a MathTransforms.linear(MathTransform, DirectPosition) convenience method.
278310d is described below

commit 278310dd5683eec70241789b95148b2244c0c5a7
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Nov 24 23:09:49 2018 +0100

    Add a MathTransforms.linear(MathTransform, DirectPosition) convenience method.
---
 .../operation/transform/MathTransforms.java        | 45 ++++++++++++++++---
 .../operation/transform/MathTransformsTest.java    | 51 +++++++++++++++++++---
 2 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
index f7660fe..0d42310 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
@@ -155,6 +155,35 @@ public final class MathTransforms extends Static {
     }
 
     /**
+     * Returns a linear (usually affine) transform which approximates the given transform
in the vicinity of the given position.
+     * If the given transform is already an instance of {@link LinearTransform}, then it
is returned.
+     * Otherwise an approximation for the given position is created using the
+     * {@linkplain MathTransform#derivative(DirectPosition) transform derivative} at that
position.
+     *
+     * <p><b>Invariant:</b> transforming the given position using the given
transform produces the same result
+     * (ignoring rounding error) than transforming the same position using the returned transform.</p>
+     *
+     * @param  transform  the transform to approximate by an affine transform.
+     * @param  position   position in source CRS around which to get the an affine transform
approximation.
+     * @return a transform approximating the given transform around the given position.
+     * @throws TransformException if an error occurred while transforming the given position
+     *         or computing the derivative at that position.
+     *
+     * @since 1.0
+     *
+     * @see #getMatrix(MathTransform, DirectPosition)
+     */
+    public static LinearTransform linear(final MathTransform transform, final DirectPosition
position) throws TransformException {
+        if (transform instanceof LinearTransform) {
+            // We accept null position here for consistency with MathTransform.derivative(DirectPosition).
+            ArgumentChecks.ensureDimensionMatches("position", transform.getSourceDimensions(),
position);
+            return (LinearTransform) transform;
+        } else {
+            return linear(getMatrix(transform, position));
+        }
+    }
+
+    /**
      * Creates a transform for the <i>y=f(x)</i> function where <var>y</var>
are computed by a linear interpolation.
      * Both {@code preimage} (the <var>x</var>) and {@code values} (the <var>y</var>)
arguments can be null:
      *
@@ -510,24 +539,26 @@ public final class MathTransforms extends Static {
      * Otherwise the returned matrix can be used for {@linkplain #linear(Matrix) building
a linear transform} which can be
      * used as an approximation of the given transform for short distances around the given
position.
      *
-     * @param  transform  the transform to approximate by an affine transform, or {@code
null}.
-     * @param  position   position around which to get the coefficient of an affine transform
approximation.
-     * @return the matrix of the given transform around the given position, or {@code null}
if the given transform was null.
+     * @param  transform  the transform to approximate by an affine transform.
+     * @param  position   position in source CRS around which to get the coefficients of
an affine transform approximation.
+     * @return the matrix of the given transform around the given position.
      * @throws TransformException if an error occurred while transforming the given position
or computing the derivative at
      *         that position.
      *
      * @since 1.0
+     *
+     * @see #linear(MathTransform, DirectPosition)
      */
     public static Matrix getMatrix(final MathTransform transform, final DirectPosition position)
throws TransformException {
-        if (transform == null) {
-            return null;
-        }
+        ArgumentChecks.ensureNonNull("transform", transform);
         final int srcDim = transform.getSourceDimensions();
-        ArgumentChecks.ensureDimensionMatches("position", srcDim, position);
+        ArgumentChecks.ensureDimensionMatches("position", srcDim, position);            //
Null position is okay for now.
         final Matrix affine = getMatrix(transform);
         if (affine != null) {
             return affine;
+            // We accept null position here for consistency with MathTransform.derivative(DirectPosition).
         }
+        ArgumentChecks.ensureNonNull("position", position);
         final int tgtDim = transform.getTargetDimensions();
         double[] pts = new double[Math.max(srcDim + 1, tgtDim)];
         for (int i=0; i<srcDim; i++) {
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformsTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformsTest.java
index 6866535..1dcaf1c 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformsTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformsTest.java
@@ -26,6 +26,7 @@ import org.apache.sis.referencing.operation.matrix.Matrix2;
 import org.apache.sis.referencing.operation.matrix.Matrix3;
 import org.apache.sis.referencing.operation.matrix.Matrix4;
 import org.apache.sis.geometry.GeneralDirectPosition;
+import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -126,18 +127,26 @@ public final strictfp class MathTransformsTest extends TestCase {
     }
 
     /**
+     * Returns a three-dimensional transform which is non-linear in the second dimension.
+     * A sample source point is (x, 1.5, y), which interpolates to (x, 8, y) where 8 is
+     * the mid-point between 6 and 14.
+     */
+    private static MathTransform nonLinear3D() {
+        MathTransform tr = MathTransforms.interpolate(null, new double[] {2, 6, 14, 15});
+        tr = MathTransforms.passThrough(1, tr, 1);
+        return tr;
+    }
+
+    /**
      * Tests {@link MathTransforms#getMatrix(MathTransform, DirectPosition)}.
      *
      * @throws TransformException if an error occurred while computing the derivative.
      */
     @Test
     public void testGetMatrix() throws TransformException {
-        // Prepare a transform with a non-linear component.
-        MathTransform tr = MathTransforms.interpolate(null, new double[] {2, 6, 14, 15});
-        tr = MathTransforms.passThrough(1, tr, 1);
-        tr = MathTransforms.concatenate(tr, MathTransforms.linear(new Matrix4(
+        MathTransform tr = MathTransforms.concatenate(nonLinear3D(), MathTransforms.linear(new
Matrix4(
             5,  0,  0,  9,
-            0,  1,  0,  0,
+            0,  1,  0,  0,      // Non-linear transform will be concatenated at this dimension.
             0,  0,  2, -7,
             0,  0,  0,  1)));
 
@@ -146,7 +155,7 @@ public final strictfp class MathTransformsTest extends TestCase {
         final Matrix affine = MathTransforms.getMatrix(tr, pos);
         assertMatrixEquals("Affine approximation", new Matrix4(
             5,  0,  0,  9,
-            0,  8,  0, -2,
+            0,  8,  0, -2,      // Non-linear transform shall be the only one with different
coefficients.
             0,  0,  2, -7,
             0,  0,  0,  1), affine, STRICT);
         /*
@@ -157,4 +166,34 @@ public final strictfp class MathTransformsTest extends TestCase {
         DirectPosition actual = MathTransforms.linear(affine).transform(pos, null);
         assertEquals(expected, actual);
     }
+
+    /**
+     * Tests {@link MathTransforms#linear(MathTransform, DirectPosition)}.
+     *
+     * @throws TransformException if an error occurred while computing the derivative.
+     */
+    @Test
+    @DependsOnMethod("testGetMatrix")
+    public void testLinearUsingPosition() throws TransformException {
+        final DirectPosition pos = new GeneralDirectPosition(3, 1.5, 6);
+        MathTransform tr = MathTransforms.linear(new Matrix4(
+            0,  5,  0,  9,
+            1,  0,  0,  0,      // Non-linear transform will be concatenated at this dimension.
+            0,  0, 12, -3,
+            0,  0,  0,  1));
+
+        LinearTransform linear = MathTransforms.linear(tr, pos);
+        assertSame("Linear transform shall be returned unchanged.", tr, linear);
+
+        tr = MathTransforms.concatenate(nonLinear3D(), tr);
+        linear = MathTransforms.linear(tr, pos);
+        assertNotSame(tr, linear);
+        /*
+         * Transformation using above approximation shall produce the same result than the
original
+         * transform if we do the comparison at the position where the approximation has
been computed.
+         */
+        DirectPosition expected = tr.transform(pos, null);
+        DirectPosition actual = linear.transform(pos, null);
+        assertEquals(expected, actual);
+    }
 }


Mime
View raw message