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 {