sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1719607 [2/2] - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/provider/ main/java/org/apache/sis/referencing/datum/ main/java/org/apache/sis/referencing/operation/matrix/ main/java/org/apache...
Date Sat, 12 Dec 2015 00:51:26 GMT
Copied: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform.java
(from r1719083, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform.java?p2=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform.java&p1=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java&r1=1719083&r2=1719607&rev=1719607&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform.java
[UTF-8] Sat Dec 12 00:51:25 2015
@@ -23,7 +23,6 @@ import javax.measure.quantity.Length;
 import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.geometry.MismatchedDimensionException;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
@@ -37,15 +36,17 @@ import org.apache.sis.metadata.iso.citat
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.referencing.datum.DatumShiftGrid;
-import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Debug;
 
 
 /**
- * Transforms between two geographic CRS by performing geocentric translations interpolated
from a grid file.
- * This transform is used mainly for <cite>"France geocentric interpolation"</cite>
(ESPG:9655) datum shifts,
- * but Apache SIS implementation allows the use for other regions.
+ * Transforms between two geographic CRS by performing geocentric translations interpolated
from a grid file, but using
+ * Molodensky approximation. This transformation is conceptually defined as a translation
in geocentric coordinates
+ * as performed by {@link InterpolatedGeocentricTransform}, but uses the {@linkplain MolodenskyTransform
Molodensy}
+ * (non-abridged) approximation for performance reasons.
+ * Errors are less than 3 centimetres for the <cite>"France geocentric interpolation"</cite>
(ESPG:9655).
+ * By comparison, the finest accuracy reported in the grid file for France is 5 centimetres.
  *
  * <div class="section">Algorithm</div>
  * This class transforms two- or three- dimensional coordinates from a geographic CRS to
another geographic CRS.
@@ -53,65 +54,31 @@ import org.apache.sis.util.Debug;
  * position. Those changes are provided in a {@linkplain DatumShiftGrid datum shift grid},
usually loaded from one
  * or two files.
  *
- * <p>Many datum shift grids like NADCON and NTv2 apply the changes directly on geographic
coordinates.
+ * <p>Many datum shift grids like NADCON and NTv2 apply the interpolated translations
directly on geographic coordinates.
  * This relatively simple case is handled by {@link InterpolatedTransform}.
- * But the {@code InterpolatedGeocentricTransform} algorithm uses the grid in a more complex
way:</p>
- *
- * <ol>
- *   <li>Convert input geographic coordinate (λ,φ) to geocentric coordinate (X,Y,Z).</li>
- *   <li>Ask {@link DatumShiftGrid} for the offset to apply for coordinate (λ,φ).
- *       But instead of returning a (Δλ, Δφ) offset, the grid shall return a (ΔX, ΔY,
ΔZ) offset.</li>
- *   <li>Convert the shifted geocentric coordinate (X+ΔX, Y+ΔY, Z+ΔZ) back to a
geographic coordinate.</li>
- * </ol>
- *
- * <div class="note"><b>Source:</b> IGN document {@code NTG_88.pdf},
- * <cite>"Grille de paramètres de transformation de coordonnées"</cite>
- * at <a href="http://www.ign.fr">http://www.ign.fr</a>.
- * Note however that the signs of (ΔX, ΔY, ΔZ) values expected by this class are the opposite
of the
- * signs used in NTG_88 document. This is because NTG_88 grid defines shifts from target
to source,
- * while this class expects shifts from source to target.
+ * But in the {@code InterpolatedMolodenskyTransform} case, the interpolated translations
are rather the
+ * ({@linkplain #tX}, {@linkplain #tY}, {@linkplain #tZ}) parameters of a Molodensky transformation.</p>
  *
- * <p><b>Note:</b> this algorithm is not the same as a (theoretical) {@link
EllipsoidToCentricTransform} →
- * {@link InterpolatedTransform} → (inverse of {@code EllipsoidToCentricTransform}) concatenation
- * because the {@code DatumShiftGrid} inputs are geographic coordinates even if the interpolated
- * grid values are in geocentric space.</p></div>
- *
- * <div class="section">Implementation</div>
- * While this transformation is conceptually defined as a translation in geocentric coordinates,
the current
- * Apache SIS implementation rather uses the {@linkplain MolodenskyTransform Molodensy} (non-abridged)
approximation
- * for performance reasons. Errors are less than 3 centimetres for the France geocentric
interpolation.
- * By comparison, the finest accuracy reported in the grid file for France is 5 centimetres.
- *
- * @author  Simon Reynard (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
  * @version 0.7
  * @module
+ *
+ * @see InterpolatedGeocentricTransform
  */
-public class InterpolatedGeocentricTransform extends MolodenskyFormula {
+public class InterpolatedMolodenskyTransform extends MolodenskyFormula {
     /**
      * Serial number for inter-operability with different versions.
      */
     private static final long serialVersionUID = -5691721806681489940L;
 
     /**
-     * Parameter descriptor to use with the contextual parameters for the forward transformation.
-     * We do not use the <cite>"France geocentric interpolation"</cite> (ESPG:9655)
descriptor
-     * because their "forward" transformation is our "inverse" transformation, and conversely.
-     * The {@code DESCRIPTOR} defined here is non-standard, but allows this class to be used
-     * for other geographic areas than France.
-     */
-    private static final ParameterDescriptorGroup DESCRIPTOR;
-
-    /**
-     * Parameter descriptor to use with the contextual parameters for the inverse transformation.
-     * We do not use the <cite>"France geocentric interpolation"</cite> (ESPG:9655)
descriptor
-     * because it is specific to a single country, has hard-coded parameters and uses a sign
-     * convention for (ΔX,ΔY,ΔZ) translations different than the one used in this class.
-     * The {@code INVERSE} descriptor defined here is non-standard, but allows this class
-     * to be used for other geographic areas than France.
+     * Parameter descriptor to use with the contextual parameters for the forward and inverse
transformations.
+     * We do not use directly the <cite>"France geocentric interpolation"</cite>
(ESPG:9655) descriptor because
+     * this {@code InterpolatedMolodenskyTransform} is an approximation of {@link InterpolatedGeocentricTransform}
+     * and the conventions used by SIS are different than EPSG:9655 ones.
      */
-    private static final ParameterDescriptorGroup INVERSE;
+    private static final ParameterDescriptorGroup DESCRIPTOR, INVERSE;
     static {
         final ParameterBuilder builder = new ParameterBuilder()
                 .setRequired(true).setCodeSpace(Citations.SIS, Constants.SIS);
@@ -123,51 +90,51 @@ public class InterpolatedGeocentricTrans
                 Molodensky.TGT_SEMI_MINOR,
                 FranceGeocentricInterpolation.FILE
         };
-        DESCRIPTOR = builder.addName("Geocentric interpolation").createGroup(param);
-        INVERSE = builder.addName("Geocentric inverse interpolation").createGroup(param);
+        DESCRIPTOR = builder.addName("Molodensky interpolation").createGroup(param);
+        INVERSE = builder.addName("Molodensky inverse interpolation").createGroup(param);
     }
 
     /**
-     * The inverse of this interpolated geocentric transform.
+     * The inverse of this interpolated Molodensky transform.
      *
      * @see #inverse()
      */
-    private final InterpolatedGeocentricTransform inverse;
+    private final InterpolatedMolodenskyTransform inverse;
 
     /**
-     * Constructs the inverse of an interpolated geocentric transform.
+     * Constructs the inverse of an interpolated Molodensky transform.
      *
      * @param inverse The transform for which to create the inverse.
      * @param source  The source ellipsoid of the given {@code inverse} transform.
      * @param target  The target ellipsoid of the given {@code inverse} transform.
      */
-    InterpolatedGeocentricTransform(final InterpolatedGeocentricTransform inverse, Ellipsoid
source, Ellipsoid target) {
+    InterpolatedMolodenskyTransform(final InterpolatedMolodenskyTransform inverse, Ellipsoid
source, Ellipsoid target) {
         super(inverse, source, target, INVERSE);
         this.inverse = inverse;
     }
 
     /**
      * Creates a transform from the specified parameters.
-     * This {@code InterpolatedGeocentricTransform} class expects ordinate values in the
following order and units:
+     * This {@code InterpolatedMolodenskyTransform} class expects ordinate values in the
following order and units:
      * <ol>
      *   <li>longitudes in <strong>radians</strong> relative to the prime
meridian (usually Greenwich),</li>
      *   <li>latitudes in <strong>radians</strong>,</li>
      *   <li>optionally heights above the ellipsoid, in same units than the source
ellipsoid axes.</li>
      * </ol>
      *
-     * For converting geographic coordinates in degrees, {@code InterpolatedGeocentricTransform}
instances
+     * For converting geographic coordinates in degrees, {@code InterpolatedMolodenskyTransform}
instances
      * need to be concatenated with the following affine transforms:
      *
      * <ul>
-     *   <li><cite>Normalization</cite> before {@code InterpolatedGeocentricTransform}:<ul>
+     *   <li><cite>Normalization</cite> before {@code InterpolatedMolodenskyTransform}:<ul>
      *     <li>Conversion of (λ,φ) from degrees to radians.</li>
      *   </ul></li>
-     *   <li><cite>Denormalization</cite> after {@code InterpolatedGeocentricTransform}:<ul>
+     *   <li><cite>Denormalization</cite> after {@code InterpolatedMolodenskyTransform}:<ul>
      *     <li>Conversion of (λ,φ) from radians to degrees.</li>
      *   </ul></li>
      * </ul>
      *
-     * After {@code InterpolatedGeocentricTransform} construction,
+     * After {@code InterpolatedMolodenskyTransform} construction,
      * the full conversion chain including the above affine transforms can be created by
      * <code>{@linkplain #getContextualParameters()}.{@linkplain ContextualParameters#completeTransform
      * completeTransform}(factory, this)}</code>.
@@ -183,7 +150,7 @@ public class InterpolatedGeocentricTrans
      *
      * @see #createGeodeticTransformation(MathTransformFactory, Ellipsoid, boolean, Ellipsoid,
boolean, DatumShiftGrid)
      */
-    protected InterpolatedGeocentricTransform(final Ellipsoid source, final boolean isSource3D,
+    protected InterpolatedMolodenskyTransform(final Ellipsoid source, final boolean isSource3D,
                                               final Ellipsoid target, final boolean isTarget3D,
                                               final DatumShiftGrid<Angle,Length> grid)
     {
@@ -194,24 +161,17 @@ public class InterpolatedGeocentricTrans
               grid.getCellMean(2),
               grid, false, DESCRIPTOR);
 
-        final int dim = grid.getTranslationDimensions();
-        if (dim != 3) {
-            throw new MismatchedDimensionException(Errors.format(Errors.Keys.MismatchedDimension_3,
"grid", 3, dim));
-        }
-        Object unit = "ratio";
-        if (grid.isCellValueRatio() || (unit = grid.getTranslationUnit()) != source.getAxisUnit())
{
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalUnitFor_2,
"translation", unit));
-        }
+        ensureGeocentricTranslation(grid, source.getAxisUnit());
         if (isSource3D || isTarget3D) {
             inverse = new Inverse(this, source, target);
         } else {
-            inverse = new InterpolatedGeocentricTransform2D.Inverse(this, source, target);
+            inverse = new InterpolatedMolodenskyTransform2D.Inverse(this, source, target);
         }
     }
 
     /**
      * Creates a transformation between two geographic CRS. This factory method combines
the
-     * {@code InterpolatedGeocentricTransform} instance with the steps needed for converting
values between
+     * {@code InterpolatedMolodenskyTransform} instance with the steps needed for converting
values between
      * degrees to radians. The transform works with input and output coordinates in the following
units:
      *
      * <ol>
@@ -241,11 +201,11 @@ public class InterpolatedGeocentricTrans
             final DatumShiftGrid<Angle,Length> grid) throws FactoryException
     {
         ArgumentChecks.ensureNonNull("grid", grid);
-        final InterpolatedGeocentricTransform tr;
+        final InterpolatedMolodenskyTransform tr;
         if (isSource3D || isTarget3D) {
-            tr = new InterpolatedGeocentricTransform(source, isSource3D, target, isTarget3D,
grid);
+            tr = new InterpolatedMolodenskyTransform(source, isSource3D, target, isTarget3D,
grid);
         } else {
-            tr = new InterpolatedGeocentricTransform2D(source, target, grid);
+            tr = new InterpolatedMolodenskyTransform2D(source, target, grid);
         }
         tr.inverse.context.completeTransform(factory, null);
         return tr.context.completeTransform(factory, tr);
@@ -288,7 +248,8 @@ public class InterpolatedGeocentricTrans
         final double[] vector = new double[3];
         final double λ = srcPts[srcOff];
         final double φ = srcPts[srcOff+1];
-        grid.interpolateAtNormalized(λ, φ, vector);
+        grid.interpolateInCell(grid.normalizedToGridX(λ),
+                               grid.normalizedToGridY(φ), vector);
         return transform(λ, φ, isSource3D ? srcPts[srcOff+2] : 0,
                 dstPts, dstOff, vector[0], vector[1], vector[2], null, derivate);
     }
@@ -335,7 +296,8 @@ public class InterpolatedGeocentricTrans
         while (--numPts >= 0) {
             final double λ = srcPts[srcOff  ];
             final double φ = srcPts[srcOff+1];
-            grid.interpolateAtNormalized(λ, φ, offset);
+            grid.interpolateInCell(grid.normalizedToGridX(λ),
+                                   grid.normalizedToGridY(φ), offset);
             transform(λ, φ, isSource3D ? srcPts[srcOff+2] : 0,
                       dstPts, dstOff, offset[0], offset[1], offset[2], null, false);
             srcOff += srcInc;
@@ -355,7 +317,7 @@ public class InterpolatedGeocentricTrans
      */
 
     /**
-     * Returns the inverse of this interpolated geocentric transform.
+     * Returns the inverse of this interpolated Molodensky transform.
      * The source ellipsoid of the returned transform will be the target ellipsoid of this
transform, and conversely.
      *
      * @return A transform from the target ellipsoid to the source ellipsoid of this transform.
@@ -370,7 +332,7 @@ public class InterpolatedGeocentricTrans
 
 
     /**
-     * The inverse of the enclosing {@link InterpolatedGeocentricTransform}.
+     * The inverse of the enclosing {@link InterpolatedMolodenskyTransform}.
      * This transform applies an algorithm similar to the one documented in the enclosing
class,
      * with the following differences:
      *
@@ -385,20 +347,20 @@ public class InterpolatedGeocentricTrans
      * @version 0.7
      * @module
      */
-    static class Inverse extends InterpolatedGeocentricTransform {
+    static class Inverse extends InterpolatedMolodenskyTransform {
         /**
          * Serial number for inter-operability with different versions.
          */
         private static final long serialVersionUID = -3520896803296425651L;
 
         /**
-         * Constructs the inverse of an interpolated geocentric transform.
+         * Constructs the inverse of an interpolated Molodensky transform.
          *
          * @param inverse The transform for which to create the inverse.
          * @param source  The source ellipsoid of the given {@code inverse} transform.
          * @param target  The target ellipsoid of the given {@code inverse} transform.
          */
-        Inverse(final InterpolatedGeocentricTransform inverse, final Ellipsoid source, final
Ellipsoid target) {
+        Inverse(final InterpolatedMolodenskyTransform inverse, final Ellipsoid source, final
Ellipsoid target) {
            super(inverse, source, target);
         }
 
@@ -471,7 +433,7 @@ public class InterpolatedGeocentricTrans
     }
 
     /**
-     * Returns a description of the internal parameters of this {@code InterpolatedGeocentricTransform}
transform.
+     * Returns a description of the internal parameters of this {@code InterpolatedMolodenskyTransform}
transform.
      * The returned group contains parameters for the source ellipsoid semi-axis lengths
and the differences between
      * source and target ellipsoid parameters.
      *

Copied: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform2D.java
(from r1719083, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform2D.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform2D.java?p2=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform2D.java&p1=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform2D.java&r1=1719083&r2=1719607&rev=1719607&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform2D.java
[UTF-8] Sat Dec 12 00:51:25 2015
@@ -28,14 +28,14 @@ import org.apache.sis.referencing.datum.
 
 
 /**
- * An interpolated geocentric transform for two-dimensional input and output coordinates.
+ * An interpolated Molodensky transform for two-dimensional input and output coordinates.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
  * @version 0.7
  * @module
  */
-final class InterpolatedGeocentricTransform2D extends InterpolatedGeocentricTransform implements
MathTransform2D {
+final class InterpolatedMolodenskyTransform2D extends InterpolatedMolodenskyTransform implements
MathTransform2D {
     /**
      * Serial number for compatibility with different versions.
      */
@@ -44,7 +44,7 @@ final class InterpolatedGeocentricTransf
     /**
      * Constructs a 2D transform.
      */
-    InterpolatedGeocentricTransform2D(final Ellipsoid source, final Ellipsoid target, final
DatumShiftGrid<Angle,Length> grid) {
+    InterpolatedMolodenskyTransform2D(final Ellipsoid source, final Ellipsoid target, final
DatumShiftGrid<Angle,Length> grid) {
         super(source, false, target, false, grid);
     }
 
@@ -81,27 +81,27 @@ final class InterpolatedGeocentricTransf
     }
 
     /**
-     * The inverse of the enclosing {@link InterpolatedGeocentricTransform2D}.
+     * The inverse of the enclosing {@link InterpolatedMolodenskyTransform2D}.
      *
      * @author  Martin Desruisseaux (Geomatys)
      * @since   0.7
      * @version 0.7
      * @module
      */
-    static final class Inverse extends InterpolatedGeocentricTransform.Inverse implements
MathTransform2D {
+    static final class Inverse extends InterpolatedMolodenskyTransform.Inverse implements
MathTransform2D {
         /**
          * Serial number for inter-operability with different versions.
          */
         private static final long serialVersionUID = 3175846640786132902L;
 
         /**
-         * Constructs the inverse of an interpolated geocentric transform.
+         * Constructs the inverse of an interpolated Molodensky transform.
          *
          * @param inverse The transform for which to create the inverse.
          * @param source  The source ellipsoid of the given {@code inverse} transform.
          * @param target  The target ellipsoid of the given {@code inverse} transform.
          */
-        Inverse(final InterpolatedGeocentricTransform inverse, final Ellipsoid source, final
Ellipsoid target) {
+        Inverse(final InterpolatedMolodenskyTransform inverse, final Ellipsoid source, final
Ellipsoid target) {
            super(inverse, source, target);
         }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java?rev=1719607&r1=1719606&r2=1719607&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java
[UTF-8] Sat Dec 12 00:51:25 2015
@@ -16,10 +16,8 @@
  */
 package org.apache.sis.referencing.operation.transform;
 
-import java.io.Serializable;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Length;
-import javax.measure.converter.UnitConverter;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.datum.Ellipsoid;
@@ -37,16 +35,13 @@ import org.apache.sis.util.Debug;
 
 import static java.lang.Math.*;
 
-// Branch-specific imports
-import java.util.Objects;
-
 
 /**
- * Implementation of Molodensky formulas. This class is used by
+ * Implementation of Molodensky formulas. This class is used by:
  *
  * <ul>
  *   <li>The "real" {@link MolodenskyTransform} (see that class for documentation about
Molodensky transform).</li>
- *   <li>{@link InterpolatedGeocentricTransform}, which conceptually works on geocentric
coordinates but
+ *   <li>{@link InterpolatedMolodenskyTransform}, which conceptually works on geocentric
coordinates but
  *       is implemented in Apache SIS using Molodensky (never abridged) formulas for performance
reasons.
  *       However this implementation choice should be hidden to users (except by mention
in javadoc).</li>
  * </ul>
@@ -56,7 +51,7 @@ import java.util.Objects;
  * @version 0.7
  * @module
  */
-abstract class MolodenskyFormula extends AbstractMathTransform implements Serializable {
+abstract class MolodenskyFormula extends DatumShiftTransform {
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -143,20 +138,6 @@ abstract class MolodenskyFormula extends
     protected final double eccentricitySquared;
 
     /**
-     * The parameters used for creating this conversion.
-     * They are used for formatting <cite>Well Known Text</cite> (WKT) and error
messages.
-     *
-     * @see #getContextualParameters()
-     */
-    final ContextualParameters context;
-
-    /**
-     * The grid of datum shifts from source datum to target datum.
-     * This can be non-null only for {@link InterpolatedGeocentricTransform}.
-     */
-    final DatumShiftGrid<?,?> grid;
-
-    /**
      * Constructs the inverse of a Molodensky transform.
      *
      * @param inverse     The transform for which to create the inverse.
@@ -194,6 +175,7 @@ abstract class MolodenskyFormula extends
                       final DatumShiftGrid<?,?> grid, final boolean isAbridged,
                       final ParameterDescriptorGroup descriptor)
     {
+        super(descriptor, isSource3D ? 4 : 3, isTarget3D ? 4 : 3, grid);
         ArgumentChecks.ensureNonNull("source", source);
         ArgumentChecks.ensureNonNull("target", target);
         final DefaultEllipsoid src = DefaultEllipsoid.castOrCopy(source);
@@ -205,7 +187,6 @@ abstract class MolodenskyFormula extends
         this.tX         = tX;
         this.tY         = tY;
         this.tZ         = tZ;
-        this.grid       = grid;
 
         final double semiMinor = src.getSemiMinorAxis();
         final double Δf = src.flatteningDifference(target);
@@ -217,12 +198,7 @@ abstract class MolodenskyFormula extends
          * by MolodenskyTransform, but we need to store them in case the user asks for them.
          */
         final Unit<Length> unit = src.getAxisUnit();
-        final UnitConverter c = target.getAxisUnit().getConverterTo(unit);
-        context = new ContextualParameters(descriptor, isSource3D ? 4 : 3, isTarget3D ? 4
: 3);
-        context.getOrCreate(Molodensky.SRC_SEMI_MAJOR).setValue(semiMajor, unit);
-        context.getOrCreate(Molodensky.SRC_SEMI_MINOR).setValue(semiMinor, unit);
-        context.getOrCreate(Molodensky.TGT_SEMI_MAJOR).setValue(c.convert(target.getSemiMajorAxis()),
unit);
-        context.getOrCreate(Molodensky.TGT_SEMI_MINOR).setValue(c.convert(target.getSemiMinorAxis()),
unit);
+        setContextParameters(semiMajor, semiMinor, unit, target);
         completeParameters(context, semiMinor, unit, Δf);
         /*
          * Prepare two affine transforms to be executed before and after the MolodenskyTransform:
@@ -300,20 +276,6 @@ abstract class MolodenskyFormula extends
     }
 
     /**
-     * Returns the parameters used for creating the complete transformation. Those parameters
describe a sequence
-     * of <cite>normalize</cite> → {@code this} → <cite>denormalize</cite>
transforms, <strong>not</strong>
-     * including {@linkplain org.apache.sis.referencing.cs.CoordinateSystems#swapAndScaleAxes
axis swapping}.
-     * Those parameters are used for formatting <cite>Well Known Text</cite>
(WKT) and error messages.
-     *
-     * @return The parameters values for the sequence of
-     *         <cite>normalize</cite> → {@code this} → <cite>denormalize</cite>
transforms.
-     */
-    @Override
-    protected ContextualParameters getContextualParameters() {
-        return context;
-    }
-
-    /**
      * Gets the dimension of input points.
      *
      * @return The input dimension, which is 2 or 3.
@@ -341,7 +303,7 @@ abstract class MolodenskyFormula extends
      * <ul>
      *   <li>{@code tX}, {@code tY} and {@code tZ} parameters always have the values
of {@link #tX}, {@link #tY}
      *       and {@link #tZ} fields when this method is invoked by {@link MolodenskyTransform}.
But those values
-     *       may be slightly different when this method is invoked by {@link InterpolatedGeocentricTransform}.</li>
+     *       may be slightly different when this method is invoked by {@link InterpolatedMolodenskyTransform}.</li>
      * </ul>
      *
      * @param λ           Longitude (radians).
@@ -403,8 +365,8 @@ abstract class MolodenskyFormula extends
             φt = φ + (cmsφ * scaleY);
             if (offset == null) break;
 
-            // Following is executed only in InterpolatedGeocentricTransform case.
-            grid.interpolateAtNormalized(λt, φt, offset);
+            // Following is executed only in InterpolatedMolodenskyTransform case.
+            grid.interpolateInCell(grid.normalizedToGridX(λt), grid.normalizedToGridY(φt),
offset);
             tX = -offset[0];
             tY = -offset[1];
             tZ = -offset[2];
@@ -497,7 +459,7 @@ abstract class MolodenskyFormula extends
                 + 31 * (Double.doubleToLongBits(tY)
                 + 31 * (Double.doubleToLongBits(tZ)))));
         if (isAbridged) code = ~code;
-        return code + Objects.hashCode(grid);
+        return code;
     }
 
     /**
@@ -522,8 +484,7 @@ abstract class MolodenskyFormula extends
                 && Numerics.epsilonEqual(Δa,                  that.Δa,        
         mode)
                 && Numerics.epsilonEqual(Δfmod,               that.Δfmod,     
         mode)
                 && Numerics.epsilonEqual(semiMajor,           that.semiMajor,   
       mode)
-                && Numerics.epsilonEqual(eccentricitySquared, that.eccentricitySquared,
mode)
-                && Objects .equals(grid, that.grid);
+                && Numerics.epsilonEqual(eccentricitySquared, that.eccentricitySquared,
mode);
                 // No need to compare the contextual parameters since this is done by super-class.
         }
         return false;

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java?rev=1719607&r1=1719606&r2=1719607&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java
[UTF-8] Sat Dec 12 00:51:25 2015
@@ -23,7 +23,6 @@ import org.opengis.referencing.datum.Ell
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolation;
-import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.referencing.CommonCRS;
 
@@ -39,13 +38,7 @@ import static org.opengis.test.Assert.*;
 
 
 /**
- * Tests {@link InterpolatedGeocentricTransform}. The accuracy of using the Molodensky approximation
- * instead than the real geocentric translation is verified by the following tests:
- *
- * <ul>
- *   <li>{@link GeocentricTranslationTest#testFranceGeocentricInterpolationPoint()}</li>
- *   <li>{@link MolodenskyTransformTest#testFranceGeocentricInterpolationPoint()}</li>
- * </ul>
+ * Tests {@link InterpolatedGeocentricTransform}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
@@ -53,23 +46,28 @@ import static org.opengis.test.Assert.*;
  * @module
  */
 @DependsOn({
-    MolodenskyTransformTest.class,
     GeocentricTranslationTest.class,
     FranceGeocentricInterpolationTest.class
 })
-public final strictfp class InterpolatedGeocentricTransformTest extends MathTransformTestCase
{
+public strictfp class InterpolatedGeocentricTransformTest extends MathTransformTestCase {
     /**
      * Creates the <cite>"France geocentric interpolation"</cite> transform,
      * including the normalization and denormalization parts.
      *
      * @throws FactoryException if an error occurred while loading the grid.
      */
-    private void createGeodeticTransformation() throws FactoryException {
+    void createGeodeticTransformation() throws FactoryException {
+        createGeodeticTransformation(new FranceGeocentricInterpolation());
+    }
+
+    /**
+     * Creates the transform using the given provider.
+     */
+    final void createGeodeticTransformation(final FranceGeocentricInterpolation provider)
throws FactoryException {
         final URL file = FranceGeocentricInterpolationTest.class.getResource(FranceGeocentricInterpolationTest.TEST_FILE);
         assertNotNull("Test file \"" + FranceGeocentricInterpolationTest.TEST_FILE + "\"
not found.", file);
         final Ellipsoid source = HardCodedDatum.NTF.getEllipsoid();     // Clarke 1880 (IGN)
         final Ellipsoid target = CommonCRS.ETRS89.ellipsoid();          // GRS 1980 ellipsoid
-        final FranceGeocentricInterpolation provider = new FranceGeocentricInterpolation();
         final ParameterValueGroup values = provider.getParameters().createValue();
         values.parameter("src_semi_major").setValue(source.getSemiMajorAxis());
         values.parameter("src_semi_minor").setValue(source.getSemiMinorAxis());
@@ -77,7 +75,7 @@ public final strictfp class Interpolated
         values.parameter("tgt_semi_minor").setValue(target.getSemiMinorAxis());
         values.parameter("Geocentric translations file").setValue(file);    // Automatic
conversion from URL to Path.
         transform = provider.createMathTransform(DefaultFactories.forBuildin(MathTransformFactory.class),
values);
-        tolerance = Formulas.ANGULAR_TOLERANCE;
+        tolerance = FranceGeocentricInterpolationTest.ANGULAR_TOLERANCE;
     }
 
     /**
@@ -99,7 +97,8 @@ public final strictfp class Interpolated
         /*
          * Input:     2.424971108333333    48.84444583888889
          * Expected:  2.425671861111111    48.84451225
-         * Actual:    2.4256718922236735   48.84451219111167
+         * Actual:    2.425671863799633    48.844512255374376   (interpolated geocentric
transform)
+         * Actual:    2.4256718922236735   48.84451219111167    (interpolated Molodensky
transform)
          */
     }
 
@@ -187,13 +186,13 @@ public final strictfp class Interpolated
                 "    Parameter[“A0”, 0.017453292519943295, Id[“EPSG”, 8623]],\n"
+   // Degrees to radians conversion
                 "    Parameter[“B1”, 0.017453292519943295, Id[“EPSG”, 8640]]],\n"
+
                 "  Param_MT[“Geocentric inverse interpolation”,\n" +
+                "    Parameter[“dim”, 2],\n" +
                 "    Parameter[“src_semi_major”, 6378249.2],\n" +
                 "    Parameter[“src_semi_minor”, 6356515.0],\n" +
-                "    Parameter[“Semi-major axis length difference”, -112.2],\n" +
-                "    Parameter[“Flattening difference”, -5.4738838833299144E-5],\n" +
+                "    Parameter[“tgt_semi_major”, 6378137.0],\n" +
+                "    Parameter[“tgt_semi_minor”, 6356752.314140356],\n" +
                 "    ParameterFile[“Geocentric translations file”, “\\E.*\\W\\Q" +
-                                   FranceGeocentricInterpolationTest.TEST_FILE + "”, Id[“EPSG”,
8727]],\n" +
-                "    Parameter[“dim”, 2]],\n" +
+                                   FranceGeocentricInterpolationTest.TEST_FILE + "”, Id[“EPSG”,
8727]]],\n" +
                 "  Param_MT[“Affine parametric transformation”,\n" +
                 "    Parameter[“A0”, 57.29577951308232, Id[“EPSG”, 8623]],\n" + 
    // Radians to degrees conversion
                 "    Parameter[“B1”, 57.29577951308232, Id[“EPSG”, 8640]]]]\\E");

Copied: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransformTest.java
(from r1719083, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransformTest.java?p2=sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransformTest.java&p1=sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java&r1=1719083&r2=1719607&rev=1719607&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransformTest.java
[UTF-8] Sat Dec 12 00:51:25 2015
@@ -16,30 +16,20 @@
  */
 package org.apache.sis.referencing.operation.transform;
 
-import java.net.URL;
 import org.opengis.util.FactoryException;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.referencing.datum.Ellipsoid;
-import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolation;
+import org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolationTest;
 import org.apache.sis.internal.referencing.Formulas;
-import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.referencing.CommonCRS;
 
 // Test dependencies
-import org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolationTest;
 import org.apache.sis.internal.referencing.provider.GeocentricTranslationTest;
-import org.apache.sis.referencing.datum.HardCodedDatum;
+import org.apache.sis.internal.referencing.provider.MolodenskyInterpolation;
 import org.apache.sis.test.DependsOn;
-import org.apache.sis.test.DependsOnMethod;
 import org.junit.Test;
 
-import static org.opengis.test.Assert.*;
-
 
 /**
- * Tests {@link InterpolatedGeocentricTransform}. The accuracy of using the Molodensky approximation
+ * Tests {@link InterpolatedMolodenskyTransform}. The accuracy of using the Molodensky approximation
  * instead than the real geocentric translation is verified by the following tests:
  *
  * <ul>
@@ -55,86 +45,20 @@ import static org.opengis.test.Assert.*;
 @DependsOn({
     MolodenskyTransformTest.class,
     GeocentricTranslationTest.class,
-    FranceGeocentricInterpolationTest.class
+    InterpolatedGeocentricTransformTest.class
 })
-public final strictfp class InterpolatedGeocentricTransformTest extends MathTransformTestCase
{
-    /**
-     * Creates the <cite>"France geocentric interpolation"</cite> transform,
-     * including the normalization and denormalization parts.
-     *
-     * @throws FactoryException if an error occurred while loading the grid.
-     */
-    private void createGeodeticTransformation() throws FactoryException {
-        final URL file = FranceGeocentricInterpolationTest.class.getResource(FranceGeocentricInterpolationTest.TEST_FILE);
-        assertNotNull("Test file \"" + FranceGeocentricInterpolationTest.TEST_FILE + "\"
not found.", file);
-        final Ellipsoid source = HardCodedDatum.NTF.getEllipsoid();     // Clarke 1880 (IGN)
-        final Ellipsoid target = CommonCRS.ETRS89.ellipsoid();          // GRS 1980 ellipsoid
-        final FranceGeocentricInterpolation provider = new FranceGeocentricInterpolation();
-        final ParameterValueGroup values = provider.getParameters().createValue();
-        values.parameter("src_semi_major").setValue(source.getSemiMajorAxis());
-        values.parameter("src_semi_minor").setValue(source.getSemiMinorAxis());
-        values.parameter("tgt_semi_major").setValue(target.getSemiMajorAxis());
-        values.parameter("tgt_semi_minor").setValue(target.getSemiMinorAxis());
-        values.parameter("Geocentric translations file").setValue(file);    // Automatic
conversion from URL to Path.
-        transform = provider.createMathTransform(DefaultFactories.forBuildin(MathTransformFactory.class),
values);
-        tolerance = Formulas.ANGULAR_TOLERANCE;
-    }
-
-    /**
-     * Tests transformation of sample point from RGF93 to NTF.
-     * We call this transformation "forward" because it uses the grid values directly,
-     * without doing first an approximation followed by an iteration.
-     *
-     * @throws FactoryException if an error occurred while loading the grid.
-     * @throws TransformException if an error occurred while transforming the coordinate.
-     */
-    @Test
-    public void testForwardTransform() throws FactoryException, TransformException {
-        createGeodeticTransformation();   // Create the inverse of the transform we are interrested
in.
-        transform = transform.inverse();
-        isInverseTransformSupported = false;
-        verifyTransform(FranceGeocentricInterpolationTest.samplePoint(3),
-                        FranceGeocentricInterpolationTest.samplePoint(1));
-        validate();
-        /*
-         * Input:     2.424971108333333    48.84444583888889
-         * Expected:  2.425671861111111    48.84451225
-         * Actual:    2.4256718922236735   48.84451219111167
-         */
-    }
-
-    /**
-     * Tests transformation of sample point from NTF to RGF93.
-     *
-     * @throws FactoryException if an error occurred while loading the grid.
-     * @throws TransformException if an error occurred while transforming the coordinate.
-     */
-    @Test
-    @DependsOnMethod("testForwardTransform")
-    public void testInverseTransform() throws FactoryException, TransformException {
-        createGeodeticTransformation();
-        isInverseTransformSupported = false;
-        verifyTransform(FranceGeocentricInterpolationTest.samplePoint(1),
-                        FranceGeocentricInterpolationTest.samplePoint(3));
-        validate();
-    }
-
+public final strictfp class InterpolatedMolodenskyTransformTest extends InterpolatedGeocentricTransformTest
{
     /**
-     * Tests the derivatives at the sample point. This method compares the derivatives computed
by
-     * the transform with an estimation of derivatives computed by the finite differences
method.
+     * Creates an approximation of the <cite>"France geocentric interpolation"</cite>
transform
+     * using the Molodensky transform. This method relax slightly the tolerance threshold
since
+     * Molodensky transformations are approximation of translations in geocentric domain.
      *
      * @throws FactoryException if an error occurred while loading the grid.
-     * @throws TransformException if an error occurred while transforming the coordinate.
      */
-    @Test
-    @DependsOnMethod("testForwardTransform")
-    public void testDerivative() throws FactoryException, TransformException {
-        createGeodeticTransformation();
-        transform = transform.inverse();
-        final double delta = (100.0 / 60) / 1852;      // Approximatively 100 metres.
-        derivativeDeltas = new double[] {delta, delta};
-        tolerance = 1E-5;   // Empirical value.
-        verifyDerivative(FranceGeocentricInterpolationTest.samplePoint(1));
+    @Override
+    final void createGeodeticTransformation() throws FactoryException {
+        createGeodeticTransformation(new MolodenskyInterpolation());
+        tolerance = Formulas.ANGULAR_TOLERANCE;     // Relax tolerance threshold.
     }
 
     /**
@@ -145,11 +69,12 @@ public final strictfp class Interpolated
      * @throws TransformException should never happen.
      */
     @Test
+    @Override
     public void testWKT() throws FactoryException, TransformException {
         createGeodeticTransformation();
         transform = transform.inverse();
         assertWktEqualsRegex("(?m)\\Q" +
-                "PARAM_MT[“Geocentric interpolation”,\n" +
+                "PARAM_MT[“Molodensky interpolation”,\n" +
                 "  PARAMETER[“dim”, 2],\n" +
                 "  PARAMETER[“src_semi_major”, 6378137.0],\n" +
                 "  PARAMETER[“src_semi_minor”, 6356752.314140356],\n" +
@@ -160,7 +85,7 @@ public final strictfp class Interpolated
 
         transform = transform.inverse();
         assertWktEqualsRegex("(?m)\\Q" +
-                "PARAM_MT[“Geocentric inverse interpolation”,\n" +
+                "PARAM_MT[“Molodensky inverse interpolation”,\n" +
                 "  PARAMETER[“dim”, 2],\n" +
                 "  PARAMETER[“src_semi_major”, 6378249.2],\n" +
                 "  PARAMETER[“src_semi_minor”, 6356515.0],\n" +
@@ -179,6 +104,7 @@ public final strictfp class Interpolated
      * @throws TransformException should never happen.
      */
     @Test
+    @Override
     public void testInternalWKT() throws FactoryException, TransformException {
         createGeodeticTransformation();
         assertInternalWktEqualsRegex("(?m)\\Q" +
@@ -186,7 +112,7 @@ public final strictfp class Interpolated
                 "  Param_MT[“Affine parametric transformation”,\n" +
                 "    Parameter[“A0”, 0.017453292519943295, Id[“EPSG”, 8623]],\n"
+   // Degrees to radians conversion
                 "    Parameter[“B1”, 0.017453292519943295, Id[“EPSG”, 8640]]],\n"
+
-                "  Param_MT[“Geocentric inverse interpolation”,\n" +
+                "  Param_MT[“Molodensky inverse interpolation”,\n" +
                 "    Parameter[“src_semi_major”, 6378249.2],\n" +
                 "    Parameter[“src_semi_minor”, 6356515.0],\n" +
                 "    Parameter[“Semi-major axis length difference”, -112.2],\n" +

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=1719607&r1=1719606&r2=1719607&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] Sat Dec 12 00:51:25 2015
@@ -140,6 +140,7 @@ import org.junit.BeforeClass;
     org.apache.sis.internal.referencing.provider.AllProvidersTest.class,
     org.apache.sis.referencing.operation.transform.InterpolatedTransformTest.class,
     org.apache.sis.referencing.operation.transform.InterpolatedGeocentricTransformTest.class,
+    org.apache.sis.referencing.operation.transform.InterpolatedMolodenskyTransformTest.class,
     org.apache.sis.referencing.operation.transform.DefaultMathTransformFactoryTest.class,
 
     // Test map projections. Those tests need the providers tested above.




Mime
View raw message