sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1738930 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/ main/java/org/apache/sis/referencing/operation/ test/java/org/apache/sis/referencing/operation/ test/java/org/apache/sis/test/suite/
Date Wed, 13 Apr 2016 12:49:22 GMT
Author: desruisseaux
Date: Wed Apr 13 12:49:22 2016
New Revision: 1738930

URL: http://svn.apache.org/viewvc?rev=1738930&view=rev
Log:
Add test for DefaultCoordinateOperationFactory.

Added:
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.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/DefaultConcatenatedOperation.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/PositionalAccuracyConstant.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -67,7 +67,7 @@ public final class PositionalAccuracyCon
      *
      * @see org.apache.sis.referencing.operation.AbstractCoordinateOperation#getLinearAccuracy()
      */
-    private static final double UNKNOWN_ACCURACY = 3000;
+    public static final double UNKNOWN_ACCURACY = 3000;
 
     /**
      * Default accuracy of datum shift, if not explicitly provided in the EPSG database.

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=1738930&r1=1738929&r2=1738930&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] Wed Apr 13 12:49:22 2016
@@ -160,7 +160,7 @@ public class AbstractCoordinateOperation
      * (i.e., instantiation due to the stochastic nature of the parameters).
      *
      * <p><b>Consider this field as final!</b>
-     * This field is modified only at unmarshalling time by {@link #setOperationVersion(String)}</p>
+     * This field is modified only at unmarshalling time by {@link #setOperationVersion(String)}.</p>
      *
      * @see #getOperationVersion()
      */
@@ -181,7 +181,7 @@ public class AbstractCoordinateOperation
      * Area in which this operation is valid, or {@code null} if not available.
      *
      * <p><b>Consider this field as final!</b>
