sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1712672 - 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/transform/ test/java/org/apache/si...
Date Wed, 04 Nov 2015 22:01:36 GMT
Author: desruisseaux
Date: Wed Nov  4 22:01:36 2015
New Revision: 1712672

URL: http://svn.apache.org/viewvc?rev=1712672&view=rev
Log:
EllipsoidalToCartesianTransform and MolodenskyTransform force usage of static factory methods (not anymore just convenience methods).
Added MolodenskyTransform2D (part of the reason why we need to force usage of static factory methods).
Moved documentation about units of measurement in the appropriate contructor or factory method.
Complete implementation of Molodensky provider.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java   (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.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/datum/DefaultEllipsoid.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.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/EllipsoidalToCartesianTransform.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/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransformTest.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/GeographicToGeocentric.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java?rev=1712672&r1=1712671&r2=1712672&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/GeographicToGeocentric.java [UTF-8] Wed Nov  4 22:01:36 2015
@@ -149,9 +149,8 @@ public final class GeographicToGeocentri
         }
         final ParameterValue<?> semiMajor = values.parameter(Constants.SEMI_MAJOR);
         final Unit<Length> unit = semiMajor.getUnit().asType(Length.class);
-        return new EllipsoidalToCartesianTransform(semiMajor.doubleValue(),
-                values.parameter(Constants.SEMI_MINOR).doubleValue(unit), unit, is3D)
-                .createGeodeticConversion(factory);
+        return EllipsoidalToCartesianTransform.createGeodeticConversion(factory, semiMajor.doubleValue(),
+                values.parameter(Constants.SEMI_MINOR).doubleValue(unit), unit, is3D);
     }
 
     /**

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=1712672&r1=1712671&r2=1712672&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] Wed Nov  4 22:01:36 2015
@@ -16,10 +16,15 @@
  */
 package org.apache.sis.internal.referencing.provider;
 
+import java.util.Map;
+import java.util.Collections;
 import javax.xml.bind.annotation.XmlTransient;
 import javax.measure.unit.SI;
 import javax.measure.unit.Unit;
+import javax.measure.quantity.Length;
+import javax.measure.converter.UnitConverter;
 import org.opengis.util.FactoryException;
+import org.opengis.parameter.ParameterValue;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterDescriptorGroup;
@@ -29,6 +34,10 @@ import org.opengis.referencing.operation
 import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.parameter.Parameters;
+import org.apache.sis.referencing.datum.DefaultEllipsoid;
+import org.apache.sis.referencing.operation.transform.MolodenskyTransform;
+import org.apache.sis.internal.referencing.NilReferencingObject;
+import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.util.ArgumentChecks;
 
 
@@ -191,27 +200,65 @@ public final class Molodensky extends Ge
         if (dimension != 0) {
             sourceDimensions = targetDimensions = dimension;
         }
