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();
|