sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1738569 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/factory/sql/ main/java/org/apache/sis/referencing/operation/ test/java/org/apache/sis/referencing/operation/
Date Mon, 11 Apr 2016 11:14:36 GMT
Author: desruisseaux
Date: Mon Apr 11 11:14:36 2016
New Revision: 1738569

URL: http://svn.apache.org/viewvc?rev=1738569&view=rev
Log:
Add a test and debug the case where axis order does not match the EPSG definition.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.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/DefaultConcatenatedOperation.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java?rev=1738569&r1=1738568&r2=1738569&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
[UTF-8] Mon Apr 11 11:14:36 2016
@@ -1159,8 +1159,12 @@ addURIs:    for (int i=0; ; i++) {
      * @return The name together with a set of properties.
      */
     private Map<String,Object> createProperties(final String table, final String name,
final Integer code,
-            final String domainCode, String scope, String remarks, final boolean deprecated)
throws SQLException, FactoryException
+            final String domainCode, String scope, final String remarks, final boolean deprecated)
+            throws SQLException, FactoryException
     {
+        if ("?".equals(scope)) {                // EPSG sometime uses this value for unspecified
scope.
+            scope = null;
+        }
         final Map<String,Object> properties = createProperties(table, name, code, remarks,
deprecated);
         if (domainCode != null) {
             properties.put(Datum.DOMAIN_OF_VALIDITY_KEY, owner.createExtent(domainCode));
@@ -2895,6 +2899,7 @@ next:               while (r.next()) {
                             }
                         }
                         opProperties.put(ReferencingServices.OPERATION_TYPE_KEY, opType);
+                        opProperties.put(ReferencingServices.PARAMETERS_KEY, parameters);
                         /*
                          * Following restriction will be removed in a future SIS version
if the method is added to GeoAPI.
                          */

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1738569&r1=1738568&r2=1738569&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
[UTF-8] Mon Apr 11 11:14:36 2016
@@ -871,11 +871,12 @@ check:      for (int isTarget=0; ; isTar
         final FormattableObject enclosing = formatter.getEnclosingElement(1);
         final boolean isSubOperation = (enclosing instanceof PassThroughOperation);
         final boolean isComponent    = (enclosing instanceof ConcatenatedOperation);
+        final boolean isConcatenated =      (this instanceof ConcatenatedOperation);
         if (!isSubOperation) {
             if (!isComponent) {
                 append(formatter, getSourceCRS(), WKTKeywords.SourceCRS);
             }
-            if (!(this instanceof ConcatenatedOperation)) {
+            if (!isConcatenated) {
                 append(formatter, getTargetCRS(), WKTKeywords.TargetCRS);
             }
         }
@@ -899,7 +900,7 @@ check:      for (int isTarget=0; ; isTar
                 formatter.indent(-1);
             }
         }
-        if (!isSubOperation && !isComponent) {
+        if (!isSubOperation && !isConcatenated) {
             append(formatter, getInterpolationCRS(), WKTKeywords.InterpolationCRS);
             final double accuracy = getLinearAccuracy();
             if (accuracy > 0) {

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=1738569&r1=1738568&r2=1738569&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] Mon Apr 11 11:14:36 2016
@@ -40,6 +40,7 @@ import org.opengis.referencing.operation
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.cs.CoordinateSystems;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
@@ -490,30 +491,33 @@ final class CoordinateOperationRegistry
         CoordinateReferenceSystem crs;
         if (Utilities.equalsApproximatively(sourceCRS, crs = operation.getSourceCRS())) sourceCRS
= crs;
         if (Utilities.equalsApproximatively(targetCRS, crs = operation.getTargetCRS())) targetCRS
= crs;
+        final Map<String,Object> properties = new HashMap<>(derivedFrom(operation));
         /*
          * Determine whether the operation to create is a Conversion or a Transformation.
          * Conversion may also be a more accurate type like Projection. We want the GeoAPI
          * interface. The most reliable way is to ask to the operation, but this is SIS-specific.
          * The fallback uses reflection.
          */
-        final Class<? extends CoordinateOperation> type;
-        if (operation instanceof AbstractCoordinateOperation) {
-            type = ((AbstractCoordinateOperation) operation).getInterface();
+        if (operation instanceof AbstractIdentifiedObject) {
+            properties.put(ReferencingServices.OPERATION_TYPE_KEY,
+                    ((AbstractIdentifiedObject) operation).getInterface());
         } else {
             final Class<? extends CoordinateOperation>[] types =
                     Classes.getLeafInterfaces(operation.getClass(), CoordinateOperation.class);
-            type = (types.length != 0) ? types[0] : SingleOperation.class;
+            if (types.length != 0) {
+                properties.put(ReferencingServices.OPERATION_TYPE_KEY, types[0]);
+            }
         }
         /*
          * Reuse the same operation method, just changing its number of dimension.
          */
         OperationMethod method = null;
         if (operation instanceof SingleOperation) {
-            method = DefaultOperationMethod.redimension(((SingleOperation) operation).getMethod(),
+            final SingleOperation single = (SingleOperation) operation;
+            properties.put(ReferencingServices.PARAMETERS_KEY, single.getParameterValues());
+            method = DefaultOperationMethod.redimension(single.getMethod(),
                             transform.getSourceDimensions(), transform.getTargetDimensions());
         }
-        final Map<String,Object> properties = new HashMap<>(derivedFrom(operation));
-        properties.put(ReferencingServices.OPERATION_TYPE_KEY, type);
         return factorySIS.createSingleOperation(properties, sourceCRS, targetCRS,
                 AbstractCoordinateOperation.getInterpolationCRS(operation), method, transform);
     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java?rev=1738569&r1=1738568&r2=1738569&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
[UTF-8] Mon Apr 11 11:14:36 2016
@@ -34,6 +34,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.Transformation;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
+import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.internal.util.CollectionsExt;
@@ -177,6 +178,7 @@ final class DefaultConcatenatedOperation
                             final boolean                   setAccuracy)
             throws FactoryException
     {
+        double coarsestAccuracy = 0;
         CoordinateReferenceSystem previous = null;
         for (int i=0; i<operations.length; i++) {
             final CoordinateOperation op = operations[i];
@@ -222,12 +224,18 @@ final class DefaultConcatenatedOperation
              * See javadoc for a rational about why we take only transformations in account.
              */
             if (setAccuracy && op instanceof Transformation) {
-                Collection<PositionalAccuracy> candidates = op.getCoordinateOperationAccuracy();
+                final Collection<PositionalAccuracy> candidates = op.getCoordinateOperationAccuracy();
                 if (!Containers.isNullOrEmpty(candidates)) {
-                    if (coordinateOperationAccuracy == null) {
-                        coordinateOperationAccuracy = new LinkedHashSet<>();
+                    final double accuracy = PositionalAccuracyConstant.getLinearAccuracy(op);
+                    if (accuracy > coarsestAccuracy) {
+                        coarsestAccuracy = accuracy;
+                        if (coordinateOperationAccuracy == null) {
+                            coordinateOperationAccuracy = new LinkedHashSet<>(candidates);
+                        } else {
+                            coordinateOperationAccuracy.clear();
+                            coordinateOperationAccuracy.addAll(candidates);
+                        }
                     }
-                    coordinateOperationAccuracy.addAll(candidates);
                 }
             }
         }
@@ -337,6 +345,7 @@ final class DefaultConcatenatedOperation
     protected String formatTo(final Formatter formatter) {
         super.formatTo(formatter);
         for (final CoordinateOperation component : operations) {
+            formatter.newLine();
             formatter.append(castOrCopy(component));
         }
         formatter.setInvalidWKT(this, null);

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java?rev=1738569&r1=1738568&r2=1738569&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
[UTF-8] Mon Apr 11 11:14:36 2016
@@ -16,10 +16,14 @@
  */
 package org.apache.sis.referencing.operation;
 
+import java.util.List;
 import java.text.ParseException;
 import org.opengis.util.FactoryException;
+import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.referencing.crs.CRSAuthorityFactory;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.SingleOperation;
+import org.opengis.referencing.operation.ConcatenatedOperation;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
 import org.opengis.referencing.operation.TransformException;
@@ -29,22 +33,39 @@ import org.apache.sis.io.wkt.WKTFormat;
 
 // Test dependencies
 import org.apache.sis.referencing.operation.transform.MathTransformTestCase;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.DependsOn;
 import org.junit.BeforeClass;
 import org.junit.AfterClass;
 import org.junit.Test;
 
+import static org.apache.sis.internal.referencing.Formulas.ANGULAR_TOLERANCE;
 import static org.apache.sis.test.ReferencingAssert.*;
 import static org.junit.Assume.*;
 
 
 /**
  * Tests {@link CoordinateOperationRegistry}.
+ * This class tests the following operations:
+ *
+ * <ul>
+ *   <li><cite>"NTF (Paris) to WGS 84 (1)"</cite> operation (EPSG:8094),
which implies a longitude rotation
+ *       followed by a geocentric translation in the geographic domain.</li>
+ * </ul>
+ *
+ * The operations are tested with various axis order and dimension in source and target CRS.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
  * @version 0.7
  * @module
  */
+@DependsOn({
+    DefaultConversionTest.class,
+    DefaultTransformationTest.class,
+    DefaultPassThroughOperationTest.class,
+    DefaultConcatenatedOperationTest.class
+})
 public final strictfp class CoordinateOperationRegistryTest extends MathTransformTestCase
{
     /**
      * Tolerance threshold for strict comparisons of floating point numbers.
@@ -92,6 +113,9 @@ public final strictfp class CoordinateOp
     public static void createFactory() throws ParseException {
         factory = new DefaultCoordinateOperationFactory();
         parser  = new WKTFormat(null, null);
+        parser.addFragment("NTF",
+                "Datum[“Nouvelle Triangulation Française (Paris)”,\n" +
+                "  Ellipsoid[“Clarke 1880 (IGN)”, 6378249.2, 293.4660212936269]]");
     }
 
     /**
@@ -111,33 +135,104 @@ public final strictfp class CoordinateOp
     }
 
     /**
-     * Tests a datum shift between two geographic CRS which also implies a change of prime
meridian.
-     * The expected coordinate operation is EPSG:8094.
+     * Tests <cite>"NTF (Paris) to WGS 84 (1)"</cite> operation with source and
target CRS conform to EPSG definitions.
      *
      * @throws ParseException if a CRS used in this test can not be parsed.
      * @throws FactoryException if the operation can not be created.
      * @throws TransformException if an error occurred while converting the test points.
      */
     @Test
-    public void testDatumShiftWithLongitudeRotation() throws ParseException, FactoryException,
TransformException {
+    public void testLongitudeRotationBetweenConformCRS() throws ParseException, FactoryException,
TransformException {
         final CoordinateReferenceSystem sourceCRS = parse(
                 "GeodeticCRS[“NTF (Paris)”,\n" +
-                "  Datum[“Nouvelle Triangulation Française (Paris)”,\n" +
-                "    Ellipsoid[“Clarke 1880 (IGN)”, 6378249.2, 293.4660212936269]],\n"
+
+                "  $NTF,\n" +
                 "    PrimeMeridian[“Paris”, 2.5969213],\n" +
                 "  CS[ellipsoidal, 2],\n" +
                 "    Axis[“Latitude (φ)”, NORTH],\n" +
                 "    Axis[“Longitude (λ)”, EAST],\n" +
-                "    Unit[“grade”, 0.015707963267948967]\n," +
-                "  Id[“EPSG”, 4807]]");
+                "    Unit[“grade”, 0.015707963267948967]]");
+                // Intentionally omit Id[“EPSG”, 4807] for testing capability to find
it back.
 
         final CoordinateReferenceSystem targetCRS = CommonCRS.WGS84.geographic();
         final CoordinateOperation operation = registry.createOperation(sourceCRS, targetCRS);
         assertEpsgNameAndIdentifierEqual("NTF (Paris) to WGS 84 (1)", 8094, operation);
-        assertEquals("linearAccuracy", 2, CRS.getLinearAccuracy(operation), STRICT);
+        assertEpsgNameAndIdentifierEqual("NTF (Paris)", 4807, operation.getSourceCRS());
+        assertEpsgNameAndIdentifierEqual("WGS 84",      4326, operation.getTargetCRS());
+        verifyNTF(operation);
+        /*
+         * Same test point than the one used in FranceGeocentricInterpolationTest:
+         *
+         * NTF: 48°50′40.2441″N  2°25′32.4187″E
+         * RGF: 48°50′39.9967″N  2°25′29.8273″E     (close to WGS84)
+         */
+        transform  = operation.getMathTransform();
+        tolerance  = ANGULAR_TOLERANCE;
+        λDimension = new int[] {1};
+        verifyTransform(new double[] {54.271680278,  0.098269657},      // in grads east
of Paris
+                        new double[] {48.844443528,  2.424952028});     // in degrees east
of Greenwich
+        validate();
+    }
 
-        transform = operation.getMathTransform();
-        assertFalse(transform.isIdentity());
+    /**
+     * Tests <cite>"NTF (Paris) to WGS 84 (1)"</cite> operation with normalized
source and target CRS.
+     * {@link CoordinateOperationRegistry} should be able to find the operation despite the
difference
+     * in axis order an units.
+     *
+     * @throws ParseException if a CRS used in this test can not be parsed.
+     * @throws FactoryException if the operation can not be created.
+     * @throws TransformException if an error occurred while converting the test points.
+     */
+    @Test
+    @DependsOnMethod("testLongitudeRotationBetweenConformCRS")
+    public void testLongitudeRotationBetweenNormalizedCRS() throws ParseException, FactoryException,
TransformException {
+        final CoordinateReferenceSystem sourceCRS = parse(
+                "GeodeticCRS[“NTF (Paris)”,\n" +
+                "  $NTF,\n" +
+                "    PrimeMeridian[“Paris”, 2.33722917],\n" +
+                "  CS[ellipsoidal, 2],\n" +
+                "    Axis[“Longitude (λ)”, EAST],\n" +
+                "    Axis[“Latitude (φ)”, NORTH],\n" +
+                "    Unit[“degree”, 0.017453292519943295]]");
+
+        final CoordinateReferenceSystem targetCRS = CommonCRS.WGS84.normalizedGeographic();
+        final CoordinateOperation operation = registry.createOperation(sourceCRS, targetCRS);
+        verifyNTF(operation);
+
+        transform  = operation.getMathTransform();
+        tolerance  = ANGULAR_TOLERANCE;
+        λDimension = new int[] {1};
+        verifyTransform(new double[] {0.088442691, 48.844512250},      // in degrees east
of Paris
+                        new double[] {2.424952028, 48.844443528});     // in degrees east
of Greenwich
         validate();
     }
+
+    /**
+     * Verifies a coordinate operation which is expected to be <cite>"NTF (Paris) to
WGS 84 (1)"</cite> (EPSG:8094).
+     */
+    static void verifyNTF(final CoordinateOperation operation) {
+        assertEquals("name",           "NTF (Paris) to WGS 84 (1)",  operation.getName().getCode());
+        assertEquals("sourceCRS.name", "NTF (Paris)",                operation.getSourceCRS().getName().getCode());
+        assertEquals("targetCRS.name", "WGS 84",                     operation.getTargetCRS().getName().getCode());
+        assertEquals("Should report only the coarsest accuracy.", 1, operation.getCoordinateOperationAccuracy().size());
+        assertEquals("linearAccuracy",                            2, CRS.getLinearAccuracy(operation),
STRICT);
+
+        assertInstanceOf("Operation should have two steps.", ConcatenatedOperation.class,
operation);
+        final List<? extends CoordinateOperation> steps = ((ConcatenatedOperation)
operation).getOperations();
+        assertEquals("Operation should have two steps.", 2, steps.size());
+
+        final SingleOperation step1 = (SingleOperation) steps.get(0);
+        final SingleOperation step2 = (SingleOperation) steps.get(1);
+        assertSame("SourceCRS shall be the targetCRS of previous step.",    step1.getTargetCRS(),
step2.getSourceCRS());
+        assertEquals("Step 1",   "NTF (Paris) to NTF (1)",                  step1.getName().getCode());
+        assertEquals("Step 2",   "NTF to WGS 84 (1)",                       step2.getName().getCode());
+        assertEquals("Method 1", "Longitude rotation",                      step1.getMethod().getName().getCode());
+        assertEquals("Method 2", "Geocentric translations (geog2D domain)", step2.getMethod().getName().getCode());
+
+        final ParameterValueGroup p1 = step1.getParameterValues();
+        final ParameterValueGroup p2 = step2.getParameterValues();
+        assertEquals("Longitude offset", 2.5969213, p1.parameter("Longitude offset")  .doubleValue(),
STRICT);
+        assertEquals("X-axis translation",    -168, p2.parameter("X-axis translation").doubleValue(),
STRICT);
+        assertEquals("Y-axis translation",     -60, p2.parameter("Y-axis translation").doubleValue(),
STRICT);
+        assertEquals("Z-axis translation",     320, p2.parameter("Z-axis translation").doubleValue(),
STRICT);
+    }
 }



Mime
View raw message