sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1689049 - /sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
Date Fri, 03 Jul 2015 17:37:53 GMT
Author: desruisseaux
Date: Fri Jul  3 17:37:53 2015
New Revision: 1689049

URL: http://svn.apache.org/r1689049
Log:
WKT 2: implement parsing of CoordinateOperation (missing only the call to a factory method).

Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1689049&r1=1689048&r2=1689049&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
[UTF-8] Fri Jul  3 17:37:53 2015
@@ -357,6 +357,27 @@ final class GeodeticObjectParser extends
     }
 
     /**
+     * Parses a coordinate reference system wrapped in an element of the given name.
+     *
+     * @param  parent   The parent element containing the CRS to parse.
+     * @param  mode     {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
+     * @param  keyword  "SourceCRS", "TargetCRS" or "InterpolationCRS".
+     * @return The coordinate reference system, or {@code null} if none.
+     * @throws ParseException if the CRS can not be parsed.
+     */
+    private CoordinateReferenceSystem parseCoordinateReferenceSystem(final Element parent,
final int mode,
+            final String keyword) throws ParseException
+    {
+        final Element element = parent.pullElement(mode, keyword);
+        if (element == null) {
+            return null;
+        }
+        final CoordinateReferenceSystem crs = parseCoordinateReferenceSystem(element, true);
+        element.close(ignoredElements);
+        return crs;
+    }
+
+    /**
      * Returns the value associated to {@link IdentifiedObject#IDENTIFIERS_KEY} as an {@code
Identifier} object.
      * This method shall accept all value types that {@link #parseMetadataAndClose(Element,
Object)} may store.
      *
@@ -1157,6 +1178,43 @@ final class GeodeticObjectParser extends
     }
 
     /**
+     * Parses a {@code "Method"} (WKT 2) element, without the parameters.
+     *
+     * @param  parent   The parent element.
+     * @param  keywords The element keywords.
+     * @return The operation method.
+     * @throws ParseException if the {@code "Method"} element can not be parsed.
+     */
+    private OperationMethod parseMethod(final Element parent, final String... keywords) throws
ParseException {
+        final Element element    = parent.pullElement(MANDATORY, keywords);
+        final String  name       = element.pullString("method");
+        Map<String,?> properties = parseMetadataAndClose(element, name, null);
+        final Identifier id      = toIdentifier(properties.remove(IdentifiedObject.IDENTIFIERS_KEY));
 // See NOTE 2 in parseDerivingConversion.
+        /*
+         * The map projection method may be specified by an EPSG identifier (or any other
authority),
+         * which is preferred to the method name since the later is potentially ambiguous.
However not
+         * all CoordinateOperationFactory may accept identifier as an argument to 'getOperationMethod'.
+         * So if an identifier is present, we will try to use it but fallback on the name
if we can
+         * not use the identifier.
+         */
+        FactoryException suppressed = null;
+        if (id != null) try {
+            // CodeSpace is a mandatory attribute in ID[…] elements, so we do not test
for null values.
+            return opFactory.getOperationMethod(id.getCodeSpace() + DefaultNameSpace.DEFAULT_SEPARATOR
+ id.getCode());
+        } catch (FactoryException e) {
+            suppressed = e;
+        }
+        try {
+            return opFactory.getOperationMethod(name);
+        } catch (FactoryException e) {
+            if (suppressed != null) {
+                e.addSuppressed(suppressed);
+            }
+            throw element.parseFailed(e);
+        }
+    }
+
+    /**
      * Parses a {@code "Method"} (WKT 2) element, followed by parameter values. The syntax
is given by
      * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#62">WKT 2
specification §9.3</a>.
      *
@@ -1195,25 +1253,8 @@ final class GeodeticObjectParser extends
             }
             name = parent.pullString("name");
         }
-        final Element element    = parent.pullElement(MANDATORY, WKTKeywords.Method, WKTKeywords.Projection);
-        final String  methodName = element.pullString("method");
-        Map<String,?> properties = parseMetadataAndClose(element, methodName, null);
-        final Identifier id      = toIdentifier(properties.remove(IdentifiedObject.IDENTIFIERS_KEY));
// See NOTE 2.
-        /*
-         * The map projection method may be specified by an EPSG identifier (or any other
authority),
-         * which is preferred to the method name since the later is potentially ambiguous.
However not
-         * all CoordinateOperationFactory may accept identifier as an argument to 'getOperationMethod'.
-         * So if an identifier is present, we will try to use it but fallback on the name
if we can
-         * not use the identifier.
-         */
-        OperationMethod  method     = null;
-        FactoryException suppressed = null;
-        if (id != null) try {
-            // CodeSpace is a mandatory attribute in ID[…] elements, so we do not test
for null values.
-            method = opFactory.getOperationMethod(id.getCodeSpace() + DefaultNameSpace.DEFAULT_SEPARATOR
+ id.getCode());
-        } catch (FactoryException e) {
-            suppressed = e;
-        }
+        OperationMethod method = parseMethod(parent, WKTKeywords.Method, WKTKeywords.Projection);
+        Map<String,?> properties = this.properties;  // Same properties then OperationMethod,
with ID removed.
         /*
          * Set the list of parameters.
          *
@@ -1224,32 +1265,26 @@ final class GeodeticObjectParser extends
          *         but we shall not inherit the OperationMethod identifier. This is the reason
why we invoked
          *         properties.remove(IdentifiedObject.IDENTIFIERS_KEY)) above.
          */
