sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1600769 - /sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/
Date Thu, 05 Jun 2014 21:16:43 GMT
Author: desruisseaux
Date: Thu Jun  5 21:16:42 2014
New Revision: 1600769

URL: http://svn.apache.org/r1600769
Log:
Ported PassThroughTransform.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform2D.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformDirect2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ProjectiveTransform2D.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java?rev=1600769&r1=1600768&r2=1600769&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
[UTF-8] Thu Jun  5 21:16:42 2014
@@ -102,7 +102,7 @@ public abstract class AbstractMathTransf
     }
 
     /**
-     * Transform the specified shape. The default implementation computes quadratic curves
+     * Transforms the specified shape. The default implementation computes quadratic curves
      * using three points for each line segment in the shape. The returned object is often
      * a {@link Path2D}, but may also be a {@link Line2D} or a {@link QuadCurve2D} if such
      * simplification is possible.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform2D.java?rev=1600769&r1=1600768&r2=1600769&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform2D.java
[UTF-8] Thu Jun  5 21:16:42 2014
@@ -60,7 +60,7 @@ final class ConcatenatedTransform2D exte
 
     /**
      * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
-     * This method is a copy of {@link AbstractMathTransform2D#transform(Point2D, Point2D)}
+     * This method is a copy of {@link AbstractMathTransform2D#transform(Point2D, Point2D)}.
      */
     @Override
     public Point2D transform(final Point2D ptSrc, final Point2D ptDst) throws TransformException
{
@@ -75,7 +75,7 @@ final class ConcatenatedTransform2D exte
     }
 
     /**
-     * Transform the specified shape.
+     * Transforms the specified shape.
      *
      * @param  shape Shape to transform.
      * @return Transformed shape.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformDirect2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformDirect2D.java?rev=1600769&r1=1600768&r2=1600769&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformDirect2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransformDirect2D.java
[UTF-8] Thu Jun  5 21:16:42 2014
@@ -69,7 +69,7 @@ final class ConcatenatedTransformDirect2
     }
 
     /**
-     * Transform the specified shape.
+     * Transforms the specified shape.
      *
      * @param  shape Shape to transform.
      * @return Transformed shape.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java?rev=1600769&r1=1600768&r2=1600769&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform.java
[UTF-8] Thu Jun  5 21:16:42 2014
@@ -16,24 +16,581 @@
  */
 package org.apache.sis.referencing.operation.transform;
 
-import org.opengis.referencing.operation.MathTransform;
+import java.util.Arrays;
+import java.io.Serializable;
+import org.opengis.geometry.DirectPosition;
 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.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.internal.referencing.DirectPositionView;