-     * This field is modified only at unmarshalling time by {@link #setDomainOfValidity(Extent)}</p>
+     * This field is modified only at unmarshalling time by {@link #setDomainOfValidity(Extent)}.</p>
      *
      * @see #getDomainOfValidity()
      */
@@ -191,7 +191,7 @@ public class AbstractCoordinateOperation
      * Description of domain of usage, or limitations of usage, for which this operation
is valid.
      *
      * <p><b>Consider this field as final!</b>
-     * This field is modified only at unmarshalling time by {@link #setScope(InternationalString)}</p>
+     * This field is modified only at unmarshalling time by {@link #setScope(InternationalString)}.</p>
      *
      * @see #getScope()
      */
@@ -203,7 +203,7 @@ public class AbstractCoordinateOperation
      *
      * <p><b>Consider this field as final!</b>
      * This field is non-final only for the convenience of constructors and for initialization
-     * at XML unmarshalling time by {@link AbstractSingleOperation#afterUnmarshal(Unmarshaller,
Object)}</p>
+     * at XML unmarshalling time by {@link AbstractSingleOperation#afterUnmarshal(Unmarshaller,
Object)}.</p>
      */
     MathTransform 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=1738930&r1=1738929&r2=1738930&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] Wed Apr 13 12:49:22 2016
@@ -17,17 +17,13 @@
 package org.apache.sis.referencing.operation;
 
 import java.util.Map;
-import java.util.Set;
 import java.util.List;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
-import java.util.LinkedHashSet;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import org.opengis.util.FactoryException;
-import org.opengis.metadata.quality.PositionalAccuracy;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.ConcatenatedOperation;
@@ -37,8 +33,6 @@ import org.opengis.referencing.operation
 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;
-import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
@@ -115,9 +109,8 @@ final class DefaultConcatenatedOperation
     {
         super(properties);
         ArgumentChecks.ensureNonNull("operations", operations);
-        final boolean setAccuracy = (coordinateOperationAccuracy == null);
         final List<CoordinateOperation> flattened = new ArrayList<>(operations.length);
-        initialize(properties, operations, flattened, mtFactory, setAccuracy);
+        initialize(properties, operations, flattened, mtFactory, (coordinateOperationAccuracy
== null));
         if (flattened.size() < 2) {
             throw new IllegalArgumentException(Errors.getResources(properties).getString(
                     Errors.Keys.TooFewOccurrences_2, 2, CoordinateOperation.class));
@@ -126,10 +119,6 @@ final class DefaultConcatenatedOperation
         this.operations = UnmodifiableArrayList.wrap(operations);
         this.sourceCRS  = operations[0].getSourceCRS();
         this.targetCRS  = operations[operations.length - 1].getTargetCRS();
-        if (setAccuracy) {
-            coordinateOperationAccuracy = CollectionsExt.unmodifiableOrCopy(
-                    (Set<PositionalAccuracy>) coordinateOperationAccuracy);
-        }
         checkDimensions(properties);
     }
 
@@ -148,11 +137,11 @@ final class DefaultConcatenatedOperation
      * in the given list. This should not happen according ISO 19111 standard, but we try
to be safe.
      *
      * <div class="section">How coordinate operation accuracy is determined</div>
-     * If {@code setAccuracy} is {@code true}, then this method collects all accuracy information
found in the
-     * {@link Transformation} instances. This method ignores instances of other kinds for
the following reason:
+     * If {@code setAccuracy} is {@code true}, then this method copies accuracy information
found in the single
+     * {@link Transformation} instance. This method ignores instances of other kinds for
the following reason:
      * some {@link Conversion} instances declare an accuracy, which is typically close to
zero. If a concatenated
      * operation contains such conversion together with a transformation with unknown accuracy,
then we do not want
-     * to declare that a 0 meter error as the concatenated operation accuracy; it would be
a false information.
+     * to declare "0 meter" as the concatenated operation accuracy; it would be a false information.
      * An other reason is that a concatenated operation typically contains an arbitrary amount
of conversions,
      * but only one transformation. So considering only transformations usually means to
pickup only one operation
      * in the given {@code operations} list, which make things clearer.
@@ -175,10 +164,9 @@ final class DefaultConcatenatedOperation
                             final CoordinateOperation[]     operations,
                             final List<CoordinateOperation> flattened,
                             final MathTransformFactory      mtFactory,
-                            final boolean                   setAccuracy)
+                            boolean                         setAccuracy)
             throws FactoryException
     {
-        double coarsestAccuracy = 0;
         CoordinateReferenceSystem previous = null;
         for (int i=0; i<operations.length; i++) {
             final CoordinateOperation op = operations[i];
@@ -220,22 +208,22 @@ final class DefaultConcatenatedOperation
                 transform = (transform != null) ? mtFactory.createConcatenatedTransform(transform,
step) : step;
             }
             /*
-             * Optionally update the coordinate operation accuracy.
-             * See javadoc for a rational about why we take only transformations in account.
+             * Optionally copy the coordinate operation accuracy from the transformation
(or from a concatenated
+             * operation on the assumption that its accuracy was computed by the same algorithm
than this method).
+             * See javadoc for a rational about why we take only transformations in account.
If more than one
+             * transformation is found, clear the collection and abandon the attempt to set
the accuracy information.
+             * Instead the user will get a better result by invoking PositionalAccuracyConstant.getLinearAccuracy(…)
+             * since that method conservatively computes the sum of all linear accuracy.
              */
-            if (setAccuracy && op instanceof Transformation) {
-                final Collection<PositionalAccuracy> candidates = op.getCoordinateOperationAccuracy();
-                if (!Containers.isNullOrEmpty(candidates)) {
-                    final double accuracy = PositionalAccuracyConstant.getLinearAccuracy(op);
-                    if (accuracy > coarsestAccuracy) {
-                        coarsestAccuracy = accuracy;
-                        if (coordinateOperationAccuracy == null) {
-                            coordinateOperationAccuracy = new LinkedHashSet<>(candidates);
-                        } else {
-                            coordinateOperationAccuracy.clear();
-                            coordinateOperationAccuracy.addAll(candidates);
-                        }
+            if (setAccuracy && (op instanceof Transformation || op instanceof ConcatenatedOperation))
{
+                if (coordinateOperationAccuracy == null) {
+                    setAccuracy = (PositionalAccuracyConstant.getLinearAccuracy(op) >
0);
+                    if (setAccuracy) {
+                        coordinateOperationAccuracy = op.getCoordinateOperationAccuracy();
                     }
+                } else {
+                    coordinateOperationAccuracy = null;
+                    setAccuracy = false;
                 }
             }
         }
@@ -391,8 +379,7 @@ final class DefaultConcatenatedOperation
      */
     private void setSteps(final CoordinateOperation[] steps) throws FactoryException {
         final List<CoordinateOperation> flattened = new ArrayList<>(steps.length);
-        initialize(null, steps, flattened, DefaultFactories.forBuildin(MathTransformFactory.class),
true);
+        initialize(null, steps, flattened, DefaultFactories.forBuildin(MathTransformFactory.class),
coordinateOperationAccuracy == null);
         operations = UnmodifiableArrayList.wrap(flattened.toArray(new CoordinateOperation[flattened.size()]));
-        coordinateOperationAccuracy = CollectionsExt.unmodifiableOrCopy((Set<PositionalAccuracy>)
coordinateOperationAccuracy);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -82,6 +82,12 @@ import org.apache.sis.util.Utilities;
  */
 public class DefaultCoordinateOperationFactory extends AbstractFactory implements CoordinateOperationFactory
{
     /**
+     * Whether this class is allowed to use the EPSG authority factory for searching coordinate
operation paths.
+     * This flag should always be {@code true}, except temporarily for testing purposes.
+     */
+    static final boolean USE_EPSG_FACTORY = true;
+
+    /**
      * The default properties, or an empty map if none. This map shall not change after construction
in
      * order to allow usage without synchronization in multi-thread context. But we do not
need to wrap
      * in a unmodifiable map since {@code DefaultCoordinateOperationFactory} does not provide
public
@@ -667,10 +673,10 @@ next:   for (int i=components.size(); --
      * validity} and the {@linkplain CoordinateOperationContext#getAreaOfInterest() area
of interest} is returned.
      *
      * <p>The default implementation is equivalent to the following code
-     * (omitting the cast safety check for brevity):</p>
+     * (omitting the {@code registry} type check and cast for brevity):</p>
      *
      * {@preformat java
-     *   CoordinateOperationAuthorityFactory registry = (CoordinateOperationAuthorityFactory)
CRS.getAuthorityFactory("EPSG");
+     *   CoordinateOperationAuthorityFactory registry = CRS.getAuthorityFactory("EPSG");
   // Actually needs cast
      *   return new CoordinateOperationFinder(registry, this, context).createOperation(sourceCRS,
targetCRS);
      * }
      *
@@ -693,7 +699,7 @@ next:   for (int i=components.size(); --
                                                final CoordinateOperationContext context)
             throws OperationNotFoundException, FactoryException
     {
-        final AuthorityFactory registry = CRS.getAuthorityFactory(Constants.EPSG);
+        final AuthorityFactory registry = USE_EPSG_FACTORY ? CRS.getAuthorityFactory(Constants.EPSG)
: null;
         return new CoordinateOperationFinder((registry instanceof CoordinateOperationAuthorityFactory)
?
                 (CoordinateOperationAuthorityFactory) registry : null, this, context).createOperation(sourceCRS,
targetCRS);
     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -91,7 +91,7 @@ final class InverseOperationMethod exten
             }
             if (!useSameParameters) {
                 Identifier name = method.getName();
-                name = new ImmutableIdentifier(null, name.getCodeSpace(), "Inverse " + name.getCode());
+                name = new ImmutableIdentifier(null, null, "Inverse of " + name.getCode());
                 final Map<String,Object> properties = new HashMap<>(6);
                 properties.put(NAME_KEY,    name);
                 properties.put(FORMULA_KEY, method.getFormula());

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=1738930&r1=1738929&r2=1738930&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] Wed Apr 13 12:49:22 2016
@@ -313,7 +313,7 @@ public final strictfp class CoordinateOp
      * @param domain  either {@code "geog2D domain"} or either {@code "geog3D domain"}.
      * @param isEPSG  {@code true} if the coordinate operation is expected to contain EPSG
identifiers.
      */
-    static void verifyNTF(final CoordinateOperation operation, final String domain, final
boolean isEPSG) {
+    private static void verifyNTF(final CoordinateOperation operation, final String domain,
final boolean isEPSG) {
         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());
@@ -342,9 +342,7 @@ public final strictfp class CoordinateOp
         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);
-
-        assertEquals("Should report only the coarsest accuracy.", 1, operation.getCoordinateOperationAccuracy().size());
-        assertEquals("linearAccuracy",                            2, CRS.getLinearAccuracy(operation),
STRICT);
+        assertEquals("linearAccuracy",           2, CRS.getLinearAccuracy(operation),   
             STRICT);
     }
 
     /**

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java?rev=1738930&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+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.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.ConcatenatedOperation;
+import org.opengis.referencing.operation.CoordinateOperation;
+import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
+import org.opengis.referencing.operation.SingleOperation;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.internal.referencing.Formulas;
+import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.geometry.DirectPosition2D;
+import org.apache.sis.io.wkt.WKTFormat;
+import org.apache.sis.referencing.CRS;
+
+// 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.test.ReferencingAssert.*;
+
+
+/**
+ * Tests {@link DefaultCoordinateOperationFactory}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+@DependsOn({
+    CoordinateOperationRegistryTest.class,
+    CoordinateOperationFinderTest.class
+})
+public final strictfp class DefaultCoordinateOperationFactoryTest extends MathTransformTestCase
{
+    /**
+     * Tolerance threshold for strict comparisons of floating point numbers.
+     * This constant can be used like below, where {@code expected} and {@code actual} are
{@code double} values:
+     *
+     * {@preformat java
+     *     assertEquals(expected, actual, STRICT);
+     * }
+     */
+    private static final double STRICT = 0;
+
+    /**
+     * The transformation factory to use for testing.
+     */
+    private static DefaultCoordinateOperationFactory factory;
+
+    /**
+     * The parser to use for WKT strings used in this test.
+     */
+    private static WKTFormat parser;
+
+    /**
+     * Creates a new {@link DefaultCoordinateOperationFactory} to use for testing purpose.
+     * The same factory will be used for all tests in this class.
+     *
+     * @throws ParseException if an error occurred while preparing the WKT parser.
+     */
+    @BeforeClass
+    public static void createFactory() throws ParseException {
+        factory = new DefaultCoordinateOperationFactory();
+        parser  = new WKTFormat(null, null);
+        parser.addFragment("NTF",
+                "ProjectedCRS[“NTF (Paris) / Lambert zone II”,\n" +
+                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "    Datum[“Nouvelle Triangulation Française (Paris)”,\n" +
+                "      Ellipsoid[“Clarke 1880 (IGN)”, 6378249.2, 293.4660212936269]],\n"
+
+                "      PrimeMeridian[“Paris”, 2.5969213],\n" +
+                "    Unit[“grade”, 0.015707963267948967]]\n," +
+                "  Conversion[“Lambert zone II”,\n" +
+                "    Method[“Lambert Conic Conformal (1SP)”],\n" +
+                "    Parameter[“Latitude of natural origin”, 52.0],\n" +
+                "    Parameter[“Scale factor at natural origin”, 0.99987742],\n" +
+                "    Parameter[“False easting”, 600000.0],\n" +
+                "    Parameter[“False northing”, 2200000.0]],\n" +
+                "  CS[Cartesian, 2]\n," +
+                "    Axis[“Easting (X)”, east],\n" +
+                "    Axis[“Northing (Y)”, north],\n" +
+                "    Unit[“metre”, 1],\n" +
+                "  Id[“EPSG”, 27572]]");
+
+        parser.addFragment("Mercator",
+                "ProjectedCRS[“WGS 84 / World Mercator”,\n" +
+                "  BaseGeodCRS[“WGS 84”,\n" +
+                "    Datum[“World Geodetic System 1984”,\n" +
+                "      Ellipsoid[“WGS 84”, 6378137.0, 298.257223563]],\n" +
+                "    Unit[“degree”, 0.017453292519943295]],\n" +
+                "  Conversion[“World Mercator”,\n" +
+                "    Method[“Mercator (variant A)”]],\n" +
+                "  CS[Cartesian, 2]\n," +
+                "    Axis[“Easting (X)”, east],\n" +
+                "    Axis[“Northing (Y)”, north],\n" +
+                "    Unit[“metre”, 1],\n" +
+                "  Id[“EPSG”, 3395]]");
+    }
+
+    /**
+     * Disposes the factory created by {@link #createFactory()} after all tests have been
executed.
+     */
+    @AfterClass
+    public static void disposeFactory() {
+        factory = null;
+        parser  = null;
+    }
+
+    /**
+     * Returns the CRS for the given Well Known Text.
+     */
+    private static CoordinateReferenceSystem parse(final String wkt) throws ParseException
{
+        return (CoordinateReferenceSystem) parser.parseObject(wkt);
+    }
+
+    /**
+     * Returns {@code true} if {@link #factory} is expected to use the EPSG factory.
+     */
+    private static boolean isUsingEpsgFactory() throws FactoryException {
+        return DefaultCoordinateOperationFactory.USE_EPSG_FACTORY &&
+               CRS.getAuthorityFactory(Constants.EPSG) instanceof CoordinateOperationAuthorityFactory;
+    }
+
+    /**
+     * Tests a transformation between 2D projected CRS which implies a change of prime meridian.
+     *
+     * @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 testProjectionAndLongitudeRotation() throws ParseException, FactoryException,
TransformException {
+        final CoordinateReferenceSystem sourceCRS = parse("$NTF");
+        final CoordinateReferenceSystem targetCRS = parse("$Mercator");
+        final CoordinateOperation operation = factory.createOperation(sourceCRS, targetCRS);
+        assertSame      ("sourceCRS", sourceCRS, operation.getSourceCRS());
+        assertSame      ("targetCRS", targetCRS, operation.getTargetCRS());
+        assertInstanceOf("operation", ConcatenatedOperation.class, operation);
+        /*
+         * The accuracy of the coordinate operation depends on whether a path as been found
with the help
+         * of the EPSG database (in which case the reported accuracy is 2 metres) or if we
had to find an
+         * operation by ourselves (in which case we conservatively report an accuracy of
3000 metres, bu
+         * in practice observe an error of about 80 metres for this test).
+         */
+        final boolean isUsingEpsgFactory = verifyParametersNTF(((ConcatenatedOperation) operation).getOperations(),
1);
+        assertEquals("linearAccuracy", isUsingEpsgFactory ? 2 : PositionalAccuracyConstant.UNKNOWN_ACCURACY,
+                                       CRS.getLinearAccuracy(operation), STRICT);
+
+        tolerance = isUsingEpsgFactory ? Formulas.LINEAR_TOLERANCE : 100;
+        transform = operation.getMathTransform();
+        /*
+         * Test using the location of Paris (48.856578°N, 2.351828°E) first,
+         * then using a coordinate different than the prime meridian.
+         */
+        verifyTransform(new double[] {
+            601124.99, 2428693.45,
+            600000.00, 2420000.00
+        }, new double[] {
+            261804.30, 6218365.73,
+            260098.74, 6205194.95
+        });
+        validate();
+    }
+
+    /**
+     * Tests a transformation from a 4D projection to a 2D projection which imply a change
of
+     * prime meridian. This is the same test than {@link #testProjectionAndLongitudeRotation()},
+     * with extra dimension which should be just dropped.
+     *
+     * <p>This tests requires the EPSG database, because it requires the coordinate
operation
+     * path which is defined there.</p>
+     *
+     * @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("testProjectionAndLongitudeRotation")
+    public void testCompoundAndLongitudeRotation() throws ParseException, FactoryException,
TransformException {
+        final CoordinateReferenceSystem sourceCRS = parse(
+                "CompoundCRS[“NTF 4D”," +
+                "  $NTF,\n" +
+                "  VerticalCRS[“Ellipsoidal height”,\n" +
+                "    VerticalDatum[“Ellipsoid”],\n" +
+                "    CS[vertical, 1],\n" +
+                "      Axis[“Ellipsoidal height (h)”, up],\n" +
+                "      Unit[“metre”, 1]],\n" +
+                "  TimeCRS[“Modified Julian”,\n" +
+                "    TimeDatum[“Modified Julian”, TimeOrigin[1858-11-17T00:00:00.0Z]],\n"
+
+                "    CS[temporal, 1],\n" +
+                "      Axis[“Time (t)”, future],\n" +
+                "      TimeUnit[“day”, 86400]]]");
+
+        final CoordinateReferenceSystem targetCRS = parse("$Mercator");
+        final CoordinateOperation operation = factory.createOperation(sourceCRS, targetCRS);
+        assertSame      ("sourceCRS", sourceCRS, operation.getSourceCRS());
+        assertSame      ("targetCRS", targetCRS, operation.getTargetCRS());
+        assertInstanceOf("operation", ConcatenatedOperation.class, operation);
+        /*
+         * The accuracy of the coordinate operation depends on whether a path as been found
with the help
+         * of the EPSG database. See testProjectionAndLongitudeRotation() for more information.
+         */
+        final boolean isUsingEpsgFactory = verifyParametersNTF(((ConcatenatedOperation) operation).getOperations(),
2);
+        assertEquals("linearAccuracy", isUsingEpsgFactory ? 2 : PositionalAccuracyConstant.UNKNOWN_ACCURACY,
+                                       CRS.getLinearAccuracy(operation), STRICT);
+
+        tolerance = isUsingEpsgFactory ? Formulas.LINEAR_TOLERANCE : 100;
+        transform = operation.getMathTransform();
+        isInverseTransformSupported = false;
+        /*
+         * Same coordinates than testProjectionAndLongitudeRotation(),
+         * but with random elevation and time which should be dropped.
+         */
+        verifyTransform(new double[] {
+            601124.99, 2428693.45, 400, 1000,
+            600000.00, 2420000.00, 400, 1000
+        }, new double[] {
+            261804.30, 6218365.73,
+            260098.74, 6205194.95
+        });
+        validate();
+    }
+
+    /**
+     * Verifies the datum shift parameters in the <cite>"NTF to WGS 84 (1)"</cite>
transformation.
+     * Those parameters depends on whether an EPSG database have been used or not.
+     *
+     * @param  steps            the list returned by {@link DefaultConcatenatedOperation#getOperations()}.
+     * @param  datumShiftIndex  index of the datum shift operations in the {@code steps}
list.
+     * @return the {@link #isUsingEpsgFactory()} value, returned for convenience.
+     */
+    private static boolean verifyParametersNTF(final List<? extends CoordinateOperation>
steps, final int datumShiftIndex)
+            throws FactoryException
+    {
+        if (isUsingEpsgFactory()) {
+            final SingleOperation step1 = (SingleOperation) steps.get(datumShiftIndex);
+            final SingleOperation step2 = (SingleOperation) steps.get(datumShiftIndex + 1);
+            assertEpsgNameAndIdentifierEqual("NTF (Paris) to NTF (1)", 1763, step1);
+            assertEpsgNameAndIdentifierEqual("NTF to WGS 84 (1)",      1193, step2);
+            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);
+            return true;
+        } else {
+            assertSame(CoordinateOperationFinder.ELLIPSOID_CHANGE, steps.get(datumShiftIndex).getName());
+            return false;
+        }
+    }
+
+    /**
+     * Tests the conversion from Mercator projection to the Google projection. The referencing
module
+     * should detects that the conversion is something more complex that an identity transform.
+     *
+     * @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 testMercatorToGoogle() throws ParseException, FactoryException, TransformException
{
+        final CoordinateReferenceSystem sourceCRS = parse("$Mercator");
+        final CoordinateReferenceSystem targetCRS = parse(
+                "ProjectedCRS[“WGS 84 / Pseudo-Mercator”,\n" +
+                "  BaseGeodCRS[“WGS 84”,\n" +
+                "    Datum[“World Geodetic System 1984”,\n" +
+                "      Ellipsoid[“WGS 84”, 6378137.0, 298.257223563]],\n" +
+                "    Unit[“degree”, 0.017453292519943295]],\n" +
+                "  Conversion[“Popular Visualisation Pseudo-Mercator”,\n" +
+                "    Method[“Popular Visualisation Pseudo Mercator”]],\n" +
+                "  CS[Cartesian, 2],\n" +
+                "    Axis[“Easting (X)”, east],\n" +
+                "    Axis[“Northing (Y)”, north],\n" +
+                "    Unit[“metre”, 1],\n" +
+                "  Id[“EPSG”, 3857]]");
+
+        final CoordinateOperation operation = factory.createOperation(sourceCRS, targetCRS);
+        assertSame      ("sourceCRS", sourceCRS, operation.getSourceCRS());
+        assertSame      ("targetCRS", targetCRS, operation.getTargetCRS());
+        assertInstanceOf("operation", ConcatenatedOperation.class, operation);
+
+        transform = operation.getMathTransform();
+        tolerance = 1;
+
+        assertFalse("Mercator to Google should not be an identity transform.", transform.isIdentity());
+        final DirectPosition2D sourcePt = new DirectPosition2D(334000, 4840000);        //
Approximatively 40°N 3°W
+        final DirectPosition2D targetPt = new DirectPosition2D();
+        assertSame(targetPt, transform.transform(sourcePt, targetPt));
+        assertEquals("Easting should be unchanged", sourcePt.getX(),  targetPt.getX(), STRICT);
+        assertEquals("Expected 27 km shift", 27476, targetPt.getY() - sourcePt.getY(), tolerance);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactoryTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1738930&r1=1738929&r2=1738930&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] Wed Apr 13 12:49:22 2016
@@ -217,8 +217,9 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.CRSTest.class,
 
     // Coordinate operation finders are last, since they need everything else.
-    org.apache.sis.referencing.operation.CoordinateOperationFinderTest.class,
     org.apache.sis.referencing.operation.CoordinateOperationRegistryTest.class,
+    org.apache.sis.referencing.operation.CoordinateOperationFinderTest.class,
+    org.apache.sis.referencing.operation.DefaultCoordinateOperationFactoryTest.class,
     org.apache.sis.referencing.operation.builder.LinearTransformBuilderTest.class,
 
     // Geometry




Mime
View raw message