sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1667591 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/j2d/ main/java/org/apache/sis/referencing/operation/transform/ test/java/org/apache/sis/referencing/operation/transform/
Date Wed, 18 Mar 2015 17:09:19 GMT
Author: desruisseaux
Date: Wed Mar 18 17:09:19 2015
New Revision: 1667591

URL: http://svn.apache.org/r1667591
Log:
Referencing: after call to NonLinearParameters.createConcatenatedTransform(...), stores the
normalize/denormalize transforms as immutable matrices if possible.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
      - copied, changed from r1667487, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.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/DefaultMathTransformFactory.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/NonLinearParameters.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/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java?rev=1667591&r1=1667590&r2=1667591&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/j2d/AffineTransform2D.java
[UTF-8] Wed Mar 18 17:09:19 2015
@@ -53,7 +53,7 @@ import static org.apache.sis.util.Argume
  * @see ProjectiveTransform
  */
 public class AffineTransform2D extends ImmutableAffineTransform implements MathTransform2D,
-        LinearTransform, LenientComparable, Parameterized, Cloneable
+        LinearTransform, LenientComparable, Parameterized
 {
     /**
      * Serial number for inter-operability with different versions.

Copied: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
(from r1667487, 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/AbstractLinearTransform.java?p2=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java&p1=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform.java&r1=1667487&r2=1667591&rev=1667591&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/AbstractLinearTransform.java
[UTF-8] Wed Mar 18 17:09:19 2015
@@ -16,132 +16,75 @@
  */
 package org.apache.sis.referencing.operation.transform;
 
-import java.util.Arrays;
-import java.io.Serializable;
-import org.opengis.geometry.DirectPosition;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.Matrix;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
-import org.apache.sis.util.ComparisonMode;
 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.internal.referencing.provider.Affine;
-import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
 
 
 /**
- * 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.
+ * Base class of linear transforms. For efficiency reasons, this transform implements itself
the matrix
+ * to be returned by {@link #getMatrix()}.
  *
- * <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>
+ * <p>Subclasses need to implement the following methods:</p>
+ * <ul>
+ *   <li>{@link #isAffine()}</li>
+ *   <li>{@link #getElement(int, int)}</li>
+ * </ul>
  *
- * @author  Martin Desruisseaux (IRD, Geomatys)
- * @since   0.5
- * @version 0.5
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.6
+ * @version 0.6
  * @module
- *
- * @see java.awt.geom.AffineTransform
  */
-class ProjectiveTransform extends AbstractMathTransform implements LinearTransform, ExtendedPrecisionMatrix,
-        Serializable // Not Cloneable, despite the clone() method.
+abstract class AbstractLinearTransform extends AbstractMathTransform
+        implements LinearTransform, Matrix // Not Cloneable, despite the clone() method.
 {
     /**
-     * Serial number for inter-operability with different versions.
-     */
-    private static final long serialVersionUID = -2104496465933824935L;
-
-    /**
-     * The number of rows.
-     */
-    private final int numRow;
-
-    /**
-     * The number of columns.
-     */
-    private final int numCol;
-
-    /**
-     * 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>
-     */
-    private final double[] elt;
-
-    /**
-     * The inverse transform. Will be created only when first needed. This field is part
of the serialization form
-     * in order to avoid rounding errors if a user asks for the inverse of the inverse (i.e.
the original transform)
-     * after deserialization.
+     * Constructs a transform.
      */
-    AbstractMathTransform inverse;
+    AbstractLinearTransform() {
+    }
 
     /**
-     * Constructs a transform from the specified matrix.
-     * The matrix is usually square and affine, but this is not enforced.
+     * Returns {@code true} if this transform is affine.
      *
-     * @param matrix The matrix.
+     * @return {@code true} if this transform is affine, or {@code false} otherwise.
      */
-    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);
-                }
-            }
-        }
-    }
+    public abstract boolean isAffine();
 
     /**
-     * Gets the dimension of input points.
+     * Returns a copy of the matrix that user can modify.
      */
     @Override
