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";
     }
 }


Reply via email to