sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1713730 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/ sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/ sis-referencing/src/main/java/org/apache/sis/refer...
Date Tue, 10 Nov 2015 21:34:43 GMT
Author: desruisseaux
Date: Tue Nov 10 21:34:43 2015
New Revision: 1713730

URL: http://svn.apache.org/viewvc?rev=1713730&view=rev
Log:
SIS-260: Implemented the "Geographic 3D to 2D conversions" (EPSG:9659)
While this operation is in principle very trivial (just drop the last ordinate value), a difficulty
is to ensure that the inverse of that operation set the ellipsoidal height to zero instead of NaN.
Since this operation is often just before or after a "degrees to radians" conversions, those two
steps have been put together in a new ScaleTransform package-private class as an optimization of
ProjectiveTransform when all the non-zero matrix terms are on the diagonal.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java   (with props)
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java
      - copied, changed from r1713526, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java   (with props)
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java   (with props)
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java   (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectBuilder.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomainTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ProjectiveTransformTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java

Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java?rev=1713730&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.referencing.provider;
+
+import javax.xml.bind.annotation.XmlTransient;
+import org.opengis.util.FactoryException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
+
+
+/**
+ * The provider for <cite>"Geographic 3D to 2D conversion"</cite> (EPSG:9659).
+ * This is a trivial operation that just drop the height in a geographic coordinate.
+ * The inverse operation arbitrarily set the ellipsoidal height to zero.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+@XmlTransient
+public final class Geographic3Dto2D extends AbstractProvider {
+    /**
+     * Serial number for inter-operability with different versions.
+     */
+    private static final long serialVersionUID = -9103595336196565505L;
+
+    /**
+     * The group of all parameters expected by this coordinate operation (in this case, none).
+     */
+    private static final ParameterDescriptorGroup PARAMETERS =
+            builder().addIdentifier("9659").addName("Geographic3D to 2D conversion").createGroup();
+
+    /**
+     * The unique instance, created when first needed.
+     */
+    private transient MathTransform transform;
+
+    /**
+     * Constructs a provider with default parameters.
+     */
+    public Geographic3Dto2D() {
+        super(3, 2, PARAMETERS);
+    }
+
+    /**
+     * Returns the operation type.
+     *
+     * @return Interface implemented by all coordinate operations that use this method.
+     */
+    @Override
+    public Class<Conversion> getOperationType() {
+        return Conversion.class;
+    }
+
+    /**
+     * Returns the transform.
+     *
+     * <div class="note"><b>Implementation note:</b>
+     * creating a transform that drop a dimension is trivial. We even have a helper method for that:
+     * {@link Matrices#createDimensionSelect}  The difficulty is that the inverse of that transform
+     * will set the height to NaN, while we want zero. The trick is to first create the transform for
+     * the inverse transform with the zero that we want, then get the inverse of that inverse transform.
+     * The transform that we get will remember where it come from (its inverse).
+     *
+     * <p>This work with SIS implementation, but is not guaranteed to work with other implementations.
+     * For that reason, this method does not use the given {@code factory}.</p></div>
+     *
+     * @param  factory Ignored (can be null).
+     * @param  values Ignored.
+     * @return The math transform.
+     * @throws FactoryException should never happen.
+     */
+    @Override
+    public synchronized MathTransform createMathTransform(MathTransformFactory factory, ParameterValueGroup values)
+            throws FactoryException
+    {
+        if (transform == null) try {
+            final MatrixSIS m = Matrices.createDiagonal(4, 3);
+            m.setElement(2, 2, 0);  // Here is the height value that we want.
+            m.setElement(3, 2, 1);
+            transform = MathTransforms.linear(m).inverse();
+        } catch (NoninvertibleTransformException e) {
+            throw new FactoryException(e);  // Should never happen.
+        }
+        return transform;
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2D.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -519,6 +519,9 @@ public final class Matrices extends Stat
      * }
      * </div>
      *
+     * The inverse of the matrix created by this method will put {@link Double#NaN} values in the extra dimensions.
+     * Other dimensions will work as expected.
+     *
      * @param  sourceDimensions The number of dimensions in source coordinates.
      * @param  selectedDimensions The 0-based indices of source ordinate values to keep.
      *         The length of this array will be the number of dimensions in target coordinates.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -21,6 +21,7 @@ import org.opengis.parameter.ParameterVa
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.internal.referencing.provider.Affine;
 import org.apache.sis.util.ComparisonMode;
@@ -106,6 +107,29 @@ abstract class AbstractLinearTransform e
     }
 
     /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
+        if (inverse == null) {
+            /*
+             * Should never be the identity transform at this point (except during tests) because
+             * MathTransforms.linear(…) should never instantiate this class in the identity case.
+             * But we check anyway as a paranoiac safety.
+             */
+            if (isIdentity()) {
+                inverse = this;
+            } else {
+                inverse = MathTransforms.linear(Matrices.inverse(this));
+                if (inverse instanceof AbstractLinearTransform) {
+                    ((AbstractLinearTransform) inverse).inverse = this;
+                }
+            }
+        }
+        return inverse;
+    }
+
+    /**
      * Returns the parameter descriptors for this math transform.
      *
      * @return {@inheritDoc}

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -79,9 +79,9 @@ final class CopyTransform extends Abstra
     static CopyTransform create(final Matrix matrix) {
         final int srcDim = matrix.getNumCol() - 1;
         final int dstDim = matrix.getNumRow() - 1;
-        for (int i=0; i<=srcDim; i++) {
+        for (int i=0; i <= srcDim; i++) {
             if (matrix.getElement(dstDim, i) != (i == srcDim ? 1 : 0)) {
-                // Not an affine transform.
+                // Not an affine transform (ignoring if square or not).
                 return null;
             }
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -143,7 +143,7 @@ public final class MathTransforms extend
         if (candidate != null) {
             return candidate;
         }
-        return new ProjectiveTransform(matrix);
+        return new ProjectiveTransform(matrix).optimize();
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -19,8 +19,6 @@ package org.apache.sis.referencing.opera
 import java.util.Arrays;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.operation.Matrix;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
@@ -90,6 +88,30 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
+     * If a more efficient implementation of this math transform can be used, returns it.
+     * Otherwise returns {@code this} unchanged.
+     */
+    final LinearTransform optimize() {
+        final int n = (numRow - 1) * numCol;
+        for (int i = 0; i != numCol;) {
+            if (elt[n + i] != (++i == numCol ? 1 : 0)) {
+                return this;    // Transform is not affine (ignoring if square or not).
+            }
+        }
+        /*
+         * Note: we could check for CopyTransform case here, but this check is rather done in
+         * MathTransforms.linear(Matrix) in order to avoid ProjectiveTransform instantiation.
+         */
+        for (int i=0; i<n; i++) {
+            // Non-zero elements are allowed to appear only on the diagonal.
+            if (elt[i] != 0 && (i / numCol) != (i % numCol)) {
+                return this;
+            }
+        }
+        return new ScaleTransform(numRow, numCol, elt);
+    }
+
+    /**
      * Gets the dimension of input points.
      */
     @Override
