You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/03/27 18:04:02 UTC
svn commit: r1669621 - in /sis/branches/JDK8/core/sis-referencing/src:
main/java/org/apache/sis/referencing/operation/matrix/
main/java/org/apache/sis/referencing/operation/projection/
main/java/org/apache/sis/referencing/operation/transform/ test/java...
Author: desruisseaux
Date: Fri Mar 27 17:04:01 2015
New Revision: 1669621
URL: http://svn.apache.org/r1669621
Log:
Referencing: completed ContextualParameters implementation, added documentation and tests.
Added:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ContextualParametersTest.java (with props)
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -57,9 +57,13 @@ import java.util.Objects;
* {@link #isAffine isAffine},
* {@link #isIdentity isIdentity},
* {@link #equals(Matrix, Matrix, double, boolean) equals},
- * {@link #equals(Matrix, Matrix, ComparisonMode) equals},
* {@link #toString(Matrix) toString}.
* </li>
+ * <li>Miscellaneous:
+ * {@link #multiply multiply},
+ * {@link #inverse inverse},
+ * {@link #unmodifiable unmodifiable},
+ * </li>
* </ul>
*
* @author Martin Desruisseaux (IRD, Geomatys)
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -32,13 +32,24 @@ import org.apache.sis.util.resources.Err
* A {@link Matrix} able to perform some operations of interest to Spatial Information Systems (SIS).
* This class completes the GeoAPI {@link Matrix} interface with some operations used by {@code sis-referencing}.
* It is not a {@code MatrixSIS} goal to provide all possible Matrix operations, as there is too many of them.
- * This class focuses only on:
+ * This class focuses on:
*
* <ul>
- * <li>basic operations needed for <cite>referencing by coordinates</cite>:
- * {@link #transpose()}, {@link #inverse()}, {@link #multiply(Matrix)};</li>
- * <li>some operations more specific to referencing by coordinates:
- * {@link #isAffine()}, {@link #normalizeColumns()}, {@link #concatenate(int, Number, Number)}.</li>
+ * <li>Only the basic matrix operations needed for <cite>referencing by coordinates</cite>:
+ * <ul>
+ * <li>{@link #isIdentity()}</li>
+ * <li>{@link #multiply(Matrix)}</li>
+ * <li>{@link #inverse()}</li>
+ * <li>{@link #transpose()}</li>
+ * </ul>
+ * </li><li>Other operations which are not general-purpose matrix operations,
+ * but are needed in the context of referencing by coordinates:
+ * <ul>
+ * <li>{@link #isAffine()}</li>
+ * <li>{@link #normalizeColumns()}</li>
+ * <li>{@link #concatenate(int, Number, Number)}</li>
+ * </ul>
+ * </li>
* </ul>
*
* @author Martin Desruisseaux (IRD, Geomatys)
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/UnmodifiableMatrix.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -127,6 +127,6 @@ final class UnmodifiableMatrix extends M
*/
@Override
public MatrixSIS clone() {
- return MatrixSIS.castOrCopy(matrix.clone());
+ return castOrCopy(matrix.clone());
}
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -60,13 +60,19 @@ import java.util.Objects;
* affine transform.</li>
* </ul>
*
- * The normalize and denormalize steps are represented below by the matrices on the left and right sides respectively.
- * The matrices below show only the basic parameters common to all projections. Some projections will put more elements
- * in those matrices.
+ * The normalize and denormalize steps are represented below by the matrices immediately on the left and right
+ * sides of {@code NormalizedProjection} respectively. The first matrix on the left side is for
+ * {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes swapping axes}
+ * from (<var>latitude</var>, <var>longitude</var>) to (<var>longitude</var>, <var>latitude</var>) order,
+ * and is shown here for completeness.
+ * The matrices below show only the basic parameters common to most projections.
+ * Some projections will put more elements in those matrices.
*
* <center>
* <table class="compact" style="td {vertical-align: middle}" summary="Decomposition of a map projection">
* <tr>
+ * <td>{@include ../transform/formulas.html#SwapAxes}</td>
+ * <td>→</td>
* <td>{@include ../transform/formulas.html#NormalizeGeographic}</td>
* <td>→</td>
* <td>{@code NormalizedProjection}</td>
@@ -176,10 +182,12 @@ public abstract class NormalizedProjecti
}
/**
- * Returns the parameters used for creating the complete map projection. Those parameters describe a sequence
- * of <cite>normalize</cite> → {@code this} → <cite>denormalize</cite> transforms. They are used for formatting
- * <cite>Well Known Text</cite> (WKT) and error messages. Subclasses shall not use the values defined in the
- * returned object for computation purpose, except at construction time.
+ * Returns the parameters used for creating the complete map projection. Those parameters describe a sequence of
+ * <cite>normalize</cite> → {@code this} → <cite>denormalize</cite> transforms, <strong>not</strong> including
+ * {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes axis swapping}.
+ * Those parameters are used for formatting <cite>Well Known Text</cite> (WKT) and error messages.
+ * Subclasses shall not use the values defined in the returned object for computation purpose,
+ * except at construction time.
*
* @return The parameters values for the sequence of <cite>normalize</cite> → {@code this} → <cite>denormalize</cite>
* transforms, or {@code null} if unspecified.
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/package-info.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -115,7 +115,9 @@
*
*
* <div class="section">Projection on unit ellipse</div>
- * A map projection in this package is actually the concatenation of the following transforms, in that order:
+ * A map projection in this package is actually the concatenation of the following transforms, in that order
+ * (ignoring {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes axis order changes}
+ * and conversions from/to units other then degrees and metres, which are not the purpose of this package):
*
* <ul>
* <li>A {@linkplain org.apache.sis.referencing.operation.transform.ContextualParameters#normalizeGeographicInputs normalization} affine transform</li>
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -211,6 +211,8 @@ public abstract class AbstractMathTransf
* Callers should not modify the returned parameters, since modifications (if allowed)
* will generally not be reflected back in this {@code MathTransform}.
*
+ * @see org.apache.sis.referencing.operation.projection.NormalizedProjection#getContextualParameters()
+ *
* @since 0.6
*/
protected ContextualParameters getContextualParameters() {
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -17,9 +17,8 @@
package org.apache.sis.referencing.operation.transform;
import java.util.List;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Objects;
-import java.util.Collections;
import java.io.Serializable;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.MathTransform;
@@ -69,7 +68,9 @@ import static org.apache.sis.util.Argume
* This object is used mostly for Apache SIS implementation of map projections, where the non-linear kernel is a
* {@linkplain org.apache.sis.referencing.operation.projection.NormalizedProjection normalized projection}.
* The {@linkplain #completeTransform(MathTransformFactory, MathTransform) complete map projection} is a chain
- * of 3 transforms a below:
+ * of 3 transforms as shown below. Note that this chain does not include the step for
+ * {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes swapping the axis order}.
+ * Axes swapping and conversions from units other than degrees is performed outside {@code ContextualParameters}.
*
* <center>
* <table class="compact" style="td {vertical-align: middle}" summary="Decomposition of a map projection">
@@ -107,7 +108,10 @@ import static org.apache.sis.util.Argume
* <li>After all parameter values have been set and the normalize / denormalize matrices defined,
* the {@link #completeTransform(MathTransformFactory, MathTransform) completeTransform(…)} method
* will mark this {@code ContextualParameters} object as unmodifiable and create the complete chain
- * of transforms, from (λ,φ) in angular degrees to (x,y) in metres.</li>
+ * of transforms, from (λ,φ) in angular degrees to (x,y) in metres. Note that conversions to other
+ * units and {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes changes
+ * in axis order} are not the purpose of this transforms chain; they are separated steps.
+ * </li>
* </ol>
*
* <div class="section">Serialization</div>
@@ -148,10 +152,19 @@ public class ContextualParameters extend
private Matrix normalize, denormalize;
/**
- * The list of parameter values. This list is modifiable after construction, but is replaced by an
- * unmodifiable list after {@link #completeTransform(MathTransformFactory, MathTransform)} has been invoked.
+ * The parameter values. Null elements in this array are empty slots available for adding new parameter values.
+ * The array length is the maximum number of parameters allowed, which is determined by the {@link #descriptor}.
+ *
+ * <p>This array is modifiable after construction, but is considered unmodifiable after
+ * {@link #completeTransform(MathTransformFactory, MathTransform)} has been invoked.</p>
+ */
+ private ParameterValue<?>[] values;
+
+ /**
+ * {@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)}.
*/
- private List<GeneralParameterValue> values;
+ private boolean isFrozen;
/**
* Creates a new group of parameters for the given non-linear coordinate operation method.
@@ -161,13 +174,15 @@ public class ContextualParameters extend
*
* <ul>
* <li>Set the relevant parameter values by calls to
- * <code>{@linkplain #parameter(ParameterDescriptor) parameter}(…).setValue(…)</code>.</li>
+ * <code>{@linkplain #parameter(ParameterDescriptor) parameter(…)}.setValue(…)</code>.</li>
* <li>Modify the element values in {@linkplain #getMatrix(boolean) 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>
* </ul>
*
+ * See class javadoc for more information.
+ *
* @param method The non-linear operation method for which to define the parameter values.
*/
public ContextualParameters(final OperationMethod method) {
@@ -175,15 +190,7 @@ public class ContextualParameters extend
descriptor = method.getParameters();
normalize = linear("sourceDimensions", method.getSourceDimensions());
denormalize = linear("targetDimensions", method.getTargetDimensions());
- values = new ArrayList<>(descriptor.descriptors().size()); // See isModifiable() below.
- }
-
- /**
- * Returns {@code true} if this parameter group is modifiable, or {@code false} if it has been made
- * unmodifiable by a call to {@link #completeTransform(MathTransformFactory, MathTransform)}.
- */
- private boolean isModifiable() {
- return values.getClass() == ArrayList.class; // '==' is faster than 'instanceof'.
+ values = new ParameterValue<?>[descriptor.descriptors().size()];
}
/**
@@ -195,7 +202,8 @@ public class ContextualParameters extend
if (size == null) {
throw new IllegalArgumentException(Errors.format(Errors.Keys.MissingValueForProperty_1, name));
}
- return Matrices.create(size, size, ExtendedPrecisionMatrix.IDENTITY);
+ final int n = size + 1;
+ return Matrices.create(n, n, ExtendedPrecisionMatrix.IDENTITY);
}
/**
@@ -221,12 +229,12 @@ public class ContextualParameters extend
}
/**
- * Returns the affine transforms to be applied before or after the kernel operation.
+ * Returns the affine transforms to be applied before or after the non-linear kernel operation.
*
* <p>Immediately after {@linkplain #ContextualParameters(OperationMethod) construction}, those matrices
* are modifiable identity matrices. Callers can modify the matrix element values, typically by calls to
- * the {@link MatrixSIS#concatenate(int, Number, Number)} method. Alternatively, the following methods
- * can be invoked for applying some frequently used configurations:
+ * the {@link MatrixSIS#concatenate(int, Number, Number) MatrixSIS.concatenate(…)} method. Alternatively,
+ * the following methods can be invoked for applying some frequently used configurations:
*
* <ul>
* <li>{@link #normalizeGeographicInputs(double)}</li>
@@ -243,7 +251,7 @@ public class ContextualParameters extend
*/
public final MatrixSIS getMatrix(final boolean norm) {
final Matrix m = norm ? normalize : denormalize;
- if (isModifiable()) {
+ if (!isFrozen) {
return (MatrixSIS) m; // Must be the same instance, not a copy.
} else {
return Matrices.unmodifiable(m);
@@ -256,7 +264,7 @@ public class ContextualParameters extend
* @throws IllegalStateException if this {@code ContextualParameter} has been made unmodifiable.
*/
private void ensureModifiable() throws IllegalStateException {
- if (!isModifiable()) {
+ if (isFrozen) {
throw new IllegalStateException(Errors.format(Errors.Keys.UnmodifiableObject_1, getClass()));
}
}
@@ -266,8 +274,8 @@ public class ContextualParameters extend
* The normalization can optionally subtract the given λ₀ value (in degrees) from the longitude.
*
* <p>Invoking this method is equivalent to {@linkplain java.awt.geom.AffineTransform#concatenate concatenating}
- * the normalization matrix by the following matrix. This will have the effect of applying the conversion described
- * above before any other operation:</p>
+ * the normalization matrix with the following matrix. This will have the effect of applying the conversion
+ * described above before any other operation:</p>
*
* <center>{@include formulas.html#NormalizeGeographic}</center>
*
@@ -299,8 +307,9 @@ public class ContextualParameters extend
* in the two first dimensions from radians to degrees. After this conversion, the denormalization
* can optionally add the given λ₀ value (in degrees) to the longitude.
*
- * <p>Invoking this method is equivalent to convert coordinates using the following
- * affine transform after the non-linear kernel:</p>
+ * <p>Invoking this method is equivalent to {@linkplain java.awt.geom.AffineTransform#concatenate concatenating}
+ * the denormalization matrix with the following matrix. This will have the effect of applying the conversion
+ * described above after the non-linear kernel operation:</p>
*
* <center>{@include formulas.html#DeormalizeGeographic}</center>
*
@@ -323,8 +332,9 @@ public class ContextualParameters extend
* in the two first dimensions.
* In map projection, the translation terms are <cite>false easting</cite> (FE) and <cite>false northing</cite> (FN).
*
- * <p>Invoking this method is equivalent to convert coordinates using the following
- * affine transform after the non-linear kernel:</p>
+ * <p>Invoking this method is equivalent to {@linkplain java.awt.geom.AffineTransform#concatenate concatenating}
+ * the denormalization matrix with the following matrix. This will have the effect of applying the conversion
+ * described above after the non-linear kernel operation:</p>
*
* <center>{@include formulas.html#DenormalizeCartesian}</center>
*
@@ -350,6 +360,12 @@ public class ContextualParameters extend
* This method shall be invoked only after the {@linkplain #getMatrix(boolean) (de)normalization}
* matrices have been set to their final values.
*
+ * <p>The transforms chain created by this method does not include any step for
+ * {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes changing axis order}
+ * or for converting to units other than degrees or metres. Such steps, if desired, should be defined
+ * outside {@code ContextualParameters}. Efficient concatenation of those steps will happen "under
+ * the hood".</p>
+ *
* @param factory The factory to use for creating math transform instances.
* @param kernel The (usually non-linear) kernel.
* @return The concatenation of <cite>normalize</cite> → <cite>the given kernel</cite> → <cite>denormalize</cite>
@@ -359,12 +375,16 @@ public class ContextualParameters extend
public MathTransform completeTransform(final MathTransformFactory factory, final MathTransform kernel)
throws FactoryException
{
- if (isModifiable()) {
- final GeneralParameterValue[] p = values.toArray(new GeneralParameterValue[values.size()]);
- for (int i=0; i<p.length; i++) {
- p[i] = DefaultParameterValue.unmodifiable((ParameterValue<?>) p[i]);
+ if (!isFrozen) {
+ isFrozen = true;
+ for (int i=0; i < values.length; i++) {
+ final ParameterValue<?> p = values[i];
+ if (p == null) {
+ values = Arrays.copyOf(values, i); // Trim extra values.
+ break;
+ }
+ values[i] = DefaultParameterValue.unmodifiable(p);
}
- values = UnmodifiableArrayList.wrap(p);
}
/*
* Creates the ConcatenatedTransform, letting the factory returns the cached instance
@@ -380,6 +400,8 @@ public class ContextualParameters extend
/**
* Returns the parameter value of the given name.
+ * This method can be invoked either before or after the call to {@link #completeTransform completeTransform(…)},
+ * but the returned parameter will be modifiable only before that call.
*
* @param name The name of the parameter to search.
* @return The parameter value for the given name.
@@ -387,16 +409,37 @@ public class ContextualParameters extend
*/
@Override
public ParameterValue<?> parameter(final String name) throws ParameterNotFoundException {
- final GeneralParameterDescriptor p = descriptor.descriptor(name);
- if (p instanceof ParameterDescriptor<?>) {
- return parameter((ParameterDescriptor<?>) p);
- } else {
+ final GeneralParameterDescriptor desc = descriptor.descriptor(name);
+ if (!(desc instanceof ParameterDescriptor<?>)) {
throw parameterNotFound(name);
}
- }
-
- public ParameterValue<?> parameter(final ParameterDescriptor<?> param) throws ParameterNotFoundException {
- throw new UnsupportedOperationException("Not supported yet."); // TODO
+ /*
+ * Search for existing parameter instance. This implementation does not scale,
+ * but should be okay since the amount of parameters is typically very small
+ * (rarely more than 6 parameters in map projections).
+ */
+ for (int i=0; i < values.length; i++) {
+ ParameterValue<?> p = values[i];
+ if (p == null) {
+ /*
+ * No existing parameter instance. Create a new one if this ContextualParameter
+ * is still modifiable.
+ */
+ ensureModifiable();
+ p = ((ParameterDescriptor<?>) desc).createValue();
+ values[i] = p;
+ } else if (p.getDescriptor() != desc) { // Identity comparison should be okay here.
+ continue;
+ }
+ return p; // Found or created a parameter.
+ }
+ ensureModifiable();
+ /*
+ * Should never reach this point. If it happen anyway, this means that the descriptor now accepts
+ * more parameters than what it declared at ContextualParameteres construction time, or that some
+ * ParameterDescriptor instances changed.
+ */
+ throw new IllegalStateException(Errors.format(Errors.Keys.UnexpectedChange_1, descriptor.getName()));
}
/**
@@ -406,19 +449,17 @@ public class ContextualParameters extend
* @return All parameter values.
*/
@Override
+ @SuppressWarnings("unchecked")
public List<GeneralParameterValue> values() {
- if (isModifiable()) {
- return Collections.unmodifiableList(values);
- } else {
- // Already unmodifiable, no need to protect against changes.
- assert (values instanceof UnmodifiableArrayList<?>);
- return values;
+ int upper = values.length;
+ while (upper != 0 && values[upper - 1] == null) {
+ upper--;
}
+ return UnmodifiableArrayList.wrap(values, 0, upper);
}
/**
* Unsupported operation, since {@code ContextualParameters} groups do not contain sub-groups.
- * This limitation may be revisited in future SIS version.
*
* @param name Ignored.
* @return Never returned.
@@ -430,7 +471,6 @@ public class ContextualParameters extend
/**
* Unsupported operation, since {@code ContextualParameters} groups do not contain sub-groups.
- * This limitation may be revisited in future SIS version.
*
* @param name Ignored.
* @return Never returned.
@@ -449,19 +489,35 @@ public class ContextualParameters extend
}
/**
- * Returns a clone of this parameter value group.
+ * Returns a modifiable clone of this parameter value group.
*
* @return A clone of this parameter value group.
*/
@Override
public ContextualParameters clone() {
+ /*
+ * Creates a new parameter array with enough room for adding new parameters.
+ * Then replace each element by a modifiable clone.
+ */
+ final ParameterValue<?>[] param = Arrays.copyOf(values, descriptor.descriptors().size());
+ for (int i=0; i<param.length; i++) {
+ final ParameterValue<?> p = param[i];
+ if (p == null) {
+ break;
+ }
+ param[i] = param[i].clone();
+ }
+ /*
+ * Now proceed to the clone of this ContextualParameters instance.
+ */
final ContextualParameters clone;
try {
clone = (ContextualParameters) super.clone();
} catch (CloneNotSupportedException e) {
- throw new AssertionError(e);
+ throw new AssertionError(e); // Should never happen since we are cloneable.
}
- clone. normalize = normalize.clone();
+ clone.values = param;
+ clone.normalize = normalize.clone();
clone.denormalize = denormalize.clone();
return clone;
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/formulas.html [UTF-8] Fri Mar 27 17:04:01 2015
@@ -117,6 +117,32 @@
+ <h2>SwapAxes</h2>
+ <math display="block" alttext="MathML capable browser required">
+ <mfenced open="[" close="]">
+ <mtable>
+ <mtr>
+ <mtd><mn>0</mn></mtd>
+ <mtd><mn>1</mn></mtd>
+ <mtd><mn>0</mn></mtd>
+ </mtr>
+ <mtr>
+ <mtd><mn>1</mn></mtd>
+ <mtd><mn>0</mn></mtd>
+ <mtd><mn>0</mn></mtd>
+ </mtr>
+ <mtr>
+ <mtd><mn>0</mn></mtd>
+ <mtd><mn>0</mn></mtd>
+ <mtd><mn>1</mn></mtd>
+ </mtr>
+ </mtable>
+ </mfenced>
+ </math>
+
+
+
+
<h2>NormalizeGeographic</h2>
<math display="block" alttext="MathML capable browser required">
<mfenced open="[" close="]">
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/DefaultParameterDescriptorGroupTest.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -57,7 +57,7 @@ public final strictfp class DefaultParam
* The very last parameter has a maximum number of occurrence of 2, which is illegal
* according ISO 19111 but nevertheless supported by Apache SIS.
*/
- static final DefaultParameterDescriptorGroup M1_M1_O1_O2;
+ public static final DefaultParameterDescriptorGroup M1_M1_O1_O2;
static {
final Class<Integer> type = Integer.class;
final Map<String,Object> properties = new HashMap<>(4);
Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ContextualParametersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ContextualParametersTest.java?rev=1669621&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ContextualParametersTest.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ContextualParametersTest.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+import java.util.Collections;
+import org.opengis.util.FactoryException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.apache.sis.referencing.operation.DefaultOperationMethod;
+import org.apache.sis.parameter.DefaultParameterDescriptorGroupTest;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.MetadataAssert.*;
+
+
+/**
+ * Tests {@link ContextualParameters}.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.6
+ * @version 0.6
+ * @module
+ */
+@DependsOn(DefaultParameterDescriptorGroupTest.class)
+public final strictfp class ContextualParametersTest extends TestCase {
+ /**
+ * Creates an instance to use for testing purpose.
+ */
+ private static ContextualParameters create(final int srcDim, final int dstDim) {
+ return new ContextualParameters(new DefaultOperationMethod(
+ Collections.singletonMap(DefaultOperationMethod.NAME_KEY, "Test method"),
+ srcDim, dstDim, DefaultParameterDescriptorGroupTest.M1_M1_O1_O2));
+ }
+
+ /**
+ * Tests {@link ContextualParameters#parameter(String)} and {@link ContextualParameters#values()}.
+ */
+ @Test
+ public void testParameters() {
+ final ContextualParameters p = create(1, 1);
+ assertTrue("values().isEmpty()", p.values().isEmpty());
+ assertTrue("normalize.isIdentity()", p.getMatrix(true).isIdentity());
+ assertTrue("denormalize.isIdentity()", p.getMatrix(false).isIdentity());
+
+ final ParameterValue<?> p1 = p.parameter("Mandatory 1");
+ final ParameterValue<?> p2 = p.parameter("Mandatory 2");
+ try {
+ p.parameter("Mandatory 3");
+ fail("Shall not find a non-existent parameter.");
+ } catch (ParameterNotFoundException e) {
+ // This is the expected exception.
+ final String message = e.getMessage();
+ assertTrue(message, message.contains("Mandatory 3"));
+ }
+
+ assertNotSame(p1, p2);
+ assertSame(p1, p.parameter("Mandatory 1"));
+ assertSame(p2, p.parameter("Mandatory 2"));
+ assertEquals("values().size()", 2, p.values().size());
+ assertArrayEquals("values.toArray()", new ParameterValue<?>[] {p1, p2}, p.values().toArray());
+ }
+
+ /**
+ * Tests Well Known Text (WKT) formatting.
+ */
+ @DependsOnMethod("testParameters")
+ public void testWKT() {
+ final ContextualParameters p = create(1, 1);
+ p.parameter("Mandatory 1").setValue(4);
+ p.parameter("Mandatory 2").setValue(5);
+ assertWktEquals(
+ "Param_MT[“Test group”,\n" +
+ " Parameter[“Mandatory 1”, 4],\n" +
+ " Parameter[“Mandatory 2”, 5]]", p);
+ }
+
+ /**
+ * Tests {@link ContextualParameters#completeTransform(MathTransformFactory, MathTransform)}
+ * with identity normalization / denormalization transform. The complete transform should be
+ * equals to the kernel (often the same instance, but not necessarily because of caching).
+ *
+ * @throws FactoryException Should never happen.
+ */
+ @Test
+ public void testSameTransform() throws FactoryException {
+ final ContextualParameters p = create(1, 1);
+ final MathTransform kernel = MathTransforms.linear(3, 4);
+ assertEquals(kernel, p.completeTransform(DefaultMathTransformFactoryTest.FACTORY, kernel));
+ try {
+ p.parameter("Mandatory 1");
+ fail("Shall not be allowed to modify an immutable instance.");
+ } catch (IllegalStateException e) {
+ // This is the expected exception.
+ final String message = e.getMessage();
+ assertTrue(message, message.contains("ContextualParameters"));
+ }
+ }
+}
Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ContextualParametersTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/ContextualParametersTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactoryTest.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -27,8 +27,6 @@ import org.apache.sis.internal.util.Cons
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
import org.junit.Test;
import static org.opengis.test.Assert.*;
@@ -52,23 +50,7 @@ public final strictfp class DefaultMathT
/**
* The factory being tested.
*/
- private static DefaultMathTransformFactory factory;
-
- /**
- * Creates the factory to be tested.
- */
- @BeforeClass
- public static void createFactory() {
- factory = new DefaultMathTransformFactory();
- }
-
- /**
- * Releases the factory used for the tests.
- */
- @AfterClass
- public static void releaseFactory() {
- factory = null;
- }
+ static final DefaultMathTransformFactory FACTORY = new DefaultMathTransformFactory();
/**
* Tests the {@link DefaultMathTransformFactory#getOperationMethod(String)} method.
@@ -78,11 +60,11 @@ public final strictfp class DefaultMathT
@Test
public void testGetOperationMethod() throws NoSuchIdentifierException {
// A conversion which is not a projection.
- OperationMethod method = factory.getOperationMethod(Constants.AFFINE);
+ OperationMethod method = FACTORY.getOperationMethod(Constants.AFFINE);
assertInstanceOf("Affine", Affine.class, method);
// Same than above, using EPSG code.
- assertSame("EPSG:9624", method, factory.getOperationMethod("EPSG:9624"));
+ assertSame("EPSG:9624", method, FACTORY.getOperationMethod("EPSG:9624"));
}
/**
@@ -92,7 +74,7 @@ public final strictfp class DefaultMathT
@DependsOnMethod("testGetOperationMethod")
public void testNonExistentCode() {
try {
- factory.getOperationMethod("EPXX:9624");
+ FACTORY.getOperationMethod("EPXX:9624");
fail("Expected NoSuchIdentifierException");
} catch (NoSuchIdentifierException e) {
final String message = e.getLocalizedMessage();
@@ -108,16 +90,16 @@ public final strictfp class DefaultMathT
@Test
@DependsOnMethod("testGetOperationMethod")
public void testGetAvailableMethods() throws NoSuchIdentifierException {
- final Set<OperationMethod> transforms = factory.getAvailableMethods(SingleOperation.class);
- final Set<OperationMethod> conversions = factory.getAvailableMethods(Conversion.class);
- final Set<OperationMethod> projections = factory.getAvailableMethods(Projection.class);
+ final Set<OperationMethod> transforms = FACTORY.getAvailableMethods(SingleOperation.class);
+ final Set<OperationMethod> conversions = FACTORY.getAvailableMethods(Conversion.class);
+ final Set<OperationMethod> projections = FACTORY.getAvailableMethods(Projection.class);
/*
* Following tests should not cause loading of more classes than needed.
*/
assertFalse(transforms .isEmpty());
assertFalse(conversions.isEmpty());
assertTrue (projections.isEmpty());
- assertTrue (conversions.contains(factory.getOperationMethod(Constants.AFFINE)));
+ assertTrue (conversions.contains(FACTORY.getOperationMethod(Constants.AFFINE)));
/*
* Following tests will force instantiation of all remaining OperationMethod.
*/
Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1669621&r1=1669620&r2=1669621&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Fri Mar 27 17:04:01 2015
@@ -85,6 +85,7 @@ import org.junit.BeforeClass;
org.apache.sis.referencing.operation.transform.ConcatenatedTransformTest.class,
org.apache.sis.referencing.operation.transform.TransferFunctionTest.class,
org.apache.sis.referencing.operation.transform.MathTransformsTest.class,
+ org.apache.sis.referencing.operation.transform.ContextualParametersTest.class,
// Test map projections.
org.apache.sis.referencing.operation.DefaultFormulaTest.class,