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/05 01:12:46 UTC

svn commit: r1712691 - in /sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis: internal/referencing/provider/Molodensky.java referencing/operation/transform/MolodenskyTransform.java

Author: desruisseaux
Date: Thu Nov  5 00:12:45 2015
New Revision: 1712691

URL: http://svn.apache.org/viewvc?rev=1712691&view=rev
Log:
Rollback the attempt to do too much analysis of unit of measurement in Molodensky.
The OGC 01-009 specification said explictly that heights are in metres anyway.
In MolodenskyTransform, fix the documentation about units of measurements.

Modified:
    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/MolodenskyTransform.java

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=1712691&r1=1712690&r2=1712691&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  5 00:12:45 2015
@@ -21,13 +21,11 @@ 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;
+import org.opengis.parameter.ParameterNotFoundException;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.OperationMethod;
@@ -200,38 +198,53 @@ public final class Molodensky extends Ge
         if (dimension != 0) {
             sourceDimensions = targetDimensions = dimension;
         }
-        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);
+        /*
+         * Following method calls implicitly convert parameter values to metres.
+         * We do not try to match ellipsoid axis units because:
+         *
+         *   1) It complicates the code.
+         *   2) We have no guarantees that ellipsoid unit match the coordinate system unit.
+         *   3) OGC 01-009 explicitly said that angles are in degrees and heights in metres.
+         *   4) The above is consistent with what we do for map projections.
+         */
+        double sa = values.doubleValue(SRC_SEMI_MAJOR);
+        double sb = values.doubleValue(SRC_SEMI_MINOR);
+        double ta = optional(values,   TGT_SEMI_MAJOR);
+        double tb = optional(values,   TGT_SEMI_MINOR);
+        double Δa = optional(values, AXIS_LENGTH_DIFFERENCE);
+        double Δf = optional(values, FLATTENING_DIFFERENCE);
         if (Double.isNaN(ta)) {
-            ta = c.convert(sa + Δa);
+            ta = 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);
+        final Ellipsoid source = new Ellipsoid(name, sa, sb,  Δa,  Δf);
+        final Ellipsoid target = new Ellipsoid(name, ta, tb, -Δa, -Δf);
         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),
+                values.doubleValue(TX),
+                values.doubleValue(TY),
+                values.doubleValue(TZ),
                 isAbridged);
     }
 
     /**
+     * Returns the value of the given parameter, or NaN if undefined.
+     */
+    private static double optional(final Parameters values, final ParameterDescriptor<Double> parameter) {
+        try {
+            return values.doubleValue(parameter);
+        } catch (ParameterNotFoundException | IllegalStateException e) {
+            return Double.NaN;
+        }
+    }
+
+    /**
      * 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.
@@ -241,12 +254,12 @@ public final class Molodensky extends Ge
         /** The EPSG parameter values, or NaN if unspecified. */
         private final double Δa, Δf;
 
-        /** The ellipsoid for which Δa and Δf are valids. */
+        /** The ellipsoid for which Δa and Δf are valid. */
         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);
+        Ellipsoid(Map<String,?> name, double a, double b, double Δa, double Δf) {
+            super(name, a, b, Formulas.getInverseFlattening(a, b), false, SI.METRE);
             this.Δa = Δa;
             this.Δf = Δf;
         }

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=1712691&r1=1712690&r2=1712691&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  5 00:12:45 2015
@@ -71,7 +71,8 @@ import static java.lang.Math.*;
  *   <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>
+ *       work with angular values in degrees and heights in the same units than the <strong>source</strong> ellipsoid
+ *       axes (usually metres).</li>
  * </ul>
  *
  * @author  Rueben Schulz (UBC)
@@ -175,7 +176,7 @@ public class MolodenskyTransform extends
      * <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>optionally heights above the ellipsoid, in same units than the source ellipsoids axes.</li>
      * </ol>
      *
      * For converting geographic coordinates in degrees, {@code MolodenskyTransform} instances
@@ -199,9 +200,9 @@ public class MolodenskyTransform extends
      * @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 tX          The geocentric <var>X</var> translation in same units than the source ellipsoid axes.
+     * @param tY          The geocentric <var>Y</var> translation in same units than the source ellipsoid axes.
+     * @param tZ          The geocentric <var>Z</var> translation in same units than the source ellipsoid axes.
      * @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)
@@ -272,7 +273,7 @@ public class MolodenskyTransform extends
      * <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>
+     *   <li>optionally heights above the ellipsoid, in same units than the source ellipsoids axes.</li>
      * </ol>
      *
      * @param factory     The factory to use for creating the transform.
@@ -280,9 +281,9 @@ public class MolodenskyTransform extends
      * @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 tX          The geocentric <var>X</var> translation in same units than the source ellipsoid axes.
+     * @param tY          The geocentric <var>Y</var> translation in same units than the source ellipsoid axes.
+     * @param tZ          The geocentric <var>Z</var> translation in same units than the source ellipsoid axes.
      * @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.