You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/11/19 11:35:48 UTC

svn commit: r1715151 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/provider/ main/java/org/apache/sis/referencing/operation/transform/ test/java/org/apache/sis/referencing/operation/transform/

Author: desruisseaux
Date: Thu Nov 19 10:35:48 2015
New Revision: 1715151

URL: http://svn.apache.org/viewvc?rev=1715151&view=rev
Log:
Rearrange the Molodensky parameters in a way more consistent with other transforms.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java?rev=1715151&r1=1715150&r2=1715151&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] Thu Nov 19 10:35:48 2015
@@ -83,7 +83,9 @@ public final class FranceGeocentricInter
     public static final ParameterDescriptor<Path> FILE;
 
     /**
-     * The group of all parameters expected by this coordinate operation.
+     * The group of all parameters expected by this coordinate operation. The only parameter formally defined by EPSG
+     * is {@link #FILE}. All other parameters have been taken from {@link Molodensky} since geocentric interpolations
+     * can be though as a Molodensky operations with non-constant (ΔX, ΔY, ΔZ) geocentric translation terms.
      */
     public static final ParameterDescriptorGroup PARAMETERS;
     static {
@@ -95,11 +97,11 @@ public final class FranceGeocentricInter
         PARAMETERS = builder
                 .addIdentifier("9655")
                 .addName("France geocentric interpolation")
-                .createGroup(GeocentricAffineBetweenGeographic.DIMENSION,       // Not an EPSG parameter.
-                             GeocentricAffineBetweenGeographic.SRC_SEMI_MAJOR,
-                             GeocentricAffineBetweenGeographic.SRC_SEMI_MINOR,
-                             GeocentricAffineBetweenGeographic.TGT_SEMI_MAJOR,
-                             GeocentricAffineBetweenGeographic.TGT_SEMI_MINOR,
+                .createGroup(Molodensky.DIMENSION,       // Not an EPSG parameter.
+                             Molodensky.SRC_SEMI_MAJOR,
+                             Molodensky.SRC_SEMI_MINOR,
+                             Molodensky.TGT_SEMI_MAJOR,
+                             Molodensky.TGT_SEMI_MINOR,
                              FILE);
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java?rev=1715151&r1=1715150&r2=1715151&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java [UTF-8] Thu Nov 19 10:35:48 2015
@@ -96,27 +96,24 @@ public final class Molodensky extends Ge
         final ParameterBuilder builder = builder();
         AXIS_LENGTH_DIFFERENCE = builder.addName("Semi-major axis length difference").create(Double.NaN, SI.METRE);
         FLATTENING_DIFFERENCE  = builder.addName("Flattening difference").createBounded(-1, +1, Double.NaN, Unit.ONE);
-        builder.setRequired(false);
-        ParameterDescriptor<Double> a = builder.addName(TGT_SEMI_MAJOR.getName()).createStrictlyPositive(Double.NaN, SI.METRE);
-        ParameterDescriptor<Double> b = builder.addName(TGT_SEMI_MINOR.getName()).createStrictlyPositive(Double.NaN, SI.METRE);
         PARAMETERS = builder.setRequired(true)
                 .addIdentifier("9604")
                 .addName("Molodensky")
                 .addName(Citations.OGC, "Molodenski")
                 .createGroup(DIMENSION,                         // OGC only
+                             SRC_SEMI_MAJOR, SRC_SEMI_MINOR,    // OGC only
+                             TGT_SEMI_MAJOR, TGT_SEMI_MINOR,    // OGC only - redundant with differences
                              TX,                                // OGC and EPSG
                              TY,                                // OGC and EPSG
                              TZ,                                // OGC and EPSG
                              AXIS_LENGTH_DIFFERENCE,            // EPSG only
-                             FLATTENING_DIFFERENCE,             // EPSG only
-                             SRC_SEMI_MAJOR, SRC_SEMI_MINOR,    // OGC only
-                             a, b);                             // OGC only
+                             FLATTENING_DIFFERENCE);            // EPSG only
     }
 
     /**
      * Creates a descriptor for the internal parameters of {@link MolodenskyTransform}.
-     * This is identical to the standard parameters except that the last 3 OGC parameters
-     * are replaced by the eccentricity.
+     * This is similar to the standard parameters except that the redundant target axes
+     * lengths are omitted.
      *
      * @return Internal parameter descriptor.
      */
