Author: desruisseaux
Date: Tue Jul 19 11:21:15 2016
New Revision: 1753364
URL: http://svn.apache.org/viewvc?rev=1753364&view=rev
Log:
Consolidation in the way CoordinateOperationFinder try to invert coordinate
operations.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java?rev=1753364&r1=1753363&r2=1753364&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationFinder.java
[UTF-8] Tue Jul 19 11:21:15 2016
@@ -354,8 +354,10 @@ public class CoordinateOperationFinder e
final CoordinateOperation step1;
try {
step1 = inverse(sourceCRS.getConversionFromBase());
- } catch (NoninvertibleTransformException exception) {
- throw new OperationNotFoundException(notFoundMessage(sourceCRS,
targetCRS), exception);
+ } catch (OperationNotFoundException exception) {
+ throw exception;
+ } catch (FactoryException | NoninvertibleTransformException exception)
{
+ throw new OperationNotFoundException(canNotInvert(sourceCRS),
exception);
}
return concatenate(step1, step2);
}
@@ -385,8 +387,10 @@ public class CoordinateOperationFinder e
final CoordinateOperation step1;
try {
step1 = inverse(sourceCRS.getConversionFromBase());
- } catch (NoninvertibleTransformException exception) {
- throw new OperationNotFoundException(notFoundMessage(sourceCRS,
targetCRS), exception);
+ } catch (OperationNotFoundException exception) {
+ throw exception;
+ } catch (FactoryException | NoninvertibleTransformException exception)
{
+ throw new OperationNotFoundException(canNotInvert(sourceCRS),
exception);
}
return concatenate(step1, step2, step3);
}
@@ -1058,4 +1062,15 @@ public class CoordinateOperationFinder e
private static String notFoundMessage(final IdentifiedObject source, final
IdentifiedObject target) {
return Errors.format(Errors.Keys.CoordinateOperationNotFound_2,
CRSPair.label(source), CRSPair.label(target));
}
+
+ /**
+ * Returns an error message for "Can not invert operation XYZ.".
+ * This is used for the construction of {@link OperationNotFoundException}.
+ *
+ * @param crs the CRS having a conversion that can not be inverted.
+ * @return A default error message.
+ */
+ private static String canNotInvert(final GeneralDerivedCRS crs) {
+ return Errors.format(Errors.Keys.NonInvertibleOperation_1,
crs.getConversionFromBase().getName().getCode());
+ }
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java?rev=1753364&r1=1753363&r2=1753364&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationRegistry.java
[UTF-8] Tue Jul 19 11:21:15 2016
@@ -493,24 +493,52 @@ class CoordinateOperationRegistry {
/**
* Creates the inverse of the given single operation.
+ * If this operation succeed, then the returned coordinate operations has
the following properties:
+ *
+ * <ul>
+ * <li>Its {@code sourceCRS} is the {@code targetCRS} of the given
operation.</li>
+ * <li>Its {@code targetCRS} is the {@code sourceCRS} of the given
operation.</li>
+ * <li>Its {@code interpolationCRS} is {@code null}.</li>
+ * <li>Its {@code MathTransform} is the
+ * {@linkplain
org.apache.sis.referencing.operation.transform.AbstractMathTransform#inverse()
inverse}
+ * of the {@code MathTransform} of this operation.</li>
+ * <li>Its domain of validity and accuracy is the same.</li>
+ * </ul>
+ *
+ * <div class="note"><b>Note:</b>
+ * in many cases, the inverse operation is numerically less accurate than
the direct operation because it
+ * uses approximations like series expansions or iterative methods.
However the numerical errors caused by
+ * those approximations are not of interest here, because they are usually
much smaller than the inaccuracy
+ * due to the stochastic nature of coordinate transformations (not to be
confused with coordinate conversions;
+ * see ISO 19111 for more information).</div>
*/
final CoordinateOperation inverse(final SingleOperation op) throws
NoninvertibleTransformException, FactoryException {
final CoordinateReferenceSystem sourceCRS = op.getSourceCRS();
final CoordinateReferenceSystem targetCRS = op.getTargetCRS();
final MathTransform transform = op.getMathTransform().inverse();
+ final OperationMethod method =
InverseOperationMethod.create(op.getMethod());
+ final Map<String,Object> properties = properties(INVERSE_OPERATION);
+ InverseOperationMethod.properties(op, properties);
+ /*
+ * Find a hint about whether the coordinate operation is a
transformation or a conversion,
+ * but do not set any conversion subtype. In particular, do not
specify a Projection type,
+ * because the inverse of a Projection does not implement the
Projection interface.
+ */
Class<? extends CoordinateOperation> type = null;
if (op instanceof Transformation) type = Transformation.class;
else if (op instanceof Conversion) type = Conversion.class;
- final Map<String,Object> properties = properties(INVERSE_OPERATION);
- InverseOperationMethod.putMetadata(op, properties);
- InverseOperationMethod.putParameters(op, properties);
- return createFromMathTransform(properties, targetCRS, sourceCRS,
- transform, InverseOperationMethod.create(op.getMethod()),
null, type);
+ return createFromMathTransform(properties, targetCRS, sourceCRS,
transform, method, null, type);
}
/**
* Creates the inverse of the given operation, which may be single or
compound.
*
+ * <p><b>Design note:</b>
+ * we do not provide a {@code AbstractCoordinateOperation.inverse()}
method. If the user wants an inverse method,
+ * he should invoke {@code CRS.findOperation(targetCRS, sourceCRS, null)}
or something equivalent. This is because
+ * a new query of EPSG database may be necessary, and if no explicit
definition is found there is too many arbitrary
+ * values to set in a default inverse operation for making that API
public.</p>
+ *
* @param operation The operation to invert, or {@code null}.
* @return The inverse of {@code operation}, or {@code null} if none.
* @throws NoninvertibleTransformException if the operation is not
invertible.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java?rev=1753364&r1=1753363&r2=1753364&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
[UTF-8] Tue Jul 19 11:21:15 2016
@@ -45,7 +45,7 @@ import org.apache.sis.util.Deprecable;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.7
- * @version 0.7
+ * @version 0.8
* @module
*/
@XmlTransient
@@ -107,7 +107,15 @@ final class InverseOperationMethod exten
}
/**
- * Copies accuracy and domain of validity metadata from the given
operation into the given properties map.
+ * Infers the properties to give to an inverse coordinate operation.
+ * The returned map will contains three kind of information:
+ *
+ * <ul>
+ * <li>Metadata (domain of validity, accuracy)</li>
+ * <li>Parameter values, if possible</li>
+ * </ul>
+ *
+ * This method copies accuracy and domain of validity metadata from the
given operation.
* We presume that the inverse operation has the same accuracy than the
direct operation.
*
* <div class="note"><b>Note:</b>
@@ -116,25 +124,25 @@ final class InverseOperationMethod exten
* those approximations are not of interest here, because they are usually
much smaller than the inaccuracy
* due to the stochastic nature of coordinate transformations (not to be
confused with coordinate conversions;
* see ISO 19111 for more information).</div>
+ *
+ * If the inverse of the given operation can be represented by inverting
the sign of all numerical
+ * parameter values, then this method copies also those parameters in a
{@code "parameters"} entry.
+ *
+ * @param source the operation for which to get the inverse parameters.
+ * @param target where to store the inverse parameters.
*/
- static void putMetadata(final SingleOperation source, final
Map<String,Object> target) {
+ static void properties(final SingleOperation source, final
Map<String,Object> target) {
target.put(SingleOperation.DOMAIN_OF_VALIDITY_KEY,
source.getDomainOfValidity());
final Collection<PositionalAccuracy> accuracy =
source.getCoordinateOperationAccuracy();
if (!Containers.isNullOrEmpty(accuracy)) {
target.put(SingleOperation.COORDINATE_OPERATION_ACCURACY_KEY,
accuracy.toArray(new PositionalAccuracy[accuracy.size()]));
}
- }
-
- /**
- * If the inverse of the given operation can be represented by inverting
the sign of all numerical
- * parameter values, copies those parameters in a {@code "parameters"}
entry in the given map.
- * Otherwise does nothing.
- *
- * @param source the operation for which to get the inverse parameters.
- * @param target where to store the inverse parameters.
- */
- static void putParameters(final SingleOperation source, final
Map<String,Object> target) {
+ /*
+ * If the inverse of the given operation can be represented by
inverting the sign of all numerical
+ * parameter values, copies those parameters in a "parameters" entry
in the properties map.
+ * Otherwise does nothing.
+ */
final boolean isInvertible = isInvertible(source.getMethod());
final ParameterValueGroup parameters = source.getParameterValues();
final ParameterValueGroup copy =
parameters.getDescriptor().createValue();
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1753364&r1=1753363&r2=1753364&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] Tue Jul 19 11:21:15 2016
@@ -807,6 +807,11 @@ public final class Errors extends Indexe
public static final short NonInvertibleMatrix_2 = 81;
/**
+ * Can not invert the “{0}” operation.
+ */
+ public static final short NonInvertibleOperation_1 = 232;
+
+ /**
* Transform is not invertible.
*/
public static final short NonInvertibleTransform = 82;
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1753364&r1=1753363&r2=1753364&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] Tue Jul 19 11:21:15 2016
@@ -166,6 +166,7 @@ NodeNotFound_1 = No \
NonEquilibratedParenthesis_2 = Missing a \u2018{1}\u2019 parenthesis in
\u201c{0}\u201d.
NonInvertibleConversion = Conversion is not invertible.
NonInvertibleMatrix_2 = Non invertible {0}\u00d7{1} matrix.
+NonInvertibleOperation_1 = Can not invert the \u201c{0}\u201d
operation.
NonInvertibleTransform = Transform is not invertible.
NonAngularUnit_1 = \u201c{0}\u201d is not an angular unit.
NonLinearUnit_1 = \u201c{0}\u201d is not a linear unit.
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1753364&r1=1753363&r2=1753364&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] Tue Jul 19 11:21:15 2016
@@ -163,6 +163,7 @@ NodeNotFound_1 = Aucu
NonEquilibratedParenthesis_2 = Il manque une parenth\u00e8se
\u2018{1}\u2019 dans \u00ab\u202f{0}\u202f\u00bb.
NonInvertibleConversion = La conversion n\u2019est pas inversible.
NonInvertibleMatrix_2 = Matrice {0}\u00d7{1} non inversible.
+NonInvertibleOperation_1 = Ne peut pas inverser l\u2019op\u00e9ration
\u00ab\u202f{0}\u202f\u00bb.
NonInvertibleTransform = La transformation n\u2019est pas
inversible.
NonAngularUnit_1 = \u00ab\u202f{0}\u202f\u00bb n\u2019est pas
une unit\u00e9 d\u2019angles.
NonLinearUnit_1 = \u00ab\u202f{0}\u202f\u00bb n\u2019est pas
une unit\u00e9 de longueurs.