-        /*
-         * The code below implicitly converts all parameter values to metres.
-         * We do not try to preserve user-specified units since the unit used
-         * in the geocentric domain does not have any impact on the input/output
-         * geographic coordinates.
-         */
-        final double semiMajor = values.doubleValue(SRC_SEMI_MAJOR);
-        final double semiMinor = values.doubleValue(SRC_SEMI_MINOR);
-        final double ta, tb;
-        double d = values.doubleValue(AXIS_LENGTH_DIFFERENCE);
-        ta = Double.isNaN(d) ? values.doubleValue(TGT_SEMI_MAJOR) : semiMajor + d;
-        d = values.doubleValue(FLATTENING_DIFFERENCE);
-        if (Double.isNaN(d)) {
-            tb = values.doubleValue(TGT_SEMI_MINOR);
-        } else {
-            tb = ta*(semiMinor/semiMajor - d);
-        }
-        final double tX = values.doubleValue(TX);
-        final double tY = values.doubleValue(TY);
-        final double tZ = values.doubleValue(TZ);
-//      ΔFlattening    =  (ta-tb)/ta - (semiMajor-semiMinor)/semiMajor;
-        throw new UnsupportedOperationException("Not supported yet.");
+        final ParameterValue<?> sp = values.parameter("src_semi_major");
+        final ParameterValue<?> tp = values.parameter("tgt_semi_major");
+        final Unit<Length> srcUnit = sp.getUnit().asType(Length.class);
+        final Unit<Length> tgtUnit = tp.getUnit().asType(Length.class);
+        double sa = sp.doubleValue();
+        double ta = tp.doubleValue();
+        double sb = values.parameter("src_semi_minor").doubleValue(srcUnit);
+        double tb = values.parameter("tgt_semi_minor").doubleValue(tgtUnit);
+        double Δa = values.parameter("Semi-major axis length difference").doubleValue(srcUnit);
+        double Δf = values.parameter("Flattening difference").doubleValue(Unit.ONE);
+        final UnitConverter c = srcUnit.getConverterTo(tgtUnit);
+        if (Double.isNaN(ta)) {
+            ta = c.convert(sa + Δa);
+        }
+        if (Double.isNaN(tb)) {
+            tb = ta*(sb/sa - Δf);
+        }
+        final Map<String,?> name = Collections.singletonMap(DefaultEllipsoid.NAME_KEY, NilReferencingObject.UNNAMED);
+        final Ellipsoid source = new Ellipsoid(name, sa, sb, Δa, Δf, srcUnit);
+        final Ellipsoid target = new Ellipsoid(name, ta, tb, c.convert(-Δa), c.convert(-Δf), tgtUnit);
+        source.other = target;
+        target.other = source;
+        return MolodenskyTransform.createGeodeticTransformation(factory,
+                source, sourceDimensions >= 3,
+                target, targetDimensions >= 3,
+                values.getOrCreate(TX).doubleValue(srcUnit),
+                values.getOrCreate(TY).doubleValue(srcUnit),
+                values.getOrCreate(TZ).doubleValue(srcUnit),
+                isAbridged);
+    }
+
+    /**
+     * A temporary ellipsoid used only for passing arguments to the {@link MolodenskyTransform} constructor.
+     * The intend is to use the Δa and Δf values explicitely specified in the EPSG parameters if available,
+     * or to compute them only if no Δa or Δf values where specified.
+     */
+    @SuppressWarnings("serial")
+    private static final class Ellipsoid extends DefaultEllipsoid {
+        /** The EPSG parameter values, or NaN if unspecified. */
+        private final double Δa, Δf;
+
+        /** The ellipsoid for which Δa and Δf are valids. */
+        Ellipsoid other;
+
+        /** Creates a new temporary ellipsoid with explicitely provided Δa and Δf values. */
+        Ellipsoid(Map<String,?> name, double a, double b, double Δa, double Δf, Unit<Length> unit) {
+            super(name, a, b, Formulas.getInverseFlattening(a, b), false, unit);
+            this.Δa = Δa;
+            this.Δf = Δf;
+        }
+
+        /** Returns Δa as specified in the parameters if possible, or compute it otherwise. */
+        @Override public double semiMajorDifference(final org.opengis.referencing.datum.Ellipsoid target) {
+            return (target == other && !Double.isNaN(Δa)) ? Δa : super.semiMajorDifference(target);
+        }
+
+        /** Returns Δf as specified in the parameters if possible, or compute it otherwise. */
+        @Override public double flatteningDifference(final org.opengis.referencing.datum.Ellipsoid target) {
+            return (target == other && !Double.isNaN(Δf)) ? Δf : super.flatteningDifference(target);
+        }
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1712672&r1=1712671&r2=1712672&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] Wed Nov  4 22:01:36 2015
@@ -615,11 +615,37 @@ public class DefaultEllipsoid extends Ab
     }
 
     /**
+     * Returns the difference between the semi-major axis length of two ellipsoids.
+     * If the two ellipsoid does not use the same unit of measurement, than the axis
+     * length of the other ellipsoid is converted into the units of this ellipsoid axis.
+     *
+     * <div class="note"><b>Example:</b>
+     * {@code WGS84.semiMajorDifference(ED50)} returns 251 metres. This information is a parameter of
+     * {@linkplain org.apache.sis.referencing.operation.transform.MolodenskyTransform Molodensky transformations}.</div>
+     *
+     * @param  other The other ellipsoid from which to get semi-major axis length difference.
+     * @return (<var>other</var> ellipsoid semi-major axis) - (<var>this</var> ellipsoid semi-major axis).
+     *
+     * @since 0.7
+     */
+    public double semiMajorDifference(final Ellipsoid other) {
+        double semiMajor = other.getSemiMajorAxis();
+        semiMajor = other.getAxisUnit().getConverterTo(getAxisUnit()).convert(semiMajor);   // Often a no-op.
+        final DoubleDouble a = new DoubleDouble(semiMajor);     // Presumed accurate in base 10 if no unit conversion.
+        a.subtract(getSemiMajorAxis());                         // Presumed accurate in base 10 (not 2) by definition.
+        return a.value;
+    }
+
+    /**
      * Returns the difference between the flattening factor of two ellipsoids.
      * This method returns 0 if the two ellipsoids are equal.
      *
+     * <div class="note"><b>Example:</b>
+     * {@code WGS84.flatteningDifference(ED50)} returns approximatively 1.41927E-05. This information is a parameter of
+     * {@linkplain org.apache.sis.referencing.operation.transform.MolodenskyTransform Molodensky transformations}.</div>
+     *
      * @param  other The other ellipsoid from which to get flattening difference.
-     * @return (other ellipsoid flattening) - (this ellipsoid flattening).
+     * @return (<var>other</var> ellipsoid flattening) - (<var>this</var> ellipsoid flattening).
      *
      * @since 0.7
      */

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java?rev=1712672&r1=1712671&r2=1712672&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] Wed Nov  4 22:01:36 2015
@@ -105,7 +105,7 @@ public abstract class AbstractMathTransf
     }
 
     /**
-     * Implementation of {@link #transform(DirectPosition, DirectPosition)} shared by the inverse transform.
+     * Implementation of {@link #transform(Point2D, Point2D)} shared by the inverse transform.
      */
     static Point2D transform(final AbstractMathTransform tr, final Point2D ptSrc, final Point2D ptDst) throws TransformException {
         final double[] ord = new double[] {ptSrc.getX(), ptSrc.getY()};

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=1712672&r1=1712671&r2=1712672&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] Wed Nov  4 22:01:36 2015
@@ -491,8 +491,7 @@ public class ContextualParameters extend
      * @throws FactoryException if an error occurred while creating a math transform instance.
      *
      * @see org.apache.sis.referencing.operation.projection.NormalizedProjection#createMapProjection(MathTransformFactory)