@@ -126,13 +123,13 @@ public final class Molodensky extends Ge
         ParameterDescriptor<Boolean> abridged = builder.addName("abridged").create(Boolean.class, null);
         return builder.addName("Molodensky")
                 .createGroup(DIMENSION,
+                             SRC_SEMI_MAJOR,
+                             SRC_SEMI_MINOR,
+                             AXIS_LENGTH_DIFFERENCE,
+                             FLATTENING_DIFFERENCE,
                              TX,
                              TY,
                              TZ,
-                             AXIS_LENGTH_DIFFERENCE,
-                             FLATTENING_DIFFERENCE,
-                             SRC_SEMI_MAJOR,
-                             MapProjection.ECCENTRICITY,
                              abridged);
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java?rev=1715151&r1=1715150&r2=1715151&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java [UTF-8] Thu Nov 19 10:35:48 2015
@@ -512,7 +512,6 @@ public class ContextualParameters extend
      *
      * @see org.apache.sis.referencing.operation.projection.NormalizedProjection#createMapProjection(MathTransformFactory)
      */
-    @SuppressWarnings("AssignmentToForLoopParameter")
     public synchronized MathTransform completeTransform(final MathTransformFactory factory, final MathTransform kernel)
             throws FactoryException
     {
@@ -528,6 +527,9 @@ public class ContextualParameters extend
         Matrix m;
         if ((m = MathTransforms.getMatrix(n)) != null)   normalize = m;
         if ((m = MathTransforms.getMatrix(d)) != null) denormalize = m;
+        if (kernel == null) {   // Undocumented feature useful for MolodenskyTransform constructor.
+            return null;
+        }
         return factory.createConcatenatedTransform(factory.createConcatenatedTransform(n, kernel), d);
     }
 

Modified: 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/InterpolatedGeocentricTransform.java?rev=1715151&r1=1715150&r2=1715151&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/InterpolatedGeocentricTransform.java [UTF-8] Thu Nov 19 10:35:48 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.referencing.operation.transform;
 
+import javax.measure.unit.Unit;
 import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
@@ -26,10 +27,10 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolation;
 import org.apache.sis.internal.referencing.provider.GeocentricAffineBetweenGeographic;
-import org.apache.sis.internal.referencing.provider.MapProjection;
 import org.apache.sis.internal.referencing.provider.Molodensky;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.parameter.Parameters;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.referencing.datum.DatumShiftGrid;
 import org.apache.sis.util.ArgumentChecks;