@@ -195,7 +217,7 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) {
+    public final void transform(double[] srcPts, int srcOff, final double[] dstPts, int dstOff, int numPts) {
         final int srcDim, dstDim;
         int srcInc = srcDim = numCol - 1; // The last ordinate will be assumed equal to 1.
         int dstInc = dstDim = numRow - 1;
@@ -266,7 +288,7 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) {
+    public final void transform(float[] srcPts, int srcOff, final float[] dstPts, int dstOff, int numPts) {
         final int srcDim, dstDim;
         int srcInc = srcDim = numCol-1;
         int dstInc = dstDim = numRow-1;
@@ -322,7 +344,7 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(double[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) {
+    public final void transform(final double[] srcPts, int srcOff, final float[] dstPts, int dstOff, int numPts) {
         final int srcDim = numCol-1;
         final int dstDim = numRow-1;
         final double[] buffer = new double[numRow];
@@ -357,7 +379,7 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(float[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) {
+    public final void transform(final float[] srcPts, int srcOff, final double[] dstPts, int dstOff, int numPts) {
         final int srcDim = numCol - 1;
         final int dstDim = numRow - 1;
         final double[] buffer = new double[numRow];
@@ -404,29 +426,6 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
-     * Creates the inverse transform of this object.
-     */
-    @Override
-    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
-        if (inverse == null) {
-            /*
-             * Should never be the identity transform at this point (except during tests) because
-             * MathTransforms.linear(…) should never instantiate this class in the identity case.
-             * But we check anyway as a paranoiac safety.
-             */
-            if (isIdentity()) {
-                inverse = this;
-            } else {
-                inverse = MathTransforms.linear(Matrices.inverse(this));
-                if (inverse instanceof AbstractLinearTransform) {
-                    ((AbstractLinearTransform) inverse).inverse = this;
-                }
-            }
-        }
-        return inverse;
-    }
-
-    /**
      * {@inheritDoc}
      *
      * @return {@inheritDoc}

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -26,6 +26,9 @@ import org.opengis.referencing.operation
 
 /**
  * Projective transform in 2D case.
+ * This class is used only if the transform is not affine, i.e. the last row in the 3×3 matrix is not [0 0 1].
+ * Otherwise {@link org.apache.sis.internal.referencing.j2d.AffineTransform2D} should be used instead
+ * (unless {@link java.awt.geom.AffineTransform} is not available on the target platform).
  *
  * @author  Jan Jezek (UWB)
  * @author  Martin Desruisseaux (Geomatys)

Copied: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java (from r1713526, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java?p2=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java&p1=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java&r1=1713526&r2=1713730&rev=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ScaleTransform.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -19,124 +19,126 @@ package org.apache.sis.referencing.opera
 import java.util.Arrays;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.referencing.operation.Matrix;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
 import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.ArraysExt;
 
 
 /**
- * A usually affine, or otherwise a projective transform for the generic cases.
- * This implementation is used for cases other than identity, 1D, 2D or axis swapping.
+ * An affine transform that multiply the ordinate values by constant values, and optionally drop the last ordinates.
+ * This is an optimization of {@link ProjectiveTransform} for a common case.
  *
- * <p>A projective transform is capable of mapping an arbitrary quadrilateral into another arbitrary quadrilateral,
- * while preserving the straightness of lines. In the special case where the transform is affine, the parallelism of
- * lines in the source is preserved in the output.</p>
+ * <div class="note"><b>Note:</b> we do not provide two-dimensional specialization because
+ * {@link org.apache.sis.internal.referencing.j2d.AffineTransform2D} should be used in such case.</div>
  *
- * @author  Martin Desruisseaux (IRD, Geomatys)
- * @since   0.5
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
  * @version 0.7
  * @module
- *
- * @see java.awt.geom.AffineTransform
  */
-class ProjectiveTransform extends AbstractLinearTransform implements ExtendedPrecisionMatrix {
+final class ScaleTransform extends AbstractLinearTransform implements ExtendedPrecisionMatrix {
     /**
      * Serial number for inter-operability with different versions.
      */
-    private static final long serialVersionUID = -2104496465933824935L;
+    private static final long serialVersionUID = 8527439133082104085L;
 
     /**
-     * The number of rows.
+     * Multiplication factors, to be applied in the same order than ordinate values.
+     * The length of this array is the number of target dimensions.
      */
-    private final int numRow;
+    private final double[] factors;
 
     /**
-     * The number of columns.
+     * The error terms in double-double arithmetic, or {@code null} if none.
+     * May be shorter than {@code factors} if all remaining errors are zero.
      */
-    private final int numCol;
+    private final double[] errors;
 
     /**
-     * Elements of the matrix. Column indices vary fastest.
-     *
-     * <p>This array may have twice the normal length ({@link #numRow} × {@link #numCol}),
-     * in which case the second half contains the error terms in double-double arithmetic.</p>
+     * Number of ordinate values to drop after the values that we multiplied.
+     * Values to drop happen for example in Geographic 3D to 2D conversions.
      */
-    private final double[] elt;
+    private final int numDroppedDimensions;
 
     /**
-     * Constructs a transform from the specified matrix.
-     * The matrix is usually square and affine, but this is not enforced.
-     *
-     * @param matrix The matrix.
+     * Constructs a scale transform from a matrix having the given elements.
+     * This constructors assumes that the matrix is affine and contains only
+     * scale coefficients (this is not verified).
      */
-    protected ProjectiveTransform(final Matrix matrix) {
-        numRow = matrix.getNumRow();
-        numCol = matrix.getNumCol();
-        if (matrix instanceof ExtendedPrecisionMatrix) {
-            elt = ((ExtendedPrecisionMatrix) matrix).getExtendedElements();
-            assert (elt.length % (numRow * numCol)) == 0;
-        } else {
-            elt = new double[numRow * numCol];
-            int mix = 0;
-            for (int j=0; j<numRow; j++) {
-                for (int i=0; i<numCol; i++) {
-                    elt[mix++] = matrix.getElement(j,i);
+    ScaleTransform(final int numRow, final int numCol, final double[] elements) {
+        numDroppedDimensions = numCol - numRow;
+        final int n = numRow * numCol;
+        factors = new double[numRow - 1];
+        double[] errors = null;
+        int lastError = -1;
+        for (int i=0; i<factors.length; i++) {
+            int j = numCol*i + i;
+            factors[i] = elements[j];
+            if ((j += n) < elements.length) {
+                final double e = elements[j];
+                if (e != 0) {
+                    if (errors == null) {
+                        errors = new double[numRow];
+                    }
+                    errors[i] = e;
+                    lastError = i;
                 }
             }
         }
+        this.errors = ArraysExt.resize(errors, lastError + 1);
     }
 
     /**
-     * Gets the dimension of input points.
-     */
-    @Override
-    public final int getSourceDimensions() {
-        return numCol - 1;
-    }
-
-    /**
-     * Gets the dimension of output points.
-     */
-    @Override
-    public final int getTargetDimensions() {
-        return numRow - 1;
-    }
-
-    /**
-     * Gets the number of rows in the matrix.
+     * Returns a copy of matrix elements, including error terms if any.
      */
     @Override
-    public final int getNumRow() {
-        return numRow;
+    public double[] getExtendedElements() {
+        final int numCol = getNumCol();
+        final int n = getNumRow() * numCol;
+        final double[] elements = new double[(errors == null) ? n : (n << 1)];
+        for (int i=0; i<factors.length; i++) {
+            final int j = numCol*i + i;
+            elements[j] = factors[i];
+            if (errors != null && i < errors.length) {
+                elements[j + n] = errors[i];
+            }
+        }
+        elements[n - 1] = 1;
+        return elements;
     }
 
     /**
-     * Gets the number of columns in the matrix.
+     * Gets the dimension of input points.
      */
     @Override
-    public final int getNumCol() {
-        return numCol;
+    public int getSourceDimensions() {
+        return factors.length + numDroppedDimensions;
     }
 
     /**
-     * Returns a copy of matrix elements, including error terms if any.
+     * Gets the dimension of output points.
      */
     @Override
-    public final double[] getExtendedElements() {
-        return elt.clone();
+    public int getTargetDimensions() {
+        return factors.length;
     }
 
     /**
      * Returns the matrix element at the given index.
      */
     @Override
-    public final double getElement(final int row, final int column) {
-        ArgumentChecks.ensureBetween("row",    0, numRow - 1, row);
-        ArgumentChecks.ensureBetween("column", 0, numCol - 1, column);
-        return elt[row * numCol + column];
+    public double getElement(final int row, final int column) {
+        final int dstDim = factors.length;
+        final int srcDim = dstDim + numDroppedDimensions;
+        ArgumentChecks.ensureBetween("row",    0, dstDim, row);
+        ArgumentChecks.ensureBetween("column", 0, srcDim, column);
+        if (row == dstDim) {
+            return (column == srcDim) ? 1 : 0;
+        } else {
+            return (row == column) ? factors[row] : 0;
+        }
     }
 
     /**
@@ -148,16 +150,13 @@ class ProjectiveTransform extends Abstra
      * instead than using a factory method.</div>
      */
     @Override
-    public final boolean isIdentity() {
-        if (numRow != numCol) {
+    public boolean isIdentity() {
+        if (numDroppedDimensions != 0) {
             return false;
         }
-        int mix = 0;
-        for (int j=0; j<numRow; j++) {
-            for (int i=0; i<numCol; i++) {
-                if (elt[mix++] != (i == j ? 1 : 0)) {
-                    return false;
-                }
+        for (int i=0; i<factors.length; i++) {
+            if (factors[i] != 1) {
+                return false;
             }
         }
         return true;
@@ -170,9 +169,9 @@ class ProjectiveTransform extends Abstra
      * @return {@inheritDoc}
      */
     @Override
-    public final Matrix transform(final double[] srcPts, final int srcOff,
-                                  final double[] dstPts, final int dstOff,
-                                  final boolean derivate)
+    public Matrix transform(final double[] srcPts, final int srcOff,
+                            final double[] dstPts, final int dstOff,
+                            final boolean derivate)
     {
         transform(srcPts, srcOff, dstPts, dstOff, 1);
         return derivate ? derivative((DirectPosition) null) : null;
@@ -195,57 +194,20 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) {
-        final int srcDim, dstDim;
-        int srcInc = srcDim = numCol - 1; // The last ordinate will be assumed equal to 1.
-        int dstInc = dstDim = numRow - 1;
+    public void transform(double[] srcPts, int srcOff, final double[] dstPts, int dstOff, int numPts) {
         if (srcPts == dstPts) {
-            switch (IterationStrategy.suggest(srcOff, srcDim, dstOff, dstDim, numPts)) {
-                case ASCENDING: {
-                    break;
-                }
-                case DESCENDING: {
-                    srcOff += (numPts - 1) * srcDim;
-                    dstOff += (numPts - 1) * dstDim;
-                    srcInc = -srcInc;
-                    dstInc = -dstInc;
-                    break;
-                }
-                default: {
-                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcDim);
-                    srcOff = 0;
-                    break;
-                }
+            final int dstDim = factors.length;
+            final int srcDim = dstDim + numDroppedDimensions;
+            if (IterationStrategy.suggest(srcOff, srcDim, dstOff, dstDim, numPts) != IterationStrategy.ASCENDING) {
+                srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcDim);
+                srcOff = 0;
             }
         }
-        final double[] buffer = new double[numRow];
         while (--numPts >= 0) {
-            int mix = 0;
-            for (int j=0; j<numRow; j++) {
-                double sum = elt[mix + srcDim];
-                for (int i=0; i<srcDim; i++) {
-                    final double e = elt[mix++];
-                    if (e != 0) {
-                        /*
-                         * The purpose of the test for non-zero value is not performance (it is actually more likely
-                         * to slow down the calculation), but to get a valid sum even if some source ordinates are NaN.
-                         * This occurs when the ProjectiveTransform is used for excluding some dimensions, for example
-                         * getting 2D points from 3D points. In such case, the fact that the excluded dimensions had
-                         * NaN values should not force the retained dimensions to get NaN values.
-                         */
-                        sum += srcPts[srcOff + i] * e;
-                    }
-                }
-                buffer[j] = sum;
-                mix++;
+            for (int i=0; i<factors.length; i++) {
+                dstPts[dstOff++] = srcPts[srcOff++] * factors[i];
             }
-            final double w = buffer[dstDim];
-            for (int j=0; j<dstDim; j++) {
-                // 'w' is equal to 1 if the transform is affine.
-                dstPts[dstOff + j] = buffer[j] / w;
-            }
-            srcOff += srcInc;
-            dstOff += dstInc;
+            srcOff += numDroppedDimensions;
         }
     }
 
@@ -266,49 +228,20 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) {
-        final int srcDim, dstDim;
-        int srcInc = srcDim = numCol-1;
-        int dstInc = dstDim = numRow-1;
+    public void transform(float[] srcPts, int srcOff, final float[] dstPts, int dstOff, int numPts) {
         if (srcPts == dstPts) {
-            switch (IterationStrategy.suggest(srcOff, srcDim, dstOff, dstDim, numPts)) {
-                case ASCENDING: {
-                    break;
-                }
-                case DESCENDING: {
-                    srcOff += (numPts - 1) * srcDim;
-                    dstOff += (numPts - 1) * dstDim;
-                    srcInc = -srcInc;
-                    dstInc = -dstInc;
-                    break;
-                }
-                default: {
-                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcDim);
-                    srcOff = 0;
-                    break;
-                }
+            final int dstDim = factors.length;
+            final int srcDim = dstDim + numDroppedDimensions;
+            if (IterationStrategy.suggest(srcOff, srcDim, dstOff, dstDim, numPts) != IterationStrategy.ASCENDING) {
+                srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcDim);
+                srcOff = 0;
             }
         }
-        final double[] buffer = new double[numRow];
         while (--numPts >= 0) {
-            int mix = 0;
-            for (int j=0; j<numRow; j++) {
-                double sum = elt[mix + srcDim];
-                for (int i=0; i<srcDim; i++) {
-                    final double e = elt[mix++];
-                    if (e != 0) { // See comment in transform(double[], ...)
-                        sum += srcPts[srcOff + i] * e;
-                    }
-                }
-                buffer[j] = sum;
-                mix++;
+            for (int i=0; i<factors.length; i++) {
+                dstPts[dstOff++] = (float) (srcPts[srcOff++] * factors[i]);
             }
-            final double w = buffer[dstDim];
-            for (int j=0; j<dstDim; j++) {
-                dstPts[dstOff + j] = (float) (buffer[j] / w);
-            }
-            srcOff += srcInc;
-            dstOff += dstInc;
+            srcOff += numDroppedDimensions;
         }
     }
 
@@ -322,28 +255,12 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(double[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) {
-        final int srcDim = numCol-1;
-        final int dstDim = numRow-1;
-        final double[] buffer = new double[numRow];
+    public void transform(final double[] srcPts, int srcOff, final float[] dstPts, int dstOff, int numPts) {
         while (--numPts >= 0) {
-            int mix = 0;
-            for (int j=0; j<numRow; j++) {
-                double sum = elt[mix + srcDim];
-                for (int i=0; i<srcDim; i++) {
-                    final double e = elt[mix++];
-                    if (e != 0) { // See comment in transform(double[], ...)
-                        sum += srcPts[srcOff + i] * e;
-                    }
-                }
-                buffer[j] = sum;
-                mix++;
+            for (int i=0; i<factors.length; i++) {
+                dstPts[dstOff++] = (float) (srcPts[srcOff++] * factors[i]);
             }
-            final double w = buffer[dstDim];
-            for (int j=0; j<dstDim; j++) {
-                dstPts[dstOff++] = (float) (buffer[j] / w);
-            }
-            srcOff += srcDim;
+            srcOff += numDroppedDimensions;
         }
     }
 
@@ -357,28 +274,12 @@ class ProjectiveTransform extends Abstra
      * @param numPts The number of points to be transformed.
      */
     @Override
-    public final void transform(float[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) {
-        final int srcDim = numCol - 1;
-        final int dstDim = numRow - 1;
-        final double[] buffer = new double[numRow];
+    public void transform(final float[] srcPts, int srcOff, final double[] dstPts, int dstOff, int numPts) {
         while (--numPts >= 0) {
-            int mix = 0;
-            for (int j=0; j<numRow; j++) {
-                double sum = elt[mix + srcDim];
-                for (int i=0; i<srcDim; i++) {
-                    final double e = elt[mix++];
-                    if (e != 0) { // See comment in transform(double[], ...)
-                        sum += srcPts[srcOff + i] * e;
-                    }
-                }
-                buffer[j] = sum;
-                mix++;
-            }
-            final double w = buffer[dstDim];
-            for (int j=0; j<dstDim; j++) {
-                dstPts[dstOff++] = buffer[j] / w;
+            for (int i=0; i<factors.length; i++) {
+                dstPts[dstOff++] = srcPts[srcOff++] * factors[i];
             }
-            srcOff += srcDim;
+            srcOff += numDroppedDimensions;
         }
     }
 
@@ -389,51 +290,23 @@ class ProjectiveTransform extends Abstra
      * @param point Ignored (can be {@code null}).
      */
     @Override
-    public final Matrix derivative(final DirectPosition point) {
-        final int srcDim = numCol - 1;
-        final int dstDim = numRow - 1;
-        final MatrixSIS matrix = Matrices.createZero(dstDim, srcDim);
-        int mix = 0;
-        for (int j=0; j<dstDim; j++) {
-            for (int i=0; i<srcDim; i++) {
-                matrix.setElement(j, i, elt[mix++]);
-            }
-            mix++; // Skip translation column.
+    public Matrix derivative(final DirectPosition point) {
+        final int n = factors.length;
+        final MatrixSIS matrix = Matrices.createZero(n, n + numDroppedDimensions);
+        for (int i=0; i<n; i++) {
+            matrix.setElement(i, i, factors[i]);
         }
         return matrix;
     }
 
     /**
-     * Creates the inverse transform of this object.
-     */
-    @Override
-    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
-        if (inverse == null) {
-            /*
-             * Should never be the identity transform at this point (except during tests) because
-             * MathTransforms.linear(…) should never instantiate this class in the identity case.
-             * But we check anyway as a paranoiac safety.
-             */
-            if (isIdentity()) {
-                inverse = this;
-            } else {
-                inverse = MathTransforms.linear(Matrices.inverse(this));
-                if (inverse instanceof AbstractLinearTransform) {
-                    ((AbstractLinearTransform) inverse).inverse = this;
-                }
-            }
-        }
-        return inverse;
-    }
-
-    /**
      * {@inheritDoc}
      *
      * @return {@inheritDoc}
      */
     @Override
     protected int computeHashCode() {
-        return Arrays.hashCode(elt) + 31 * super.computeHashCode();
+        return Arrays.hashCode(factors) + 31 * super.computeHashCode();
     }
 
     /**
@@ -441,9 +314,9 @@ class ProjectiveTransform extends Abstra
      */
     @Override
     protected boolean equalsSameClass(final Object object) {
-        final ProjectiveTransform that = (ProjectiveTransform) object;
-        return this.numRow == that.numRow &&
-               this.numCol == that.numCol &&
-               Arrays.equals(this.elt, that.elt);
+        final ScaleTransform that = (ScaleTransform) object;
+        return numDroppedDimensions == that.numDroppedDimensions
+               && Arrays.equals(factors, that.factors)
+               && Arrays.equals(errors,  that.errors);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod [UTF-8] Tue Nov 10 21:34:43 2015
@@ -1,6 +1,7 @@
 # Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
 # Heavier classes (e.g. having more dependencies) or classes less likely to be used, should be last.
 org.apache.sis.internal.referencing.provider.Affine
+org.apache.sis.internal.referencing.provider.Geographic3Dto2D
 org.apache.sis.internal.referencing.provider.LongitudeRotation
 org.apache.sis.internal.referencing.provider.GeocentricTranslation
 org.apache.sis.internal.referencing.provider.PositionVector7Param

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/AllProvidersTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -64,6 +64,7 @@ public final strictfp class AllProviders
             GeocentricTranslation3D.class,
             GeographicToGeocentric.class,
             GeocentricToGeographic.class,
+            Geographic3Dto2D.class,
             Molodensky.class,
             AbridgedMolodensky.class,
             Equirectangular.class,

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/CoordinateOperationMethodsHTML.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -65,7 +65,7 @@ import org.apache.sis.test.HTMLGenerator
  * @version 0.6
  * @module
  */
-public final class CoordinateOperationMethodsHTML extends HTMLGenerator {
+public final strictfp class CoordinateOperationMethodsHTML extends HTMLGenerator {
     /**
      * Generates the HTML report.
      *

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java?rev=1713730&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.referencing.provider;
+
+import org.opengis.util.FactoryException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.apache.sis.referencing.operation.transform.LinearTransform;
+import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.opengis.test.Assert.*;
+
+
+/**
+ * Tests the {@link Geographic3Dto2D} class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+@DependsOn(AffineTest.class)
+public final strictfp class Geographic3Dto2DTest extends TestCase {
+    /**
+     * Tests {@link Geographic3Dto2D#createMathTransform(ParameterValueGroup)}.
+     *
+     * @throws FactoryException should never happen.
+     * @throws NoninvertibleTransformException should never happen.
+     */
+    @Test
+    public void testCreateMathTransform() throws FactoryException, NoninvertibleTransformException {
+        final Geographic3Dto2D provider = new Geographic3Dto2D();
+        final MathTransform mt = provider.createMathTransform(null, null);
+        assertSame("Expected cached instance.", mt, provider.createMathTransform(null, null));
+        /*
+         * Verify the full matrix. Note that the longitude offset is expected to be in degrees.
+         * This conversion from grad to degrees is specific to Apache SIS and may be revised in
+         * future version. See org.apache.sis.referencing.operation package javadoc.
+         */
+        assertInstanceOf("Shall be an affine transform.", LinearTransform.class, mt);
+        assertMatrixEquals("Expected a Geographic 3D to 2D conversion.", Matrices.create(3, 4, new double[] {
+                1, 0, 0, 0,
+                0, 1, 0, 0,
+                0, 0, 0, 1}), ((LinearTransform) mt).getMatrix(), STRICT);
+        assertMatrixEquals("Expected a Geographic 2D to 3D conversion.", Matrices.create(4, 3, new double[] {
+                1, 0, 0,
+                0, 1, 0,
+                0, 0, 0,
+                0, 0, 1}), ((LinearTransform) mt.inverse()).getMatrix(), STRICT);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/Geographic3Dto2DTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParameterValueGroupWrapper.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -34,7 +34,7 @@ import org.opengis.parameter.ParameterDe
  * @module
  */
 @SuppressWarnings("CloneInNonCloneableClass")
-final class ParameterValueGroupWrapper implements ParameterValueGroup {
+final strictfp class ParameterValueGroupWrapper implements ParameterValueGroup {
     /**
      * The implementation to hide.
      */

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectBuilder.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectBuilder.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectBuilder.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -46,7 +46,7 @@ import org.apache.sis.util.resources.Err
  * @version 0.6
  * @module
  */
-public class GeodeticObjectBuilder extends Builder<GeodeticObjectBuilder> {
+public strictfp class GeodeticObjectBuilder extends Builder<GeodeticObjectBuilder> {
     /**
      * The name of the conversion used by {@code ProjectedCRS} or {@code DerivedCRS},
      * or {@code null} if unspecified.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -41,7 +41,7 @@ import static org.apache.sis.test.TestUt
     DefaultTransformationTest.class,
     SingleOperationMarshallingTest.class
 })
-public strictfp final class DefaultConcatenatedOperationTest extends XMLTestCase {
+public final strictfp class DefaultConcatenatedOperationTest extends XMLTestCase {
     /**
      * An XML file in this package containing a projected CRS definition.
      */

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultPassThroughOperationTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -43,7 +43,7 @@ import static org.opengis.test.Assert.*;
     DefaultTransformationTest.class,
     SingleOperationMarshallingTest.class
 })
-public strictfp final class DefaultPassThroughOperationTest extends XMLTestCase {
+public final strictfp class DefaultPassThroughOperationTest extends XMLTestCase {
     /**
      * An XML file in this package containing a projected CRS definition.
      */

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomainTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomainTest.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomainTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomainTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -34,7 +34,7 @@ import static org.junit.Assert.*;
  * @version 0.6
  * @module
  */
-public class CoordinateDomainTest extends TestCase {
+public strictfp class CoordinateDomainTest extends TestCase {
     /**
      * The tolerance threshold used in this test suite.
      */

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -18,20 +18,23 @@ package org.apache.sis.referencing.opera
 
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.internal.referencing.provider.Affine;
+import org.apache.sis.referencing.operation.matrix.Matrices;
 
 // Test imports
 import org.junit.Test;
 import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.DependsOnMethod;
 
 import static org.apache.sis.test.ReferencingAssert.*;
 
 
 /**
  * Tests the {@link CopyTransform} class.
+ * Also opportunistically tests consistency with {@link ProjectiveTransform}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.6
+ * @version 0.7
  * @module
  */
 @DependsOn({
@@ -88,7 +91,7 @@ public final strictfp class CopyTransfor
      * @throws TransformException should never happen.
      */
     @Test
-    public void test3D() throws TransformException {
+    public void testConstantDimension() throws TransformException {
         create(3, 2, 1, 0);
         assertIsNotIdentity(transform);
 
@@ -111,7 +114,8 @@ public final strictfp class CopyTransfor
      * @throws TransformException should never happen.
      */
     @Test
-    public void test3Dto2D() throws TransformException {
+    @DependsOnMethod("testConstantDimension")
+    public void testDimensionReduction() throws TransformException {
         isInverseTransformSupported = false;
         create(3, 0, 1);
         assertIsNotIdentity(transform);
@@ -128,4 +132,25 @@ public final strictfp class CopyTransfor
         makeProjectiveTransform();
         verifyTransform(source, target);
     }
+
+    /**
+     * Tests a transform with more output dimensions than input dimensions.
+     * The extra dimension has values set to 0. This kind of transform happen
+     * in the inverse of <cite>"Geographic 3D to 2D conversion"</cite> (EPSG:9659).
+     *
+     * @throws TransformException should never happen.
+     */
+    @Test
+    @DependsOnMethod("testDimensionReduction")
+    public void testDimensionAugmentation() throws TransformException {
+        transform = new ProjectiveTransform(Matrices.create(4, 3, new double[] {
+                0, 1, 0,
+                1, 0, 0,
+                0, 0, 0,
+                0, 0, 1}));
+
+        assertInstanceOf("inverse", CopyTransform.class, transform.inverse());
+        verifyTransform(new double[] {2,3,    6,0,    2, Double.NaN},
+                        new double[] {3,2,0,  0,6,0,  Double.NaN, 2, 0});
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ProjectiveTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ProjectiveTransformTest.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ProjectiveTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ProjectiveTransformTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.operation.transform;
 
 import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransform1D;
 import org.opengis.referencing.operation.MathTransform2D;
 import org.opengis.referencing.operation.MathTransformFactory;
@@ -44,11 +45,11 @@ import org.opengis.test.referencing.Affi
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.7
  * @module
  */
 @RunWith(JUnit4.class)
-@DependsOn(AbstractMathTransformTest.class)
+@DependsOn({AbstractMathTransformTest.class, ScaleTransformTest.class})
 public strictfp class ProjectiveTransformTest extends AffineTransformTest {
     /**
      * For {@link LinearTransformTest} constructor only.
@@ -63,12 +64,22 @@ public strictfp class ProjectiveTransfor
     public ProjectiveTransformTest() {
         super(new MathTransformFactoryBase() {
             @Override
-            public ProjectiveTransform createAffineTransform(final Matrix matrix) {
+            public MathTransform createAffineTransform(final Matrix matrix) {
+                final ProjectiveTransform pt;
                 if (matrix.getNumRow() == 3 && matrix.getNumCol() == 3) {
-                    return new ProjectiveTransform2D(matrix);
+                    pt = new ProjectiveTransform2D(matrix);
                 } else {
-                    return new ProjectiveTransform(matrix);
+                    pt = new ProjectiveTransform(matrix);
                 }
+                MathTransform tr = pt.optimize();
+                if (tr != pt) {
+                    /*
+                     * Opportunistically tests ScaledTransform together with ProjectiveTransform.
+                     * We takes ScaledTransform as a reference implementation since it is simpler.
+                     */
+                    tr = new TransformResultComparator(tr, pt);
+                }
+                return tr;
             }
         });
     }
@@ -106,6 +117,9 @@ public strictfp class ProjectiveTransfor
      */
     @After
     public final void ensureImplementRightInterface() {
+        if (transform instanceof TransformResultComparator) {
+            transform = ((TransformResultComparator) transform).tested;
+        }
         /*
          * Below is a copy of MathTransformTestCase.validate(), with minor modifications
          * due to the fact that this class does not extend MathTransformTestCase.

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java?rev=1713730&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.Matrix4;
+import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
+import org.apache.sis.internal.util.DoubleDouble;
+
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.DependsOn;
+import org.opengis.test.Assert;
+import org.junit.Test;
+
+import static org.opengis.test.Assert.*;
+
+
+/**
+ * Tests the {@link ScaleTransform} class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+@DependsOn(AbstractMathTransformTest.class)
+public final strictfp class ScaleTransformTest extends MathTransformTestCase {
+    /**
+     * Sets the {@link #transform} field to the {@link ScaleTransform} instance to test.
+     *
+     * @param sourceDimensions  expected number of source dimensions.
+     * @param targetDimensions  expected number of source dimensions.
+     * @param matrix            the data to use for creating the transform.
+     */
+    private void create(final int sourceDimensions, final int targetDimensions, final MatrixSIS matrix) {
+        final double[] elements = matrix.getElements();
+        final ScaleTransform tr = new ScaleTransform(matrix.getNumRow(), matrix.getNumCol(), elements);
+        assertEquals("sourceDimensions", sourceDimensions, tr.getSourceDimensions());
+        assertEquals("targetDimensions", targetDimensions, tr.getTargetDimensions());
+        Assert.assertMatrixEquals("matrix", matrix, tr.getMatrix(), 0.0);
+        assertArrayEquals("elements", elements, tr.getExtendedElements(), 0.0);
+        transform = tr;
+        validate();
+    }
+
+    /**
+     * Tests a transform created from a square matrix with no error terms.
+     * In this test, no dimension are dropped.
+     *
+     * @throws TransformException should never happen.
+     */
+    @Test
+    public void testConstantDimension() throws TransformException {
+        create(3, 3, new Matrix4(
+                2, 0, 0, 0,
+                0, 3, 0, 0,
+                0, 0, 8, 0,
+                0, 0, 0, 1));
+
+        verifyTransform(new double[] {1,1,1,   6, 0,  2,   2, Double.NaN,  6},
+                        new double[] {2,3,8,  12, 0, 16,   4, Double.NaN, 48});
+    }
+
+    /**
+     * Tests a transform with less output dimensions than input dimensions.
+     * This transform drops the last dimension.
+     *
+     * @throws TransformException should never happen.
+     */
+    @Test
+    @DependsOnMethod("testConstantDimension")
+    public void testDimensionReduction() throws TransformException {
+        isInverseTransformSupported = false;    // Because matrix is not square.
+        create(3, 2, Matrices.create(3, 4, new double[] {
+                2, 0, 0, 0,
+                0, 3, 0, 0,
+                0, 0, 0, 1}));
+
+        verifyTransform(new double[] {1,1,1,   6, 0, 2,   2, Double.NaN, 6},
+                        new double[] {2,3,    12, 0,      4, Double.NaN});
+    }
+
+    /**
+     * Tests a transform with more output dimensions than input dimensions.
+     * The extra dimension has values set to 0. This kind of transform happen
+     * in the inverse of <cite>"Geographic 3D to 2D conversion"</cite> (EPSG:9659).
+     *
+     * @throws TransformException should never happen.
+     */
+    @Test
+    @DependsOnMethod("testDimensionReduction")
+    public void testDimensionAugmentation() throws TransformException {
+        transform = new ProjectiveTransform(Matrices.create(4, 3, new double[] {
+                2, 0, 0,
+                0, 3, 0,
+                0, 0, 0,
+                0, 0, 1}));
+
+        assertInstanceOf("inverse", ScaleTransform.class, transform.inverse());
+        verifyTransform(new double[] {1,1,    6,  0,     2, Double.NaN},
+                        new double[] {2,3,0,  12, 0, 0,  4, Double.NaN, 0});
+    }
+
+    /**
+     * Verifies that {@link ScaleTransform} stores the error terms when they exist.
+     */
+    @Test
+    @DependsOnMethod("testConstantDimension")
+    public void testExtendedPrecision() {
+        final Number O = 0;
+        final Number l = 1;
+        final DoubleDouble r = DoubleDouble.createDegreesToRadians();
+        final MatrixSIS matrix = Matrices.create(4, 4, new Number[] {
+            r, O, O, O,
+            O, r, O, O,
+            O, O, l, O,
+            O, O, O, l
+        });
+        final double[] elements = ((ExtendedPrecisionMatrix) matrix).getExtendedElements();
+        assertTrue (r.value > r.error);
+        assertFalse(r.error == 0);          // Paranoiac checks for making sure that next assertion will test something.
+        assertArrayEquals(new double[] {    // Paranoiac check for making sure that getExtendedElements() is not broken.
+                r.value, 0, 0, 0,
+                0, r.value, 0, 0,
+                0, 0,       1, 0,
+                0, 0,       0, 1,
+                r.error, 0, 0, 0,
+                0, r.error, 0, 0,
+                0, 0,       0, 0,
+                0, 0,       0, 0}, elements, 0);
+
+        final ScaleTransform tr = new ScaleTransform(4, 4, elements);
+        assertEquals("sourceDimensions", 3, tr.getSourceDimensions());
+        assertEquals("targetDimensions", 3, tr.getTargetDimensions());
+        Assert.assertMatrixEquals("matrix", matrix, tr.getMatrix(), 0.0);
+        assertArrayEquals("elements", elements, tr.getExtendedElements(), 0.0);
+        transform = tr;
+        validate();
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ScaleTransformTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -36,7 +36,7 @@ import static org.opengis.test.Assert.*;
  * @module
  */
 @DependsOn(ExponentialTransform1DTest.class)
-public final class TransferFunctionTest extends TestCase {
+public final strictfp class TransferFunctionTest extends TestCase {
     /**
      * Tests the creation of a linear transfer function.
      */

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java?rev=1713730&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+import java.util.Arrays;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.apache.sis.geometry.GeneralDirectPosition;
+
+import static org.opengis.test.Assert.*;
+
+
+/**
+ * Compares the projection results of two {@link MathTransform} implementations.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+final strictfp class TransformResultComparator implements MathTransform {
+    /**
+     * The transform to be used as the reference.
+     */
+    private final MathTransform reference;
+
+    /**
+     * The transform to be compared with the {@link #reference} one.
+     */
+    final MathTransform tested;
+
+    /**
+     * The tolerance threshold, which is zero by default.
+     */
+    double tolerance;
+
+    /**
+     * Creates a transform which will compare the results of the two given transforms.
+     */
+    TransformResultComparator(final MathTransform reference, final MathTransform tested) {
+        this.reference = reference;
+        this.tested    = tested;
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the value is equals
+     * to the one provided by the reference implementation.
+     */
+    @Override
+    public int getSourceDimensions() {
+        final int value = tested.getSourceDimensions();
+        assertEquals("sourceDimensions", reference.getSourceDimensions(), value);
+        return value;
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the value is equals
+     * to the one provided by the reference implementation.
+     */
+    @Override
+    public int getTargetDimensions() {
+        final int value = tested.getTargetDimensions();
+        assertEquals("targetDimensions", reference.getTargetDimensions(), value);
+        return value;
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the value is equals
+     * to the one provided by the reference implementation.
+     */
+    @Override
+    public boolean isIdentity() {
+        final boolean value = tested.isIdentity();
+        assertEquals("isIdentity", reference.isIdentity(), value);
+        return value;
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the value is equals
+     * to the one provided by the reference implementation.
+     */
+    @Override
+    public Matrix derivative(DirectPosition point) throws MismatchedDimensionException, TransformException {
+        final Matrix value = tested.derivative(point);
+        assertMatrixEquals("derivative", reference.derivative(point), value, tolerance);
+        return value;
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the value is equals
+     * to the one provided by the reference implementation.
+     */
+    @Override
+    public DirectPosition transform(DirectPosition ptSrc, DirectPosition ptDst) throws TransformException {
+        GeneralDirectPosition clone = new GeneralDirectPosition(ptSrc);
+        final DirectPosition value = tested.transform(ptSrc, ptDst);
+        assertEquals("transform(DirectPosition, …)", reference.transform(clone, null), value);
+        return value;
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the values are equal
+     * to the ones provided by the reference implementation.
+     */
+    @Override
+    public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws TransformException {
+        final double[] expected = new double[numPts * reference.getTargetDimensions()];
+        reference.transform(srcPts, srcOff, expected, 0, numPts);
+        tested.transform(srcPts, srcOff, dstPts, dstOff, numPts);
+        assertArrayEquals("transform(double[], …, double[], …)", expected,
+                Arrays.copyOfRange(dstPts, dstOff, dstOff + numPts * tested.getTargetDimensions()), tolerance);
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the values are equal
+     * to the ones provided by the reference implementation.
+     */
+    @Override
+    public void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) throws TransformException {
+        final float[] expected = new float[numPts * reference.getTargetDimensions()];
+        reference.transform(srcPts, srcOff, expected, 0, numPts);
+        tested.transform(srcPts, srcOff, dstPts, dstOff, numPts);
+        assertArrayEquals("transform(float[], …, float[], …)", expected,
+                Arrays.copyOfRange(dstPts, dstOff, dstOff + numPts * tested.getTargetDimensions()), (float) tolerance);
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the values are equal
+     * to the ones provided by the reference implementation.
+     */
+    @Override
+    public void transform(float[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws TransformException {
+        final double[] expected = new double[numPts * reference.getTargetDimensions()];
+        reference.transform(srcPts, srcOff, expected, 0, numPts);
+        tested.transform(srcPts, srcOff, dstPts, dstOff, numPts);
+        assertArrayEquals("transform(float[], …, double[], …)", expected,
+                Arrays.copyOfRange(dstPts, dstOff, dstOff + numPts * tested.getTargetDimensions()), tolerance);
+    }
+
+    /**
+     * Delegates to the tested implementation and verifies that the values are equal
+     * to the ones provided by the reference implementation.
+     */
+    @Override
+    public void transform(double[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) throws TransformException {
+        final float[] expected = new float[numPts * reference.getTargetDimensions()];
+        reference.transform(srcPts, srcOff, expected, 0, numPts);
+        tested.transform(srcPts, srcOff, dstPts, dstOff, numPts);
+        assertArrayEquals("transform(double[], …, float[], …)", expected,
+                Arrays.copyOfRange(dstPts, dstOff, dstOff + numPts * tested.getTargetDimensions()), (float) tolerance);
+    }
+
+    /**
+     * Returns the inverse of this transform.
+     */
+    @Override
+    public MathTransform inverse() throws NoninvertibleTransformException {
+        return new TransformResultComparator(reference.inverse(), tested.inverse());
+    }
+
+    /**
+     * Delegates to the tested implementation. No comparison is done by this method.
+     */
+    @Override
+    public String toWKT() {
+        return tested.toWKT();
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransformResultComparator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -105,6 +105,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.transform.CoordinateDomainTest.class,
     org.apache.sis.referencing.operation.transform.IterationStrategyTest.class,
     org.apache.sis.referencing.operation.transform.AbstractMathTransformTest.class,
+    org.apache.sis.referencing.operation.transform.ScaleTransformTest.class,
     org.apache.sis.referencing.operation.transform.ProjectiveTransformTest.class,
     org.apache.sis.referencing.operation.transform.LinearTransformTest.class,
     org.apache.sis.referencing.operation.transform.ExponentialTransform1DTest.class,
@@ -124,6 +125,7 @@ import org.junit.BeforeClass;
 
     // Registration of map projections and other math transforms.
     org.apache.sis.internal.referencing.provider.AffineTest.class,
+    org.apache.sis.internal.referencing.provider.Geographic3Dto2DTest.class,
     org.apache.sis.internal.referencing.provider.LongitudeRotationTest.class,
     org.apache.sis.internal.referencing.provider.GeocentricTranslationTest.class,
     org.apache.sis.internal.referencing.provider.PositionVector7ParamTest.class,

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java?rev=1713730&r1=1713729&r2=1713730&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java [UTF-8] Tue Nov 10 21:34:43 2015
@@ -75,6 +75,7 @@ import java.util.Objects;
  *
  * @see Arrays
  */
+@SuppressWarnings("ReturnOfCollectionOrArrayField")     // Array constants in this class are immutable empty arrays.
 public final class ArraysExt extends Static {
     /**
      * An empty array of {@code double} primitive type.
@@ -399,6 +400,7 @@ public final class ArraysExt extends Sta
      * @throws IllegalArgumentException  If {@code length} is negative.
      * @throws IndexOutOfBoundsException If {@code first} or {@code first+length} is out of array bounds.
      */
+    @SuppressWarnings("SuspiciousSystemArraycopy")
     private static <T> T doRemove(final T array, final int first, final int length)
             throws NullArgumentException, IllegalArgumentException, IndexOutOfBoundsException
     {
@@ -668,6 +670,7 @@ public final class ArraysExt extends Sta
      * @throws IllegalArgumentException  If {@code length} is negative.
      * @throws IndexOutOfBoundsException If {@code first} or {@code first+length} is out of array bounds.
      */
+    @SuppressWarnings("SuspiciousSystemArraycopy")
     private static <T> T doInsert(final T array, final int first, final int length)
             throws NullArgumentException, IllegalArgumentException, IndexOutOfBoundsException
     {
@@ -961,6 +964,7 @@ public final class ArraysExt extends Sta
      * @throws IllegalArgumentException  If {@code length} is negative.
      * @throws IndexOutOfBoundsException If {@code srcOff}, {@code srcOff+length} or {@code dstOff} is out of array bounds,
      */
+    @SuppressWarnings("SuspiciousSystemArraycopy")
     private static <T> T doInsert(final T src, final int srcOff,
                                   final T dst, final int dstOff, final int length)
             throws NullArgumentException, IllegalArgumentException, IndexOutOfBoundsException



Mime
View raw message