-     * @see EllipsoidalToCartesianTransform#createGeodeticConversion(MathTransformFactory)
-     * @see MolodenskyTransform#createGeodeticTransformation(MathTransformFactory)
+     * @see EllipsoidalToCartesianTransform#createGeodeticConversion(MathTransformFactory, double, double, Unit, boolean)
      */
     @SuppressWarnings("AssignmentToForLoopParameter")
     public synchronized MathTransform completeTransform(final MathTransformFactory factory, final MathTransform kernel)

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java?rev=1712672&r1=1712671&r2=1712672&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransform.java [UTF-8] Wed Nov  4 22:01:36 2015
@@ -27,7 +27,6 @@ import org.opengis.util.FactoryException
 import org.opengis.geometry.DirectPosition;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
@@ -38,7 +37,6 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.DoubleDouble;
-import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.referencing.DirectPositionView;
 import org.apache.sis.internal.referencing.provider.GeocentricToGeographic;
@@ -65,39 +63,29 @@ import static org.apache.sis.internal.re
  * This transform is usually part of a conversion from
  * {@linkplain org.apache.sis.referencing.crs.DefaultGeographicCRS geographic} to
  * {@linkplain org.apache.sis.referencing.crs.DefaultGeocentricCRS geocentric} coordinates.
- *
- * <p>Input coordinates are expected to contain:</p>
+ * Each input coordinates is expected to contain:
  * <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 units of an ellipsoid having a semi-major axis length of 1.</li>
+ *   <li>longitude (λ) relative to the prime meridian (usually Greenwich),</li>
+ *   <li>latitude (φ),</li>
+ *   <li>optionally height above the ellipsoid (h).</li>
  * </ol>
  *
- * Output coordinates are as below, in units of an ellipsoid having a semi-major axis length of 1:
+ * Output coordinates are as below:
  * <ol>
  *   <li>distance from Earth center on the X axis (toward the intersection of prime meridian and equator),</li>
  *   <li>distance from Earth center on the Y axis (toward the intersection of 90°E meridian and equator),</li>
  *   <li>distance from Earth center on the Z axis (toward North pole).</li>
  * </ol>
  *
- * <div class="section">Geographic to geocentric conversions</div>
- * For converting geographic coordinates to geocentric coordinates, {@code EllipsoidalToCartesianTransform} instances
- * need to be concatenated with the following affine transforms:
- *
+ * The units of measurements depend on how the {@code MathTransform} has been created:
  * <ul>
