This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 27b60b2  Parse GEOGTRAN element from ESRI WKT.
27b60b2 is described below

commit 27b60b23d30d8ed59c1a23ed62b5b15a9fcb5db6
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu Feb 24 00:07:48 2022 +0100

    Parse GEOGTRAN element from ESRI WKT.
    
    https://issues.apache.org/jira/browse/SIS-538
---
 .../sis/internal/referencing/WKTKeywords.java      |  5 +-
 .../provider/CoordinateFrameRotation2D.java        |  4 +-
 .../provider/GeocentricTranslation2D.java          |  4 +-
 .../provider/PositionVector7Param2D.java           |  4 +-
 .../apache/sis/io/wkt/GeodeticObjectParser.java    | 79 ++++++++++++++++++----
 .../sis/io/wkt/GeodeticObjectParserTest.java       | 40 ++++++++++-
 6 files changed, 117 insertions(+), 19 deletions(-)

diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTKeywords.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTKeywords.java
index aab1794..5cba02d 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTKeywords.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTKeywords.java
@@ -38,7 +38,7 @@ import org.apache.sis.util.ArraysExt;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.1
+ * @version 1.2
  *
  * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html";>WKT 
2 specification</a>
  * @see <a 
href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html";>Legacy
 WKT 1</a>
@@ -190,7 +190,8 @@ public final class WKTKeywords extends Static {
             InterpolationCRS    = "InterpolationCRS",
             Parameter           = "Parameter",
             ParameterFile       = "ParameterFile",
-            ParameterGroup      = "ParameterGroup";
+            ParameterGroup      = "ParameterGroup",
+            GeogTran            = "GeogTran";               // ESRI-specific.
 
     /**
      * Related to {@link 
org.apache.sis.referencing.operation.transform.AbstractMathTransform}.
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java
index 40811bf..793ee0b 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/CoordinateFrameRotation2D.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.referencing.provider;
 
 import javax.xml.bind.annotation.XmlTransient;
 import org.opengis.parameter.ParameterDescriptorGroup;
+import org.apache.sis.metadata.iso.citation.Citations;
 
 
 /**
@@ -26,7 +27,7 @@ import org.opengis.parameter.ParameterDescriptorGroup;
  * except that the rotation angles have the opposite sign.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 1.2
  * @since   0.7
  * @module
  */
@@ -45,6 +46,7 @@ public final class CoordinateFrameRotation2D extends 
GeocentricAffineBetweenGeog
         PARAMETERS = builder()
                 .addIdentifier("9607")
                 .addName("Coordinate Frame Rotation (geog2D domain)")
+                .addName(Citations.ESRI, "Coordinate_Frame")
                 
.createGroupWithSameParameters(PositionVector7Param2D.PARAMETERS);
         /*
          * NOTE: we omit the "Bursa-Wolf" alias because it is ambiguous, since 
it can apply
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java
index 8d82430..2ddc373 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeocentricTranslation2D.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.referencing.provider;
 
 import javax.xml.bind.annotation.XmlTransient;
 import org.opengis.parameter.ParameterDescriptorGroup;
+import org.apache.sis.metadata.iso.citation.Citations;
 
 
 /**
@@ -26,7 +27,7 @@ import org.opengis.parameter.ParameterDescriptorGroup;
  * terms can be set to a non-null value.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 1.2
  * @since   0.7
  * @module
  */
@@ -45,6 +46,7 @@ public final class GeocentricTranslation2D extends 
GeocentricAffineBetweenGeogra
         PARAMETERS = builder()
                 .addIdentifier("9603")
                 .addName("Geocentric translations (geog2D domain)")
+                .addName(Citations.ESRI, "Geocentric_Translation")
                 .createGroup(SRC_SEMI_MAJOR,
                              SRC_SEMI_MINOR,
                              TGT_SEMI_MAJOR,
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java
index fd31367..9ef0cd3 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/PositionVector7Param2D.java
@@ -18,13 +18,14 @@ package org.apache.sis.internal.referencing.provider;
 
 import javax.xml.bind.annotation.XmlTransient;
 import org.opengis.parameter.ParameterDescriptorGroup;
+import org.apache.sis.metadata.iso.citation.Citations;
 
 
 /**
  * The provider for <cite>"Position Vector transformation (geog2D 
domain)"</cite> (EPSG:9606).
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 1.2
  * @since   0.7
  * @module
  */
@@ -43,6 +44,7 @@ public final class PositionVector7Param2D extends 
GeocentricAffineBetweenGeograp
         PARAMETERS = builder()
                 .addIdentifier("9606")
                 .addName("Position Vector transformation (geog2D domain)")
+                .addName(Citations.ESRI, "Position_Vector")
                 .createGroup(SRC_SEMI_MAJOR,
                              SRC_SEMI_MINOR,
                              TGT_SEMI_MAJOR,
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
index 2d30f41..3ed1bf7 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
@@ -98,7 +98,7 @@ import static java.util.Collections.singletonMap;
  * @author  Rémi Eve (IRD)
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.6
  * @module
  */
@@ -319,7 +319,8 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
             (object = parseParametricDatum  (FIRST, element       )) == null &&
             (object = parseEngineeringDatum (FIRST, element, false)) == null &&
             (object = parseImageDatum       (FIRST, element       )) == null &&
-            (object = parseOperation        (FIRST, element))        == null)
+            (object = parseOperation        (FIRST, element))        == null &&
+            (object = parseGeogTranslation  (FIRST, element))        == null)
         {
             throw element.missingOrUnknownComponent(WKTKeywords.GeodeticCRS);
         }
@@ -407,6 +408,8 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
      * @param  fallback  the fallback to use if {@code name} is empty.
      * @return a properties map with the parent name and the optional 
authority code.
      * @throws ParseException if an element can not be parsed.
+     *
+     * @see #parseParametersAndClose(Element, String, OperationMethod)
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
     private Map<String,Object> parseMetadataAndClose(final Element parent, 
final String name,
@@ -2248,6 +2251,32 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
     }
 
     /**
+     * Parses a {@code "GeogTran"} element. This is specific to ESRI.
+     *
+     * @param  mode    {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
+     * @param  parent  the parent element.
+     * @return the {@code "GeogTran"} element as a {@link CoordinateOperation} 
object.
+     * @throws ParseException if the {@code "GeogTran"} element can not be 
parsed.
+     */
+    private CoordinateOperation parseGeogTranslation(final int mode, final 
Element parent) throws ParseException {
+        final Element element = parent.pullElement(mode, WKTKeywords.GeogTran);
+        if (element == null) {
+            return null;
+        }
+        final String name = element.pullString("name");
+        final CoordinateReferenceSystem sourceCRS  = 
parseCoordinateReferenceSystem(element, true);
+        final CoordinateReferenceSystem targetCRS  = 
parseCoordinateReferenceSystem(element, true);
+        final OperationMethod           method     = parseMethod(element, 
WKTKeywords.Method);
+        final Map<String,Object>        properties = 
parseParametersAndClose(element, name, method);
+        try {
+            final DefaultCoordinateOperationFactory df = getOperationFactory();
+            return df.createSingleOperation(properties, sourceCRS, targetCRS, 
null, method, null);
+        } catch (FactoryException e) {
+            throw element.parseFailed(e);
+        }
+    }
+
+    /**
      * 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>.
      *
@@ -2267,26 +2296,50 @@ class GeodeticObjectParser extends MathTransformParser 
implements Comparator<Coo
         final CoordinateReferenceSystem interpolationCRS = 
parseCoordinateReferenceSystem(element, OPTIONAL,  
WKTKeywords.InterpolationCRS);
         final OperationMethod           method           = 
parseMethod(element, WKTKeywords.Method);
         final Element                   accuracy         = 
element.pullElement(OPTIONAL, WKTKeywords.OperationAccuracy);
-        final Map<String,Object>        properties       = 
parseMetadataAndClose(element, name, method);
-        final ParameterValueGroup       parameters       = 
method.getParameters().createValue();
-        parseParameters(element, parameters, null, null);
-        properties.put(CoordinateOperations.PARAMETERS_KEY, parameters);
+        final Map<String,Object>        properties       = 
parseParametersAndClose(element, name, method);
         if (accuracy != null) {
             
properties.put(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY,
                     
TransformationAccuracy.create(accuracy.pullDouble("accuracy")));
             accuracy.close(ignoredElements);
         }
         try {
-            final DefaultCoordinateOperationFactory df;
-            final CoordinateOperationFactory opFactory = 
factories.getCoordinateOperationFactory();
-            if (opFactory instanceof DefaultCoordinateOperationFactory) {
-                df = (DefaultCoordinateOperationFactory) opFactory;
-            } else {
-                df = CoordinateOperations.factory();
-            }
+            final DefaultCoordinateOperationFactory df = getOperationFactory();
             return df.createSingleOperation(properties, sourceCRS, targetCRS, 
interpolationCRS, method, null);
         } catch (FactoryException e) {
             throw element.parseFailed(e);
         }
     }
+
+    /**
+     * Parses a sequence of {@code "PARAMETER"} elements, then parses optional 
metadata elements and close.
+     *
+     * @param  parent  the parent element.
+     * @param  name    the name of the parent object being parsed.
+     * @param  method  the operation method, also the fallback to use if 
{@code name} is empty.
+     * @return a properties map with the parent name, the optional authority 
code and the parameters.
+     * @throws ParseException if an element can not be parsed.
+     *
+     * @see #parseMetadataAndClose(Element, String, IdentifiedObject)
+     */
+    private Map<String,Object> parseParametersAndClose(final Element parent, 
final String name,
+            final OperationMethod method) throws ParseException
+    {
+        final ParameterValueGroup parameters = 
method.getParameters().createValue();
+        parseParameters(parent, parameters, null, null);
+        final Map<String,Object> properties = parseMetadataAndClose(parent, 
name, method);
+        properties.put(CoordinateOperations.PARAMETERS_KEY, parameters);
+        return properties;
+    }
+
+    /**
+     * Returns the factory to use for creating coordinate operation.
+     */
+    private DefaultCoordinateOperationFactory getOperationFactory() {
+        final CoordinateOperationFactory opFactory = 
factories.getCoordinateOperationFactory();
+        if (opFactory instanceof DefaultCoordinateOperationFactory) {
+            return (DefaultCoordinateOperationFactory) opFactory;
+        } else {
+            return CoordinateOperations.factory();
+        }
+    }
 }
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
index 8aaeb76..e092f7f 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
@@ -31,6 +31,7 @@ import org.opengis.referencing.datum.*;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.parameter.ParameterValue;
 import org.opengis.parameter.ParameterValueGroup;
 import org.apache.sis.internal.metadata.AxisNames;