@@ -190,9 +191,29 @@ public class InterpolatedGeocentricTrans
     }
 
     /**
+     * Returns the parameter descriptor to declare for the given grid. This method returns the descriptor of
+     * <cite>"France geocentric interpolation"</cite> (ESPG:9655) only if the given grid is recognized as a
+     * grid created by the {@link FranceGeocentricInterpolation} for a geographic area likely to be France.
+     * Otherwise a more neutral (but non-standard) descriptor is returned.
+     */
+    private static ParameterDescriptorGroup descriptor(final DatumShiftGrid grid) {
+        if (grid instanceof FranceGeocentricInterpolation.Grid) {
+            return FranceGeocentricInterpolation.PARAMETERS;        // Defined by EPSG.
+        }
+        synchronized (InterpolatedGeocentricTransform.class) {
+            if (DESCRIPTOR == null) {
+                DESCRIPTOR = createDescriptor(true);                // Non-standard.
+            }
+            return DESCRIPTOR;
+        }
+    }
+
+    /**
      * Creates a Apache SIS descriptor for the {@code InterpolatedGeocentricTransform} parameters.
+     * The returned descriptor is non-standard, but allows {@code InterpolatedGeocentricTransform}
+     * to be used for other geographic areas than France.
      *
-     * @param internal  {@code true} for internal parameters, or {@code false} for contextual parameters.
+     * @param internal {@code true} for internal parameters, or {@code false} for contextual parameters.
      * @return The parameter descriptor.
      */
     private static ParameterDescriptorGroup createDescriptor(final boolean internal) {
@@ -202,16 +223,11 @@ public class InterpolatedGeocentricTrans
                 GeocentricAffineBetweenGeographic.SRC_SEMI_MINOR,
                 GeocentricAffineBetweenGeographic.TGT_SEMI_MAJOR,
                 GeocentricAffineBetweenGeographic.TGT_SEMI_MINOR,
-                GeocentricAffineBetweenGeographic.TX,
-                GeocentricAffineBetweenGeographic.TY,
-                GeocentricAffineBetweenGeographic.TZ,
                 FranceGeocentricInterpolation.FILE
         };
         if (internal) {
-            param[1] = Molodensky.AXIS_LENGTH_DIFFERENCE;
-            param[2] = Molodensky.FLATTENING_DIFFERENCE;
-            param[3] = Molodensky.SRC_SEMI_MAJOR;
-            param[4] = MapProjection.ECCENTRICITY;
+            param[3] = Molodensky.AXIS_LENGTH_DIFFERENCE;
+            param[4] = Molodensky.FLATTENING_DIFFERENCE;
         }
         return new ParameterBuilder().setRequired(true)
                 .setCodeSpace(Citations.SIS, Constants.SIS)