- *   <li><cite>Normalization</cite> before {@code EllipsoidalToCartesianTransform}:<ul>
- *     <li>Conversion of (λ,φ) from degrees to radians</li>
- *     <li>Division of (h) by the semi-major axis length</li>
- *   </ul></li>
- *   <li><cite>Denormalization</cite> after {@code EllipsoidalToCartesianTransform}:<ul>
- *     <li>Multiplication of (X,Y,Z) by the semi-major axis length</li>
- *   </ul></li>
+ *   <li>{@code EllipsoidalToCartesianTransform} instances created directly by the constructor expect (λ,φ) values
+ *       in radians and compute (X,Y,Z) values in units of an ellipsoid having a semi-major axis length of 1.
+ *       That constructor is reserved for subclasses only.</li>
+ *   <li>Transforms created by the {@link #createGeodeticConversion createGeodeticConversion(…)} static method expect
+ *       (λ,φ) values in degrees and compute (X,Y,Z) values in units of the ellipsoid axes (usually metres).</li>
  * </ul>
  *
- * The full conversion chain including the above affine transforms
- * can be created by {@link #createGeodeticConversion(MathTransformFactory)}.
- * Alternatively, the {@link #createGeodeticConversion(Ellipsoid, boolean)} convenience method can also be used.
- *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.7
  * @version 0.7
@@ -201,19 +189,51 @@ public class EllipsoidalToCartesianTrans
     private final AbstractMathTransform inverse;
 
     /**
-     * Creates a transform from an ellipsoid of semi-major axis length of 1.
-     * Angular units of input coordinates are <strong>radians</strong>.
+     * Creates a transform from angles in radians on ellipsoid having a semi-major axis length of 1.
+     * More specifically {@code EllipsoidalToCartesianTransform} instances expect input coordinates
+     * as below:
+     *
+     * <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 units of an ellipsoid having a semi-major axis length of 1.</li>
+     * </ol>
+     *
+     * Output coordinates are as below, in units of an ellipsoid having a semi-major axis length of 1:
+     * <ol>
+     *   <li>distance from Earth center on the X axis (toward the intersection of prime meridian and equator),</li>
+     *   <li>distance from Earth center on the Y axis (toward the intersection of 90°E meridian and equator),</li>
+     *   <li>distance from Earth center on the Z axis (toward North pole).</li>
+     * </ol>
      *
-     * <p>For a conversion from angles in degrees and height in metres, see the
-     * {@link #createGeodeticConversion(MathTransformFactory)} method.</p>
+     * <div class="section">Geographic to geocentric conversions</div>
+     * For converting geographic coordinates to geocentric coordinates, {@code EllipsoidalToCartesianTransform}
+     * instances need to be concatenated with the following affine transforms:
+     *
+     * <ul>
+     *   <li><cite>Normalization</cite> before {@code EllipsoidalToCartesianTransform}:<ul>
+     *     <li>Conversion of (λ,φ) from degrees to radians</li>
+     *     <li>Division of (h) by the semi-major axis length</li>
+     *   </ul></li>
+     *   <li><cite>Denormalization</cite> after {@code EllipsoidalToCartesianTransform}:<ul>
+     *     <li>Multiplication of (X,Y,Z) by the semi-major axis length</li>
+     *   </ul></li>
+     * </ul>
+     *
+     * After {@code EllipsoidalToCartesianTransform} construction,
+     * the full conversion chain including the above affine transforms can be created by
+     * <code>{@linkplain #getContextualParameters()}.{@linkplain ContextualParameters#completeTransform
+     * completeTransform}(factory, this)}</code>.
      *
      * @param semiMajor  The semi-major axis length.
      * @param semiMinor  The semi-minor axis length.
      * @param unit       The unit of measurement for the semi-axes and the ellipsoidal height.
      * @param withHeight {@code true} if geographic coordinates include an ellipsoidal height (i.e. are 3-D),
      *                   or {@code false} if they are only 2-D.
+     *
+     * @see #createGeodeticConversion(MathTransformFactory, double, double, Unit, boolean)
      */
-    public EllipsoidalToCartesianTransform(final double semiMajor, final double semiMinor,
+    protected EllipsoidalToCartesianTransform(final double semiMajor, final double semiMinor,
             final Unit<Length> unit, final boolean withHeight)
     {
         ArgumentChecks.ensureStrictlyPositive("semiMajor", semiMajor);
@@ -268,9 +288,9 @@ public class EllipsoidalToCartesianTrans
     }
 
     /**
-     * Creates a transform from geographic to geocentric coordinates. This convenience method combines the
-     * {@code EllipsoidalToCartesianTransform} instance with the steps needed for converting degrees to radians and
-     * expressing the results in units of the given ellipsoid.
+     * Creates a transform from geographic to geocentric coordinates. This factory method combines the
+     * {@code EllipsoidalToCartesianTransform} instance with the steps needed for converting degrees to
+     * radians and expressing the results in units of the given ellipsoid.
      *
      * <p>Input coordinates are expected to contain:</p>
      * <ol>
@@ -286,47 +306,21 @@ public class EllipsoidalToCartesianTrans
      *   <li>distance from Earth center on the Z axis (toward North pole).</li>
      * </ol>
      *
-     * @param ellipsoid  The ellipsoid of source coordinates.
+     * @param factory    The factory to use for creating and concatenating the affine transforms.
+     * @param semiMajor  The semi-major axis length.
+     * @param semiMinor  The semi-minor axis length.
+     * @param unit       The unit of measurement for the semi-axes and the ellipsoidal height.
      * @param withHeight {@code true} if geographic coordinates include an ellipsoidal height (i.e. are 3-D),
      *                   or {@code false} if they are only 2-D.
      * @return The conversion from geographic to geocentric coordinates.
-     */
-    public static MathTransform createGeodeticConversion(final Ellipsoid ellipsoid, final boolean withHeight) {
-        ArgumentChecks.ensureNonNull("ellipsoid", ellipsoid);
-        try {
-            return new EllipsoidalToCartesianTransform(
-                    ellipsoid.getSemiMajorAxis(), ellipsoid.getSemiMinorAxis(), ellipsoid.getAxisUnit(), withHeight)
-                    .createGeodeticConversion(DefaultFactories.forBuildin(MathTransformFactory.class));
-        } catch (FactoryException e) {
-            /*
-             * Should not happen with SIS factory implementation. If it happen anyway,
-             * maybe we got some custom factory implementation with limited functionality.
-             */
-            throw new IllegalStateException(e.getLocalizedMessage(), e);
-        }
-    }
-
-    /**
-     * Returns the sequence of <cite>normalization</cite> → {@code this} → <cite>denormalization</cite>
-     * transforms as a whole. The transform returned by this method expects input coordinate having the
-     * following values:
-     *
-     * <ol>
-     *   <li>longitudes in degrees relative to the prime meridian (usually Greenwich),</li>
-     *   <li>latitudes in degrees,</li>
-     *   <li>optionally heights above the ellipsoid, in the units given to the constructor (usually metres).</li>
-     * </ol>
-     *
-     * The converted coordinates will be lengths in the units given to the constructor (usually metres).
-     *
-     * @param  factory The factory to use for creating the transform.
-     * @return The conversion from geographic to geocentric coordinates.
      * @throws FactoryException if an error occurred while creating a transform.
-     *
-     * @see ContextualParameters#completeTransform(MathTransformFactory, MathTransform)
      */
-    public MathTransform createGeodeticConversion(final MathTransformFactory factory) throws FactoryException {
-        return context.completeTransform(factory, this);
+    public static MathTransform createGeodeticConversion(final MathTransformFactory factory,
+            final double semiMajor, final double semiMinor, final Unit<Length> unit, final boolean withHeight)
+            throws FactoryException
+    {
+        EllipsoidalToCartesianTransform tr = new EllipsoidalToCartesianTransform(semiMajor, semiMinor, unit, withHeight);
+        return tr.context.completeTransform(factory, tr);
     }
 
     /**
@@ -348,7 +342,7 @@ public class EllipsoidalToCartesianTrans
      * The returned group contains parameter values for the number of dimensions and the excentricity.
      *
      * <div class="note"><b>Note:</b>
-     * This method is mostly for {@linkplain org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
+     * this method is mostly for {@linkplain org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
      * since the isolation of non-linear parameters in this class is highly implementation dependent.
      * Most GIS applications will instead be interested in the {@linkplain #getContextualParameters()
      * contextual parameters}.</div>

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=1712672&r1=1712671&r2=1712672&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] Wed Nov  4 22:01:36 2015
@@ -48,9 +48,8 @@ import static java.lang.Math.*;
  * transformations (EPSG:1035 and 9603), but performed directly on geographic coordinates without
  * Geographic/Geocentric conversions.
  *
- * <div class="section">Number of dimensions</div>
- * {@code MolodenskyTransform}s works conceptually on three-dimensional coordinates, but the ellipsoidal height
- * can be omitted resulting in two-dimensional coordinates. No dimension other than 2 or 3 are allowed.
+ * <p>{@code MolodenskyTransform}s works conceptually on three-dimensional coordinates, but the ellipsoidal height
+ * can be omitted resulting in two-dimensional coordinates. No dimension other than 2 or 3 are allowed.</p>
  * <ul>
  *   <li>If the height is omitted from the input coordinates ({@code isSource3D} = {@code false}),
  *       then the {@linkplain #getSourceDimensions() source dimensions} is 2 and the height is
@@ -60,31 +59,21 @@ import static java.lang.Math.*;
  *       height (typically non-zero even if the input height was zero) is lost.</li>
  * </ul>
  *
- * <div class="section">Units of measurement</div>
- * This {@code MolodenskyTransform} class expects ordinate values if the following order and units:
+ * The transform expect ordinate values if the following order:
  * <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 ellipsoids axes.</li>
+ *   <li>longitudes (λ) relative to the prime meridian (usually Greenwich),</li>
+ *   <li>latitudes (φ),</li>
+ *   <li>optionally heights above the ellipsoid (h).</li>
  * </ol>
  *
- * For converting geographic coordinates in degrees, {@code MolodenskyTransform} instances
- * need to be concatenated with the following affine transforms:
- *
+ * The units of measurements depend on how the {@code MathTransform} has been created:
  * <ul>
- *   <li><cite>Normalization</cite> before {@code MolodenskyTransform}:<ul>
- *     <li>Conversion of (λ,φ) from degrees to radians</li>
- *   </ul></li>
- *   <li><cite>Denormalization</cite> after {@code MolodenskyTransform}:<ul>
- *     <li>Conversion of (λ,φ) from radians to degrees</li>
- *   </ul></li>
+ *   <li>{@code MolodenskyTransform} instances created directly by the constructor work with angular values in radians.
+ *       That constructor is reserved for subclasses only.</li>
+ *   <li>Transforms created by the {@link #createGeodeticTransformation createGeodeticTransformation(…)} static method
+ *       work with angular values in degrees and heights in the same units than the ellipsoid axes (usually metres).</li>
  * </ul>
  *
- * The full conversion chain including the above affine transforms
- * can be created by {@link #createGeodeticTransformation(MathTransformFactory)}.
- * Alternatively, the {@link #createGeodeticTransformation(Ellipsoid, Ellipsoid, boolean)}
- * convenience method can also be used.
- *
  * @author  Rueben Schulz (UBC)
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Rémi Maréchal (Geomatys)
@@ -182,7 +171,29 @@ public class MolodenskyTransform extends
 
     /**
      * Creates a Molodensky transform from the specified parameters.
-     * Angular units of input coordinates and output coordinates are <strong>radians</strong>.
+     * This {@code MolodenskyTransform} class expects ordinate values if 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 ellipsoids axes.</li>
+     * </ol>
+     *
+     * For converting geographic coordinates in degrees, {@code MolodenskyTransform} instances
+     * need to be concatenated with the following affine transforms:
+     *
+     * <ul>
+     *   <li><cite>Normalization</cite> before {@code MolodenskyTransform}:<ul>
+     *     <li>Conversion of (λ,φ) from degrees to radians</li>
+     *   </ul></li>
+     *   <li><cite>Denormalization</cite> after {@code MolodenskyTransform}:<ul>
+     *     <li>Conversion of (λ,φ) from radians to degrees</li>
+     *   </ul></li>
+     * </ul>
+     *
+     * After {@code MolodenskyTransform} construction,
+     * the full conversion chain including the above affine transforms can be created by
+     * <code>{@linkplain #getContextualParameters()}.{@linkplain ContextualParameters#completeTransform
+     * completeTransform}(factory, this)}</code>.
      *
      * @param source      The source ellipsoid.
      * @param isSource3D  {@code true} if the source coordinates have a height.
@@ -192,6 +203,8 @@ public class MolodenskyTransform extends
      * @param tY          The geocentric <var>Y</var> translation in meters.
      * @param tZ          The geocentric <var>Z</var> translation in meters.
      * @param isAbridged  {@code true} for the abridged formula, or {@code false} for the complete one.
+     *
+     * @see #createGeodeticTransformation(MathTransformFactory, Ellipsoid, boolean, Ellipsoid, boolean, double, double, double, boolean)
      */
     protected MolodenskyTransform(final Ellipsoid source, final boolean isSource3D,
                                   final Ellipsoid target, final boolean isTarget3D,
@@ -205,13 +218,13 @@ public class MolodenskyTransform extends
         if (isSource3D) type |= SOURCE_DIMENSION_MASK;
         if (isTarget3D) type |= TARGET_DIMENSION_MASK;
         this.type      = type;
-        this.semiMajor = source.getSemiMajorAxis();
-        this.Δa        = target.getSemiMajorAxis() - semiMajor;
+        this.semiMajor = src.getSemiMajorAxis();
+        this.Δa        = src.semiMajorDifference(target);
         this.tX        = tX;
         this.tY        = tY;
         this.tZ        = tZ;
 
-        final double semiMinor   = source.getSemiMinorAxis();
+        final double semiMinor   = src.getSemiMinorAxis();
         final double ΔFlattening = src.flatteningDifference(target);
         excentricitySquared      = src.getEccentricitySquared();
         Δfmod = isAbridged ? (semiMajor * ΔFlattening) + (semiMajor - semiMinor) * (Δa / semiMajor)
@@ -226,7 +239,7 @@ public class MolodenskyTransform extends
         if (isSource3D == isTarget3D) {
             context.getOrCreate(Molodensky.DIMENSION).setValue(isSource3D ? 3 : 2);
         }
-        final Unit<Length> unit = source.getAxisUnit();
+        final Unit<Length> unit = src.getAxisUnit();
         context.getOrCreate(Molodensky.TX)                    .setValue(tX, unit);
         context.getOrCreate(Molodensky.TY)                    .setValue(tY, unit);
         context.getOrCreate(Molodensky.TZ)                    .setValue(tZ, unit);
@@ -252,8 +265,9 @@ public class MolodenskyTransform extends
     }
 
     /**
-     * Returns the sequence of <cite>normalization</cite> → {@code this} → <cite>denormalization</cite>
-     * transforms as a whole. The transform works with input and output coordinates in the following units:
+     * Creates a transformation between two from geographic CRS. This factory method combines the
+     * {@code MolodenskyTransform} 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>
      *   <li>longitudes in degrees relative to the prime meridian (usually Greenwich),</li>
@@ -261,14 +275,31 @@ public class MolodenskyTransform extends
      *   <li>optionally heights above the ellipsoid, in the units given to the constructor (usually metres).</li>
      * </ol>
      *
-     * @param  factory The factory to use for creating the transform.
+     * @param factory     The factory to use for creating the transform.
+     * @param source      The source ellipsoid.
+     * @param isSource3D  {@code true} if the source coordinates have a height.
+     * @param target      The target ellipsoid.
+     * @param isTarget3D  {@code true} if the target coordinates have a height.
+     * @param tX          The geocentric <var>X</var> translation in meters.
+     * @param tY          The geocentric <var>Y</var> translation in meters.
+     * @param tZ          The geocentric <var>Z</var> translation in meters.
+     * @param isAbridged  {@code true} for the abridged formula, or {@code false} for the complete one.
      * @return The transformation between geographic coordinates.
      * @throws FactoryException if an error occurred while creating a transform.
-     *
-     * @see ContextualParameters#completeTransform(MathTransformFactory, MathTransform)
      */
-    public MathTransform createGeodeticTransformation(final MathTransformFactory factory) throws FactoryException {
-        return context.completeTransform(factory, this);
+    public static MathTransform createGeodeticTransformation(final MathTransformFactory factory,
+            final Ellipsoid source, final boolean isSource3D,
+            final Ellipsoid target, final boolean isTarget3D,
+            final double tX, final double tY, final double tZ,
+            final boolean isAbridged) throws FactoryException
+    {
+        final MolodenskyTransform tr;
+        if (!isSource3D && !isTarget3D) {
+            tr = new MolodenskyTransform2D(source, target, tX, tY, tZ, isAbridged);
+        } else {
+            tr = new MolodenskyTransform(source, isSource3D, target, isTarget3D, tX, tY, tZ, isAbridged);
+        }
+        return tr.context.completeTransform(factory, tr);
     }
 
     /**
@@ -290,7 +321,7 @@ public class MolodenskyTransform extends
      * The returned group contains parameter values for the number of dimensions and the excentricity.
      *
      * <div class="note"><b>Note:</b>
-     * This method is mostly for {@linkplain org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
+     * this method is mostly for {@linkplain org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
      * since the isolation of non-linear parameters in this class is highly implementation dependent.
      * Most GIS applications will instead be interested in the {@linkplain #getContextualParameters()
      * contextual parameters}.</div>

Added: 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=1712672&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java (added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform2D.java [UTF-8] Wed Nov  4 22:01:36 2015
@@ -0,0 +1,84 @@
+/*
+ * 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.transform;
+
+import java.awt.Shape;
+import java.awt.geom.Point2D;
+import org.opengis.referencing.datum.Ellipsoid;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.TransformException;
+
+
+/**
+ * A Molodensky transforms for two-dimensional input and output coordinates.
+ *
+ * @author  Rueben Schulz (UBC)
+ * @author  Martin Desruisseaux (IRD, Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+final class MolodenskyTransform2D extends MolodenskyTransform implements MathTransform2D {
+    /**
+     * Serial number for compatibility with different versions.
+     */
+    private static final long serialVersionUID = -7205339479409468581L;
+
+    /**
+     * Constructs a 2D transform.
+     */
+    MolodenskyTransform2D(final Ellipsoid source, final Ellipsoid target,
+                          final double tX, final double tY, final double tZ,
+                          final boolean isAbridged)
+    {
+        super(source, false, target, false, tX, tY, tZ, isAbridged);
+    }
+
+    /**
+     * Computes the derivative at the given position point.
+     */
+    @Override
+    public Matrix derivative(Point2D point) throws TransformException {
+        return AbstractMathTransform2D.derivative(this, point);
+    }
+
+    /**
+     * Transforms a single point.
+     */
+    @Override
+    public Point2D transform(Point2D ptSrc, Point2D ptDst) throws TransformException {
+        return AbstractMathTransform2D.transform(this, ptSrc, ptDst);
+    }
+
+    /**
+     * Transforms the given shape.
+     */
+    @Override
+    public Shape createTransformedShape(Shape shape) throws TransformException {
+        return AbstractMathTransform2D.createTransformedShape(this, shape, null, null, false);
+    }
+
+    /**
+     * Returns the inverse transform of this transform.
+     */
+    @Override
+    public MathTransform2D inverse() throws NoninvertibleTransformException {
+        return (MathTransform2D) super.inverse();
+    }
+}

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

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

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java?rev=1712672&r1=1712671&r2=1712672&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java [UTF-8] Wed Nov  4 22:01:36 2015
@@ -84,6 +84,19 @@ public final strictfp class DefaultEllip
     }
 
     /**
+     * Tests {@link DefaultEllipsoid#semiMajorDifference(Ellipsoid)}. This test uses the data provided
+     * in §2.4.4.2 of IOGP Publication 373-7-2 – Geomatics Guidance Note number 7, part 2 – April 2015.
+     *
+     * @since 0.7
+     */
+    @Test
+    public void testSemiMajorDifference() {
+        final DefaultEllipsoid e = new DefaultEllipsoid(GeodeticDatumMock.WGS84.getEllipsoid());
+        assertEquals("semiMajorDifference",   0, e.semiMajorDifference(GeodeticDatumMock.WGS84.getEllipsoid()), STRICT);
+        assertEquals("semiMajorDifference", 251, e.semiMajorDifference(GeodeticDatumMock.ED50 .getEllipsoid()), STRICT);
+    }
+
+    /**
      * Tests {@link DefaultEllipsoid#flatteningDifference(Ellipsoid)}. This test uses the data provided
      * in §2.4.4.2 of IOGP Publication 373-7-2 – Geomatics Guidance Note number 7, part 2 – April 2015.
      *

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransformTest.java?rev=1712672&r1=1712671&r2=1712672&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/EllipsoidalToCartesianTransformTest.java [UTF-8] Wed Nov  4 22:01:36 2015
@@ -54,15 +54,27 @@ import static org.apache.sis.test.Assert
 })
 public final strictfp class EllipsoidalToCartesianTransformTest extends MathTransformTestCase {
     /**
+     * Convenience method for creating an instance from an ellipsoid.
+     */
+    private void createGeodeticConversion(final Ellipsoid ellipsoid, boolean is3D) throws FactoryException {
+        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(
+                DefaultFactories.forBuildin(MathTransformFactory.class),
+                ellipsoid.getSemiMajorAxis(),
+                ellipsoid.getSemiMinorAxis(),
+                ellipsoid.getAxisUnit(), is3D);
+    }
+
+    /**
      * Tests conversion of a single point from geographic to geocentric coordinates.
      * This test uses the example given in EPSG guidance note #7.
      * The point in WGS84 is 53°48'33.820"N, 02°07'46.380"E, 73.00 metres.
      *
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException if conversion of the sample point failed.
      */
     @Test
-    public void testGeographicToGeocentric() throws TransformException {
-        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
+    public void testGeographicToGeocentric() throws FactoryException, TransformException {
+        createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
         isInverseTransformSupported = false;    // Geocentric to geographic is not the purpose of this test.
         validate();
 
@@ -77,11 +89,13 @@ public final strictfp class EllipsoidalT
      * Tests conversion of a single point from geocentric to geographic coordinates.
      * This method uses the same point than {@link #testGeographicToGeocentric()}.
      *
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException if conversion of the sample point failed.
      */
     @Test
-    public void testGeocentricToGeographic() throws TransformException {
-        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true).inverse();
+    public void testGeocentricToGeographic() throws FactoryException, TransformException {
+        createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
+        transform = transform.inverse();
         isInverseTransformSupported = false;    // Geographic to geocentric is not the purpose of this test.
         validate();
 
@@ -96,6 +110,7 @@ public final strictfp class EllipsoidalT
     /**
      * Tests conversion of random points.
      *
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException if a conversion failed.
      */
     @Test
@@ -103,12 +118,12 @@ public final strictfp class EllipsoidalT
         "testGeographicToGeocentric",
         "testGeocentricToGeographic"
     })
-    public void testRandomPoints() throws TransformException {
+    public void testRandomPoints() throws FactoryException, TransformException {
         final double delta = toRadians(100.0 / 60) / 1852;          // Approximatively 100 metres
         derivativeDeltas  = new double[] {delta, delta, 100};       // (Δλ, Δφ, Δh)
         tolerance         = Formulas.LINEAR_TOLERANCE;
         toleranceModifier = ToleranceModifier.PROJECTION;
-        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
+        createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
         verifyInDomain(CoordinateDomain.GEOGRAPHIC, 306954540);
     }
 
@@ -117,13 +132,14 @@ public final strictfp class EllipsoidalT
      * The {@link EllipsoidalToCartesianTransform} may need to use an iterative method
      * for reaching the expected precision.
      *
-     * @throws FactoryException if an error occurred while creating the transform.
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException if conversion of the sample point failed.
      */
     @Test
-    public void testHighExcentricity() throws TransformException, FactoryException {
-        transform = new EllipsoidalToCartesianTransform(6000000, 4000000, SI.METRE, true)
-                .createGeodeticConversion(DefaultFactories.forBuildin(MathTransformFactory.class));
+    public void testHighExcentricity() throws FactoryException, TransformException, FactoryException {
+        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(
+                DefaultFactories.forBuildin(MathTransformFactory.class),
+                6000000, 4000000, SI.METRE, true);
 
         final double delta = toRadians(100.0 / 60) / 1852;
         derivativeDeltas  = new double[] {delta, delta, 100};
@@ -138,10 +154,11 @@ public final strictfp class EllipsoidalT
      * @param  ellipsoid The ellipsoid to use for the test.
      * @param  hasHeight {@code true} if geographic coordinates include an ellipsoidal height (i.e. are 3-D),
      *         or {@code false} if they are only 2-D.
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException should never happen.
      */
-    private void testDerivative(final Ellipsoid ellipsoid, final boolean hasHeight) throws TransformException {
-        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(ellipsoid, hasHeight);
+    private void testDerivative(final Ellipsoid ellipsoid, final boolean hasHeight) throws FactoryException, TransformException {
+        createGeodeticConversion(ellipsoid, hasHeight);
         DirectPosition point = hasHeight ? new GeneralDirectPosition(-10, 40, 200) : new DirectPosition2D(-10, 40);
         /*
          * Derivative of the direct transform.
@@ -162,10 +179,11 @@ public final strictfp class EllipsoidalT
     /**
      * Tests the {@link EllipsoidalToCartesianTransform#derivative(DirectPosition)} method on a sphere.
      *
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException should never happen.
      */
     @Test
-    public void testDerivativeOnSphere() throws TransformException {
+    public void testDerivativeOnSphere() throws FactoryException, TransformException {
         testDerivative(CommonCRS.SPHERE.ellipsoid(), true);
         testDerivative(CommonCRS.SPHERE.ellipsoid(), false);
     }
@@ -173,11 +191,12 @@ public final strictfp class EllipsoidalT
     /**
      * Tests the {@link EllipsoidalToCartesianTransform#derivative(DirectPosition)} method on an ellipsoid.
      *
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException should never happen.
      */
     @Test
     @DependsOnMethod("testDerivativeOnSphere")
-    public void testDerivative() throws TransformException {
+    public void testDerivative() throws FactoryException, TransformException {
         testDerivative(CommonCRS.WGS84.ellipsoid(), true);
         testDerivative(CommonCRS.WGS84.ellipsoid(), false);
     }
@@ -187,12 +206,13 @@ public final strictfp class EllipsoidalT
      * and {@link #testGeocentricToGeographic()}, but on the deserialized instance. This allow us to verify
      * that transient fields have been correctly restored.
      *
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException if conversion of the sample point failed.
      */
     @Test
     @DependsOnMethod("testRandomPoints")
-    public void testSerialization() throws TransformException {
-        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
+    public void testSerialization() throws FactoryException, TransformException {
+        createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
         transform = assertSerializedEquals(transform);
         /*
          * Below is basically a copy-and-paste of testGeographicToGeocentric(), but
@@ -209,11 +229,12 @@ public final strictfp class EllipsoidalT
      * Tests the standard Well Known Text (version 1) formatting.
      * The result is what we show to users, but is quite different than what SIS has in memory.
      *
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException should never happen.
      */
     @Test
-    public void testWKT() throws TransformException {
-        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
+    public void testWKT() throws FactoryException, TransformException {
+        createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
         assertWktEquals("PARAM_MT[“Ellipsoid_To_Geocentric”,\n" +
                         "  PARAMETER[“semi_major”, 6378137.0],\n" +
                         "  PARAMETER[“semi_minor”, 6356752.314245179]]");
@@ -229,11 +250,12 @@ public final strictfp class EllipsoidalT
      * This WKT shows what SIS has in memory for debugging purpose.
      * This is normally not what we show to users.
      *
+     * @throws FactoryException if an error occurred while creating a transform.
      * @throws TransformException should never happen.
      */
     @Test
-    public void testInternalWKT() throws TransformException {
-        transform = EllipsoidalToCartesianTransform.createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
+    public void testInternalWKT() throws FactoryException, TransformException {
+        createGeodeticConversion(CommonCRS.WGS84.ellipsoid(), true);
         assertInternalWktEquals(
                 "Concat_MT[Param_MT[“Affine”,\n" +
                 "    Parameter[“num_row”, 4],\n" +

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=1712672&r1=1712671&r2=1712672&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] Wed Nov  4 22:01:36 2015
@@ -58,8 +58,9 @@ public final strictfp class MolodenskyTr
     private void create(final boolean abridged) throws FactoryException {
         final Ellipsoid source = CommonCRS.WGS84.ellipsoid();
         final Ellipsoid target = CommonCRS.ED50.ellipsoid();
-        transform = new MolodenskyTransform(source, true, target, true, 84.87, 96.49, 116.95, abridged)
-                .createGeodeticTransformation(DefaultFactories.forBuildin(MathTransformFactory.class));
+        transform = MolodenskyTransform.createGeodeticTransformation(
+                DefaultFactories.forBuildin(MathTransformFactory.class),
+                source, true, target, true, 84.87, 96.49, 116.95, abridged);
 
         final double delta = toRadians(100.0 / 60) / 1852;          // Approximatively 100 metres
         derivativeDeltas = new double[] {delta, delta, 100};        // (Δλ, Δφ, Δh)



Mime
View raw message