sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1712579 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/datum/ test/java/org/apache/sis/referencing/datum/ test/java/org/apache/sis/test/mock/
Date Wed, 04 Nov 2015 16:15:02 GMT
Author: desruisseaux
Date: Wed Nov  4 16:14:52 2015
New Revision: 1712579

URL: http://svn.apache.org/viewvc?rev=1712579&view=rev
Log:
Add convenience method for computing the difference between flattening factors.

Modified:
    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/datum/Sphere.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/test/mock/GeodeticDatumMock.java

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=1712579&r1=1712578&r2=1712579&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 16:14:52 2015
@@ -31,6 +31,7 @@ import org.opengis.metadata.Identifier;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.apache.sis.geometry.DirectPosition2D;
 import org.apache.sis.internal.util.Numerics;
+import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.internal.jaxb.gml.Measure;
 import org.apache.sis.internal.jaxb.referencing.SecondDefiningParameter;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
@@ -399,15 +400,76 @@ public class DefaultEllipsoid extends Ab
     }
 
     /**
-     * The ratio of the distance between the center and a focus of the ellipse
-     * to the length of its semi-major axis. The eccentricity can alternately be
-     * computed from the equation: <code>e = sqrt(2f - f²)</code>.
+     * The ratio of the distance between the center and a focus of the ellipse to the length
of its semi-major axis.
+     * The eccentricity can alternately be computed from the equation: ℯ = √(2f - f²)
where <var>f</var> is the
+     * flattening factor (not inverse).
      *
-     * @return The eccentricity of this ellipsoid.
+     * @return ℯ, the eccentricity of this ellipsoid.
      */
     public double getEccentricity() {
-        final double f = 1 - getSemiMinorAxis() / getSemiMajorAxis();
-        return sqrt(2*f - f*f);
+        final DoubleDouble e = excentricitySquared();
+        e.sqrt();
+        return e.value;
+    }
+
+    /**
+     * Returns the square of the {@link #getEccentricity() eccentricity} value.
+     *
+     * <div class="note"><b>Purpose:</b>
+     * this convenience method is provided because ℯ² is frequently used in coordinate
operations,
+     * actually more often than ℯ. This convenience method avoids the cost of computing
the square
+     * root when not needed.</div>
+     *
+     * @return ℯ², the square of the eccentricity value.
+     *
+     * @since 0.7
+     */
+    public double getEccentricitySquared() {
+        return excentricitySquared().value;
+    }
+
+    /**
+     * Computes the square of the eccentricity value with ℯ² = 2f - f².
+     *
+     * <div class="note"><b>Implementation note:</b>
+     * we use the flattening factor for this computation because the inverse flattening factor
is usually the
+     * second defining parameter.  But even if the second defining parameter of this ellipsoid
was rather the
+     * semi-minor axis, the fact that we use double-double arithmetic should give the same
result anyway.</div>
+     */
+    private DoubleDouble excentricitySquared() {
+        final DoubleDouble f = flattening(this);
+        final DoubleDouble excentricitySquared = new DoubleDouble(f);
+        excentricitySquared.multiply(2, 0);
+        f.square();
+        excentricitySquared.subtract(f);
+        return excentricitySquared;
+    }
+
+    /**
+     * Computes the flattening factor (not inverse) of the given ellipsoid.
+     * This method chooses the formula depending on whether the defining parameter is the
inverse flattening factor
+     * or the semi-minor axis length. The defining parameters are presumed fully accurate
in base 10 (even if this
+     * is of course not possible in the reality), because those parameters are definitions
given by authorities.
+     *
+     * <div class="note"><b>Analogy:</b>
+     * the conversion factor from inches to centimetres is 2.54 <em>by definition</em>.
Even if we could find a more
+     * accurate value matching historical measurements, the 2.54 value is the internationally
agreed value for all
+     * conversions. This value is (by convention) defined in base 10 and has no exact {@code
double} representation.
+     * </div>
+     */
+    private static DoubleDouble flattening(final Ellipsoid e) {
+        final DoubleDouble f;
+        if (e.isIvfDefinitive()) {
+            f = new DoubleDouble(e.getInverseFlattening());   // Presumed accurate in base
10 (not 2) by definition.
+            f.inverseDivide(1, 0);
+        } else {
+            f = new DoubleDouble(e.getSemiMajorAxis());       // Presumed accurate in base
10 (not 2) by definition.
+            final double value = f.value;
+            final double error = f.error;
+            f.subtract(e.getSemiMinorAxis());                 // Presumed accurate in base
10 (not 2) by definition.
+            f.divide(value, error);
+        }
+        return f;
     }
 
     /**
@@ -553,6 +615,21 @@ public class DefaultEllipsoid extends Ab
     }
 
     /**
+     * Returns the difference between the flattening factor of two ellipsoids.
+     * This method returns 0 if the two ellipsoids are equal.
+     *
+     * @param  other The other ellipsoid from which to get flattening difference.
+     * @return (other ellipsoid flattening) - (this ellipsoid flattening).
+     *
+     * @since 0.7
+     */
+    public double flatteningDifference(final Ellipsoid other) {
+        final DoubleDouble f = flattening(other);
+        f.subtract(flattening(this));
+        return f.value;
+    }
+
+    /**
      * Compares this ellipsoid with the specified object for equality.
      *
      * @param  object The object to compare to {@code this}.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java?rev=1712579&r1=1712578&r2=1712579&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java
[UTF-8] Wed Nov  4 16:14:52 2015
@@ -20,6 +20,7 @@ import java.util.Map;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Length;
 import javax.xml.bind.annotation.XmlTransient;
+import org.opengis.referencing.datum.Ellipsoid;
 
 import static java.lang.Math.*;
 
@@ -35,7 +36,7 @@ import static java.lang.Math.*;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 @XmlTransient
@@ -82,6 +83,22 @@ final class Sphere extends DefaultEllips
     }
 
     /**
+     * Eccentricity of a sphere is always zero.
+     */
+    @Override
+    public double getEccentricitySquared() {
+        return 0;
+    }
+
+    /**
+     * Returns the flattening factor of the other ellipsoid, since the flattening factor
of {@code this} is zero.
+     */
+    @Override
+    public double flatteningDifference(final Ellipsoid other) {
+        return 1 / other.getInverseFlattening();
+    }
+
+    /**
      * Returns the orthodromic distance between two geographic coordinates.
      * The orthodromic distance is the shortest distance between two points
      * on a sphere's surface. The orthodromic path is always on a great circle.

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=1712579&r1=1712578&r2=1712579&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 16:14:52 2015
@@ -38,7 +38,7 @@ import static org.apache.sis.test.Metada
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.7
  * @module
  */
 @DependsOn({
@@ -70,6 +70,33 @@ public final strictfp class DefaultEllip
     }
 
     /**
+     * Tests {@link DefaultEllipsoid#getEccentricity()}.
+     *
+     * @since 0.7
+     */
+    @Test
+    public void testGetEccentricity() {
+        final DefaultEllipsoid e = new DefaultEllipsoid(GeodeticDatumMock.WGS84.getEllipsoid());
+        assertEquals("semiMajorAxis",       6378137.0,            e.getSemiMajorAxis(), 
     STRICT);   // By definition
+        assertEquals("inverseFlattening",   298.257223563,        e.getInverseFlattening(),
  STRICT);   // By definition
+        assertEquals("eccentricitySquared", 0.006694379990141317, e.getEccentricitySquared(),
STRICT);
+        assertEquals("eccentricity",        0.0818191908426215,   e.getEccentricity(),  
     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.
+     *
+     * @since 0.7
+     */
+    @Test
+    public void testFlatteningDifference() {
+        final DefaultEllipsoid e = new DefaultEllipsoid(GeodeticDatumMock.WGS84.getEllipsoid());
+        assertEquals("flatteningDifference", 0.0,         e.flatteningDifference(GeodeticDatumMock.WGS84.getEllipsoid()),
STRICT);
+        assertEquals("flatteningDifference", 1.41927E-05, e.flatteningDifference(GeodeticDatumMock.ED50
.getEllipsoid()), 1E-10);
+    }
+
+    /**
      * Tests the orthodromic distances computed by {@link DefaultEllipsoid}. There is actually
two algorithms:
      * one for the ellipsoidal model, and a simpler one for spherical model. This method
tests the ellipsoidal
      * model using known values of nautical mile at different latitude.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/mock/GeodeticDatumMock.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/mock/GeodeticDatumMock.java?rev=1712579&r1=1712578&r2=1712579&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/mock/GeodeticDatumMock.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/mock/GeodeticDatumMock.java
[UTF-8] Wed Nov  4 16:14:52 2015
@@ -33,7 +33,7 @@ import org.apache.sis.internal.metadata.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  */
 @SuppressWarnings("serial")
@@ -59,6 +59,11 @@ public final strictfp class GeodeticDatu
     public static final GeodeticDatum NAD27 = new GeodeticDatumMock("NAD27", 6378206.4, 6356583.8,
294.97869821390583, false);
 
     /**
+     * The "European Datum 1950" datum with "International 1924" ellipsoid.
+     */
+    public static final GeodeticDatum ED50 = new GeodeticDatumMock("ED50", 6378388, 6356912,
297, true);
+
+    /**
      * The "Nouvelle Triangulation Française" (EPSG:6807) datum with "Clarke 1880 (IGN)"
ellipsoid.
      * This is the same datum than "Nouvelle Triangulation Française (Paris)" (EPSG:6275)
except
      * for the prime meridian, which is Greenwich instead of Paris.



Mime
View raw message