sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1679564 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/provider/ main/java/org/apache/sis/referencing/operation/ test/java/org/apache/sis/referencing/crs/ test/java/org/apache/sis/referencin...
Date Fri, 15 May 2015 13:38:12 GMT
Author: desruisseaux
Date: Fri May 15 13:38:11 2015
New Revision: 1679564

URL: http://svn.apache.org/r1679564
Log:
Referencing: fix a confusion with theory: LongitudeRotation is a transformation, not a conversion,
because it changes the prime meridian, which is part of datum.
Improved the check in DefaultConversion for making sure that we do not change the datum.
This force us to revisit the DefaultConversionTest, which was wrong from a theory point of
view.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MismatchedDatumException.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRS.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConversionTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java?rev=1679564&r1=1679563&r2=1679564&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/LongitudeRotation.java
[UTF-8] Fri May 15 13:38:11 2015
@@ -20,7 +20,7 @@ import org.opengis.parameter.ParameterVa
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.parameter.ParameterNotFoundException;
-import org.opengis.referencing.operation.Conversion;
+import org.opengis.referencing.operation.Transformation;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
@@ -88,8 +88,8 @@ public final class LongitudeRotation ext
      * @return Interface implemented by all coordinate operations that use this method.
      */
     @Override
-    public Class<Conversion> getOperationType() {
-        return Conversion.class;
+    public Class<Transformation> getOperationType() {
+        return Transformation.class;
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java?rev=1679564&r1=1679563&r2=1679564&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
[UTF-8] Fri May 15 13:38:11 2015
@@ -134,10 +134,12 @@ public class DefaultConversion extends A
      *
      * @param properties The properties to be given to the identified object.
      * @param sourceCRS  The source CRS.
-     * @param targetCRS  The target CRS.
+     * @param targetCRS  The target CRS, which shall use a datum
+     *                   {@linkplain Utilities#equalsIgnoreMetadata equals (ignoring metadata)}
to the source CRS datum.
      * @param interpolationCRS The CRS of additional coordinates needed for the operation,
or {@code null} if none.
      * @param method     The coordinate operation method (mandatory in all cases).
      * @param transform  Transform from positions in the source CRS to positions in the target
CRS.
+     * @throws MismatchedDatumException if the source and target CRS use different datum.
      */
     public DefaultConversion(final Map<String,?>             properties,
                              final CoordinateReferenceSystem sourceCRS,
@@ -149,13 +151,14 @@ public class DefaultConversion extends A
         super(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
         ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
         ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
+        ensureCompatibleDatum("targetCRS", sourceCRS, targetCRS);
     }
 
     /**
      * Creates a defining conversion from the given transform and/or parameters.
      * This conversion has no source and target CRS since those elements are usually unknown
-     * at <cite>defining conversion</cite> construction time. The source and
target CRS will
-     * become known later, at the
+     * at <cite>defining conversion</cite> construction time.
+     * The source and target CRS will become known later, at the
      * {@linkplain org.apache.sis.referencing.crs.DefaultDerivedCRS Derived CRS} or
      * {@linkplain org.apache.sis.referencing.crs.DefaultProjectedCRS Projected CRS}
      * construction time.
@@ -299,6 +302,8 @@ public class DefaultConversion extends A
      * @throws ClassCastException if a contradiction is found between the given {@code baseType},
      *         the defining {@linkplain DefaultConversion#getInterface() conversion type}
and
      *         the {@linkplain DefaultOperationMethod#getOperationType() method operation
type}.
+     * @throws MismatchedDatumException if the given CRS do not use the same datum than the
source and target CRS
+     *         of this conversion.
      * @throws FactoryException if the creation of a {@link MathTransform} from the {@linkplain
#getParameterValues()
      *         parameter values}, or a {@linkplain CoordinateSystems#swapAndScaleAxes change
of axis order or units}
      *         failed.
@@ -313,8 +318,28 @@ public class DefaultConversion extends A
         ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
         ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
         ArgumentChecks.ensureNonNull("factory",   factory);
+        /*
+         * Conceptual consistency check: verify that the new CRS use the same datum than
the previous ones,
+         * since the purpose of this method is not to apply datum changes. Datum changes
are the purpose of
+         * a dedicated kind of operations, namely Transformation.
+         */
         ensureCompatibleDatum("sourceCRS", super.getSourceCRS(), sourceCRS);
-        ensureCompatibleDatum("targetCRS", super.getTargetCRS(), targetCRS);
+        if (!(targetCRS instanceof GeneralDerivedCRS)) {
+            ensureCompatibleDatum("targetCRS", super.getTargetCRS(), targetCRS);
+        } else {
+            /*
+             * Special case for derived and projected CRS: we can not check directly the
datum of the target CRS
+             * of a derived CRS, because this method is invoked indirectly by SIS AbstractDerivedCRS
constructor
+             * before its 'conversionFromBase' field is set. Since the Apache SIS implementations
of derived CRS
+             * map the datum to getConversionFromBase().getSourceCRS().getDatum(), invoking
targetCRS.getDatum()
+             * below may result in a NullPointerException. Instead we verify that 'this'
conversion use the same
+             * datum for source and target CRS, since DerivedCRS and ProjectedCRS are expected
to have the same
+             * datum than their source CRS.
+             */
+            if (super.getTargetCRS() != null) {
+                ensureCompatibleDatum("targetCRS", sourceCRS, super.getTargetCRS());
+            }
+        }
         return SubTypes.create(baseType, this, sourceCRS, targetCRS, factory);
     }
 
@@ -324,7 +349,8 @@ public class DefaultConversion extends A
      *
      * @param param     The parameter name, used only in case of error.
      * @param expected  The CRS containing the expected datum, or {@code null}.
-     * @param actual    The CRS for which to check the datam, or {@code null}.
+     * @param actual    The CRS for which to check the datum, or {@code null}.
+     * @throws MismatchedDatumException if the two CRS use different datum.
      */
     private static void ensureCompatibleDatum(final String param,
             final CoordinateReferenceSystem expected,
@@ -332,23 +358,9 @@ public class DefaultConversion extends A
     {
         if ((expected instanceof SingleCRS) && (actual instanceof SingleCRS)) {
             final Datum datum = ((SingleCRS) expected).getDatum();
-            if (datum != null) {
-                /*
-                 * HACK: this method may be invoked indirectly by DefaultDerivedCRS and DefaultProjectedCRS
constructors
-                 * before their 'conversionFromBase' field is set. Since the Apache SIS implementations
of those CRS map
-                 * the datum to getConversionFromBase().getSourceCRS().getDatum(), invoking
the actual.getDatum() method
-                 * below result in a NullPointerException.  To avoid this problem, we bypass
this check if the given CRS
-                 * is a derived CRS with a null conversion.
-                 */
-                if (!(actual instanceof GeneralDerivedCRS) || ((GeneralDerivedCRS) actual).getConversionFromBase()
!= null) {
-                    /*
-                     * Now the real check.
-                     */
-                    if (!Utilities.equalsIgnoreMetadata(datum, ((SingleCRS) actual).getDatum()))
{
-                        throw new IllegalArgumentException(Errors.format(
-                                Errors.Keys.IncompatibleDatum_2, datum.getName(), param));
-                    }
-                }
+            if (datum != null && !Utilities.equalsIgnoreMetadata(datum, ((SingleCRS)
actual).getDatum())) {
+                throw new MismatchedDatumException(Errors.format(
+                        Errors.Keys.IncompatibleDatum_2, datum.getName(), param));
             }
         }
     }

Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MismatchedDatumException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MismatchedDatumException.java?rev=1679564&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MismatchedDatumException.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/MismatchedDatumException.java
[UTF-8] Fri May 15 13:38:11 2015
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+
+/**
+ * Thrown when the source and target CRS of a {@linkplain DefaultConversion conversion} use
different datum.
+ * By definition, conversions do not perform any change of datum
+ * while {@linkplain DefaultTransformation transformations} can do.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.6
+ * @version 0.6
+ * @module
+ */
+public class MismatchedDatumException extends IllegalArgumentException {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 9209713725368948171L;
+
+    /**
+     * Constructs a new exception with no message.
+     */
+    public MismatchedDatumException() {
+        super();
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     *
+     * @param message The detail message, or {@code null} if none.
+     */
+    public MismatchedDatumException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and cause.
+     *
+     * @param message The detail message, or {@code null} if none.
+     * @param cause The cause, or {@code null} if none.
+     */
+    public MismatchedDatumException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+}

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

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

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java?rev=1679564&r1=1679563&r2=1679564&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/DefaultDerivedCRSTest.java
[UTF-8] Fri May 15 13:38:11 2015
@@ -96,7 +96,7 @@ public final strictfp class DefaultDeriv
      */
     private static DefaultDerivedCRS createLongitudeRotation() {
         final DefaultConversion conversion = DefaultConversionTest.createLongitudeRotation();
-        return new DefaultDerivedCRS(Collections.singletonMap(DefaultDerivedCRS.NAME_KEY,
"Back to WGS84"),
+        return new DefaultDerivedCRS(Collections.singletonMap(DefaultDerivedCRS.NAME_KEY,
conversion.getTargetCRS().getName()),
                 (SingleCRS) conversion.getSourceCRS(), conversion, HardCodedCS.GEODETIC_φλ);
     }
 
@@ -108,10 +108,10 @@ public final strictfp class DefaultDeriv
         final DefaultDerivedCRS crs = createLongitudeRotation();
         Validators.validate(crs);
 
-        assertEquals("name",             "Back to WGS84",         crs.getName().getCode());
-        assertEquals("baseCRS",          "Paris",                 crs.getBaseCRS().getName().getCode());
-        assertEquals("datum",            "Paris",                 crs.getDatum().getName().getCode());
-        assertSame  ("coordinateSystem", HardCodedCS.GEODETIC_φλ, crs.getCoordinateSystem());
+        assertEquals("name",    "Back to Greenwich",                crs.getName().getCode());
+        assertEquals("baseCRS", "NTF (Paris)",                      crs.getBaseCRS().getName().getCode());
+        assertEquals("datum",   "Nouvelle Triangulation Française", crs.getDatum().getName().getCode());
+        assertSame  ("coordinateSystem", HardCodedCS.GEODETIC_φλ,   crs.getCoordinateSystem());
 
         final Conversion conversion = crs.getConversionFromBase();
         assertSame("sourceCRS", crs.getBaseCRS(), conversion.getSourceCRS());
@@ -130,16 +130,16 @@ public final strictfp class DefaultDeriv
     @DependsOnMethod("testConstruction")
     public void testWKT1() {
         assertWktEquals(Convention.WKT1,
-                "FITTED_CS[“Back to WGS84”,\n" +
+                "FITTED_CS[“Back to Greenwich”,\n" +
                 "  PARAM_MT[“Affine”,\n" +
                 "    PARAMETER[“elt_0_0”, 0.0],\n" +
                 "    PARAMETER[“elt_0_1”, 1.0],\n" +
                 "    PARAMETER[“elt_0_2”, -2.33722917],\n" +
                 "    PARAMETER[“elt_1_0”, 1.0],\n" +
                 "    PARAMETER[“elt_1_1”, 0.0]],\n" +
-                "  GEOGCS[“Paris”,\n" +
-                "    DATUM[“Paris”,\n" +
-                "      SPHEROID[“WGS84”, 6378137.0, 298.257223563]],\n" +
+                "  GEOGCS[“NTF (Paris)”,\n" +
+                "    DATUM[“Nouvelle Triangulation Francaise”,\n" +
+                "      SPHEROID[“NTF”, 6378249.2, 293.4660212936269]],\n" +
                 "      PRIMEM[“Paris”, 2.33722917],\n" +
                 "    UNIT[“degree”, 0.017453292519943295],\n" +
                 "    AXIS[“Longitude”, EAST],\n" +
@@ -155,10 +155,10 @@ public final strictfp class DefaultDeriv
     @DependsOnMethod("testWKT1")
     public void testWKT2() {
         assertWktEquals(
-                "GeodeticCRS[“Back to WGS84”,\n" +
-                "  BaseGeodCRS[“Paris”,\n" +
-                "    Datum[“Paris”,\n" +
-                "      Ellipsoid[“WGS84”, 6378137.0, 298.257223563, LengthUnit[“metre”,
1]]],\n" +
+                "GeodeticCRS[“Back to Greenwich”,\n" +
+                "  BaseGeodCRS[“NTF (Paris)”,\n" +
+                "    Datum[“Nouvelle Triangulation Francaise”,\n" +
+                "      Ellipsoid[“NTF”, 6378249.2, 293.4660212936269, LengthUnit[“metre”,
1]]],\n" +
                 "      PrimeMeridian[“Paris”, 2.5969213, AngleUnit[“grade”, 0.015707963267948967]]],\n"
+
                 "  DerivingConversion[“Paris to Greenwich”,\n" +
                 "    Method[“Longitude rotation”, Id[“EPSG”, 9601, Citation[“IOGP”]]],\n"
+

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRS.java?rev=1679564&r1=1679563&r2=1679564&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRS.java
[UTF-8] Fri May 15 13:38:11 2015
@@ -18,6 +18,7 @@ package org.apache.sis.referencing.crs;
 
 import java.util.Map;
 import java.util.HashMap;
+import java.util.Collections;
 import org.opengis.referencing.datum.PixelInCell;
 import org.apache.sis.referencing.cs.HardCodedCS;
 import org.apache.sis.referencing.datum.HardCodedDatum;
@@ -84,11 +85,10 @@ public final strictfp class HardCodedCRS
      * this CRS is to test operations between CRS having different prime meridian.</p>
      *
      * @since 0.5
-     *
-     * @see DefaultProjectedCRSTest#NTF_ZONE_II
      */
     public static final DefaultGeographicCRS NTF = new DefaultGeographicCRS(
-            properties("NTF (Paris)"), HardCodedDatum.NTF, HardCodedCS.GEODETIC_2D);
+            Collections.singletonMap(DefaultGeographicCRS.NAME_KEY, "NTF (Paris)"),
+            HardCodedDatum.NTF, HardCodedCS.GEODETIC_2D);
 
     /**
      * A two-dimensional geographic coordinate reference system using a spherical datum.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConversionTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConversionTest.java?rev=1679564&r1=1679563&r2=1679564&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConversionTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConversionTest.java
[UTF-8] Fri May 15 13:38:11 2015
@@ -22,6 +22,7 @@ import java.util.Collections;
 import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterValue;
 import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.TemporalCRS;
 import org.opengis.referencing.cs.EllipsoidalCS;
@@ -37,7 +38,6 @@ import org.apache.sis.referencing.datum.
 import org.apache.sis.referencing.cs.HardCodedCS;
 import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
-import org.apache.sis.referencing.datum.DefaultGeodeticDatum;
 import org.apache.sis.referencing.operation.matrix.Matrix3;
 import org.apache.sis.referencing.operation.matrix.Matrix4;
 import org.apache.sis.referencing.operation.matrix.Matrices;
@@ -70,33 +70,47 @@ public final strictfp class DefaultConve
     private static final double OFFSET = 2.33722917;
 
     /**
-     * Creates a CRS using the WGS84 datum, except for the prime meridian which is set to
Paris.
-     * This is not a CRS is real usage (the CRS with Paris prime meridian were using an older
datum),
-     * but this is convenient for testing a conversion consisting of only a longitude rotation.
+     * Creates a CRS using the same datum than the "Nouvelle Triangulation Française (Paris)"
datum (EPSG:6807).
      *
+     * @param isSource {@code true} if creating the source CRS, or {@code false} if creating
the target CRS.
      * @param cs {@link HardCodedCS#GEODETIC_2D}, {@link HardCodedCS#GEODETIC_φλ} or other
compatible coordinate system.
+     *
+     * @see HardCodedCRS#NTF
+     */
+    private static GeographicCRS createParisCRS(final boolean isSource, final EllipsoidalCS
cs) {
+        return new DefaultGeographicCRS(Collections.singletonMap(GeographicCRS.NAME_KEY,
+                isSource ? HardCodedCRS.NTF.getName() : "Back to Greenwich"), HardCodedDatum.NTF,
cs);
+    }
+
+    /**
+     * Changes only the coordinate system of the given CRS, which is supposed geographic.
      */
-    private static GeographicCRS createParisCRS(final EllipsoidalCS cs) {
-        final Map<String, ?> name = Collections.singletonMap(GeographicCRS.NAME_KEY,
HardCodedDatum.PARIS.getName());
-        return new DefaultGeographicCRS(name, new DefaultGeodeticDatum(name,
-                HardCodedDatum.WGS84.getEllipsoid(), HardCodedDatum.PARIS), cs);
+    private static GeographicCRS changeCS(final CoordinateReferenceSystem crs, final EllipsoidalCS
cs) {
+        return new DefaultGeographicCRS(Collections.singletonMap(DefaultGeographicCRS.NAME_KEY,
+                crs.getName()), ((GeographicCRS) crs).getDatum(), cs);
     }
 
     /**
-     * Creates a very simple conversion performing a longitude rotation between two-dimensional
normalized CRS.
-     * The source CRS uses the Paris prime meridian and the target CRS uses the Greenwich
prime meridian.
-     * Both CRS use the WGS84 datum.
+     * Creates a pseudo-conversion performing a longitude rotation between two-dimensional
normalized CRS.
+     * The source CRS uses the Paris prime meridian and the target CRS "conceptually" uses
the Greenwich
+     * prime meridian.
      *
-     * @return A simple conversion performing a longitude rotation on the WGS84 geodetic
datum.
+     * <p><b>This is not really a valid conversion</b> since, strictly
speaking, <cite>Longitude rotations</cite>
+     * are coordinate <em>transformations</em> rather than conversions (because
they change the datum, since they
+     * change the prime meridian). However we handle them as conversions for testing purpose
only, because the
+     * longitude rotation is a very simple operation easy to test.</p>
+     *
+     * @return A pseudo-conversion performing a longitude rotation.
      */
     public static DefaultConversion createLongitudeRotation() {
-        return createLongitudeRotation(createParisCRS(HardCodedCS.GEODETIC_2D), HardCodedCRS.WGS84,
null);
+        return createLongitudeRotation(HardCodedCRS.NTF, createParisCRS(false, HardCodedCS.GEODETIC_2D),
null);
     }
 
     /**
-     * Creates a very simple conversion performing a longitude rotation on the WGS84 datum.
-     * The source CRS shall use the Paris prime meridian and the target CRS the Greenwich
-     * prime meridian.
+     * Creates a very simple conversion performing a longitude rotation.
+     * The source CRS shall use the Paris prime meridian and the target CRS the Greenwich
prime meridian,
+     * at least conceptually. See {@link #createLongitudeRotation(boolean)} for an explanation
about why
+     * this is not really a valid conversion.
      *
      * @param sourceCRS A CRS using the Paris prime meridian.
      * @param targetCRS A CRS using the Greenwich prime meridian.
@@ -143,8 +157,8 @@ public final strictfp class DefaultConve
      */
     private static void verifyProperties(final DefaultConversion op, final boolean swapSourceAxes)
{
         assertEquals("name",       "Paris to Greenwich", op.getName().getCode());
-        assertEquals("sourceCRS",  "Paris",              op.getSourceCRS().getName().getCode());
-        assertEquals("targetCRS",  "WGS 84",             op.getTargetCRS().getName().getCode());
+        assertEquals("sourceCRS",  "NTF (Paris)",        op.getSourceCRS().getName().getCode());
+        assertEquals("targetCRS",  "Back to Greenwich",  op.getTargetCRS().getName().getCode());
         assertEquals("method",     "Longitude rotation", op.getMethod().getName().getCode());
         assertEquals("parameters", "Longitude rotation", op.getParameterDescriptors().getName().getCode());
 
@@ -166,7 +180,7 @@ public final strictfp class DefaultConve
     }
 
     /**
-     * Tests a simple two-dimensional conversion performing a longitude rotation on the WGS84
datum.
+     * Tests a simple two-dimensional conversion performing a longitude rotation.
      */
     @Test
     public void testConstruction() {
@@ -204,9 +218,9 @@ public final strictfp class DefaultConve
          * but add a swapping of (latitude, longitude) axes.
          */
         final DefaultConversion completed = definingConversion.specialize(
-                DefaultConversion.class,                    // In normal use, this would
be 'Conversion.class'.
-                createParisCRS(HardCodedCS.GEODETIC_φλ),    // Swap axis order.
-                reference.getTargetCRS(),                   // Keep the same target CRS.
+                DefaultConversion.class,    // In normal use, this would be 'Conversion.class'.
+                changeCS(reference.getSourceCRS(), HardCodedCS.GEODETIC_φλ),
+                reference.getTargetCRS(),
                 DefaultFactories.forBuildin(MathTransformFactory.class));
 
         verifyProperties(completed, true);
@@ -225,7 +239,9 @@ public final strictfp class DefaultConve
     @DependsOnMethod("testDefiningConversion")
     public void testSpecialize() throws FactoryException {
         final MathTransformFactory factory = DefaultFactories.forBuildin(MathTransformFactory.class);
-        DefaultConversion op = createLongitudeRotation(createParisCRS(HardCodedCS.GEODETIC_3D),
HardCodedCRS.WGS84_3D, null);
+        DefaultConversion op = createLongitudeRotation(
+                createParisCRS(true,  HardCodedCS.GEODETIC_3D),
+                createParisCRS(false, HardCodedCS.GEODETIC_3D), null);
         assertMatrixEquals("Longitude rotation of a three-dimensional CRS", new Matrix4(
                 1, 0, 0, OFFSET,
                 0, 1, 0, 0,
@@ -239,7 +255,8 @@ public final strictfp class DefaultConve
         /*
          * Reducing the number of dimensions to 2 and swapping (latitude, longitude) axes.
          */
-        op = op.specialize(DefaultConversion.class, createParisCRS(HardCodedCS.GEODETIC_3D),
HardCodedCRS.WGS84_φλ, factory);
+        op = op.specialize(DefaultConversion.class, op.getSourceCRS(),
+                changeCS(op.getTargetCRS(), HardCodedCS.GEODETIC_φλ), factory);
         assertMatrixEquals("Longitude rotation of a two-dimensional CRS", Matrices.create(3,
4, new double[] {
                 0, 1, 0, 0,
                 1, 0, 0, OFFSET,
@@ -264,8 +281,8 @@ public final strictfp class DefaultConve
     @Test
     @DependsOnMethod("testDefiningConversion")
     public void testWithInterpolationCRS() throws FactoryException {
-        DefaultConversion op = createLongitudeRotation(
-                createParisCRS(HardCodedCS.GEODETIC_2D), HardCodedCRS.WGS84, HardCodedCRS.TIME);
+        DefaultConversion op = createLongitudeRotation(HardCodedCRS.NTF,
+                createParisCRS(false, HardCodedCS.GEODETIC_2D), HardCodedCRS.TIME);
         assertMatrixEquals("Longitude rotation of a time-varying CRS", new Matrix4(
                 1, 0, 0, 0,
                 0, 1, 0, OFFSET,
@@ -275,7 +292,7 @@ public final strictfp class DefaultConve
         op = op.specialize(
                 DefaultConversion.class,    // In normal use, this would be 'Conversion.class'.
                 op.getSourceCRS(),          // Keep the same source CRS.
-                HardCodedCRS.WGS84_φλ,      // Swap axis order.
+                changeCS(op.getTargetCRS(), HardCodedCS.GEODETIC_φλ),   // Swap axis order.
                 DefaultFactories.forBuildin(MathTransformFactory.class));
 
         assertMatrixEquals("Longitude rotation of a time-varying CRS", new Matrix4(
@@ -295,21 +312,20 @@ public final strictfp class DefaultConve
         final MathTransformFactory factory = DefaultFactories.forBuildin(MathTransformFactory.class);
         final DefaultConversion op = createLongitudeRotation();
         try {
-            op.specialize(Conversion.class, HardCodedCRS.WGS84, HardCodedCRS.WGS84, factory);
+            op.specialize(Conversion.class, HardCodedCRS.WGS84, HardCodedCRS.NTF, factory);
             fail("Should not have accepted to change the geodetic datum.");
         } catch (IllegalArgumentException e) {
             final String message = e.getMessage();
             assertTrue(message, message.contains("sourceCRS"));
-            assertTrue(message, message.contains("Paris"));
+            assertTrue(message, message.contains("Nouvelle Triangulation Française"));
         }
-        GeographicCRS crs = (GeographicCRS) op.getSourceCRS();
         try {
-            op.specialize(Conversion.class, crs, crs, factory);
+            op.specialize(Conversion.class, HardCodedCRS.NTF, HardCodedCRS.WGS84, factory);
             fail("Should not have accepted to change the geodetic datum.");
         } catch (IllegalArgumentException e) {
             final String message = e.getMessage();
             assertTrue(message, message.contains("targetCRS"));
-            assertTrue(message, message.contains("World Geodetic System 1984"));
+            assertTrue(message, message.contains("Nouvelle Triangulation Française"));
         }
     }
 



Mime
View raw message