@@ -56,7 +57,7 @@ import static 
org.apache.sis.internal.util.StandardDateFormat.MILLISECONDS_PER_D
  * Tests {@link GeodeticObjectParser}.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.6
  * @module
  */
@@ -1089,6 +1090,43 @@ public final strictfp class GeodeticObjectParserTest 
extends TestCase {
     }
 
     /**
+     * Tests the parsing of a {@code GEOGTRAN} coordinate operation.
+     * This is specific to ESRI.
+     *
+     * @throws ParseException if the parsing failed.
+     *
+     * @since 1.2
+     */
+    @Test
+    @DependsOnMethod("testGeographicWithImplicitAxes")
+    public void testGeogTran() throws ParseException {
+        final CoordinateOperation op = parse(CoordinateOperation.class,
+                "GEOGTRAN[“Palestine_1923_to_WGS_84_1”,\n" +
+                "  GEOGCS[“GCS_Palestine_1923”,\n" +
+                "    DATUM[“D_Palestine_1923”,\n" +
+                "      SPHEROID[“Clarke_1880_Benoit”, 6378300.789, 
293.46631553898]],\n" +
+                "      PRIMEM[“Greenwich”, 0.0], UNIT[“Degree”, 
0.0174532925199433]],\n" +
+                "  GEOGCS[“GCS_WGS_1984”,\n" +
+                "    DATUM[“D_WGS_1984”,\n" +
+                "    SPHEROID[“WGS_1984”, 6378137.0, 298.257223563]],\n" +
+                "    PRIMEM[“Greenwich”, 0.0], UNIT[“Degree”, 
0.0174532925199433]],\n" +
+                "  METHOD[“Position_Vector”],\n" +
+                "    PARAMETER[“X_Axis_Translation”, -275.7224],\n" +
+                "    PARAMETER[“Y_Axis_Translation”, 94.7824],\n" +
+                "    PARAMETER[“Z_Axis_Translation”, 340.8944],\n" +
+                "    PARAMETER[“X_Axis_Rotation”, -8.001],\n" +
+                "    PARAMETER[“Y_Axis_Rotation”, -4.42],\n" +
+                "    PARAMETER[“Z_Axis_Rotation”,-11.821],\n" +
+                "    PARAMETER[“Scale_Difference”, 1.0],\n" +
+                "  AUTHORITY[“EPSG”, 1074]]");
+
+        final GeographicCRS sourceCRS = (GeographicCRS) op.getSourceCRS();
+        final GeographicCRS targetCRS = (GeographicCRS) op.getTargetCRS();
+        assertNameAndIdentifierEqual("GCS_Palestine_1923", 0, sourceCRS);
+        assertNameAndIdentifierEqual("GCS_WGS_1984",       0, targetCRS);
+    }
+
+    /**
      * Ensures that parsing a WKT with wrong units throws an exception.
      */
     @Test

Reply via email to