+        final ParameterValueGroup parameters = method.getParameters().createValue();
+        parseParameters(parent, parameters, defaultUnit, defaultAngularUnit);
+        if (wrapper != null) {
+            properties = parseMetadataAndClose(parent, name, method);
+            /*
+             * DEPARTURE FROM ISO 19162: the specification in §9.3.2 said:
+             *
+             *     "If an identifier is provided as an attribute within the <map projection
conversion> object,
+             *     because it is expected to describe a complete collection of zone name,
method, parameters and
+             *     parameter values, it shall override any identifiers given within the map
projection method and
+             *     map projection parameter objects."
+             *
+             * However this would require this GeodeticObjectParser to hold a CoordinateOperationAuthorityFactory,
+             * which we do not yet implement. See https://issues.apache.org/jira/browse/SIS-210
+             */
+        }
         try {
-            if (method == null) {
-                method = opFactory.getOperationMethod(methodName);
-            }
-            final ParameterValueGroup parameters = method.getParameters().createValue();
-            parseParameters(parent, parameters, defaultUnit, defaultAngularUnit);
-            if (wrapper != null) {
-                properties = parseMetadataAndClose(parent, name, method);
-                /*
-                 * DEPARTURE FROM ISO 19162: the specification in §9.3.2 said:
-                 *
-                 *     "If an identifier is provided as an attribute within the <map projection
conversion> object,
-                 *     because it is expected to describe a complete collection of zone name,
method, parameters and
-                 *     parameter values, it shall override any identifiers given within the
map projection method and
-                 *     map projection parameter objects."
-                 *
-                 * However this would require this GeodeticObjectParser to hold a CoordinateOperationAuthorityFactory,
-                 * which we do not yet implement. See https://issues.apache.org/jira/browse/SIS-210
-                 */
-            }
             return opFactory.createDefiningConversion(properties, method, parameters);
         } catch (FactoryException exception) {
-            if (suppressed != null) {
-                exception.addSuppressed(suppressed);
-            }
-            throw element.parseFailed(exception);
+            throw parent.parseFailed(exception);
         }
     }
 
@@ -1935,8 +1970,10 @@ final class GeodeticObjectParser extends
     }
 
     /**
-     * Parses a {@code "COMPD_CS"} element.
-     * This element has the following pattern:
+     * Parses a {@code "CompoundCRS"} element. The syntax is given by
+     * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#110">WKT 2
specification §16</a>.
+     *
+     * The legacy WKT 1 specification was:
      *
      * {@preformat text
      *     COMPD_CS["<name>", <head cs>, <tail cs> {,<authority>}]
@@ -1944,8 +1981,8 @@ final class GeodeticObjectParser extends
      *
      * @param  mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
      * @param  parent The parent element.
-     * @return The {@code "COMPD_CS"} element as a {@link CompoundCRS} object.
-     * @throws ParseException if the {@code "COMPD_CS"} element can not be parsed.
+     * @return The {@code "CompoundCRS"} element as a {@link CompoundCRS} object.
+     * @throws ParseException if the {@code "CompoundCRS"} element can not be parsed.
      */
     private CompoundCRS parseCompoundCRS(final int mode, final Element parent) throws ParseException
{
         final Element element = parent.pullElement(mode, WKTKeywords.CompoundCRS, WKTKeywords.Compd_CS);
@@ -2023,7 +2060,33 @@ final class GeodeticObjectParser extends
         }
     }
 
+    /**
+     * Parses a {@code "CoordinateOperation"} element. The syntax is given by
+     * <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#113">WKT 2
specification §17</a>.
+     *
+     * @param  mode {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
+     * @param  parent The parent element.
+     * @return The {@code "CoordinateOperation"} element as a {@link CoordinateOperation}
object.
+     * @throws ParseException if the {@code "CoordinateOperation"} element can not be parsed.
+     */
     private CoordinateOperation parseOperation(final int mode, final Element parent) throws
ParseException {
+        final Element element = parent.pullElement(mode, WKTKeywords.CoordinateOperation);
+        if (element == null) {
+            return null;
+        }
+        final String name = element.pullString("name");
+        final CoordinateReferenceSystem sourceCRS        = parseCoordinateReferenceSystem(element,
MANDATORY, WKTKeywords.SourceCRS);
+        final CoordinateReferenceSystem targetCRS        = parseCoordinateReferenceSystem(element,
MANDATORY, WKTKeywords.TargetCRS);
+        final CoordinateReferenceSystem interpolationCRS = parseCoordinateReferenceSystem(element,
OPTIONAL,  WKTKeywords.InterpolationCRS);
+        final OperationMethod           method           = parseMethod(parent, WKTKeywords.Method);
+        final Element                   accuracy         = parent.pullElement(OPTIONAL, WKTKeywords.OperationAccuracy);
+        final Map<String,Object>        properties       = parseMetadataAndClose(parent,
name, method);
+        final ParameterValueGroup       parameters       = method.getParameters().createValue();
+        parseParameters(parent, parameters, null, null);
+        if (accuracy != null) {
+            accuracy.pullDouble("accuracy");    // TODO: share the code from EPSG factory.
+            accuracy.close(ignoredElements);
+        }
         return null;    // Not yet implemented.
     }
 }



Mime
View raw message