Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -25,6 +25,7 @@ import org.opengis.referencing.operation
import org.opengis.referencing.operation.Matrix;
import org.apache.sis.referencing.operation.matrix.Matrix2;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.ContextualParameters;
import org.apache.sis.internal.referencing.provider.PolarStereographicA;
import org.apache.sis.internal.referencing.provider.PolarStereographicB;
import org.apache.sis.internal.referencing.provider.PolarStereographicC;
@@ -207,7 +208,7 @@ public class PolarStereographic extends
*
* In the spherical case, should give ρ == 2.
*/
- ρ = verbatim(2 / sqrt(pow(1+excentricity, 1+excentricity) * pow(1-excentricity, 1-excentricity)));
+ ρ = verbatim(2 / sqrt(pow(1+eccentricity, 1+eccentricity) * pow(1-eccentricity, 1-eccentricity)));
ρF = null;
} else {
/*
@@ -229,19 +230,19 @@ public class PolarStereographic extends
*/
final double sinφ1 = sin(φ1);
final double mF = initializer.scaleAtφ(sinφ1, cos(φ1));
- ρ = verbatim(mF / expOfNorthing(φ1, excentricity*sinφ1));
+ ρ = verbatim(mF / expOfNorthing(φ1, eccentricity*sinφ1));
ρF = (variant == C) ? verbatim(-mF) : null;
}
/*
* At this point, all parameters have been processed. Now process to their
* validation and the initialization of (de)normalize affine transforms.
*/
- final MatrixSIS denormalize = context.getMatrix(false);
+ final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
denormalize.convertBefore(0, ρ, null);
denormalize.convertBefore(1, ρ, ρF);
if (isNorth) {
final Number reverseSign = verbatim(-1);
- final MatrixSIS normalize = context.getMatrix(true);
+ final MatrixSIS normalize = context.getMatrix(ContextualParameters.MatrixRole.NORMALIZATION);
normalize .convertAfter (1, reverseSign, null);
denormalize.convertBefore(1, reverseSign, null);
}
@@ -269,7 +270,7 @@ public class PolarStereographic extends
@Override
public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
PolarStereographic kernel = this;
- if (excentricity == 0) {
+ if (eccentricity == 0) {
kernel = new Spherical(this);
}
return context.completeTransform(factory, kernel);
@@ -304,7 +305,7 @@ public class PolarStereographic extends
* The next step is to compute ρ = 2⋅a⋅k₀⋅t / …, but those steps are
* applied by the denormalization matrix and shall not be done here.
*/
- final double t = expOfNorthing(φ, excentricity*sinφ);
+ final double t = expOfNorthing(φ, eccentricity*sinφ);
final double x = t * sinθ;
final double y = t * cosθ;
if (dstPts != null) {
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -25,6 +25,7 @@ import org.opengis.referencing.operation
import org.opengis.referencing.operation.OperationMethod;
import org.apache.sis.referencing.operation.matrix.Matrix2;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.ContextualParameters;
import org.apache.sis.internal.referencing.provider.TransverseMercatorSouth;
import org.apache.sis.internal.util.DoubleDouble;
import org.apache.sis.parameter.Parameters;
@@ -72,7 +73,7 @@ public class TransverseMercator extends
/**
* Coefficients in the series expansion of the forward projection,
- * depending only on {@linkplain #excentricity excentricity} value.
+ * depending only on {@linkplain #eccentricity eccentricity} value.
* The series expansion is of the following form:
*
* <blockquote>cf₂⋅f(2θ) + cf₄⋅f(4θ) + cf₆⋅f(6θ) + cf₈⋅f(8θ)</blockquote>
@@ -164,7 +165,7 @@ public class TransverseMercator extends
* NOTE: the EPSG documentation makes special cases for φ₀ = 0 or ±π/2. This is not
* needed here; we verified that the code below produces naturally the expected values.
*/
- final double Q = asinh(tan(φ0)) - excentricity * atanh(excentricity * sin(φ0));
+ final double Q = asinh(tan(φ0)) - eccentricity * atanh(eccentricity * sin(φ0));
final double β = atan(sinh(Q));
final DoubleDouble M0 = new DoubleDouble();
M0.value = cf8 * sin(8*β)
@@ -188,7 +189,7 @@ public class TransverseMercator extends
* - Multiply by the scale factor (done by the super-class constructor).
* - Add false easting and false northing (done by the super-class constructor).
*/
- final MatrixSIS denormalize = context.getMatrix(false);
+ final MatrixSIS denormalize = context.getMatrix(ContextualParameters.MatrixRole.DENORMALIZATION);
denormalize.convertBefore(0, B, null);
denormalize.convertBefore(1, B, M0);
/*
@@ -216,7 +217,7 @@ public class TransverseMercator extends
* 'n' value at serialization time.
*/
final DoubleDouble t = new DoubleDouble(1, 0);
- t.subtract(excentricitySquared, 0);
+ t.subtract(eccentricitySquared, 0);
t.sqrt();
t.ratio_1m_1p();
computeCoefficients(t.doubleValue());
@@ -240,7 +241,7 @@ public class TransverseMercator extends
*
* As much as possible, b/a should be computed from the map projection parameters.
* However if those parameters are not available anymore, then they can be computed
- * from the excentricity as:
+ * from the eccentricity as:
*
* <blockquote>b/a = √(1 - ℯ²)</blockquote>
*
@@ -294,7 +295,7 @@ public class TransverseMercator extends
@Override
public MathTransform createMapProjection(final MathTransformFactory factory) throws FactoryException {
TransverseMercator kernel = this;
- if (excentricity == 0) {
+ if (eccentricity == 0) {
kernel = new Spherical(this);
}
return context.completeTransform(factory, kernel);
@@ -316,8 +317,8 @@ public class TransverseMercator extends
final double λ = srcPts[srcOff ];
final double φ = srcPts[srcOff+1];
final double sinλ = sin(λ);
- final double ℯsinφ = sin(φ) * excentricity;
- final double Q = asinh(tan(φ)) - atanh(ℯsinφ) * excentricity;
+ final double ℯsinφ = sin(φ) * eccentricity;
+ final double Q = asinh(tan(φ)) - atanh(ℯsinφ) * eccentricity;
final double coshQ = cosh(Q);
final double η0 = atanh(sinλ / coshQ);
/*
@@ -418,7 +419,7 @@ public class TransverseMercator extends
final double sqrt1_thQchη0 = sqrt(1 - (tanhQ * tanhQ) * (coshη0 * coshη0)); //-- Qη0
//-- dQ_dλ = 0;
- final double dQ_dφ = 1 / cosφ - excentricitySquared * cosφ / (1 - ℯsinφ * ℯsinφ);
+ final double dQ_dφ = 1 / cosφ - eccentricitySquared * cosφ / (1 - ℯsinφ * ℯsinφ);
final double dη0_dλ = cosλ * coshQ / cosh2Q_sin2λ;
final double dη0_dφ = - dQ_dφ * sinλ * sinhQ / cosh2Q_sin2λ;
@@ -542,10 +543,12 @@ public class TransverseMercator extends
final double Q = asinh(tan(β));
/*
* Following usually converges in 4 iterations.
+ * The first iteration is unrolled.
*/
- double Qp = Q, p = 0;
- for (int i=0; i<MAXIMUM_ITERATIONS; i++) {
- final double c = excentricity * atanh(excentricity * tanh(Qp));
+ double p = eccentricity * atanh(eccentricity * tanh(Q));
+ double Qp = Q + p;
+ for (int it=0; it<MAXIMUM_ITERATIONS; it++) {
+ final double c = eccentricity * atanh(eccentricity * tanh(Qp));
Qp = Q + c;
if (abs(c - p) <= ITERATION_TOLERANCE) {
dstPts[dstOff ] = asin(tanh(η0) / cos(β));
@@ -558,6 +561,8 @@ public class TransverseMercator extends
}
+
+
/**
* Provides the transform equations for the spherical case of the Transverse Mercator projection.
*
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -16,9 +16,12 @@
*/
package org.apache.sis.referencing.operation.transform;
+import java.io.Serializable;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.internal.referencing.provider.Affine;
import org.apache.sis.util.ComparisonMode;
@@ -37,13 +40,23 @@ import org.apache.sis.util.resources.Err
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.6
- * @version 0.6
+ * @version 0.7
* @module
*/
-@SuppressWarnings("CloneInNonCloneableClass")
-abstract class AbstractLinearTransform extends AbstractMathTransform
- implements LinearTransform, Matrix // Not Cloneable, despite the clone() method.
-{
+@SuppressWarnings("CloneInNonCloneableClass") // Intentionally not Cloneable despite the clone() method.
+abstract class AbstractLinearTransform extends AbstractMathTransform implements LinearTransform, Matrix, Serializable {
+ /**
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = -4649708313541868599L;
+
+ /**
+ * The inverse transform, or {@code null} if not yet created.
+ * 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.
+ */
+ MathTransform inverse;
+
/**
* Constructs a transform.
*/
@@ -94,6 +107,29 @@ abstract class AbstractLinearTransform e
}
/**
+ * Creates the inverse transform of this object.
+ */
+ @Override
+ public synchronized MathTransform inverse() throws NoninvertibleTransformException {
+ if (inverse == null) {
+ /*
+ * Should never be the identity transform at this point (except during tests) because
+ * MathTransforms.linear(…) should never instantiate this class in the identity case.
+ * But we check anyway as a paranoiac safety.
+ */
+ if (isIdentity()) {
+ inverse = this;
+ } else {
+ inverse = MathTransforms.linear(Matrices.inverse(this));
+ if (inverse instanceof AbstractLinearTransform) {
+ ((AbstractLinearTransform) inverse).inverse = this;
+ }
+ }
+ }
+ return inverse;
+ }
+
+ /**
* Returns the parameter descriptors for this math transform.
*
* @return {@inheritDoc}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -21,12 +21,14 @@ import java.util.Arrays;
import java.io.Serializable;
import javax.measure.unit.SI;
import javax.measure.unit.NonSI;
+import org.opengis.util.FactoryException;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.opengis.referencing.operation.OperationMethod;
@@ -79,7 +81,7 @@ import static org.apache.sis.util.Argume
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.5
- * @version 0.6
+ * @version 0.7
* @module
*
* @see DefaultMathTransformFactory
@@ -234,8 +236,8 @@ public abstract class AbstractMathTransf
* @param expected The expected dimension.
* @param dimension The wrong dimension.
*/
- static String mismatchedDimension(final String argument, final int expected, final int dimension) {
- return Errors.format(Errors.Keys.MismatchedDimension_3, argument, expected, dimension);
+ static MismatchedDimensionException mismatchedDimension(final String argument, final int expected, final int dimension) {
+ return new MismatchedDimensionException(Errors.format(Errors.Keys.MismatchedDimension_3, argument, expected, dimension));
}
/**
@@ -341,8 +343,8 @@ public abstract class AbstractMathTransf
* @param derivate {@code true} for computing the derivative, or {@code false} if not needed.
* @return The matrix of the transform derivative at the given source position,
* or {@code null} if the {@code derivate} argument is {@code false}.
- * @throws TransformException If the point can not be transformed or if a problem occurred while calculating the
- * derivative.
+ * @throws TransformException if the point can not be transformed or
+ * if a problem occurred while calculating the derivative.
*
* @see #derivative(DirectPosition)
* @see #transform(DirectPosition, DirectPosition)
@@ -752,7 +754,7 @@ public abstract class AbstractMathTransf
final int dimSource = getSourceDimensions();
final double[] coordinate = point.getCoordinate();
if (coordinate.length != dimSource) {
- throw new MismatchedDimensionException(mismatchedDimension("point", coordinate.length, dimSource));
+ throw mismatchedDimension("point", dimSource, coordinate.length);
}
final Matrix derivative = transform(coordinate, 0, null, 0, true);
if (derivative == null) {
@@ -778,9 +780,9 @@ public abstract class AbstractMathTransf
}
/**
- * Concatenates in an optimized way this math transform with the given one. A new math transform
- * is created to perform the combined transformation. The {@code applyOtherFirst} value determines
- * the transformation order as bellow:
+ * Concatenates in an optimized way this math transform with the given one.
+ * A new math transform is created to perform the combined transformation.
+ * The {@code applyOtherFirst} value determines the transformation order as bellow:
*
* <ul>
* <li>If {@code applyOtherFirst} is {@code true}, then transforming a point
@@ -802,9 +804,12 @@ public abstract class AbstractMathTransf
* @param other The math transform to apply.
* @param applyOtherFirst {@code true} if the transformation order is {@code other} followed by {@code this},
* or {@code false} if the transformation order is {@code this} followed by {@code other}.
+ * @param factory The factory which is (indirectly) invoking this method, or {@code null} if none.
* @return The combined math transform, or {@code null} if no optimized combined transform is available.
*/
- MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+ MathTransform concatenate(MathTransform other, boolean applyOtherFirst, MathTransformFactory factory)
+ throws FactoryException
+ {
return null;
}
@@ -901,6 +906,10 @@ public abstract class AbstractMathTransf
if (mode.isIgnoringMetadata()) {
return true;
}
+ /*
+ * We do not compare getParameters() because they usually duplicate the internal fields.
+ * Contextual parameters, on the other hand, typically contain new information.
+ */
return Utilities.deepEquals(this.getContextualParameters(),
that.getContextualParameters(), mode);
}
@@ -921,7 +930,7 @@ public abstract class AbstractMathTransf
* @param transforms The full chain of concatenated transforms.
* @param index The index of this transform in the {@code transforms} chain.
* @param inverse Always {@code false}, except if we are formatting the inverse transform.
- * @return Index of the last transform processed. Iteration should continue at that index + 1.
+ * @return Index of this transform in the {@code transforms} chain after processing.
*
* @see ConcatenatedTransform#getPseudoSteps()
*/
@@ -1087,14 +1096,19 @@ public abstract class AbstractMathTransf
* but with the knowledge that this transform is an inverse transform.
*/
@Override
- final int beforeFormat(final List<Object> transforms, final int index, final boolean inverse) {
- return AbstractMathTransform.this.beforeFormat(transforms, index, !inverse);
+ int beforeFormat(final List<Object> transforms, final int index, final boolean inverse) {
+ final ContextualParameters parameters = getContextualParameters();
+ if (parameters != null) {
+ return parameters.beforeFormat(transforms, index, inverse);
+ } else {
+ return AbstractMathTransform.this.beforeFormat(transforms, index, !inverse);
+ }
}
/**
* Formats the inner part of a <cite>Well Known Text</cite> version 1 (WKT 1) element.
- * If this inverse math transform has any parameter values, then this method format the
- * WKT as in the {@linkplain AbstractMathTransform#formatWKT super-class method}.
+ * If this inverse math transform has any parameter values, then this method formats
+ * the WKT as in the {@linkplain AbstractMathTransform#formatWKT super-class method}.
* Otherwise this method formats the math transform as an {@code "Inverse_MT"} entity.
*
* <div class="note"><b>Compatibility note:</b>
@@ -1111,6 +1125,7 @@ public abstract class AbstractMathTransf
WKTUtilities.appendParamMT(parameters, formatter);
return WKTKeywords.Param_MT;
} else {
+ formatter.newLine();
formatter.append((FormattableObject) AbstractMathTransform.this);
return WKTKeywords.Inverse_MT;
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -105,7 +105,7 @@ public abstract class AbstractMathTransf
}
/**
- * Implementation of {@link #transform(DirectPosition, DirectPosition)} shared by the inverse transform.
+ * Implementation of {@link #transform(Point2D, Point2D)} shared by the inverse transform.
*/
static Point2D transform(final AbstractMathTransform tr, final Point2D ptSrc, final Point2D ptDst) throws TransformException {
final double[] ord = new double[] {ptSrc.getX(), ptSrc.getY()};
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.opera
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
+import org.opengis.util.FactoryException;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.parameter.ParameterValueGroup;
@@ -27,10 +28,12 @@ import org.opengis.referencing.operation
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransform1D;
import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.apache.sis.parameter.Parameterized;
import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.internal.referencing.provider.GeocentricAffine;
import org.apache.sis.internal.metadata.WKTKeywords;
import org.apache.sis.internal.system.Semaphores;
import org.apache.sis.util.Classes;
@@ -53,7 +56,7 @@ import org.apache.sis.util.resources.Err
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.5
- * @version 0.5
+ * @version 0.7
* @module
*
* @see org.opengis.referencing.operation.MathTransformFactory#createConcatenatedTransform(MathTransform, MathTransform)
@@ -144,18 +147,21 @@ class ConcatenatedTransform extends Abst
*
* @param tr1 The first math transform.
* @param tr2 The second math transform.
- * @return The concatenated transform.
+ * @param factory The factory which is (indirectly) invoking this method, or {@code null} if none.
+ * @return The concatenated transform.
*
* @see MathTransforms#concatenate(MathTransform, MathTransform)
*/
- public static MathTransform create(MathTransform tr1, MathTransform tr2) throws MismatchedDimensionException {
+ public static MathTransform create(MathTransform tr1, MathTransform tr2, final MathTransformFactory factory)
+ throws FactoryException, MismatchedDimensionException
+ {
final int dim1 = tr1.getTargetDimensions();
final int dim2 = tr2.getSourceDimensions();
if (dim1 != dim2) {
throw new MismatchedDimensionException(Errors.format(Errors.Keys.CanNotConcatenateTransforms_2, getName(tr1),
getName(tr2)) + ' ' + Errors.format(Errors.Keys.MismatchedDimension_2, dim1, dim2));
}
- MathTransform mt = createOptimized(tr1, tr2);
+ MathTransform mt = createOptimized(tr1, tr2, factory);
if (mt != null) {
return mt;
}
@@ -188,9 +194,9 @@ class ConcatenatedTransform extends Abst
final ConcatenatedTransform ctr = (ConcatenatedTransform) candidate;
if (first) {
c1 = candidate = ctr.transform1;
- c2 = create(ctr.transform2, c2);
+ c2 = create(ctr.transform2, c2, factory);
} else {
- c1 = create(c1, ctr.transform1);
+ c1 = create(c1, ctr.transform1, factory);
c2 = candidate = ctr.transform2;
}
final int c = getStepCount(c1) + getStepCount(c2);
@@ -208,7 +214,7 @@ class ConcatenatedTransform extends Abst
* Tries again the check for optimized cases (identity, etc.), because a
* transform may have been simplified to identity as a result of the above.
*/
- mt = createOptimized(tr1, tr2);
+ mt = createOptimized(tr1, tr2, factory);
if (mt != null) {
return mt;
}
@@ -251,8 +257,12 @@ class ConcatenatedTransform extends Abst
* Tries to returns an optimized concatenation, for example by merging two affine transforms
* into a single one. If no optimized cases has been found, returns {@code null}. In the later
* case, the caller will need to create a more heavy {@link ConcatenatedTransform} instance.
+ *
+ * @param factory The factory which is (indirectly) invoking this method, or {@code null} if none.
*/
- private static MathTransform createOptimized(final MathTransform tr1, final MathTransform tr2) {
+ private static MathTransform createOptimized(final MathTransform tr1, final MathTransform tr2,
+ final MathTransformFactory factory) throws FactoryException
+ {
/*
* Trivial - but actually essential!! - check for the identity cases.
*/
@@ -268,7 +278,7 @@ class ConcatenatedTransform extends Abst
if (matrix2 != null) {
final Matrix matrix = Matrices.multiply(matrix2, matrix1);
if (Matrices.isIdentity(matrix, IDENTITY_TOLERANCE)) {
- return MathTransforms.identity(matrix.getNumRow() - 1);
+ return MathTransforms.identity(matrix.getNumRow() - 1); // Returns a cached instance.
}
/*
* NOTE: It is quite tempting to "fix rounding errors" in the matrix before to create the transform.
@@ -277,7 +287,11 @@ class ConcatenatedTransform extends Abst
* Apache SIS performs matrix operations using double-double arithmetic in the hope to get exact
* results at the 'double' accuracy, which avoid the need for a tolerance threshold.
*/
- return MathTransforms.linear(matrix);
+ if (factory != null) {
+ return factory.createAffineTransform(matrix);
+ } else {
+ return MathTransforms.linear(matrix);
+ }
}
/*
* If the second transform is a passthrough transform and all passthrough ordinates
@@ -287,9 +301,17 @@ class ConcatenatedTransform extends Abst
final PassThroughTransform candidate = (PassThroughTransform) tr2;
final Matrix sub = candidate.toSubMatrix(matrix1);
if (sub != null) {
- return PassThroughTransform.create(candidate.firstAffectedOrdinate,
- create(MathTransforms.linear(sub), candidate.subTransform),
- candidate.numTrailingOrdinates);
+ if (factory != null) {
+ return factory.createPassThroughTransform(
+ candidate.firstAffectedOrdinate,
+ factory.createConcatenatedTransform(factory.createAffineTransform(sub), candidate.subTransform),
+ candidate.numTrailingOrdinates);
+ } else {
+ return PassThroughTransform.create(
+ candidate.firstAffectedOrdinate,
+ create(MathTransforms.linear(sub), candidate.subTransform, factory),
+ candidate.numTrailingOrdinates);
+ }
}
}
}
@@ -300,20 +322,20 @@ class ConcatenatedTransform extends Abst
if (areInverse(tr1, tr2) || areInverse(tr2, tr1)) {
assert tr1.getSourceDimensions() == tr2.getTargetDimensions();
assert tr1.getTargetDimensions() == tr2.getSourceDimensions();
- return MathTransforms.identity(tr1.getSourceDimensions());
+ return MathTransforms.identity(tr1.getSourceDimensions()); // Returns a cached instance.
}
/*
* Gives a chance to AbstractMathTransform to returns an optimized object.
* The main use case is Logarithmic vs Exponential transforms.
*/
if (tr1 instanceof AbstractMathTransform) {
- final MathTransform optimized = ((AbstractMathTransform) tr1).concatenate(tr2, false);
+ final MathTransform optimized = ((AbstractMathTransform) tr1).concatenate(tr2, false, factory);
if (optimized != null) {
return optimized;
}
}
if (tr2 instanceof AbstractMathTransform) {
- final MathTransform optimized = ((AbstractMathTransform) tr2).concatenate(tr1, true);
+ final MathTransform optimized = ((AbstractMathTransform) tr2).concatenate(tr1, true, factory);
if (optimized != null) {
return optimized;
}
@@ -327,11 +349,15 @@ class ConcatenatedTransform extends Abst
*/
private static String getName(final MathTransform transform) {
if (transform instanceof AbstractMathTransform) {
- ParameterValueGroup params = ((AbstractMathTransform) transform).getParameterValues();
- if (params != null) {
- String name = params.getDescriptor().getName().getCode();
- if (name != null && !(name = name.trim()).isEmpty()) {
- return name;
+ ParameterValueGroup params;
+ params = ((AbstractMathTransform) transform).getContextualParameters();
+ if (params == null) {
+ params = ((AbstractMathTransform) transform).getParameterValues();
+ if (params != null) {
+ String name = params.getDescriptor().getName().getCode();
+ if (name != null && !(name = name.trim()).isEmpty()) {
+ return name;
+ }
}
}
}
@@ -454,6 +480,11 @@ class ConcatenatedTransform extends Abst
after = null;
}
}
+ /*
+ * Special case for datum shifts. Need to be done only after we processed
+ * 'beforeFormat(…)' for all objects and concatenated the affine transforms.
+ */
+ GeocentricAffine.asDatumShift(transforms);
return transforms;
}
@@ -837,11 +868,13 @@ class ConcatenatedTransform extends Abst
@Override
public synchronized MathTransform inverse() throws NoninvertibleTransformException {
assert isValid();
- if (inverse == null) {
- inverse = create(transform2.inverse(), transform1.inverse());
+ if (inverse == null) try {
+ inverse = create(transform2.inverse(), transform1.inverse(), null);
if (inverse instanceof ConcatenatedTransform) {
((ConcatenatedTransform) inverse).inverse = this;
}
+ } catch (FactoryException e) {
+ throw new NoninvertibleTransformException(Errors.format(Errors.Keys.NonInvertibleTransform), e);
}
return inverse;
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -23,8 +23,6 @@ import java.util.IdentityHashMap;
import java.util.Iterator;
import java.io.Serializable;
import org.opengis.util.FactoryException;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.OperationMethod;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.GeneralParameterDescriptor;
import org.opengis.parameter.ParameterValue;
@@ -32,7 +30,9 @@ import org.opengis.parameter.ParameterVa
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
import org.apache.sis.internal.referencing.WKTUtilities;
@@ -110,7 +110,7 @@ import org.apache.sis.internal.jdk7.Obje
* and gives the linear parameters to the {@link #normalizeGeographicInputs normalizeGeographicInputs(…)} and
* {@link MatrixSIS#convertAfter MatrixSIS.convertAfter(…)} methods, which will create the matrices show above.
* The projection constructor is free to apply additional operations on the two affine transforms
- * ({@linkplain #getMatrix(boolean) normalize / denormalize}) before or after the above-cited
+ * ({@linkplain #getMatrix(MatrixRole) normalize / denormalize}) before or after the above-cited
* methods have been invoked.</li>
*
* <li>After all parameter values have been set and the normalize / denormalize matrices defined,
@@ -128,7 +128,7 @@ import org.apache.sis.internal.jdk7.Obje
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.6
- * @version 0.6
+ * @version 0.7
* @module
*
* @see org.apache.sis.referencing.operation.projection.NormalizedProjection
@@ -136,13 +136,57 @@ import org.apache.sis.internal.jdk7.Obje
*/
public class ContextualParameters extends Parameters implements Serializable {
/**
+ * Whether a matrix is used for <cite>normalization</cite> or <cite>denormalization</cite>
+ * before or after a non-linear operation.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.7
+ * @version 0.7
+ * @module
+ *
+ * @see ContextualParameters#getMatrix(MatrixRole)
+ */
+ public static enum MatrixRole {
+ /**
+ * Matrix for converting angular degrees to radians, or any other linear operations needed
+ * before to apply a non-linear operation. For example in a map projection, this matrix is
+ * typically (but not necessarily) as below:
+ *
+ * <center>{@include formulas.html#NormalizeGeographic}</center>
+ */
+ NORMALIZATION,
+
+ /**
+ * Inverse of the {@link #NORMALIZATION} matrix.
+ * For example in a map projection, this matrix is typically (but not necessarily) as below:
+ *
+ * <center>{@include formulas.html#DeormalizeGeographic}</center>
+ */
+ INVERSE_NORMALIZATION,
+
+ /**
+ * Matrix for scaling Cartesian coordinates to the size of the planet, or any other linear operations needed
+ * after execution of a non-linear operation. For example in a map projection, this matrix is typically
+ * (but not necessarily) as below:
+ *
+ * <center>{@include formulas.html#DenormalizeCartesian}</center>
+ */
+ DENORMALIZATION,
+
+ /**
+ * Inverse of the {@link #DENORMALIZATION} matrix.
+ */
+ INVERSE_DENORMALIZATION
+ }
+
+ /**
* For cross-version compatibility.
*/
- private static final long serialVersionUID = 4899134192407586472L;
+ private static final long serialVersionUID = 6769546741493459341L;
/**
* The parameters that represents the sequence of transforms as a whole. The parameter values may be used
- * in the {@linkplain #getMatrix(boolean) (de)normalization} transforms, in the kernel, or both.
+ * in the {@linkplain #getMatrix(MatrixRole) (de)normalization} transforms, in the kernel, or both.
*
* @see #getDescriptor()
*/
@@ -151,11 +195,11 @@ public class ContextualParameters extend
/**
* The affine transform to be applied before (<cite>normalize</cite>) and after (<cite>denormalize</cite>)
* the kernel operation. On {@code ContextualParameters} construction, those affines are initially identity
- * transforms, to be modified in-place by callers of {@link #getMatrix(boolean)} or related methods.
+ * transforms, to be modified in-place by callers of {@link #getMatrix(MatrixRole)} or related methods.
* After the {@link #completeTransform(MathTransformFactory, MathTransform)} method has been invoked,
* those matrices are typically (but not necessarily) replaced by the {@link LinearTransform} instances itself.
*
- * @see #getMatrix(boolean)
+ * @see #getMatrix(MatrixRole)
*/
private Matrix normalize, denormalize;
@@ -169,8 +213,16 @@ public class ContextualParameters extend
private ParameterValue<?>[] values;
/**
+ * If the inverse coordinate operation can be described by another {@code ContextualParameters} instance,
+ * a reference to that instance. Otherwise {@code null}.
+ */
+ private ContextualParameters inverse;
+
+ /**
* {@code false} if this parameter group is modifiable, or {@code true} if it has been made unmodifiable
* (frozen) by a call to {@link #completeTransform(MathTransformFactory, MathTransform)}.
+ *
+ * @see #freeze()
*/
private boolean isFrozen;
@@ -183,7 +235,7 @@ public class ContextualParameters extend
* <ul>
* <li>Set the relevant parameter values by calls to
* <code>{@linkplain #parameter(String) parameter(…)}.setValue(…)</code>.</li>
- * <li>Modify the element values in {@linkplain #getMatrix(boolean) normalization / denormalization}
+ * <li>Modify the element values in {@linkplain #getMatrix(MatrixRole) normalization / denormalization}
* affine transforms, optionally by calls to the convenience methods in this class.</li>
* <li>Get the complete transforms chain with a call
* {@link #completeTransform(MathTransformFactory, MathTransform) completeTransform(…)}</li>
@@ -202,9 +254,38 @@ public class ContextualParameters extend
}
/**
+ * Equivalent to the public constructor, but avoid the need for an {@link OperationMethod} instance.
+ *
+ * @param descriptor The parameter descriptor.
+ * @param srcSize Size of the normalization matrix: source dimensions + 1.
+ * @param tgtSize Size of the denormalization matrix: target dimensions + 1.
+ */
+ ContextualParameters(final ParameterDescriptorGroup descriptor, final int srcSize, final int tgtSize) {
+ this.descriptor = descriptor;
+ this.normalize = Matrices.create(srcSize, srcSize, ExtendedPrecisionMatrix.IDENTITY);
+ this.denormalize = Matrices.create(tgtSize, tgtSize, ExtendedPrecisionMatrix.IDENTITY);
+ this.values = new ParameterValue<?>[descriptor.descriptors().size()];
+ }
+
+ /**
+ * Creates a {@code ContextualParameters} for the inverse operation.
+ *
+ * @param desc Descriptor of the inverse operation.
+ * @param forward The parameters created for the forward operation.
+ */
+ private ContextualParameters(final ParameterDescriptorGroup desc, final ContextualParameters forward) {
+ descriptor = desc;
+ normalize = forward.getMatrix(MatrixRole.INVERSE_DENORMALIZATION);
+ denormalize = forward.getMatrix(MatrixRole.INVERSE_NORMALIZATION);
+ values = forward.values;
+ inverse = forward;
+ isFrozen = true;
+ }
+
+ /**
* Creates a matrix for a linear step of the transforms chain.
* It is important that the matrices created here are instances of {@link MatrixSIS}, in order
- * to allow {@link #getMatrix(boolean)} to return the reference to the (de)normalize matrices.
+ * to allow {@link #getMatrix(MatrixRole)} to return the reference to the (de)normalize matrices.
*/
private static MatrixSIS linear(final String name, final Integer size) {
if (size == null) {
@@ -215,19 +296,36 @@ public class ContextualParameters extend
}
/**
+ * Creates a {@code ContextualParameters} for the inverse operation.
+ *
+ * @param desc Descriptor of the inverse operation.
+ * @return Parameters for the inverse operation.
+ */
+ final synchronized ContextualParameters inverse(final ParameterDescriptorGroup desc) {
+ if (inverse == null) {
+ if (!isFrozen) {
+ freeze();
+ }
+ inverse = new ContextualParameters(desc, this);
+ }
+ assert inverse.descriptor == desc;
+ return inverse;
+ }
+
+ /**
* Returns the parameters for the <cite>normalize</cite> → <cite>non-linear kernel</cite> →
* <cite>denormalize</cite> sequence as a whole. This is the parameter descriptor of the
* {@linkplain org.apache.sis.referencing.operation.DefaultOperationMethod operation method}
* given to the constructor.
*
* <p>The values for those parameters is given by the {@link #values()} method. Those values may be used in
- * the {@linkplain #getMatrix(boolean) normalization / denormalization} transforms, in the kernel, or both.</p>
+ * the {@linkplain #getMatrix(MatrixRole) normalization / denormalization} transforms, in the kernel, or both.</p>
*
* <div class="note"><b>Note:</b>
* The definition of "kernel" is left to implementors.
* In the particular case of Apache SIS implementation of map projections,
- * kernels are subclasses of {@link org.apache.sis.referencing.operation.projection.NormalizedProjection}.
- * </div>
+ * kernels are instances of {@link org.apache.sis.referencing.operation.projection.NormalizedProjection}.
+ * Other "kernels" in SIS are {@link EllipsoidToCentricTransform} and {@link MolodenskyTransform}.</div>
*
* @return The description of the parameters.
*/
@@ -237,17 +335,27 @@ public class ContextualParameters extend
}
/**
- * Ensures that this instance is modifiable.
+ * Ensures that this {@code ContextualParameters} instance is modifiable.
*
* @throws IllegalStateException if this {@code ContextualParameter} has been made unmodifiable.
*/
private void ensureModifiable() throws IllegalStateException {
+ assert Thread.holdsLock(this);
if (isFrozen) {
throw new IllegalStateException(Errors.format(Errors.Keys.UnmodifiableObject_1, getClass()));
}
}
/**
+ * Returns the given matrix as an unmodifiable one if this {@code ContextualParameters} instance is unmodifiable.
+ * Note that if this instance is modifiable, then we <strong>must</strong> return a direct reference to the matrix,
+ * not a wrapper, because the caller may need to modify it.
+ */
+ private MatrixSIS toMatrixSIS(final Matrix m) {
+ return isFrozen ? Matrices.unmodifiable(m) : (MatrixSIS) m;
+ }
+
+ /**
* Returns the affine transforms to be applied before or after the non-linear kernel operation.
* Immediately after {@linkplain #ContextualParameters(OperationMethod) construction}, those matrices
* are modifiable identity matrices. Callers can modify the matrix element values, typically by calls to
@@ -263,33 +371,68 @@ public class ContextualParameters extend
* invoked, the matrices returned by this method are {@linkplain Matrices#unmodifiable(Matrix) unmodifiable}.
*
*
- * <div class="section">Application to map projections</div>
- * After {@link org.apache.sis.referencing.operation.projection.NormalizedProjection} construction, the matrices
+ * <div class="note"><b>Application to map projections:</b>
+ * after {@link org.apache.sis.referencing.operation.projection.NormalizedProjection} construction, the matrices
* returned by {@code projection.getContextualParameters().getMatrix(…)} are initialized to the values shown below.
* Note that some {@code NormalizedProjection} subclasses apply further modifications to those matrices.
*
* <table class="sis">
- * <caption>Initial matrix coefficients after construction</caption>
+ * <caption>Initial matrix coefficients after {@code NormalizedProjection} construction</caption>
* <tr>
- * <th>{@code getMatrix(true)}</th>
- * <th class="sep">{@code getMatrix(false)}</th>
+ * <th>{@code getMatrix(NORMALIZATION)}</th>
+ * <th class="sep">{@code getMatrix(DENORMALIZATION)}</th>
* </tr><tr>
* <td>{@include formulas.html#NormalizeGeographic}</td>
* <td class="sep">{@include formulas.html#DenormalizeCartesian}</td>
* </tr>
* </table>
+ * </div>
+ *
+ * @param role {@code NORMALIZATION} for fetching the <cite>normalization</cite> transform to apply before the kernel,
+ * {@code DENORMALIZATION} for the <cite>denormalization</cite> transform to apply after the kernel,
+ * or {@code INVERSE_*} for the inverse of the above-cited matrices.
+ * @return The matrix for the requested normalization or denormalization affine transform.
+ *
+ * @since 0.7
+ */
+ public final MatrixSIS getMatrix(MatrixRole role) {
+ final Matrix fallback;
+ final ContextualParameters inverse;
+ synchronized (this) {
+ switch (role) {
+ default: throw new AssertionError(role);
+ case NORMALIZATION: return toMatrixSIS(normalize);
+ case DENORMALIZATION: return toMatrixSIS(denormalize);
+ case INVERSE_NORMALIZATION: role = MatrixRole.DENORMALIZATION; fallback = normalize; break;
+ case INVERSE_DENORMALIZATION: role = MatrixRole.NORMALIZATION; fallback = denormalize; break;
+ }
+ inverse = this.inverse; // Copy the reference while we are inside the synchronized block.
+ }
+ /*
+ * Following must be outside the synchronized block in order to avoid potential deadlock while invoking
+ * inverse.getMatrix(role). We do not cache the matrix here, but 'inverse' is likely to have cached it.
+ */
+ final Matrix m;
+ if (inverse != null) {
+ m = inverse.getMatrix(role);
+ } else try {
+ m = Matrices.inverse(fallback);
+ } catch (NoninvertibleMatrixException e) {
+ throw new IllegalStateException(Errors.format(Errors.Keys.CanNotCompute_1, role), e);
+ }
+ return Matrices.unmodifiable(m);
+ }
+
+ /**
+ * @deprecated Replaced by {@link #getMatrix(MatrixRole)}.
*
* @param norm {@code true} for fetching the <cite>normalization</cite> transform to apply before the kernel,
* or {@code false} for the <cite>denormalization</cite> transform to apply after the kernel.
* @return The matrix for the requested normalization ({@code true}) or denormalization ({@code false}) affine transform.
*/
+ @Deprecated
public final MatrixSIS getMatrix(final boolean norm) {
- final Matrix m = norm ? normalize : denormalize;
- if (!isFrozen) {
- return (MatrixSIS) m; // Must be the same instance, not a copy.
- } else {
- return Matrices.unmodifiable(m);
- }
+ return getMatrix(norm ? MatrixRole.NORMALIZATION : MatrixRole.DENORMALIZATION);
}
/**
@@ -307,7 +450,7 @@ public class ContextualParameters extend
* Callers can change that matrix directly if they want to apply additional normalization operations.
* @throws IllegalStateException if this {@code ContextualParameter} has been made unmodifiable.
*/
- public MatrixSIS normalizeGeographicInputs(final double λ0) {
+ public synchronized MatrixSIS normalizeGeographicInputs(final double λ0) {
ensureModifiable();
/*
* In theory the check for (λ0 != 0) is useless. However Java has a notion of negative zero, and we want
@@ -341,7 +484,7 @@ public class ContextualParameters extend
* Callers can change that matrix directly if they want to apply additional denormalization operations.
* @throws IllegalStateException if this {@code ContextualParameter} has been made unmodifiable.
*/
- public MatrixSIS denormalizeGeographicOutputs(final double λ0) {
+ public synchronized MatrixSIS denormalizeGeographicOutputs(final double λ0) {
ensureModifiable();
final DoubleDouble toDegrees = DoubleDouble.createRadiansToDegrees();
final MatrixSIS denormalize = (MatrixSIS) this.denormalize; // Must be the same instance, not a copy.
@@ -353,7 +496,7 @@ public class ContextualParameters extend
/**
* Marks this {@code ContextualParameter} as unmodifiable and creates the
* <cite>normalize</cite> → {@code kernel} → <cite>denormalize</cite> transforms chain.
- * This method shall be invoked only after the {@linkplain #getMatrix(boolean) (de)normalization}
+ * This method shall be invoked only after the {@linkplain #getMatrix(MatrixRole) (de)normalization}
* matrices have been set to their final values.
*
* <p>The transforms chain created by this method does not include any step for
@@ -372,51 +515,11 @@ public class ContextualParameters extend
* @see org.apache.sis.referencing.operation.projection.NormalizedProjection#createMapProjection(MathTransformFactory)
*/
@SuppressWarnings("AssignmentToForLoopParameter")
- public MathTransform completeTransform(final MathTransformFactory factory, final MathTransform kernel)
+ public synchronized MathTransform completeTransform(final MathTransformFactory factory, final MathTransform kernel)
throws FactoryException
{
if (!isFrozen) {
- isFrozen = true;
- /*
- * Sort the parameter values in the same order than the parameter descriptor. This is not essential,
- * but makes easier to read 'toString()' output by ensuring a consistent order for most projections.
- * Some WKT parsers other than SIS may also require the parameter values to be listed in that specific
- * order. We proceed by first copying all parameters in a temporary HashMap:
- */
- final Map<ParameterDescriptor<?>, ParameterValue<?>> parameters =
- new IdentityHashMap<ParameterDescriptor<?>, ParameterValue<?>>(values.length);
- for (ParameterValue<?> p : values) {
- if (p == null) {
- break; // The first null value in the array indicates the end of sequence.
- }
- p = DefaultParameterValue.unmodifiable(p);
- final ParameterDescriptor<?> desc = p.getDescriptor();
- if (parameters.put(desc, p) != null) {
- // Should never happen unless ParameterValue.descriptor changed (contract violation).
- throw new IllegalStateException(Errors.format(Errors.Keys.ElementAlreadyPresent_1, desc.getName()));
- }
- }
- /*
- * Then, copy all HashMap values back to the 'values' array in the order they are declared in the
- * descriptor. Implementation note: the iteration termination condition uses the values array, not
- * the descriptors list, because the former is often shorter than the later. We should never reach
- * the end of descriptors list before the end of values array because 'descriptors' contains all
- * 'parameters' keys. This is verified by the 'assert' below.
- */
- values = new ParameterValue<?>[parameters.size()];
- assert descriptor.descriptors().containsAll(parameters.keySet());
- final Iterator<GeneralParameterDescriptor> it = descriptor.descriptors().iterator();
- for (int i=0; i < values.length;) {
- /*
- * No need to check for it.hasNext(), since a NoSuchElementException below would be a bug in
- * our algorithm (or a concurrent change in the 'descriptor.descriptors()' list, which would
- * be a contract violation). See above 'assert'.
- */
- final ParameterValue<?> p = parameters.get(it.next());
- if (p != null) {
- values[i++] = p;
- }
- }
+ freeze();
}
/*
* Creates the ConcatenatedTransform, letting the factory returns the cached instance
@@ -431,6 +534,55 @@ public class ContextualParameters extend
}
/**
+ * Marks this contextual parameter as unmodifiable.
+ *
+ * @see #ensureModifiable()
+ */
+ private void freeze() {
+ isFrozen = true;
+ /*
+ * Sort the parameter values in the same order than the parameter descriptor. This is not essential,
+ * but makes easier to read 'toString()' output by ensuring a consistent order for most projections.
+ * Some WKT parsers other than SIS may also require the parameter values to be listed in that specific
+ * order. We proceed by first copying all parameters in a temporary HashMap:
+ */
+ final Map<ParameterDescriptor<?>, ParameterValue<?>> parameters =
+ new IdentityHashMap<ParameterDescriptor<?>, ParameterValue<?>>(values.length);
+ for (ParameterValue<?> p : values) {
+ if (p == null) {
+ break; // The first null value in the array indicates the end of sequence.
+ }
+ p = DefaultParameterValue.unmodifiable(p);
+ final ParameterDescriptor<?> desc = p.getDescriptor();
+ if (parameters.put(desc, p) != null) {
+ // Should never happen unless ParameterValue.descriptor changed (contract violation).
+ throw new IllegalStateException(Errors.format(Errors.Keys.ElementAlreadyPresent_1, desc.getName()));
+ }
+ }
+ /*
+ * Then, copy all HashMap values back to the 'values' array in the order they are declared in the
+ * descriptor. Implementation note: the iteration termination condition uses the values array, not
+ * the descriptors list, because the former is often shorter than the later. We should never reach
+ * the end of descriptors list before the end of values array because 'descriptors' contains all
+ * 'parameters' keys. This is verified by the 'assert' below.
+ */
+ values = new ParameterValue<?>[parameters.size()];
+ assert descriptor.descriptors().containsAll(parameters.keySet());
+ final Iterator<GeneralParameterDescriptor> it = descriptor.descriptors().iterator();
+ for (int i=0; i < values.length;) {
+ /*
+ * No need to check for it.hasNext(), since a NoSuchElementException below would be a bug in
+ * our algorithm (or a concurrent change in the 'descriptor.descriptors()' list, which would
+ * be a contract violation). See above 'assert'.
+ */
+ final ParameterValue<?> p = parameters.get(it.next());
+ if (p != null) {
+ values[i++] = p;
+ }
+ }
+ }
+
+ /**
* Returns the parameter value of the given name.
* Before the call to {@link #completeTransform completeTransform(…)},
* this method can be used for setting parameter values like below:
@@ -446,7 +598,7 @@ public class ContextualParameters extend
* @throws ParameterNotFoundException if there is no parameter of the given name.
*/
@Override
- public ParameterValue<?> parameter(final String name) throws ParameterNotFoundException {
+ public synchronized ParameterValue<?> parameter(final String name) throws ParameterNotFoundException {
final GeneralParameterDescriptor desc = descriptor.descriptor(name);
if (!(desc instanceof ParameterDescriptor<?>)) {
throw parameterNotFound(name);
@@ -493,7 +645,7 @@ public class ContextualParameters extend
*/
@Override
@SuppressWarnings("unchecked")
- public List<GeneralParameterValue> values() {
+ public synchronized List<GeneralParameterValue> values() {
int upper = values.length;
while (upper != 0 && values[upper - 1] == null) {
upper--;
@@ -537,7 +689,7 @@ public class ContextualParameters extend
* @return A clone of this parameter value group.
*/
@Override
- public ContextualParameters clone() {
+ public synchronized ContextualParameters clone() {
/*
* Creates a new parameter array with enough room for adding new parameters.
* Then replace each element by a modifiable clone.
@@ -552,6 +704,7 @@ public class ContextualParameters extend
}
/*
* Now proceed to the clone of this ContextualParameters instance.
+ * We do not clone inverseFoo fields since they shall be null for modifiable instances.
*/
final ContextualParameters clone = (ContextualParameters) super.clone();
clone.values = param;
@@ -565,7 +718,7 @@ public class ContextualParameters extend
* implementation-dependent and may change in any future version.
*/
@Override
- public int hashCode() {
+ public synchronized int hashCode() {
return (normalize.hashCode() + 31*denormalize.hashCode()) ^ Arrays.hashCode(values) ^ (int) serialVersionUID;
}
@@ -576,7 +729,7 @@ public class ContextualParameters extend
* @return {@code true} if the given object is equal to this one.
*/
@Override
- public boolean equals(final Object object) {
+ public synchronized boolean equals(final Object object) {
if (object != null && object.getClass() == getClass()) {
final ContextualParameters that = (ContextualParameters) object;
return Objects.equals(descriptor, that.descriptor) &&
@@ -633,6 +786,7 @@ public class ContextualParameters extend
@Override
protected String formatTo(final Formatter formatter) {
if (inverse) {
+ formatter.newLine();
formatter.append(new WKT(false));
return WKTKeywords.Inverse_MT;
} else {
@@ -656,7 +810,7 @@ public class ContextualParameters extend
* @param transforms The full chain of concatenated transforms.
* @param index The index of this transform in the {@code transforms} chain.
* @param inverse Always {@code false}, except if we are formatting the inverse transform.
- * @return Index of the last transform processed. Iteration should continue at that index + 1.
+ * @return Index of this transform in the {@code transforms} chain after processing.
*
* @see ConcatenatedTransform#getPseudoSteps()
* @see AbstractMathTransform#beforeFormat(List, int, boolean)
@@ -691,17 +845,17 @@ public class ContextualParameters extend
* in order to apply a change of axis order). We need to separate the "user-defined"
* step from the "normalize" step.
*/
- Matrix userDefined = inverse ? denormalize : normalize;
- if (!inverse) try {
- userDefined = Matrices.inverse(userDefined);
- } catch (NoninvertibleMatrixException e) {
+ MatrixSIS userDefined;
+ try {
+ userDefined = getMatrix(inverse ? MatrixRole.DENORMALIZATION : MatrixRole.INVERSE_NORMALIZATION);
+ } catch (IllegalStateException 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.
unexpectedException(e);
return index;
}
if (hasBefore) {
- userDefined = Matrices.multiply(userDefined, before);
+ userDefined = userDefined.multiply(before);
}
/*
* At this point "userDefined" is the affine transform to show to user instead of the
@@ -737,10 +891,9 @@ public class ContextualParameters extend
* 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 = inverse ? normalize : denormalize;
- if (!inverse) try {
- userDefined = Matrices.inverse(userDefined);
- } catch (NoninvertibleMatrixException e) {
+ try {
+ userDefined = getMatrix(inverse ? MatrixRole.NORMALIZATION : MatrixRole.INVERSE_DENORMALIZATION);
+ } catch (IllegalStateException e) {
unexpectedException(e);
return index;
}
@@ -791,12 +944,11 @@ public class ContextualParameters extend
assert (old instanceof LinearTransform);
}
} else {
- index++;
if (hasAfter) {
- final Object old = transforms.set(index, after);
+ final Object old = transforms.set(index + 1, after);
assert (old instanceof LinearTransform);
} else {
- transforms.add(index, after);
+ transforms.add(index + 1, after);
}
}
return index;
@@ -811,7 +963,7 @@ public class ContextualParameters extend
* because this error should occurs only in the context of WKT formatting of a concatenated
* transform.</p>
*/
- private static void unexpectedException(final NoninvertibleMatrixException e) {
- Logging.unexpectedException(Logging.getLogger(Loggers.WKT), ConcatenatedTransform.class, "formatTo", e);
+ private static void unexpectedException(final IllegalStateException e) {
+ Logging.unexpectedException(Logging.getLogger(Loggers.WKT), ConcatenatedTransform.class, "formatTo", e.getCause());
}
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/CopyTransform.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -17,7 +17,6 @@
package org.apache.sis.referencing.operation.transform;
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;
@@ -39,10 +38,10 @@ import org.apache.sis.referencing.operat
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.5
- * @version 0.6
+ * @version 0.7
* @module
*/
-final class CopyTransform extends AbstractLinearTransform implements Serializable {
+final class CopyTransform extends AbstractLinearTransform {
/**
* Serial number for inter-operability with different versions.
*/
@@ -61,11 +60,6 @@ final class CopyTransform extends Abstra
private final int[] indices;
/**
- * The inverse transform. Will be created only when first needed.
- */
- private transient MathTransform inverse;
-
- /**
* Creates a new transform.
*
* @param srcDim The dimension of source coordinates.
@@ -85,9 +79,9 @@ final class CopyTransform extends Abstra
static CopyTransform create(final Matrix matrix) {
final int srcDim = matrix.getNumCol() - 1;
final int dstDim = matrix.getNumRow() - 1;
- for (int i=0; i<=srcDim; i++) {
+ for (int i=0; i <= srcDim; i++) {
if (matrix.getElement(dstDim, i) != (i == srcDim ? 1 : 0)) {
- // Not an affine transform.
+ // Not an affine transform (ignoring if square or not).
return null;
}
}
@@ -339,8 +333,9 @@ final class CopyTransform extends Abstra
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.
+ * Note: no need to perform the following check as this point because MathTransforms.linear(…)
+ * should never instantiate this class in the identity case and because we perform an
+ * equivalent check later anyway.
*
* if (isIdentity()) {
* inverse = this;
@@ -361,7 +356,7 @@ final class CopyTransform extends Abstra
for (int j=srcDim; --j>=0;) {
if (reverse[j] < 0) {
final MatrixSIS matrix = Matrices.createZero(srcDim + 1, dstDim + 1);
- for (j=0; j<srcDim; j++) { // NOSONAR: the outer loop will not continue.
+ for (j=0; j<srcDim; j++) { // Okay to reuse 'j' since the outer loop will not continue.
final int i = reverse[j];
if (i >= 0) {
matrix.setElement(j, i, 1);
@@ -371,14 +366,16 @@ final class CopyTransform extends Abstra
}
matrix.setElement(srcDim, dstDim, 1);
inverse = MathTransforms.linear(matrix);
- if (inverse instanceof ProjectiveTransform) {
- ((ProjectiveTransform) inverse).inverse = this;
+ if (inverse instanceof AbstractLinearTransform) {
+ ((AbstractLinearTransform) inverse).inverse = this;
}
return inverse;
}
}
/*
- * At this point, we known that we can create the inverse transform.
+ * At this point, we know that we can create the inverse transform.
+ * If this transform is the identity transform (we should never happen,
+ * but we are paranoiac), then the old and new arrays would be equal.
*/
CopyTransform copyInverse = this;
if (!Arrays.equals(reverse, indices)) {
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -152,7 +152,7 @@ import org.apache.sis.internal.jdk8.JDK8
*
* @author Martin Desruisseaux (Geomatys, IRD)
* @since 0.6
- * @version 0.6
+ * @version 0.7
* @module
*
* @see MathTransformProvider
@@ -560,7 +560,7 @@ public class DefaultMathTransformFactory
* NormalizedProjection class (our base class for all map projection implementations)
* to known that the ellipsoid definitive parameter is the inverse flattening factor
* instead than the semi-major axis length. It makes a small difference in the accuracy
- * of the excentricity parameter.
+ * of the eccentricity parameter.
*/
if (isIvfDefinitive) try {
parameters.parameter(Constants.INVERSE_FLATTENING).setValue(ellipsoid.getInverseFlattening());
@@ -782,12 +782,15 @@ public class DefaultMathTransformFactory
throws FactoryException
{
lastMethod.remove();
+ ArgumentChecks.ensureNonNull("tr1", tr1);
+ ArgumentChecks.ensureNonNull("tr2", tr2);
final MathTransform tr;
try {
- tr = MathTransforms.concatenate(tr1, tr2);
+ tr = ConcatenatedTransform.create(tr1, tr2, this);
} catch (IllegalArgumentException exception) {
throw new FactoryException(exception);
}
+ assert MathTransforms.isValid(MathTransforms.getSteps(tr)) : tr;
return unique(tr);
}
Copied: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java (from r1714140, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java?p2=sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java&r1=1714140&r2=1714141&rev=1714141&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -738,6 +738,7 @@ next: while (--numPts >= 0) {
* Creates the inverse of the enclosing transform.
*/
Inverse() {
+ EllipsoidToCentricTransform.this.super();
}
/**
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ExponentialTransform1D.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -19,6 +19,8 @@ package org.apache.sis.referencing.opera
import java.io.Serializable;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.util.FactoryException;
import org.apache.sis.internal.util.Numerics;
import org.apache.sis.util.ComparisonMode;
@@ -219,11 +221,13 @@ final class ExponentialTransform1D exten
* @param applyOtherFirst {@code true} if the transformation order is {@code other}
* followed by {@code this}, or {@code false} if the transformation order is
* {@code this} followed by {@code other}.
- * @return The combined math transform, or {@code null} if no optimized combined
- * transform is available.
+ * @param factory The factory which is (indirectly) invoking this method, or {@code null} if none.
+ * @return The combined math transform, or {@code null} if no optimized combined transform is available.
*/
@Override
- final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+ final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst,
+ final MathTransformFactory factory) throws FactoryException
+ {
if (other instanceof LinearTransform) {
final LinearTransform1D linear = (LinearTransform1D) other;
if (applyOtherFirst) {
@@ -240,7 +244,7 @@ final class ExponentialTransform1D exten
} else if (other instanceof LogarithmicTransform1D) {
return concatenateLog((LogarithmicTransform1D) other, applyOtherFirst);
}
- return super.concatenate(other, applyOtherFirst);
+ return super.concatenate(other, applyOtherFirst, factory);
}
/**
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/IdentityTransform.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -16,7 +16,6 @@
*/
package org.apache.sis.referencing.operation.transform;
-import java.io.Serializable;
import org.opengis.geometry.DirectPosition;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
@@ -37,7 +36,7 @@ import org.apache.sis.internal.referenci
* @version 0.6
* @module
*/
-final class IdentityTransform extends AbstractLinearTransform implements Serializable {
+final class IdentityTransform extends AbstractLinearTransform {
/**
* Serial number for inter-operability with different versions.
*/
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/LogarithmicTransform1D.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -19,6 +19,8 @@ package org.apache.sis.referencing.opera
import java.io.Serializable;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.util.FactoryException;
import org.apache.sis.internal.util.Numerics;
import org.apache.sis.math.MathFunctions;
import org.apache.sis.util.ArgumentChecks;
@@ -114,10 +116,13 @@ class LogarithmicTransform1D extends Abs
* @param other The math transform to apply.
* @param applyOtherFirst {@code true} if the transformation order is {@code other} followed by {@code this},
* or {@code false} if the transformation order is {@code this} followed by {@code other}.
+ * @param factory The factory which is (indirectly) invoking this method, or {@code null} if none.
* @return The combined math transform, or {@code null} if no optimized combined transform is available.
*/
@Override
- final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+ final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst,
+ final MathTransformFactory factory) throws FactoryException
+ {
if (other instanceof LinearTransform1D) {
final LinearTransform1D linear = (LinearTransform1D) other;
if (applyOtherFirst) {
@@ -133,7 +138,7 @@ class LogarithmicTransform1D extends Abs
} else if (other instanceof ExponentialTransform1D) {
return ((ExponentialTransform1D) other).concatenateLog(this, !applyOtherFirst);
}
- return super.concatenate(other, applyOtherFirst);
+ return super.concatenate(other, applyOtherFirst, factory);
}
/**
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.opera
import java.util.List;
import java.util.Collections;
import java.awt.geom.AffineTransform;
+import org.opengis.util.FactoryException;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
@@ -52,7 +53,7 @@ import static org.apache.sis.util.Argume
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.5
- * @version 0.6
+ * @version 0.7
* @module
*
* @see MathTransformFactory
@@ -143,7 +144,7 @@ public final class MathTransforms extend
if (candidate != null) {
return candidate;
}
- return new ProjectiveTransform(matrix);
+ return new ProjectiveTransform(matrix).optimize();
}
/**
@@ -185,7 +186,7 @@ public final class MathTransforms extend
if (compound == null) {
compound = tr;
} else {
- compound = ConcatenatedTransform.create(compound, tr);
+ compound = concatenate(compound, tr);
}
}
assert isValid(getSteps(compound)) : compound;
@@ -210,7 +211,12 @@ public final class MathTransforms extend
{
ensureNonNull("tr1", tr1);
ensureNonNull("tr2", tr2);
- final MathTransform tr = ConcatenatedTransform.create(tr1, tr2);
+ final MathTransform tr;
+ try {
+ tr = ConcatenatedTransform.create(tr1, tr2, null);
+ } catch (FactoryException e) {
+ throw new IllegalArgumentException(e); // Should never happen actually.
+ }
assert isValid(getSteps(tr)) : tr;
return tr;
}
@@ -310,7 +316,7 @@ public final class MathTransforms extend
* (because their matrices should have been multiplied together).
* This is used for assertion purposes only.
*/
- private static boolean isValid(final List<MathTransform> steps) {
+ static boolean isValid(final List<MathTransform> steps) {
boolean wasLinear = false;
for (final MathTransform step : steps) {
if (step instanceof LinearTransform) {
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java?rev=1714141&r1=1714140&r2=1714141&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/PowerTransform1D.java [UTF-8] Thu Nov 12 23:47:52 2015
@@ -19,6 +19,8 @@ package org.apache.sis.referencing.opera
import java.io.Serializable;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.util.FactoryException;
import org.apache.sis.internal.util.Numerics;
import org.apache.sis.util.ComparisonMode;
@@ -172,15 +174,18 @@ final class PowerTransform1D extends Abs
* @param other The math transform to apply.
* @param applyOtherFirst {@code true} if the transformation order is {@code other} followed by {@code this},
* or {@code false} if the transformation order is {@code this} followed by {@code other}.
+ * @param factory The factory which is (indirectly) invoking this method, or {@code null} if none.
* @return The combined math transform, or {@code null} if no optimized combined transform is available.
*/
@Override
- final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst) {
+ final MathTransform concatenate(final MathTransform other, final boolean applyOtherFirst,
+ final MathTransformFactory factory) throws FactoryException
+ {
if (other instanceof PowerTransform1D) {
return create(power + ((PowerTransform1D) other).power);
}
// TODO: more optimization could go here for logarithmic and exponential cases.
- return super.concatenate(other, applyOtherFirst);
+ return super.concatenate(other, applyOtherFirst, factory);
}
/**
|