+import org.apache.sis.geometry.GeneralDirectPosition;
+import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.util.Utilities;
+
+import static org.apache.sis.util.ArgumentChecks.*;
+
+
+/**
+ * Transform which passes through a subset of ordinates to another transform.
+ * This allows transforms to operate on a subset of ordinates.
+ *
+ * <span class="note"><b>Example:</b> giving (<var>latitude</var>,
<var>longitude</var>, <var>height</var>) coordinates,
+ * {@code PassThroughTransform} can convert the height values from feet to meters without
affecting the latitude and
+ * longitude values.</span>
+ *
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.5 (derived from geotk-1.2)
+ * @version 0.5
+ * @module
+ */
+public class PassThroughTransform extends AbstractMathTransform implements Serializable {
+    /**
+     * Serial number for inter-operability with different versions.
+     */
+    private static final long serialVersionUID = -1673997634240223449L;
 
-class PassThroughTransform {
-    int firstAffectedOrdinate;
+    /**
+     * Index of the first affected ordinate.
+     */
+    final int firstAffectedOrdinate;
 
-    int numTrailingOrdinates;
+    /**
+     * Number of unaffected ordinates after the affected ones.
+     * Always 0 when used through the strict OpenGIS API.
+     */
+    final int numTrailingOrdinates;
 
-    MathTransform subTransform;
+    /**
+     * The sub transform.
+     *
+     * @see #getSubTransform()
+     */
+    final MathTransform subTransform;
 
+    /**
+     * The inverse transform. This field will be computed only when needed,
+     * but is part of serialization in order to avoid rounding error.
+     */
+    PassThroughTransform inverse;
+
+    /**
+     * Creates a pass through transform.
+     *
+     * @param firstAffectedOrdinate Index of the first affected ordinate.
+     * @param subTransform          The sub transform.
+     * @param numTrailingOrdinates  Number of trailing ordinates to pass through.
+     *
+     * @see #create(int, MathTransform, int)
+     */
+    protected PassThroughTransform(final int firstAffectedOrdinate,
+                                   final MathTransform subTransform,
+                                   final int numTrailingOrdinates)
+    {
+        ensurePositive("firstAffectedOrdinate", firstAffectedOrdinate);
+        ensurePositive("numTrailingOrdinates",  numTrailingOrdinates);
+        if (subTransform instanceof PassThroughTransform) {
+            final PassThroughTransform passThrough = (PassThroughTransform) subTransform;
+            this.firstAffectedOrdinate = passThrough.firstAffectedOrdinate + firstAffectedOrdinate;
+            this.numTrailingOrdinates  = passThrough.numTrailingOrdinates  + numTrailingOrdinates;
+            this.subTransform          = passThrough.subTransform;
+        }  else {
+            this.firstAffectedOrdinate = firstAffectedOrdinate;
+            this.numTrailingOrdinates  = numTrailingOrdinates;
+            this.subTransform          = subTransform;
+        }
+    }
+
+    /**
+     * Creates a transform which passes through a subset of ordinates to another transform.
+     * This method returns a transform having the following dimensions:
+     *
+     * {@preformat java
+     *     Source: firstAffectedOrdinate + subTransform.getSourceDimensions() + numTrailingOrdinates
+     *     Target: firstAffectedOrdinate + subTransform.getTargetDimensions() + numTrailingOrdinates
+     * }
+     *
+     * Affected ordinates will range from {@code firstAffectedOrdinate} inclusive to
+     * {@code dimTarget - numTrailingOrdinates} exclusive.
+     *
+     * @param  firstAffectedOrdinate Index of the first affected ordinate.
+     * @param  subTransform          The sub transform.
+     * @param  numTrailingOrdinates  Number of trailing ordinates to pass through.
+     * @return A pass through transform.
+     */
     public static MathTransform create(final int firstAffectedOrdinate,
                                        final MathTransform subTransform,
                                        final int numTrailingOrdinates)
     {
-        throw new UnsupportedOperationException();
+        ensurePositive("firstAffectedOrdinate", firstAffectedOrdinate);
+        ensurePositive("numTrailingOrdinates",  numTrailingOrdinates);
+        if (firstAffectedOrdinate == 0 && numTrailingOrdinates == 0) {
+            return subTransform;
+        }
+        /*
+         * Optimizes the "Identity transform" case.
+         */
+        if (subTransform.isIdentity()) {
+            final int dimension = subTransform.getSourceDimensions();
+            if (dimension == subTransform.getTargetDimensions()) {
+                return IdentityTransform.create(firstAffectedOrdinate + dimension + numTrailingOrdinates);
+            }
+        }
+        /*
+         * Special case for transformation backed by a matrix. Is is possible to use a
+         * new matrix for such transform, instead of wrapping the sub-transform into a
+         * PassThroughTransform object. It is faster and easier to concatenate.
+         */
+        Matrix matrix = MathTransforms.getMatrix(subTransform);
+        if (matrix != null) {
+            matrix = expand(MatrixSIS.castOrCopy(matrix), firstAffectedOrdinate, numTrailingOrdinates,
1);
+            return MathTransforms.linear(matrix);
+        }
+        /*
+         * Constructs the general PassThroughTransform object. An optimization is done right
in
+         * the constructor for the case where the sub-transform is already a PassThroughTransform.
+         */
+        int dim = subTransform.getSourceDimensions();
+        if (subTransform.getTargetDimensions() == dim) {
+            dim += firstAffectedOrdinate + numTrailingOrdinates;
+            if (dim == 2) {
+                return new PassThroughTransform2D(firstAffectedOrdinate, subTransform, numTrailingOrdinates);
+            }
+        }
+        return new PassThroughTransform(firstAffectedOrdinate, subTransform, numTrailingOrdinates);
     }
 
+    /**
+     * If the given matrix to be concatenated to this transform, can be concatenated to the
+     * sub-transform instead, returns the matrix to be concatenated to the sub-transform.
+     * Otherwise returns {@code null}.
+     *
+     * <p>This method assumes that the matrix size is compatible with this transform
source dimension.
+     * It is caller responsibility to verify this condition.</p>
+     */
     final Matrix toSubMatrix(final Matrix matrix) {
-        throw new UnsupportedOperationException();
+        final int numRow = matrix.getNumRow();
+        final int numCol = matrix.getNumCol();
+        if (numRow != numCol) {
+            // Current implementation requires a square matrix.
+            return null;
+        }
+        final int subDim = subTransform.getSourceDimensions();
+        final MatrixSIS sub = Matrices.createIdentity(subDim + 1);
+        /*
+         * Ensure that every dimensions which are scaled by the affine transform are one
+         * of the dimensions modified by the sub-transform, and not any other dimension.
+         */
+        for (int j=numRow; --j>=0;) {
+            final int sj = j - firstAffectedOrdinate;
+            for (int i=numCol; --i>=0;) {
+                final double element = matrix.getElement(j, i);
+                if (sj >= 0 && sj < subDim) {
+                    final int si;
+                    final boolean pass;
+                    if (i == numCol-1) { // Translation term (last column)
+                        si = subDim;
+                        pass = true;
+                    } else { // Any term other than translation.
+                        si = i - firstAffectedOrdinate;
+                        pass = (si >= 0 && si < subDim);
+                    }
+                    if (pass) {
+                        sub.setElement(sj, si, element);
+                        continue;
+                    }
+                }
+                if (element != (i == j ? 1 : 0)) {
+                    // Found a dimension which perform some scaling or translation.
+                    return null;
+                }
+            }
+        }
+        return sub;
+    }
+
+    /**
+     * Returns the sub transform.
+     *
+     * @return The sub transform.
+     */
+    public final MathTransform getSubTransform() {
+        return subTransform;
+    }
+
+    /**
+     * Ordered sequence of positive integers defining the positions in a coordinate
+     * tuple of the coordinates affected by this pass-through transform. The returned
+     * index are for source coordinates.
+     *
+     * @return The modified coordinates.
+     */
+    public final int[] getModifiedCoordinates() {
+        final int[] index = new int[subTransform.getSourceDimensions()];
+        for (int i=0; i<index.length; i++) {
+            index[i] = i + firstAffectedOrdinate;
+        }
+        return index;
+    }
+
+    /**
+     * Gets the dimension of input points.
+     *
+     * @return {@inheritDoc}
+     */
+    @Override
+    public final int getSourceDimensions() {
+        return firstAffectedOrdinate + subTransform.getSourceDimensions() + numTrailingOrdinates;
+    }
+
+    /**
+     * Gets the dimension of output points.
+     *
+     * @return {@inheritDoc}
+     */
+    @Override
+    public final int getTargetDimensions() {
+        return firstAffectedOrdinate + subTransform.getTargetDimensions() + numTrailingOrdinates;
+    }
+
+    /**
+     * Tests whether this transform does not move any points.
+     *
+     * @return {@inheritDoc}
+     */
+    @Override
+    public boolean isIdentity() {
+        return subTransform.isIdentity();
+    }
+
+    /**
+     * Transforms a single coordinate in a list of ordinal values, and opportunistically
+     * computes the transform derivative if requested.
+     *
+     * @return {@inheritDoc}
+     * @throws TransformException If the {@linkplain #subTransform sub-transform} failed.
+     */
+    @Override
+    public Matrix transform(final double[] srcPts, final int srcOff,
+                            final double[] dstPts, final int dstOff,
+                            final boolean derivate) throws TransformException
+    {
+        Matrix derivative = null;
+        if (derivate) {
+            derivative = derivative(new DirectPositionView(srcPts, srcOff, getSourceDimensions()));
+        }
+        if (dstPts != null) {
+            transform(srcPts, srcOff, dstPts, dstOff, 1);
+        }
+        return derivative;
+    }
+
+    /**
+     * Transforms many coordinates in a list of ordinal values.
+     *
+     * @throws TransformException If the {@linkplain #getSubTransform() sub-transform} failed.
+     */
+    @Override
+    public void transform(double[] srcPts, int srcOff, final double[] dstPts, int dstOff,
int numPts)
+            throws TransformException
+    {
+        final int subDimSource = subTransform.getSourceDimensions();
+        final int subDimTarget = subTransform.getTargetDimensions();
+        int srcStep = numTrailingOrdinates;
+        int dstStep = numTrailingOrdinates;
+        if (srcPts == dstPts) {
+            final int add = firstAffectedOrdinate + numTrailingOrdinates;
+            final int dimSource = subDimSource + add;
+            final int dimTarget = subDimTarget + add;
+            switch (IterationStrategy.suggest(srcOff, dimSource, dstOff, dimTarget, numPts))
{
+                case ASCENDING: {
+                    break;
+                }
+                case DESCENDING: {
+                    srcOff += (numPts - 1) * dimSource;
+                    dstOff += (numPts - 1) * dimTarget;
+                    srcStep -= 2*dimSource;
+                    dstStep -= 2*dimTarget;
+                    break;
+                }
+                default: {
+                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*dimSource);
+                    srcOff = 0;
+                }
+            }
+        }
+        while (--numPts >= 0) {
+            System.arraycopy(      srcPts, srcOff,
+                                   dstPts, dstOff,   firstAffectedOrdinate);
+            subTransform.transform(srcPts, srcOff += firstAffectedOrdinate,
+                                   dstPts, dstOff += firstAffectedOrdinate, 1);
+            System.arraycopy(      srcPts, srcOff += subDimSource,
+                                   dstPts, dstOff += subDimTarget, numTrailingOrdinates);
+            srcOff += srcStep;
+            dstOff += dstStep;
+        }
+    }
+
+    /**
+     * Transforms many coordinates in a list of ordinal values.
+     *
+     * @throws TransformException If the {@linkplain #getSubTransform() sub-transform} failed.
+     */
+    @Override
+    public void transform(float[] srcPts, int srcOff, final float[] dstPts, int dstOff, int
numPts)
+            throws TransformException
+    {
+        final int subDimSource = subTransform.getSourceDimensions();
+        final int subDimTarget = subTransform.getTargetDimensions();
+        int srcStep = numTrailingOrdinates;
+        int dstStep = numTrailingOrdinates;
+        if (srcPts == dstPts) {
+            final int add = firstAffectedOrdinate + numTrailingOrdinates;
+            final int dimSource = subDimSource + add;
+            final int dimTarget = subDimTarget + add;
+            switch (IterationStrategy.suggest(srcOff, dimSource, dstOff, dimTarget, numPts))
{
+                case ASCENDING: {
+                    break;
+                }
+                case DESCENDING: {
+                    srcOff += (numPts - 1) * dimSource;
+                    dstOff += (numPts - 1) * dimTarget;
+                    srcStep -= 2*dimSource;
+                    dstStep -= 2*dimTarget;
+                    break;
+                }
+                default: {
+                    srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*dimSource);
+                    srcOff = 0;
+                }
+            }
+        }
+        while (--numPts >= 0) {
+            System.arraycopy(      srcPts, srcOff,
+                                   dstPts, dstOff,   firstAffectedOrdinate);
+            subTransform.transform(srcPts, srcOff += firstAffectedOrdinate,
+                                   dstPts, dstOff += firstAffectedOrdinate, 1);
+            System.arraycopy(      srcPts, srcOff += subDimSource,
+                                   dstPts, dstOff += subDimTarget, numTrailingOrdinates);
+            srcOff += srcStep;
+            dstOff += dstStep;
+        }
+    }
+
+    /**
+     * Transforms many coordinates in a list of ordinal values.
+     *
+     * @throws TransformException If the {@linkplain #getSubTransform() sub-transform} failed.
+     */
+    @Override
+    public void transform(final double[] srcPts, int srcOff, final float[] dstPts, int dstOff,
int numPts)
+            throws TransformException
+    {
+        final int subDimSource = subTransform.getSourceDimensions();
+        final int subDimTarget = subTransform.getTargetDimensions();
+        while (--numPts >= 0) {
+            for (int i=0; i<firstAffectedOrdinate; i++) {
+                dstPts[dstOff++] = (float) srcPts[srcOff++];
+            }
+            subTransform.transform(srcPts, srcOff, dstPts, dstOff, 1);
+            srcOff += subDimSource;
+            dstOff += subDimTarget;
+            for (int i=0; i<numTrailingOrdinates; i++) {
+                dstPts[dstOff++] = (float) srcPts[srcOff++];
+            }
+        }
+    }
+
+    /**
+     * Transforms many coordinates in a list of ordinal values.
+     *
+     * @throws TransformException If the {@linkplain #getSubTransform() sub-transform} failed.
+     */
+    @Override
+    public void transform(final float[] srcPts, int srcOff, final double[] dstPts, int dstOff,
int numPts)
+            throws TransformException
+    {
+        final int subDimSource = subTransform.getSourceDimensions();
+        final int subDimTarget = subTransform.getTargetDimensions();
+        while (--numPts >= 0) {
+            for (int i=0; i<firstAffectedOrdinate; i++) {
+                dstPts[dstOff++] = srcPts[srcOff++];
+            }
+            subTransform.transform(srcPts, srcOff, dstPts, dstOff, 1);
+            srcOff += subDimSource;
+            dstOff += subDimTarget;
+            for (int i=0; i<numTrailingOrdinates; i++) {
+                dstPts[dstOff++] = srcPts[srcOff++];
+            }
+        }
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     *
+     * @return {@inheritDoc}
+     * @throws TransformException If the {@linkplain #getSubTransform() sub-transform} failed.
+     */
+    @Override
+    public Matrix derivative(final DirectPosition point) throws TransformException {
+        final int nSkipped = firstAffectedOrdinate + numTrailingOrdinates;
+        final int transDim = subTransform.getSourceDimensions();
+        ensureDimensionMatches("point", transDim + nSkipped, point);
+        final GeneralDirectPosition subPoint = new GeneralDirectPosition(transDim);
+        for (int i=0; i<transDim; i++) {
+            subPoint.ordinates[i] = point.getOrdinate(i + firstAffectedOrdinate);
+        }
+        return expand(MatrixSIS.castOrCopy(subTransform.derivative(subPoint)),
+                firstAffectedOrdinate, numTrailingOrdinates, 0);
+    }
+
+    /**
+     * Creates a pass through transform from a matrix.  This method is invoked when the
+     * sub-transform can be expressed as a matrix. It is also invoked for computing the
+     * matrix returned by {@link #derivative}.
+     *
+     * @param subMatrix The sub-transform as a matrix.
+     * @param firstAffectedOrdinate Index of the first affected ordinate.
+     * @param numTrailingOrdinates Number of trailing ordinates to pass through.
+     * @param affine 0 if the matrix do not contains translation terms, or 1 if
+     *        the matrix is an affine transform with translation terms.
+     */
+    private static Matrix expand(final MatrixSIS subMatrix,
+                                 final int firstAffectedOrdinate,
+                                 final int numTrailingOrdinates,
+                                 final int affine)
+    {
+        final int nSkipped  = firstAffectedOrdinate + numTrailingOrdinates;
+        final int numSubRow = subMatrix.getNumRow() - affine;
+        final int numSubCol = subMatrix.getNumCol() - affine;
+        final int numRow    = numSubRow + (nSkipped + affine);
+        final int numCol    = numSubCol + (nSkipped + affine);
+        final Number[] elements = new Number[numRow * numCol]; // Matrix elements as row
major (column index varies faster).
+        Arrays.fill(elements, Integer.valueOf(0));
+        /*                      ┌                  ┐
+         *  Set UL part to 1:   │ 1  0             │
+         *                      │ 0  1             │
+         *                      │                  │
+         *                      │                  │
+         *                      │                  │
+         *                      └                  ┘
+         */
+        final Integer ONE = 1;
+        for (int j=0; j<firstAffectedOrdinate; j++) {
+            elements[j*numCol + j] = ONE;
+        }
+        /*                      ┌                  ┐
+         *  Set central part:   │ 1  0  0  0  0  0 │
+         *                      │ 0  1  0  0  0  0 │
+         *                      │ 0  0  ?  ?  ?  0 │
+         *                      │ 0  0  ?  ?  ?  0 │
+         *                      │                  │
+         *                      └                  ┘
+         */
+        for (int j=0; j<numSubRow; j++) {
+            for (int i=0; i<numSubCol; i++) {
+                /*
+                 * We need to store the elements as Number, not as double, for giving to
the matrix
+                 * a chance to preserve the extra precision provided by DoubleDouble numbers.
+                 */
+                elements[(j + firstAffectedOrdinate) * numCol    // Contribution of row index
+                       + (i + firstAffectedOrdinate)]            // Contribution of column
index
+                       = subMatrix.getNumber(j, i);
+            }
+        }
+        /*                      ┌                  ┐
+         *  Set LR part to 1:   │ 1  0  0  0  0  0 │
+         *                      │ 0  1  0  0  0  0 │
+         *                      │ 0  0  ?  ?  ?  0 │
+         *                      │ 0  0  ?  ?  ?  0 │
+         *                      │ 0  0  0  0  0  1 │
+         *                      └                  ┘
+         */
+        final int offset    = numSubCol - numSubRow;
+        final int numRowOut = numSubRow + nSkipped;
+        final int numColOut = numSubCol + nSkipped;
+        for (int j=numRowOut - numTrailingOrdinates; j<numRowOut; j++) {
+            elements[j * numCol + (j + offset)] = ONE;
+        }
+        if (affine != 0) {
+            // Copy the translation terms in the last column.
+            for (int j=0; j<numSubRow; j++) {
+                elements[(j + firstAffectedOrdinate) * numCol + numColOut] = subMatrix.getNumber(j,
numSubCol);
+            }
+            // Copy the last row as a safety, but it should contains only 0.
+            for (int i=0; i<numSubCol; i++) {
+                elements[numRowOut * numCol + (i + firstAffectedOrdinate)] = subMatrix.getNumber(numSubRow,
i);
+            }
+            // Copy the lower right corner, which should contains only 1.
+            elements[numRowOut * numCol + numColOut] = subMatrix.getNumber(numSubRow, numSubCol);
+        }
+        return Matrices.create(numRow, numCol, elements);
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     *
+     * @return {@inheritDoc}
+     * @throws NoninvertibleTransformException If the {@linkplain #getSubTransform() sub-transform}
is not invertible.
+     */
+    @Override
+    public synchronized MathTransform inverse() throws NoninvertibleTransformException {
+        if (inverse == null) {
+            inverse = new PassThroughTransform(
+                    firstAffectedOrdinate, subTransform.inverse(), numTrailingOrdinates);
+            inverse.inverse = this;
+        }
+        return inverse;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return {@inheritDoc}
+     */
+    @Override
+    protected int computeHashCode() {
+        // Note that numTrailingOrdinates is related to source and
+        // target dimensions, which are computed by the super-class.
+        return super.computeHashCode() ^ (subTransform.hashCode() + firstAffectedOrdinate);
+    }
+
+    /**
+     * Compares the specified object with this math transform for equality.
+     *
+     * @return {@inheritDoc}
+     */
+    @Override
+    public boolean equals(final Object object, final ComparisonMode mode) {
+        if (object == this) {
+            return true;
+        }
+        if (super.equals(object, mode)) {
+            final PassThroughTransform that = (PassThroughTransform) object;
+            return this.firstAffectedOrdinate == that.firstAffectedOrdinate &&
+                   this.numTrailingOrdinates  == that.numTrailingOrdinates  &&
+                   Utilities.deepEquals(this.subTransform, that.subTransform, mode);
+        }
+        return false;
+    }
+
+    /**
+     * Formats the inner part of a <cite>Well Known Text</cite> version 1 (WKT
1) element.
+     *
+     * @param  formatter The formatter to use.
+     * @return The WKT element name, which is {@code "PassThrough_MT"}.
+     */
+    @Override
+    public String formatTo(final Formatter formatter) {
+        formatter.append(firstAffectedOrdinate);
+        if (numTrailingOrdinates != 0) {
+            formatter.append(numTrailingOrdinates);
+            formatter.setInvalidWKT(PassThroughTransform.class, null);
+        }
+        formatter.append(subTransform);
+        return "PassThrough_MT";
     }
 }

Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform2D.java?rev=1600769&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform2D.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PassThroughTransform2D.java
[UTF-8] Thu Jun  5 21:16:42 2014
@@ -0,0 +1,107 @@
+/*
+ * 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.awt.Shape;
+import java.awt.geom.Point2D;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.apache.sis.geometry.DirectPosition2D;
+
+
+/**
+ * A pass-through transform in the two-dimensional case.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5 (derived from geotk-3.00)
+ * @version 0.5
+ * @module
+ */
+final class PassThroughTransform2D extends PassThroughTransform implements MathTransform2D
{
+    /**
+     * Serial number for inter-operability with different versions.
+     */
+    private static final long serialVersionUID = -5637760772953973708L;
+
+    /**
+     * Creates a pass through transform.
+     *
+     * @param firstAffectedOrdinate Index of the first affected ordinate.
+     * @param subTransform The sub transform.
+     * @param numTrailingOrdinates Number of trailing ordinates to pass through.
+     */
+    PassThroughTransform2D(final int firstAffectedOrdinate,
+                           final MathTransform subTransform,
+                           final int numTrailingOrdinates)
+    {
+        super(firstAffectedOrdinate, subTransform, numTrailingOrdinates);
+    }
+
+    /**
+     * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
+     * Implementation is similar but not identical to {@link AbstractMathTransform2D#transform(Point2D,
Point2D)}.
+     * The difference is in the {@code transform(…)} method invoked.
+     */
+    @Override
+    public Point2D transform(final Point2D ptSrc, final Point2D ptDst) throws TransformException
{
+        final double[] ord = new double[] {ptSrc.getX(), ptSrc.getY()};
+        transform(ord, 0, ord, 0, 1);
+        if (ptDst != null) {
+            ptDst.setLocation(ord[0], ord[1]);
+            return ptDst;
+        } else {
+            return new Point2D.Double(ord[0], ord[1]);
+        }
+    }
+
+    /**
+     * Transforms the specified shape.
+     */
+    @Override
+    public Shape createTransformedShape(final Shape shape) throws TransformException {
+        return AbstractMathTransform2D.createTransformedShape(this, shape, null, null, false);
+    }
+
+    /**
+     * Gets the derivative of this transform at a point.
+     *
+     * @return {@inheritDoc}
+     * @throws TransformException If the {@linkplain #getSubTransform() sub-transform} failed.
+     */
+    @Override
+    public Matrix derivative(final Point2D point) throws TransformException {
+        return super.derivative(point instanceof DirectPosition ?
+                (DirectPosition) point : new DirectPosition2D(point.getX(), point.getY()));
+    }
+
+    /**
+     * Creates the inverse transform of this object.
+     */
+    @Override
+    public synchronized MathTransform2D inverse() throws NoninvertibleTransformException
{
+        if (inverse == null) {
+            inverse = new PassThroughTransform2D(
+                    firstAffectedOrdinate, subTransform.inverse(), numTrailingOrdinates);
+            inverse.inverse = this;
+        }
+        return (MathTransform2D) inverse;
+    }
+}

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

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

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=1600769&r1=1600768&r2=1600769&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] Thu Jun  5 21:16:42 2014
@@ -42,18 +42,19 @@ final class ProjectiveTransform2D extend
     /**
      * Creates projective transform from a matrix.
      */
-    public ProjectiveTransform2D(final Matrix matrix) {
+    ProjectiveTransform2D(final Matrix matrix) {
         super(matrix);
     }
 
     /**
      * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}.
-     * This method is a copy of {@link AbstractMathTransform2D#transform(Point2D, Point2D)}
+     * Implementation is similar but not identical to {@link AbstractMathTransform2D#transform(Point2D,
Point2D)}.
+     * The difference is in the {@code transform(…)} method invoked.
      */
     @Override
     public Point2D transform(final Point2D ptSrc, final Point2D ptDst) {
         final double[] ord = new double[] {ptSrc.getX(), ptSrc.getY()};
-        transform(ord, 0, ord, 0, false);
+        transform(ord, 0, ord, 0, 1);
         if (ptDst != null) {
             ptDst.setLocation(ord[0], ord[1]);
             return ptDst;
@@ -63,7 +64,7 @@ final class ProjectiveTransform2D extend
     }
 
     /**
-     * Transform the specified shape.
+     * Transforms the specified shape.
      */
     @Override
     public Shape createTransformedShape(final Shape shape) throws TransformException {



Mime
View raw message