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 8b2e294570 When concatenating a change of coordinate system type
together with an uniform scale factor, move the scale factor from the Cartesian
CS side to the spherical, cylindrical or polar CS side. The rational is that
the latter will need an affine transform anyway for the conversion between
radians and degrees.
8b2e294570 is described below
commit 8b2e29457057f3385a875d3f2d22e7fe80deec87
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Jan 18 13:17:26 2024 +0100
When concatenating a change of coordinate system type together with an
uniform scale factor,
move the scale factor from the Cartesian CS side to the spherical,
cylindrical or polar CS side.
The rational is that the latter will need an affine transform anyway for
the conversion between radians and degrees.
---
.../referencing/operation/matrix/MatrixSIS.java | 2 +
.../operation/transform/AbstractMathTransform.java | 4 +-
.../operation/transform/CartesianToPolar.java | 2 +-
.../operation/transform/CartesianToSpherical.java | 2 +-
.../transform/CoordinateSystemTransform.java | 100 ++++++++++++++++++---
.../operation/transform/PolarToCartesian.java | 2 +-
.../operation/transform/SphericalToCartesian.java | 2 +-
.../referencing/util/ExtendedPrecisionMatrix.java | 27 ++++++
.../operation/transform/CartesianToPolarTest.java | 12 +--
.../transform/CartesianToSphericalTest.java | 49 +++++++---
.../operation/transform/PolarToCartesianTest.java | 20 ++---
.../transform/SphericalToCartesianTest.java | 64 ++++++++++---
12 files changed, 225 insertions(+), 61 deletions(-)
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
index 5f1eeb26cc..abd0e85050 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
@@ -145,6 +145,8 @@ public abstract class MatrixSIS implements Matrix,
LenientComparable, Cloneable,
/**
* Returns the given matrix as an extended precision matrix.
+ *
+ * @see ExtendedPrecisionMatrix#castOrWrap(Matrix)
*/
static ExtendedPrecisionMatrix asExtendedPrecision(final Matrix matrix) {
if (matrix instanceof UnmodifiableMatrix) {
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
index a01eeb41d1..fa70064ec1 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
@@ -889,8 +889,8 @@ public abstract class AbstractMathTransform extends
FormattableObject
* <p>The default implementation returns the identity transform if the
other transform is the inverse
* of this transform, or returns {@code null} otherwise. This method is
ought to be overridden
* by subclasses capable of concatenating some combination of transforms
in a special way.
- * {@link LinearTransform} implementations do not need to override this
method since matrix multiplications
- * will be handled automatically, and this method does not need to handle
the {@link #isIdentity()} case.</p>
+ * {@link LinearTransform} implementations do not need to override this
method because matrix multiplications
+ * will be handled automatically. This method does not need to handle the
{@link #isIdentity()} case neither.</p>
*
* @param applyOtherFirst {@code true} if the transformation order is
{@code other} followed by {@code this}, or
* {@code false} if the transformation order is
{@code this} followed by {@code other}.
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CartesianToPolar.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CartesianToPolar.java
index 103506b116..22b40110d4 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CartesianToPolar.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CartesianToPolar.java
@@ -65,7 +65,7 @@ final class CartesianToPolar extends
CoordinateSystemTransform implements Serial
* Output coordinates are in radians.
*/
private CartesianToPolar() {
- super("Cartesian to polar", "Cartesian to cylindrical", 2);
+ super("Cartesian to polar", "Cartesian to cylindrical", 2, new int[1],
false);
context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION)
.convertAfter(1, DoubleDouble.RADIANS_TO_DEGREES, null);
}
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java
index 9e41fd1f30..74a5c420aa 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CartesianToSpherical.java
@@ -58,7 +58,7 @@ final class CartesianToSpherical extends
CoordinateSystemTransform implements Se
* Output coordinates are in radians.
*/
private CartesianToSpherical() {
- super("Cartesian to spherical", null, 3);
+ super("Cartesian to spherical", null, 3, new int[] {2}, false);
context.denormalizeGeographicOutputs(0); // Convert
(θ,Ω) from radians to degrees.
}
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
index 95d51daa4d..4d471062cd 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/CoordinateSystemTransform.java
@@ -32,16 +32,20 @@ import
org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.OperationNotFoundException;
import org.opengis.referencing.operation.OperationMethod;
import org.apache.sis.referencing.ImmutableIdentifier;
-import org.apache.sis.referencing.internal.Resources;
-import org.apache.sis.referencing.util.WKTUtilities;
-import org.apache.sis.referencing.util.CoordinateOperations;
-import org.apache.sis.util.internal.Constants;
-import org.apache.sis.metadata.iso.citation.Citations;
-import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
import org.apache.sis.referencing.cs.AxesConvention;
import org.apache.sis.referencing.cs.CoordinateSystems;
import org.apache.sis.referencing.cs.DefaultCompoundCS;
import org.apache.sis.referencing.operation.DefaultOperationMethod;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.internal.Resources;
+import org.apache.sis.referencing.util.WKTUtilities;
+import org.apache.sis.referencing.util.CoordinateOperations;
+import org.apache.sis.referencing.util.ExtendedPrecisionMatrix;
+import org.apache.sis.referencing.util.MathTransformsOrFactory;
+import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.util.internal.Constants;
/**
@@ -53,9 +57,27 @@ import
org.apache.sis.referencing.operation.DefaultOperationMethod;
abstract class CoordinateSystemTransform extends AbstractMathTransform {
/**
* Number of input and output dimensions.
+ *
+ * @see #getSourceDimensions()
+ * @see #getTargetDimensions()
*/
private final int dimension;
+ /**
+ * Index of dimensions having linear units in the coordinate system
identified by {@link #angularIsInput}.
+ * This is used for optimizing the concatenation of this transform by an
affine transform.
+ *
+ * @see #tryConcatenate(boolean, MathTransform, MathTransformFactory)
+ */
+ private final int[] linearDimensions;
+
+ /**
+ * Whether the coordinate system having some angular units is the input
coordinate system.
+ * If {@code false}, then the coordinate system having some angular units
is the output CS.
+ * That coordinate system may also have linear units identified by {@link
#linearDimensions}.
+ */
+ private final boolean angularIsInput;
+
/**
* An operation method that describe this coordinate system conversion.
* This is used for providing a value in {@link
DefaultMathTransformFactory#getLastMethodUsed()}.
@@ -100,11 +122,15 @@ abstract class CoordinateSystemTransform extends
AbstractMathTransform {
* Subclasses may need to invoke {@link
ContextualParameters#normalizeGeographicInputs(double)}
* or {@link ContextualParameters#denormalizeGeographicOutputs(double)}
after this constructor.
*/
- CoordinateSystemTransform(final String method, final String method3D,
final int dimension) {
- this.dimension = dimension;
- this.method = method(method);
- this.method3D = (method3D != null) ? method(method3D) : this.method;
- this.context = new ContextualParameters(this.method.getParameters(),
dimension, dimension);
+ CoordinateSystemTransform(final String method, final String method3D,
final int dimension,
+ final int[] linearDimensions, final boolean
angularIsInput)
+ {
+ this.dimension = dimension;
+ this.linearDimensions = linearDimensions;
+ this.angularIsInput = angularIsInput;
+ this.method = method(method);
+ this.method3D = (method3D != null) ? method(method3D) :
this.method;
+ this.context = new
ContextualParameters(this.method.getParameters(), dimension, dimension);
}
/**
@@ -184,6 +210,58 @@ abstract class CoordinateSystemTransform extends
AbstractMathTransform {
return context;
}
+ /**
+ * Optimizes concatenation by transferring scale factors from the
Cartesian CS side to the spherical,
+ * cylindrical or polar CS side. The rational is that the affine transform
on the latter side will be
+ * needed anyway for the conversions between radians and degrees.
+ */
+ @Override
+ protected final MathTransform tryConcatenate(final boolean
applyOtherFirst, final MathTransform other,
+ final MathTransformFactory
factory) throws FactoryException
+ {
+concat: if (applyOtherFirst != angularIsInput) {
+ final ExtendedPrecisionMatrix linear =
ExtendedPrecisionMatrix.castOrWrap(MathTransforms.getMatrix(other));
+ if (linear != null) {
+ final int n = linear.getNumRow();
+ if (n == linear.getNumCol()) {
+ Number scale = null;
+ for (int j=0; j<n; j++) {
+ for (int i=0; i<n; i++) {
+ final Number e = linear.getElementOrNull(j,i);
+ if ((e == null) == (i == j)) break concat;
// Abort if matrix is not diagonal.
+ if (e != null) {
+ if (i < n-1) {
+ if (scale == null) scale = e;
+ else if (!scale.equals(e)) break concat;
// Abort if non-uniform scale.
+ } else if (e.doubleValue() != 1) break concat;
// Abort if transform is not affine.
+ }
+ }
+ }
+ /*
+ * The transform is affine and applies an uniform scale in
all dimensions.
+ * Replace it by the same scale in all output dimensions
having a linear unit.
+ *
+ */
+ if (scale != null) {
+ final MatrixSIS angular = Matrices.createIdentity(n);
+ for (int j : linearDimensions) {
+ angular.setNumber(j, j, scale);
+ }
+ final var w = MathTransformsOrFactory.wrap(factory);
+ MathTransform step1 = w.linear(angular);
+ MathTransform step2 = this;
+ if (applyOtherFirst) {
+ step2 = step1;
+ step1 = this;
+ }
+ return w.concatenate(step1, step2);
+ }
+ }
+ }
+ }
+ return super.tryConcatenate(applyOtherFirst, other, factory);
+ }
+
/**
* Adds the components of the given coordinate system in the specified
list.
* This method may invoke itself recursively if there is nested compound
CS.
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PolarToCartesian.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PolarToCartesian.java
index 03074049dd..d8ae167572 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PolarToCartesian.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PolarToCartesian.java
@@ -78,7 +78,7 @@ final class PolarToCartesian extends
CoordinateSystemTransform implements Serial
* Input coordinates are in radians.
*/
private PolarToCartesian() {
- super("Polar to Cartesian", "Cylindrical to Cartesian", 2);
+ super("Polar to Cartesian", "Cylindrical to Cartesian", 2, new int[1],
true);
context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION)
.convertBefore(1, DoubleDouble.DEGREES_TO_RADIANS, null);
}
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java
index 79a37e6fa2..ddb0093bf9 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/SphericalToCartesian.java
@@ -76,7 +76,7 @@ final class SphericalToCartesian extends
CoordinateSystemTransform implements Se
* Input coordinates are in radians.
*/
private SphericalToCartesian() {
- super("Spherical to Cartesian", null, 3);
+ super("Spherical to Cartesian", null, 3, new int[] {2}, true);
context.normalizeGeographicInputs(0); // Convert
(θ,Ω) from degrees to radians.
}
diff --git
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/ExtendedPrecisionMatrix.java
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/ExtendedPrecisionMatrix.java
index d43d4dca62..dd64ab41ca 100644
---
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/ExtendedPrecisionMatrix.java
+++
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/ExtendedPrecisionMatrix.java
@@ -54,6 +54,33 @@ public interface ExtendedPrecisionMatrix extends Matrix {
return (element == null) || element.doubleValue() == 0;
}
+ /**
+ * {@return an extended-precision view of the given matrix}.
+ * The returned matrix should be assumed read-only.
+ *
+ * @param m the matrix to cast or wrap.
+ *
+ * @see
org.apache.sis.referencing.operation.matrix.MatrixSIS#asExtendedPrecision(Matrix)
+ */
+ @SuppressWarnings("CloneDoesntCallSuperClone")
+ static ExtendedPrecisionMatrix castOrWrap(final Matrix m) {
+ if (m == null || m instanceof ExtendedPrecisionMatrix) {
+ return (ExtendedPrecisionMatrix) m;
+ }
+ return new ExtendedPrecisionMatrix() {
+ @Override public Number getElementOrNull(int j, int i) {
+ final double v = m.getElement(j, i);
+ return (v != 0) ? v : null;
+ }
+
+ @Override public double getElement(int j, int i) {return
m.getElement(j, i);}
+ @Override public int getNumRow() {return
m.getNumRow();}
+ @Override public int getNumCol() {return
m.getNumCol();}
+ @Override public String toString() {return
m.toString();}
+ @Override public Matrix clone() {return
m.clone();}
+ };
+ }
+
/**
* Returns all matrix elements in a flat, row-major (column indices vary
fastest) array.
* The array length is <code>{@linkplain #getNumRow()} * {@linkplain
#getNumCol()}</code>.
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/CartesianToPolarTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/CartesianToPolarTest.java
index eff8457bab..87a8493159 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/CartesianToPolarTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/CartesianToPolarTest.java
@@ -50,7 +50,7 @@ public final class CartesianToPolarTest extends
TransformTestCase {
*/
@Test
public void testConversion() throws FactoryException, TransformException {
- transform =
CartesianToPolar.INSTANCE.completeTransform(PolarToCartesianTest.factory());
+ transform =
CartesianToPolar.INSTANCE.completeTransform(DefaultMathTransformFactory.provider());
tolerance = 1E-12;
final double[][] data = PolarToCartesianTest.testData(false);
verifyTransform(data[1], data[0]);
@@ -65,7 +65,7 @@ public final class CartesianToPolarTest extends
TransformTestCase {
@Test
@DependsOnMethod("testConversion")
public void testCylindricalConversion() throws FactoryException,
TransformException {
- transform =
CartesianToPolar.INSTANCE.passthrough(PolarToCartesianTest.factory());
+ transform =
CartesianToPolar.INSTANCE.passthrough(DefaultMathTransformFactory.provider());
tolerance = 1E-12;
final double[][] data = PolarToCartesianTest.testData(true);
verifyTransform(data[1], data[0]);
@@ -80,7 +80,7 @@ public final class CartesianToPolarTest extends
TransformTestCase {
@Test
@DependsOnMethod("testConversion")
public void testDerivative() throws FactoryException, TransformException {
- transform =
CartesianToPolar.INSTANCE.completeTransform(PolarToCartesianTest.factory());
+ transform =
CartesianToPolar.INSTANCE.completeTransform(DefaultMathTransformFactory.provider());
derivativeDeltas = new double[] {1E-6, 1E-6};
tolerance = 1E-7;
verifyDerivative(30, 60);
@@ -95,7 +95,7 @@ public final class CartesianToPolarTest extends
TransformTestCase {
@Test
@DependsOnMethod("testDerivative")
public void testCylindricalDerivative() throws FactoryException,
TransformException {
- transform =
CartesianToPolar.INSTANCE.passthrough(PolarToCartesianTest.factory());
+ transform =
CartesianToPolar.INSTANCE.passthrough(DefaultMathTransformFactory.provider());
derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
tolerance = 1E-7;
verifyDerivative(30, 60, 100);
@@ -110,7 +110,7 @@ public final class CartesianToPolarTest extends
TransformTestCase {
@Test
@DependsOnMethod("testDerivative")
public void testConsistency() throws FactoryException, TransformException {
- transform =
CartesianToPolar.INSTANCE.completeTransform(PolarToCartesianTest.factory());
+ transform =
CartesianToPolar.INSTANCE.completeTransform(DefaultMathTransformFactory.provider());
derivativeDeltas = new double[] {1E-6, 1E-6};
tolerance = 2E-7;
verifyInDomain(new double[] {-100, -100}, // Minimal coordinates
@@ -128,7 +128,7 @@ public final class CartesianToPolarTest extends
TransformTestCase {
@Test
@DependsOnMethod("testCylindricalDerivative")
public void testCylindricalConsistency() throws FactoryException,
TransformException {
- transform =
CartesianToPolar.INSTANCE.passthrough(PolarToCartesianTest.factory());
+ transform =
CartesianToPolar.INSTANCE.passthrough(DefaultMathTransformFactory.provider());
derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
tolerance = 2E-7;
verifyInDomain(new double[] {-100, -100, -100}, // Minimal
coordinates
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java
index 802c8f671d..203db29cda 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/CartesianToSphericalTest.java
@@ -16,11 +16,15 @@
*/
package org.apache.sis.referencing.operation.transform;
+import java.util.List;
import org.opengis.util.FactoryException;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
// Test dependencies
import org.junit.Test;
+import org.junit.Before;
+import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.TestUtilities;
@@ -43,15 +47,23 @@ public final class CartesianToSphericalTest extends
TransformTestCase {
}
/**
- * Tests coordinate conversions.
+ * Creates the transform instance to test.
*
* @throws FactoryException if the transform cannot be created.
+ */
+ @Before
+ public void createInstance() throws FactoryException {
+ transform =
CartesianToSpherical.INSTANCE.completeTransform(DefaultMathTransformFactory.provider());
+ }
+
+ /**
+ * Tests coordinate conversions.
+ *
* @throws TransformException if a coordinate cannot be transformed.
*/
@Test
- public void testConversion() throws FactoryException, TransformException {
- transform =
CartesianToSpherical.INSTANCE.completeTransform(SphericalToCartesianTest.factory());
- tolerance = 1E-12;
+ public void testConversion() throws TransformException {
+ tolerance = SphericalToCartesianTest.TOLERANCE;
final double[][] data = SphericalToCartesianTest.testData();
verifyTransform(data[1], data[0]);
}
@@ -59,12 +71,10 @@ public final class CartesianToSphericalTest extends
TransformTestCase {
/**
* Tests calculation of a transform derivative.
*
- * @throws FactoryException if the transform cannot be created.
* @throws TransformException if a coordinate cannot be transformed.
*/
@Test
- public void testDerivative() throws FactoryException, TransformException {
- transform =
CartesianToSpherical.INSTANCE.completeTransform(SphericalToCartesianTest.factory());
+ public void testDerivative() throws TransformException {
derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
tolerance = 1E-7;
verifyDerivative(30, 60, 100);
@@ -73,13 +83,11 @@ public final class CartesianToSphericalTest extends
TransformTestCase {
/**
* Tests calculation of a transform derivative.
*
- * @throws FactoryException if the transform cannot be created.
* @throws TransformException if a coordinate cannot be transformed.
*/
@Test
@DependsOnMethod({"testConversion", "testDerivative"})
- public void testConsistency() throws FactoryException, TransformException {
- transform =
CartesianToSpherical.INSTANCE.completeTransform(SphericalToCartesianTest.factory());
+ public void testConsistency() throws TransformException {
derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
tolerance = 1E-5;
verifyInDomain(new double[] {-100, -100, -100}, // Minimal
coordinates
@@ -87,4 +95,25 @@ public final class CartesianToSphericalTest extends
TransformTestCase {
new int[] { 10, 10, 10},
TestUtilities.createRandomNumberGenerator());
}
+
+ /**
+ * Tests concatenation.
+ *
+ * @throws TransformException if a coordinate cannot be transformed.
+ */
+ @Test
+ @DependsOnMethod("testConversion")
+ public void testConcatenation() throws TransformException {
+ final double scale = 1000;
+ transform = MathTransforms.concatenate(MathTransforms.scale(scale,
scale, scale), transform);
+ List<MathTransform> steps = MathTransforms.getSteps(transform);
+ assertEquals(2, steps.size());
+ assertSame(CartesianToSpherical.INSTANCE, steps.get(0));
+ assertTrue(steps.get(1) instanceof LinearTransform);
+
+ double[][] data = SphericalToCartesianTest.testData();
+ SphericalToCartesianTest.multiply(data[1], 1/scale);
+ tolerance = SphericalToCartesianTest.TOLERANCE * scale;
+ verifyTransform(data[1], data[0]);
+ }
}
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/PolarToCartesianTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/PolarToCartesianTest.java
index d87b2a09e6..25ef0e410e 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/PolarToCartesianTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/PolarToCartesianTest.java
@@ -19,7 +19,6 @@ package org.apache.sis.referencing.operation.transform;
import static java.lang.StrictMath.*;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.TransformException;
-import org.opengis.referencing.operation.MathTransformFactory;
// Test dependencies
import org.junit.Test;
@@ -84,13 +83,6 @@ public final class PolarToCartesianTest extends
TransformTestCase {
return data;
}
- /**
- * Returns the factory to use for testing purpose.
- */
- static MathTransformFactory factory() {
- return DefaultMathTransformFactory.provider();
- }
-
/**
* Tests coordinate conversions in the polar case.
*
@@ -99,7 +91,7 @@ public final class PolarToCartesianTest extends
TransformTestCase {
*/
@Test
public void testConversion() throws FactoryException, TransformException {
- transform = PolarToCartesian.INSTANCE.completeTransform(factory());
+ transform =
PolarToCartesian.INSTANCE.completeTransform(DefaultMathTransformFactory.provider());
tolerance = 1E-12;
final double[][] data = testData(false);
verifyTransform(data[0], data[1]);
@@ -114,7 +106,7 @@ public final class PolarToCartesianTest extends
TransformTestCase {
@Test
@DependsOnMethod("testConversion")
public void testCylindricalConversion() throws FactoryException,
TransformException {
- transform = PolarToCartesian.INSTANCE.passthrough(factory());
+ transform =
PolarToCartesian.INSTANCE.passthrough(DefaultMathTransformFactory.provider());
tolerance = 1E-12;
final double[][] data = testData(true);
verifyTransform(data[0], data[1]);
@@ -129,7 +121,7 @@ public final class PolarToCartesianTest extends
TransformTestCase {
@Test
@DependsOnMethod("testConversion")
public void testDerivative() throws FactoryException, TransformException {
- transform = PolarToCartesian.INSTANCE.completeTransform(factory());
+ transform =
PolarToCartesian.INSTANCE.completeTransform(DefaultMathTransformFactory.provider());
derivativeDeltas = new double[] {1E-6, 1E-6};
tolerance = 1E-7;
verifyDerivative(100, 60);
@@ -144,7 +136,7 @@ public final class PolarToCartesianTest extends
TransformTestCase {
@Test
@DependsOnMethod("testDerivative")
public void testCylindricalDerivative() throws FactoryException,
TransformException {
- transform = PolarToCartesian.INSTANCE.passthrough(factory());
+ transform =
PolarToCartesian.INSTANCE.passthrough(DefaultMathTransformFactory.provider());
derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
tolerance = 1E-7;
verifyDerivative(100, 60, 25);
@@ -159,7 +151,7 @@ public final class PolarToCartesianTest extends
TransformTestCase {
@Test
@DependsOnMethod("testDerivative")
public void testConsistency() throws FactoryException, TransformException {
- transform = PolarToCartesian.INSTANCE.completeTransform(factory());
+ transform =
PolarToCartesian.INSTANCE.completeTransform(DefaultMathTransformFactory.provider());
derivativeDeltas = new double[] {1E-6, 1E-6};
tolerance = 1E-7;
verifyInDomain(new double[] { 0, -180}, // Minimal coordinates
@@ -177,7 +169,7 @@ public final class PolarToCartesianTest extends
TransformTestCase {
@Test
@DependsOnMethod("testCylindricalDerivative")
public void testCylindricalConsistency() throws FactoryException,
TransformException {
- transform = PolarToCartesian.INSTANCE.passthrough(factory());
+ transform =
PolarToCartesian.INSTANCE.passthrough(DefaultMathTransformFactory.provider());
derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
tolerance = 1E-7;
verifyInDomain(new double[] { 0, -180, -100}, // Minimal
coordinates
diff --git
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java
index 77405de7bb..45095dc9cc 100644
---
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java
+++
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/SphericalToCartesianTest.java
@@ -16,13 +16,16 @@
*/
package org.apache.sis.referencing.operation.transform;
+import java.util.List;
import static java.lang.StrictMath.*;
import org.opengis.util.FactoryException;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
-import org.opengis.referencing.operation.MathTransformFactory;
// Test dependencies
import org.junit.Test;
+import org.junit.Before;
+import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.TestUtilities;
@@ -42,6 +45,11 @@ public final class SphericalToCartesianTest extends
TransformTestCase {
public SphericalToCartesianTest() {
}
+ /**
+ * Tolerance factor for verifying the conversion results.
+ */
+ static final double TOLERANCE = 1E-12;
+
/**
* Returns coordinate tuples in spherical coordinates and their equivalent
in Cartesian coordinates.
*/
@@ -79,22 +87,33 @@ public final class SphericalToCartesianTest extends
TransformTestCase {
}
/**
- * Returns the factory to use for testing purpose.
+ * Multiples all elements of the given array by the given scale factor.
+ * This is used when the test data are modified for testing concatenation.
*/
- static MathTransformFactory factory() {
- return DefaultMathTransformFactory.provider();
+ static void multiply(final double[] data, final double scale) {
+ for (int i=0; i<data.length; i++) {
+ data[i] *= scale;
+ }
}
/**
- * Tests coordinate conversions.
+ * Creates the transform instance to test.
*
* @throws FactoryException if the transform cannot be created.
+ */
+ @Before
+ public void createInstance() throws FactoryException {
+ transform =
SphericalToCartesian.INSTANCE.completeTransform(DefaultMathTransformFactory.provider());
+ }
+
+ /**
+ * Tests coordinate conversions.
+ *
* @throws TransformException if a coordinate cannot be transformed.
*/
@Test
- public void testConversion() throws FactoryException, TransformException {
- transform = SphericalToCartesian.INSTANCE.completeTransform(factory());
- tolerance = 1E-12;
+ public void testConversion() throws TransformException {
+ tolerance = TOLERANCE;
final double[][] data = testData();
verifyTransform(data[0], data[1]);
}
@@ -102,12 +121,10 @@ public final class SphericalToCartesianTest extends
TransformTestCase {
/**
* Tests calculation of a transform derivative.
*
- * @throws FactoryException if the transform cannot be created.
* @throws TransformException if a coordinate cannot be transformed.
*/
@Test
- public void testDerivative() throws FactoryException, TransformException {
- transform = SphericalToCartesian.INSTANCE.completeTransform(factory());
+ public void testDerivative() throws TransformException {
derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
tolerance = 1E-7;
verifyDerivative(30, 60, 100);
@@ -116,13 +133,11 @@ public final class SphericalToCartesianTest extends
TransformTestCase {
/**
* Tests calculation of a transform derivative.
*
- * @throws FactoryException if the transform cannot be created.
* @throws TransformException if a coordinate cannot be transformed.
*/
@Test
@DependsOnMethod({"testConversion", "testDerivative"})
- public void testConsistency() throws FactoryException, TransformException {
- transform = SphericalToCartesian.INSTANCE.completeTransform(factory());
+ public void testConsistency() throws TransformException {
derivativeDeltas = new double[] {1E-6, 1E-6, 1E-6};
tolerance = 1E-7;
verifyInDomain(new double[] {-180, -90, 0}, // Minimal
coordinates
@@ -130,4 +145,25 @@ public final class SphericalToCartesianTest extends
TransformTestCase {
new int[] { 10, 10, 10},
TestUtilities.createRandomNumberGenerator());
}
+
+ /**
+ * Tests concatenation.
+ *
+ * @throws TransformException if a coordinate cannot be transformed.
+ */
+ @Test
+ @DependsOnMethod("testConversion")
+ public void testConcatenation() throws TransformException {
+ final double scale = 1000;
+ transform = MathTransforms.concatenate(transform,
MathTransforms.scale(scale, scale, scale));
+ List<MathTransform> steps = MathTransforms.getSteps(transform);
+ assertEquals(2, steps.size());
+ assertTrue(steps.get(0) instanceof LinearTransform);
+ assertSame(SphericalToCartesian.INSTANCE, steps.get(1));
+
+ double[][] data = testData();
+ multiply(data[1], scale);
+ tolerance = TOLERANCE * scale;
+ verifyTransform(data[0], data[1]);
+ }
}