Author: desruisseaux
Date: Sun Feb 1 22:16:42 2015
New Revision: 1656369
URL: http://svn.apache.org/r1656369
Log:
When formatting in the WKT 1 format, try to check if using the "PROJECTION"
keyword actually make sense.
Note that WKT 2 does not have this problem, since its "METHOD" keyword is more
generic.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java?rev=1656369&r1=1656368&r2=1656369&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultOperationMethod.java
[UTF-8] Sun Feb 1 22:16:42 2015
@@ -22,8 +22,10 @@ import java.util.Collections;
import org.opengis.metadata.citation.Citation;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.operation.Formula;
+import org.opengis.referencing.operation.Projection;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.OperationMethod;
+import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.apache.sis.util.Utilities;
import org.apache.sis.util.ComparisonMode;
@@ -144,9 +146,9 @@ public class DefaultOperationMethod exte
* with any number of dimensions (e.g. <cite>Affine Transform</cite>).
*
* @param properties Set of properties. Shall contain at least {@code
"name"}.
- * @param sourceDimension Number of dimensions in the source CRS of this
operation method.
- * @param targetDimension Number of dimensions in the target CRS of this
operation method.
- * @param parameters The set of parameters.
+ * @param sourceDimension Number of dimensions in the source CRS of this
operation method, or {@code null}.
+ * @param targetDimension Number of dimensions in the target CRS of this
operation method, or {@code null}.
+ * @param parameters Description of parameters expected by this
operation.
*/
public DefaultOperationMethod(final Map<String,?> properties,
final Integer sourceDimension,
@@ -331,6 +333,36 @@ public class DefaultOperationMethod exte
}
/**
+ * Returns the base interface of the {@code CoordinateOperation} instances
that use this method.
+ * The base {@code CoordinateOperation} interface is usually one of the
following subtypes:
+ *
+ * <ul>
+ * <li>{@link org.opengis.referencing.operation.Transformation}
+ * if the coordinate operation has some errors (typically of a few
metres) because of the empirical process by
+ * which the operation parameters were determined. Those errors do not
depend on the floating point precision
+ * or the accuracy of the implementation algorithm.</li>
+ * <li>{@link org.opengis.referencing.operation.Conversion}
+ * if the coordinate operation is theoretically of infinite precision,
ignoring the limitations of floating
+ * point arithmetic (including rounding errors) and the approximations
implied by finite series expansions.</li>
+ * <li>{@link org.opengis.referencing.operation.Projection}
+ * if the coordinate operation is a conversion (as defined above)
converting geodetic latitudes and longitudes
+ * to plane (map) coordinates. This type can optionally be refined
with one of the
+ * {@link org.opengis.referencing.operation.CylindricalProjection},
+ * {@link org.opengis.referencing.operation.ConicProjection} or
+ * {@link org.opengis.referencing.operation.PlanarProjection}
subtypes.</li>
+ * </ul>
+ *
+ * In case of doubt, this method can conservatively return the base type.
+ * The default implementation returns {@code CoordinateOperation.class},
+ * which is the most conservative return value.
+ *
+ * @return Interface implemented by all coordinate operations that use
this method.
+ */
+ public Class<? extends CoordinateOperation> getOperationType() {
+ return CoordinateOperation.class;
+ }
+
+ /**
* Formula(s) or procedure used by this operation method. This may be a
reference to a
* publication. Note that the operation method may not be analytic, in
which case this
* attribute references or contains the procedure, not an analytic formula.
@@ -466,6 +498,29 @@ public class DefaultOperationMethod exte
@Override
protected String formatTo(final Formatter formatter) {
super.formatTo(formatter);
- return (formatter.getConvention().majorVersion() == 1) ? "Projection"
: "Method";
+ if (formatter.getConvention().majorVersion() == 1) {
+ /*
+ * The WKT 1 keyword is "PROJECTION", which imply that the
operation method should be of type
+ * org.opengis.referencing.operation.Projection. So strictly
speaking only the first check in
+ * the following 'if' statement is relevant.
+ *
+ * Unfortunately in many cases we do not know the operation type,
because the method that we
+ * invoked - getOperationType() - is not a standard OGC/ISO
property, so this information is
+ * usually not provided in XML documents for example. The user
could also have instantiated
+ * DirectOperationMethod directly without creating a subclass.
Consequently we also accept to
+ * format the keyword as "PROJECTION" if the operation type
*could* be a projection. This is
+ * the second check in the following 'if' statement.
+ *
+ * In other words, the combination of those two checks exclude the
following operation types:
+ * Transformation, ConcatenatedOperation, PassThroughOperation, or
any user-defined type that
+ * do not extend Projection. All other operation types are
accepted.
+ */
+ final Class<? extends CoordinateOperation> type =
getOperationType();
+ if (Projection.class.isAssignableFrom(type) ||
type.isAssignableFrom(Projection.class)) {
+ return "Projection";
+ }
+ formatter.setInvalidWKT(this, null);
+ }
+ return "Method";
}
}