@@ -220,18 +236,16 @@ public class InterpolatedGeocentricTrans
     }
 
     /**
-     * Returns the parameter descriptor for the given grid.
-     */
-    private static ParameterDescriptorGroup descriptor(final DatumShiftGrid grid) {
-        if (grid instanceof FranceGeocentricInterpolation.Grid) {
-            return FranceGeocentricInterpolation.PARAMETERS;
-        }
-        synchronized (InterpolatedGeocentricTransform.class) {
-            if (DESCRIPTOR == null) {
-                DESCRIPTOR = createDescriptor(true);
-            }
-            return DESCRIPTOR;
-        }
+     * Invoked by the constructor for setting the contextual parameters.
+     *
+     * @param pg   Where to set the parameters.
+     * @param unit Ignored.
+     * @param Δf   Ignored.
+     */
+    @Override
+    void setContextualParameters(final Parameters pg, final Unit<?> unit, final double Δf) {
+        super.setContextualParameters(pg, unit, Δf);
+        // TODO
     }
 
     /**

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=1715151&r1=1715150&r2=1715151&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] Thu Nov 19 10:35:48 2015
@@ -28,7 +28,6 @@ import org.opengis.referencing.operation
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.datum.DefaultEllipsoid;
 import org.apache.sis.internal.referencing.provider.Molodensky;
-import org.apache.sis.internal.referencing.provider.MapProjection;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.ArgumentChecks;
@@ -191,11 +190,11 @@ abstract class MolodenskyFormula extends
         final Unit<Length> unit = src.getAxisUnit();
         final UnitConverter c = target.getAxisUnit().getConverterTo(unit);
         context = new ContextualParameters(descriptor, isSource3D ? 4 : 3, isTarget3D ? 4 : 3);
-        setContextualParameters(context, unit, Δf);
         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);
+        setContextualParameters(context, unit, Δf);
         /*
          * Prepare two affine transforms to be executed before and after the MolodenskyTransform:
          *
@@ -223,9 +222,9 @@ abstract class MolodenskyFormula extends
     public ParameterValueGroup getParameterValues() {
         final Parameters pg = Parameters.castOrWrap(getParameterDescriptors().createValue());
         final Unit<?> unit = context.getOrCreate(Molodensky.SRC_SEMI_MAJOR).getUnit();
-        setContextualParameters(pg, unit, context.doubleValue(Molodensky.FLATTENING_DIFFERENCE));
         pg.getOrCreate(Molodensky.SRC_SEMI_MAJOR).setValue(semiMajor, unit);
-        pg.getOrCreate(MapProjection.ECCENTRICITY).setValue(sqrt(eccentricitySquared));
+        pg.getOrCreate(Molodensky.SRC_SEMI_MINOR).setValue(context.doubleValue(Molodensky.SRC_SEMI_MINOR));
+        setContextualParameters(pg, unit, context.doubleValue(Molodensky.FLATTENING_DIFFERENCE));
         pg.parameter("abridged").setValue(isAbridged);
         return pg;
     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java?rev=1715151&r1=1715150&r2=1715151&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] Thu Nov 19 10:35:48 2015
@@ -95,7 +95,7 @@ public class MolodenskyTransform extends
      *
      * @see #inverse()
      */
-    private MolodenskyTransform inverse;
+    private final MolodenskyTransform inverse;
 
     /**
      * Creates a Molodensky transform from the specified parameters.
@@ -141,6 +141,25 @@ public class MolodenskyTransform extends
     {
         super(source, isSource3D, target, isTarget3D, tX, tY, tZ, isAbridged,
                 isAbridged ? AbridgedMolodensky.PARAMETERS : Molodensky.PARAMETERS);
+        if (!isSource3D && !isTarget3D) {
+            inverse = new MolodenskyTransform2D(this, source, target);
+        } else {
+            inverse = new MolodenskyTransform(this, source, target);
+        }
+    }
+
+    /**
+     * Constructs the inverse of a 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.
+     */
+    MolodenskyTransform(final MolodenskyTransform inverse, final Ellipsoid source, final Ellipsoid target) {
+        super(target, inverse.isTarget3D,
+              source, inverse.isSource3D,
+              -inverse.tX, -inverse.tY, -inverse.tZ, inverse.isAbridged, inverse.context.getDescriptor());
+        this.inverse = inverse;
     }
 
     /**
@@ -193,12 +212,10 @@ public class MolodenskyTransform extends
         final MolodenskyTransform tr;
         if (!isSource3D && !isTarget3D) {
             tr = new MolodenskyTransform2D(source, target, tX, tY, tZ, isAbridged);
-            tr.inverse = new MolodenskyTransform2D(target, source, -tX, -tY, -tZ, isAbridged);
         } else {
             tr = new MolodenskyTransform(source, isSource3D, target, isTarget3D, tX, tY, tZ, isAbridged);
-            tr.inverse = new MolodenskyTransform(target, isTarget3D, source, isSource3D, -tX, -tY, -tZ, isAbridged);
         }
-        tr.inverse.inverse = tr;
+        tr.inverse.context.completeTransform(factory, null);
         return tr.context.completeTransform(factory, tr);
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java?rev=1715151&r1=1715150&r2=1715151&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java [UTF-8] Thu Nov 19 10:35:48 2015
@@ -50,6 +50,17 @@ final class MolodenskyTransform2D extend
     }
 
     /**
+     * Constructs the inverse of a 2D 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.
+     */
+    MolodenskyTransform2D(final MolodenskyTransform inverse, final Ellipsoid source, final Ellipsoid target) {
+        super(inverse, source, target);
+    }
+
+    /**
      * Computes the derivative at the given position point.
      */
     @Override

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java?rev=1715151&r1=1715150&r2=1715151&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MolodenskyTransformTest.java [UTF-8] Thu Nov 19 10:35:48 2015
@@ -259,28 +259,28 @@ public final strictfp class MolodenskyTr
         create(true);
         assertWktEquals("PARAM_MT[“Abridged_Molodenski”,\n" +
                         "  PARAMETER[“dim”, 3],\n" +
+                        "  PARAMETER[“src_semi_major”, 6378137.0],\n" +
+                        "  PARAMETER[“src_semi_minor”, 6356752.314245179],\n" +
+                        "  PARAMETER[“tgt_semi_major”, 6378388.0],\n" +
+                        "  PARAMETER[“tgt_semi_minor”, 6356911.9461279465],\n" +
                         "  PARAMETER[“dx”, 84.87],\n" +
                         "  PARAMETER[“dy”, 96.49],\n" +
                         "  PARAMETER[“dz”, 116.95],\n" +
                         "  PARAMETER[“Semi-major axis length difference”, 251.0],\n" +
-                        "  PARAMETER[“Flattening difference”, 1.4192702255886284E-5],\n" +
-                        "  PARAMETER[“src_semi_major”, 6378137.0],\n" +
-                        "  PARAMETER[“src_semi_minor”, 6356752.314245179],\n" +
-                        "  PARAMETER[“tgt_semi_major”, 6378388.0],\n" +
-                        "  PARAMETER[“tgt_semi_minor”, 6356911.9461279465]]");
+                        "  PARAMETER[“Flattening difference”, 1.4192702255886284E-5]]");
 
         transform = transform.inverse();
         assertWktEquals("PARAM_MT[“Abridged_Molodenski”,\n" +
                         "  PARAMETER[“dim”, 3],\n" +
+                        "  PARAMETER[“src_semi_major”, 6378388.0],\n" +
+                        "  PARAMETER[“src_semi_minor”, 6356911.9461279465],\n" +
+                        "  PARAMETER[“tgt_semi_major”, 6378137.0],\n" +
+                        "  PARAMETER[“tgt_semi_minor”, 6356752.314245179],\n" +
                         "  PARAMETER[“dx”, -84.87],\n" +
                         "  PARAMETER[“dy”, -96.49],\n" +
                         "  PARAMETER[“dz”, -116.95],\n" +
                         "  PARAMETER[“Semi-major axis length difference”, -251.0],\n" +
-                        "  PARAMETER[“Flattening difference”, -1.4192702255886284E-5],\n" +
-                        "  PARAMETER[“src_semi_major”, 6378388.0],\n" +
-                        "  PARAMETER[“src_semi_minor”, 6356911.9461279465],\n" +
-                        "  PARAMETER[“tgt_semi_major”, 6378137.0],\n" +
-                        "  PARAMETER[“tgt_semi_minor”, 6356752.314245179]]");
+                        "  PARAMETER[“Flattening difference”, -1.4192702255886284E-5]]");
     }
 
     /**
@@ -302,13 +302,13 @@ public final strictfp class MolodenskyTr
                 "    Parameter[“elt_0_0”, 0.017453292519943295],\n" +       // Degrees to radians conversion
                 "    Parameter[“elt_1_1”, 0.017453292519943295]],\n" +
                 "  Param_MT[“Molodensky”,\n" +
+                "    Parameter[“src_semi_major”, 6378137.0],\n" +
+                "    Parameter[“src_semi_minor”, 6356752.314245179],\n" +
+                "    Parameter[“Semi-major axis length difference”, 251.0],\n" +
+                "    Parameter[“Flattening difference”, 1.4192702255886284E-5],\n" +
                 "    Parameter[“X-axis translation”, 84.87],\n" +
                 "    Parameter[“Y-axis translation”, 96.49],\n" +
                 "    Parameter[“Z-axis translation”, 116.95],\n" +
-                "    Parameter[“Semi-major axis length difference”, 251.0],\n" +
-                "    Parameter[“Flattening difference”, 1.4192702255886284E-5],\n" +
-                "    Parameter[“src_semi_major”, 6378137.0],\n" +
-                "    Parameter[“eccentricity”, 0.0818191908426215],\n" +
                 "    Parameter[“abridged”, TRUE],\n" +
                 "    Parameter[“dim”, 3]],\n" +
                 "  Param_MT[“Affine”,\n" +