-    public final int getSourceDimensions() {
-        return numCol - 1;
+    public final Matrix clone() {
+        return Matrices.copy(this);
     }
 
     /**
-     * Gets the dimension of output points.
+     * Returns an immutable view of the matrix for this transform.
      */
     @Override
-    public final int getTargetDimensions() {
-        return numRow - 1;
+    public final Matrix getMatrix() {
+        return this;
     }
 
     /**
      * Gets the number of rows in the matrix.
      */
     @Override
-    public final int getNumRow() {
-        return numRow;
+    public int getNumRow() {
+        return getTargetDimensions() + 1;
     }
 
     /**
      * Gets the number of columns in the matrix.
      */
     @Override
-    public final int getNumCol() {
-        return numCol;
-    }
-
-    /**
-     * Returns a copy of the matrix given to the constructor.
-     */
-    @Override
-    public final Matrix getMatrix() {
-        return this;
+    public int getNumCol() {
+        return getSourceDimensions() + 1;
     }
 
     /**
@@ -151,7 +94,7 @@ class ProjectiveTransform extends Abstra
      */
     @Override
     public ParameterDescriptorGroup getParameterDescriptors() {
-        return Affine.getProvider(getSourceDimensions(), getTargetDimensions(), Matrices.isAffine(this)).getParameters();
+        return Affine.getProvider(getSourceDimensions(), getTargetDimensions(), isAffine()).getParameters();
     }
 
     /**
@@ -166,366 +109,12 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
-     * Returns a copy of matrix elements, including error terms if any.
-     */
-    @Override
-    public final double[] getExtendedElements() {
-        return elt.clone();
-    }
-
-    /**
-     * 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];
-    }
-
-    /**
      * Unsupported operation, since this matrix is unmodifiable.
      */
     @Override
     public final void setElement(final int row, final int column, final double value) {
-        throw new UnsupportedOperationException(Matrices.isAffine(this)
+        throw new UnsupportedOperationException(isAffine()
                 ? Errors.format(Errors.Keys.UnmodifiableAffineTransform)
-                : Errors.format(Errors.Keys.UnmodifiableObject_1, ProjectiveTransform.class));
-    }
-
-    /**
-     * Returns a copy of the matrix that user can modify.
-     */
-    @Override
-    public final Matrix clone() {
-        return Matrices.copy(this);
-    }
-
-    /**
-     * Tests whether this transform does not move any points.
-     *
-     * <div class="note"><b>Note:</b> this method should always returns
{@code false}, since
-     * {@code MathTransforms.linear(…)} should have created specialized implementations
for identity cases.
-     * Nevertheless we perform the full check as a safety, in case someone instantiated this
class directly
-     * instead than using a factory method.</div>
-     */
-    @Override
-    public boolean isIdentity() {
-        if (numRow != numCol) {
-            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;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Converts a single coordinate point in a list of ordinal values,
-     * and optionally computes the derivative at that location.
-     *
-     * @return {@inheritDoc}
-     */
-    @Override
-    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;
-    }
-
-    /**
-     * Transforms an array of floating point coordinates by this matrix. Point coordinates
must have a dimension
-     * equal to <code>{@link Matrix#getNumCol}-1</code>. For example, for square
matrix of size 4×4, coordinate
-     * points are three-dimensional and stored in the arrays starting at the specified offset
({@code srcOff}) in
-     * the order
-     * <code>[x<sub>0</sub>, y<sub>0</sub>, z<sub>0</sub>,
-     *        x<sub>1</sub>, y<sub>1</sub>, z<sub>1</sub>...,
-     *        x<sub>n</sub>, y<sub>n</sub>, z<sub>n</sub>]</code>.
-     *
-     * @param srcPts The array containing the source point coordinates.
-     * @param srcOff The offset to the first point to be transformed in the source array.
-     * @param dstPts The array into which the transformed point coordinates are returned.
-     * @param dstOff The offset to the location of the first transformed point that is stored
in the
-     *               destination array. The source and destination array sections can overlap.
-     * @param numPts The number of points to be transformed.
-     */
-    @Override
-    public 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;
-        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 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++;
-            }
-            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;
-        }
-    }
-
-    /**
-     * Transforms an array of floating point coordinates by this matrix. Point coordinates
must have a dimension
-     * equal to <code>{@link Matrix#getNumCol()} - 1</code>. For example, for
square matrix of size 4×4, coordinate
-     * points are three-dimensional and stored in the arrays starting at the specified offset
({@code srcOff})
-     * in the order
-     * <code>[x<sub>0</sub>, y<sub>0</sub>, z<sub>0</sub>,
-     *        x<sub>1</sub>, y<sub>1</sub>, z<sub>1</sub>...,
-     *        x<sub>n</sub>, y<sub>n</sub>, z<sub>n</sub>]</code>.
-     *
-     * @param srcPts The array containing the source point coordinates.
-     * @param srcOff The offset to the first point to be transformed in the source array.
-     * @param dstPts The array into which the transformed point coordinates are returned.
-     * @param dstOff The offset to the location of the first transformed point that is stored
in the
-     *               destination array. The source and destination array sections can overlap.
-     * @param numPts The number of points to be transformed.
-     */
-    @Override
-    public 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;
-        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 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++;
-            }
-            final double w = buffer[dstDim];
-            for (int j=0; j<dstDim; j++) {
-                dstPts[dstOff + j] = (float) (buffer[j] / w);
-            }
-            srcOff += srcInc;
-            dstOff += dstInc;
-        }
-    }
-
-    /**
-     * Transforms an array of floating point coordinates by this matrix.
-     *
-     * @param srcPts The array containing the source point coordinates.
-     * @param srcOff The offset to the first point to be transformed in the source array.
-     * @param dstPts The array into which the transformed point coordinates are returned.
-     * @param dstOff The offset to the location of the first transformed point that is stored
in the destination array.
-     * @param numPts The number of points to be transformed.
-     */
-    @Override
-    public 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];
-        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++] = (float) (buffer[j] / w);
-            }
-            srcOff += srcDim;
-        }
-    }
-
-    /**
-     * Transforms an array of floating point coordinates by this matrix.
-     *
-     * @param srcPts The array containing the source point coordinates.
-     * @param srcOff The offset to the first point to be transformed in the source array.
-     * @param dstPts The array into which the transformed point coordinates are returned.
-     * @param dstOff The offset to the location of the first transformed point that is stored
in the destination array.
-     * @param numPts The number of points to be transformed.
-     */
-    @Override
-    public 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];
-        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;
-            }
-            srcOff += srcDim;
-        }
-    }
-
-    /**
-     * Gets the derivative of this transform at a point.
-     * For a matrix transform, the derivative is the same everywhere.
-     *
-     * @param point Ignored (can be {@code null}).
-     */
-    @Override
-    public 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.
-        }
-        return matrix;
-    }
-
-    /**
-     * Creates the inverse transform of this object.
-     */
-    @Override
-    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
-        if (inverse == null) {
-            /*
-             * Note: we do not perform the following optimization, because MathTransforms.linear(…)
-             *       should never instantiate this class in the identity case.
-             *
-             *       if (isIdentity()) {
-             *           inverse = this;
-             *       } else { ... }
-             */
-            MatrixSIS matrix = Matrices.copy(this);
-            matrix = matrix.inverse();
-            ProjectiveTransform inv = createInverse(matrix);
-            inv.inverse = this;
-            inverse = inv;
-        }
-        return inverse;
-    }
-
-    /**
-     * Creates an inverse transform using the specified matrix.
-     * To be overridden by {@link GeocentricTranslation}.
-     */
-    ProjectiveTransform createInverse(final Matrix matrix) {
-        return new ProjectiveTransform(matrix);
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @return {@inheritDoc}
-     */
-    @Override
-    protected int computeHashCode() {
-        return Arrays.hashCode(elt) + 31 * super.computeHashCode();
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * @return {@inheritDoc}
-     */
-    @Override
-    public boolean equals(final Object object, final ComparisonMode mode) {
-        if (object == this) { // Slight optimization
-            return true;
-        }
-        if (mode != ComparisonMode.STRICT) {
-            if (object instanceof LinearTransform) {
-                return Matrices.equals(this, ((LinearTransform) object).getMatrix(), mode);
-            }
-        } else if (super.equals(object, mode)) {
-            final ProjectiveTransform that = (ProjectiveTransform) object;
-            return this.numRow == that.numRow &&
-                   this.numCol == that.numCol &&
-                   Arrays.equals(this.elt, that.elt);
-        }
-        return false;
+                : Errors.format(Errors.Keys.UnmodifiableObject_1, AbstractLinearTransform.class));
     }
 }

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=1667591&r1=1667590&r2=1667591&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] Wed Mar 18 17:09:19 2015
@@ -22,9 +22,6 @@ import org.opengis.geometry.DirectPositi
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.ParameterDescriptorGroup;
-import org.apache.sis.internal.referencing.provider.Affine;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.util.ComparisonMode;
@@ -44,10 +41,10 @@ import org.apache.sis.util.ComparisonMod
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
-final class CopyTransform extends AbstractMathTransform implements LinearTransform, Serializable
{
+final class CopyTransform extends AbstractLinearTransform implements Serializable {
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -78,7 +75,7 @@ final class CopyTransform extends Abstra
      * @param indices The indices of ordinates to copy in the source array.
      *        The length of this array is the target dimension.
      */
-    CopyTransform(final int srcDim, final int... indices) {
+    CopyTransform(final int srcDim, final int[] indices) {
         this.srcDim  = srcDim;
         this.indices = indices;
     }
@@ -139,6 +136,14 @@ final class CopyTransform extends Abstra
     }
 
     /**
+     * Returns {@code true} since this transform is affine.
+     */
+    @Override
+    public boolean isAffine() {
+        return true;
+    }
+
+    /**
      * Tests whether this transform does not move any points.
      *
      * <div class="note"><b>Note:</b> this method should always returns
{@code false}, since
@@ -305,34 +310,11 @@ final class CopyTransform extends Abstra
     }
 
     /**
-     * Returns the parameter descriptors for this math transform.
+     * Returns the matrix element at the given row and column.
      */
     @Override
-    public ParameterDescriptorGroup getParameterDescriptors() {
-        return Affine.getProvider(srcDim, getTargetDimensions(), true).getParameters();
-    }
-
-    /**
-     * Returns the matrix elements as a group of parameters values.
-     */
-    @Override
-    public ParameterValueGroup getParameterValues() {
-        return Affine.parameters(getMatrix());
-    }
-
-    /**
-     * Returns the matrix.
-     */
-    @Override
-    public Matrix getMatrix() {
-        final int dstDim = indices.length;
-        final MatrixSIS matrix = Matrices.createZero(dstDim + 1, srcDim + 1);
-        for (int j=0; j<dstDim; j++) {
-            matrix.setElement(j, indices[j], 1);
-        }
-        matrix.setElement(dstDim, srcDim, 1);
-        assert equals(create(matrix)) : matrix;
-        return matrix;
+    public double getElement(final int row, final int column) {
+        return (((row == indices.length) ? srcDim : indices[row]) == column) ? 1 : 0;
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1667591&r1=1667590&r2=1667591&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
[UTF-8] Wed Mar 18 17:09:19 2015
@@ -735,7 +735,7 @@ public class DefaultMathTransformFactory
                  */
                 throw new FactoryException(exception);
             }
-            transform = pool.unique(transform);
+            transform = unique(transform);
             method = DefaultOperationMethod.redimension(method,
                     transform.getSourceDimensions(), transform.getTargetDimensions());
             return transform;
@@ -761,7 +761,7 @@ public class DefaultMathTransformFactory
     @Override
     public MathTransform createAffineTransform(final Matrix matrix) throws FactoryException
{
         lastMethod.remove(); // To be strict, we should set the ProjectiveTransform provider
-        return pool.unique(MathTransforms.linear(matrix));
+        return unique(MathTransforms.linear(matrix));
     }
 
     /**
@@ -784,14 +784,13 @@ public class DefaultMathTransformFactory
             throws FactoryException
     {
         lastMethod.remove();
-        MathTransform tr;
+        final MathTransform tr;
         try {
             tr = MathTransforms.concatenate(transform1, transform2);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
-        tr = pool.unique(tr);
-        return tr;
+        return unique(tr);
     }
 
     /**
@@ -824,14 +823,13 @@ public class DefaultMathTransformFactory
             throws FactoryException
     {
         lastMethod.remove();
-        MathTransform tr;
+        final MathTransform tr;
         try {
             tr = PassThroughTransform.create(firstAffectedOrdinate, subTransform, numTrailingOrdinates);
         } catch (IllegalArgumentException exception) {
             throw new FactoryException(exception);
         }
-        tr = pool.unique(tr);
-        return tr;
+        return unique(tr);
     }
 
     /**
@@ -864,6 +862,13 @@ public class DefaultMathTransformFactory
     }
 
     /**
+     * Replaces the given transform by a unique instance, if one already exists.
+     */
+    final MathTransform unique(final MathTransform tr) {
+        return pool.unique(tr);
+    }
+
+    /**
      * Returns the operation method used by the latest call to a {@code create(…)} constructor
      * in the currently running thread. Returns {@code null} if not applicable.
      *

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java?rev=1667591&r1=1667590&r2=1667591&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java
[UTF-8] Wed Mar 18 17:09:19 2015
@@ -18,14 +18,11 @@ package org.apache.sis.referencing.opera
 
 import java.io.Serializable;
 import org.opengis.geometry.DirectPosition;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.geometry.GeneralDirectPosition;
-import org.apache.sis.internal.referencing.provider.Affine;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
 
@@ -38,10 +35,10 @@ import org.apache.sis.internal.referenci
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
-final class IdentityTransform extends AbstractMathTransform implements LinearTransform, Serializable
{
+final class IdentityTransform extends AbstractLinearTransform implements Serializable {
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -105,6 +102,14 @@ final class IdentityTransform extends Ab
     }
 
     /**
+     * Returns {@code true} since this transform is affine.
+     */
+    @Override
+    public boolean isAffine() {
+        return true;
+    }
+
+    /**
      * Returns {@code true} since this transform does not move any points.
      */
     @Override
@@ -129,34 +134,16 @@ final class IdentityTransform extends Ab
     }
 
     /**
-     * Returns the parameter descriptors for this math transform.
-     */
-    @Override
-    public ParameterDescriptorGroup getParameterDescriptors() {
-        return Affine.getProvider(dimension, dimension, true).getParameters();
-    }
-
-    /**
-     * Returns the matrix elements as a group of parameters values.
-     *
-     * @return A copy of the parameter values for this math transform.
-     */
-    @Override
-    public ParameterValueGroup getParameterValues() {
-        return Affine.parameters(getMatrix());
-    }
-
-    /**
-     * Returns a copy of the identity matrix.
+     * Returns the matrix element at the given row and column.
      */
     @Override
-    public Matrix getMatrix() {
-        return Matrices.createIdentity(dimension + 1);
+    public double getElement(final int row, final int column) {
+        return (row == column) ? 1 : 0;
     }
 
     /**
-     * Gets the derivative of this transform at a point. For an identity transform,
-     * the derivative is the same everywhere.
+     * Gets the derivative of this transform at a point.
+     * For an identity transform, the derivative is the same everywhere.
      */
     @Override
     public Matrix derivative(final DirectPosition point) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/NonLinearParameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/NonLinearParameters.java?rev=1667591&r1=1667590&r2=1667591&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/NonLinearParameters.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/NonLinearParameters.java
[UTF-8] Wed Mar 18 17:09:19 2015
@@ -48,14 +48,16 @@ import static org.apache.sis.util.Argume
  * {@linkplain org.apache.sis.referencing.operation.projection.UnitaryProjection unitary
projection}.
  * See the {@linkplain org.apache.sis.referencing.operation.projection projection package}
for details.</p>
  *
- * <div class="note"><b>Note:</b>
- * Serialization of this class is appropriate for short-term storage or RMI use, but may
not be compatible
- * with future versions. For long term storage, WKT (Well Know Text) or XML are more appropriate.</div>
+ * {@section Serialization}
+ * Serialized instances of this class are not guaranteed to be compatible with future SIS
versions.
+ * Serialization should be used only for short term storage or RMI between applications running
the same SIS version.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
  * @version 0.6
  * @module
+ *
+ * @see AbstractMathTransform#getNonLinearParameters()
  */
 public abstract class NonLinearParameters extends FormattableObject implements Parameterized,
Serializable {
     /**
@@ -74,11 +76,13 @@ public abstract class NonLinearParameter
     /**
      * The affine transform to be applied before (<cite>normalize</cite>) and
after (<cite>denormalize</cite>)
      * the kernel operation. On {@code NonLinearParameters} construction, those affines are
initially identity
-     * transforms. Subclasses should set the coefficients according their parameter values.
+     * transforms, to be modified in-place by callers of {@link #normalize(boolean)}.
+     * After {@link #createConcatenatedTransform(MathTransformFactory, MathTransform)} has
been invoked,
+     * they are typically (but not necessarily) replaced by the {@link LinearTransform} instance
itself.
      *
      * @see #normalize(boolean)
      */
-    private MatrixSIS normalize, denormalize;
+    private Matrix normalize, denormalize;
 
     /**
      * Creates a new {@code NonLinearParameters} for the given coordinate operation method.
@@ -98,6 +102,8 @@ public abstract class NonLinearParameter
 
     /**
      * Creates a matrix for a linear part of the tupple.
+     * It is important that the matrices created here are instances of {@link MatrixSIS},
in order
+     * to allow {@link #normalize(boolean)} to return the reference to the (de)normalize
matrices.
      */
     private static MatrixSIS linear(final String name, final Integer size) {
         if (size == null) {
@@ -111,12 +117,12 @@ public abstract class NonLinearParameter
      * identity transforms. Subclasses should invoke this method at construction time (or
at some time close
      * to construction) in order to set the affine coefficients.
      *
-     * @param norm {@code true} for fetching the <cite>normalize</cite> transform
to apply before the kernel,
-     *        or {@code false} for the <cite>denormalize</cite> transform to
apply after the kernel.
+     * @param  norm {@code true} for fetching the <cite>normalize</cite> transform
to apply before the kernel,
+     *         or {@code false} for the <cite>denormalize</cite> transform to
apply after the kernel.
      * @return The requested normalize ({@code true}) or denormalize ({@code false}) affine
transform.
      */
     public final MatrixSIS normalize(final boolean norm) {
-        return norm ? normalize : denormalize;
+        return MatrixSIS.castOrCopy(norm ? normalize : denormalize);
     }
 
     /**
@@ -126,13 +132,18 @@ public abstract class NonLinearParameter
      * @param  kernel The (usually non-linear) kernel.
      * @return The concatenation of (<cite>normalize</cite> – the given kernel
– <cite>denormalize</cite>) transforms.
      */
-    final MathTransform createConcatenatedTransform(final MathTransformFactory factory, final
MathTransform kernel)
+    final MathTransform createConcatenatedTransform(final MathTransformFactory factory, MathTransform
kernel)
             throws FactoryException
     {
-        return factory.createConcatenatedTransform(
-               factory.createConcatenatedTransform(
-               factory.createAffineTransform(normalize), kernel),
-               factory.createAffineTransform(denormalize));
+        final MathTransform n = factory.createAffineTransform(normalize);
+        final MathTransform d = factory.createAffineTransform(denormalize);
+        Matrix m;
+        if ((m = MathTransforms.getMatrix(n)) != null)   normalize = m;
+        if ((m = MathTransforms.getMatrix(d)) != null) denormalize = m;
+        if (factory instanceof DefaultMathTransformFactory) {
+            kernel = ((DefaultMathTransformFactory) factory).unique(kernel);
+        }
+        return factory.createConcatenatedTransform(factory.createConcatenatedTransform(n,
kernel), d);
     }
 
     /**
@@ -292,9 +303,9 @@ public abstract class NonLinearParameter
          * in order to apply a change of axis order). We need to separate the "user-defined"
          * part from the "normalize" part.
          */
-        MatrixSIS userDefined = normalize(!inverse);
+        Matrix userDefined = inverse ? denormalize : normalize;
         if (!inverse) try {
-            userDefined = userDefined.inverse();
+            userDefined = MatrixSIS.castOrCopy(userDefined).inverse();
         } catch (NoninvertibleMatrixException e) {
             // Should never happen. But if it does, we abandon the attempt to change
             // the list elements and will format the objects in their "raw" format.
@@ -302,7 +313,7 @@ public abstract class NonLinearParameter
             return index;
         }
         if (hasBefore) {
-            userDefined = userDefined.multiply(before);
+            userDefined = MatrixSIS.castOrCopy(userDefined).multiply(before);
         }
         /*
          * At this point "userDefined" is the affine transform to show to user instead of
the
@@ -318,9 +329,9 @@ public abstract class NonLinearParameter
          * Note that if this operation fails, we will cancel everything we would have done
          * in this method (i.e. we do not touch the transforms list at all).
          */
-        userDefined = normalize(inverse);
+        userDefined = inverse ? normalize : denormalize;
         if (!inverse) try {
-            userDefined = userDefined.inverse();
+            userDefined = MatrixSIS.castOrCopy(userDefined).inverse();
         } catch (NoninvertibleMatrixException e) {
             unexpectedException(e);
             return index;

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=1667591&r1=1667590&r2=1667591&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] Wed Mar 18 17:09:19 2015
@@ -19,8 +19,6 @@ package org.apache.sis.referencing.opera
 import java.util.Arrays;
 import java.io.Serializable;
 import org.opengis.geometry.DirectPosition;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
@@ -28,9 +26,7 @@ import org.apache.sis.util.ComparisonMod
 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.internal.referencing.provider.Affine;
 import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.resources.Errors;
 
 
 /**
@@ -48,7 +44,7 @@ import org.apache.sis.util.resources.Err
  *
  * @see java.awt.geom.AffineTransform
  */
-class ProjectiveTransform extends AbstractMathTransform implements LinearTransform, ExtendedPrecisionMatrix,
+class ProjectiveTransform extends AbstractLinearTransform implements LinearTransform, ExtendedPrecisionMatrix,
         Serializable // Not Cloneable, despite the clone() method.
 {
     /**
@@ -137,35 +133,6 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
-     * Returns a copy of the matrix given to the constructor.
-     */
-    @Override
-    public final Matrix getMatrix() {
-        return this;
-    }
-
-    /**
-     * Returns the parameter descriptors for this math transform.
-     *
-     * @return {@inheritDoc}
-     */
-    @Override
-    public ParameterDescriptorGroup getParameterDescriptors() {
-        return Affine.getProvider(getSourceDimensions(), getTargetDimensions(), Matrices.isAffine(this)).getParameters();
-    }
-
-    /**
-     * Returns the matrix elements as a group of parameters values. The number of parameters
depends on the
-     * matrix size. Only matrix elements different from their default value will be included
in this group.
-     *
-     * @return A copy of the parameter values for this math transform.
-     */
-    @Override
-    public ParameterValueGroup getParameterValues() {
-        return Affine.parameters(this);
-    }
-
-    /**
      * Returns a copy of matrix elements, including error terms if any.
      */
     @Override
@@ -184,21 +151,11 @@ class ProjectiveTransform extends Abstra
     }
 
     /**
-     * Unsupported operation, since this matrix is unmodifiable.
-     */
-    @Override
-    public final void setElement(final int row, final int column, final double value) {
-        throw new UnsupportedOperationException(Matrices.isAffine(this)
-                ? Errors.format(Errors.Keys.UnmodifiableAffineTransform)
-                : Errors.format(Errors.Keys.UnmodifiableObject_1, ProjectiveTransform.class));
-    }
-
-    /**
-     * Returns a copy of the matrix that user can modify.
+     * Returns {@code true} if this transform is affine.
      */
     @Override
-    public final Matrix clone() {
-        return Matrices.copy(this);
+    public boolean isAffine() {
+        return Matrices.isAffine(this);
     }
 
     /**

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=1667591&r1=1667590&r2=1667591&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] Wed Mar 18 17:09:19 2015
@@ -23,13 +23,15 @@ import org.apache.sis.internal.referenci
 import org.junit.Test;
 import org.apache.sis.test.DependsOn;
 
+import static org.junit.Assert.*;
+
 
 /**
  * Tests the {@link CopyTransform} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.5
+ * @version 0.6
  * @module
  */
 @DependsOn({
@@ -52,14 +54,23 @@ public final strictfp class CopyTransfor
     }
 
     /**
+     * Initializes the {@link #transform} field to a {@link CopyTransform} instance created
+     * from the given argument. Then verifies that the matrix is consistent with the transform.
+     */
+    private void create(final int srcDim, final int... indices) {
+        transform = new CopyTransform(srcDim, indices);
+        assertEquals(transform, CopyTransform.create(((LinearTransform) transform).getMatrix()));
+        validate();
+    }
+
+    /**
      * Tests an identity transform.
      *
      * @throws TransformException should never happen.
      */
     @Test
     public void testIdentity() throws TransformException {
-        transform = new CopyTransform(3, 0, 1, 2);
-        validate();
+        create(3, 0, 1, 2);
         verifyParameters(Affine.getProvider(3, 3, true).getParameters(), null);
         verifyIsIdentity(true);
 
@@ -78,8 +89,7 @@ public final strictfp class CopyTransfor
      */
     @Test
     public void test3D() throws TransformException {
-        transform = new CopyTransform(3, 2, 1, 0);
-        validate();
+        create(3, 2, 1, 0);
         verifyIsIdentity(false);
 
         final double[] source = generateRandomCoordinates();
@@ -102,9 +112,8 @@ public final strictfp class CopyTransfor
      */
     @Test
     public void test3Dto2D() throws TransformException {
-        transform = new CopyTransform(3, 0, 1);
         isInverseTransformSupported = false;
-        validate();
+        create(3, 0, 1);
         verifyIsIdentity(false);
 
         final double[] source = generateRandomCoordinates();



Mime
View raw message