sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 02/02: Test rhumb line azimuth.
Date Sun, 11 Aug 2019 15:16:35 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 071aae3926c8f15971daa91b6f76ada74942c107
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sun Aug 11 17:16:02 2019 +0200

    Test rhumb line azimuth.
---
 .../sis/referencing/GeodesicsOnEllipsoid.java      |  2 +-
 .../apache/sis/referencing/GeodeticCalculator.java | 31 +++++++++++++++++++---
 .../sis/referencing/GeodesicsOnEllipsoidTest.java  |  8 +++---
 .../sis/referencing/GeodeticCalculatorTest.java    |  3 +++
 4 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
index fd2b087..52ba4db 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodesicsOnEllipsoid.java
@@ -977,10 +977,10 @@ class GeodesicsOnEllipsoid extends GeodeticCalculator {
             }
         }
         rhumblineLength = S * h * semiMajorAxis;
+        rhumblineAzimuth = atan2(Δλ, ΔΨ);
         if (STORE_LOCAL_VARIABLES) {
             store("Δλ", Δλ);
             store("ΔΨ", ΔΨ);
-            store("C",  atan2(Δλ, ΔΨ));         // Azimuth.
         }
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java
index 6efeac8..ffae49b 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticCalculator.java
@@ -216,6 +216,13 @@ public class GeodeticCalculator {
     double rhumblineLength;
 
     /**
+     * Constant bearing on the rhumb line path, in radians.
+     *
+     * @see #getConstantAzimuth()
+     */
+    double rhumblineAzimuth;
+
+    /**
      * A bitmask specifying which information are valid. For example if the {@link #END_POINT}
bit is not set,
      * then {@link #φ2} and {@link #λ2} need to be computed, which implies the computation
of ∂φ/∂λ as well.
      * If the {@link #GEODESIC_DISTANCE} bit is not set, then {@link #geodesicDistance} needs
to be computed,
@@ -450,7 +457,8 @@ public class GeodeticCalculator {
     }
 
     /**
-     * Returns or computes the angular heading (relative to geographic North) at the starting
point.
+     * Returns or computes the angular heading at the starting point of a geodesic path.
+     * Azimuth is relative to geographic North with values increasing clockwise.
      * This method returns the azimuth normalized to [-180 … +180]° range given in last
call to
      * {@link #setStartingAzimuth(double)} method, unless the {@link #setEndPoint(Position)
setEndPoint(…)}
      * method has been invoked more recently. In the later case, the azimuth will be computed
from the
@@ -468,7 +476,7 @@ public class GeodeticCalculator {
     }
 
     /**
-     * Sets the angular heading (relative to geographic North) at the starting point.
+     * Sets the angular heading at the starting point of a geodesic path.
      * Azimuth is relative to geographic North with values increasing clockwise.
      * The {@linkplain #getEndingAzimuth() ending azimuth}, {@linkplain #getEndPoint() end
point}
      * and {@linkplain #getRhumblineLength() rhumb line length}
@@ -488,7 +496,8 @@ public class GeodeticCalculator {
     }
 
     /**
-     * Computes the angular heading (relative to geographic North) at the ending point. This
method computes the azimuth
+     * Computes the angular heading at the ending point of a geodesic path.
+     * Azimuth is relative to geographic North with values increasing clockwise. This method
computes the azimuth
      * from the current {@linkplain #setStartPoint(Position) start point} and {@linkplain
#setEndPoint(Position) end point},
      * or from start point and the current {@linkplain #setStartingAzimuth(double) starting
azimuth} and
      * {@linkplain #setGeodesicDistance(double) geodesic distance}.
@@ -509,6 +518,20 @@ public class GeodeticCalculator {
     }
 
     /**
+     * Computes the angular heading of a rhumb line path.
+     * Azimuth is relative to geographic North with values increasing clockwise.
+     *
+     * @return the azimuth in degrees from -180° to +180°. 0° is toward North and values
are increasing clockwise.
+     * @throws IllegalStateException if a point has not been set.
+     */
+    public double getConstantAzimuth() {
+        if (isInvalid(RHUMBLINE_LENGTH)) {
+            computeRhumbLine();
+        }
+        return toDegrees(rhumblineAzimuth);
+    }
+
+    /**
      * Returns or computes the shortest distance from start point to end point. This is sometime
called "great circle"
      * or "orthodromic" distance. This method returns the value given in last call to {@link
#setGeodesicDistance(double)},
      * unless the {@link #setEndPoint(Position) setEndPoint(…)} method has been invoked
more recently. In the later case,
@@ -612,6 +635,7 @@ public class GeodeticCalculator {
         final double factor;
         if (abs(Δφ) < LATITUDE_THRESHOLD) {
             factor = Δλ * cos((φ1 + φ2)/2);
+            rhumblineAzimuth = copySign(PI/2, Δλ);
         } else {
             /*
              * Inverse of Gudermannian function is log(tan(π/4 + φ/2)).
@@ -626,6 +650,7 @@ public class GeodeticCalculator {
              */
             final double ΔΨ = log(tan(PI/4 + φ2/2) / tan(PI/4 + φ1/2));
             factor = Δφ / ΔΨ * hypot(Δλ, ΔΨ);
+            rhumblineAzimuth = atan2(Δλ, ΔΨ);
         }
         rhumblineLength = semiMajorAxis * abs(factor);
         setValid(RHUMBLINE_LENGTH);
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodesicsOnEllipsoidTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodesicsOnEllipsoidTest.java
index 7977c73..d753cae 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodesicsOnEllipsoidTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodesicsOnEllipsoidTest.java
@@ -528,10 +528,9 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT
         assertValueEquals("m₁", 0,  615.43 / scale,      1E-6, false);
         assertValueEquals("m₂", 0, 3201.59 / scale,      1E-6, false);
         assertValueEquals("Δm", 0, 2586.16 / scale,      1E-6, false);
-        assertValueEquals("C",  0, 54.9900,              1E-4, true);
+        assertEquals("azimuth",  54.99008056, testedEarth.getConstantAzimuth(), 1E-8);
         assertEquals("distance", 4507.7 * NAUTICAL_MILE, distance, 0.05 * NAUTICAL_MILE);
  // From Bennett (1996)
         assertEquals("distance", 8348285.202, distance, Formulas.LINEAR_TOLERANCE);     
   // From Karney's online calculator.
-//      assertEquals("azimuth",  54.99008056, azimuth,  1E-8);
     }
 
     /**
@@ -548,9 +547,9 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT
         assertValueEquals("Δλ", 0,  55+57.0 / 60,         1E-11, true);
         assertValueEquals("ΔΨ", 0,   -38.12 / (10800/PI), 1E-5, false);
         assertValueEquals("C",  0,  90.6505,              1E-4, true);
+        assertEquals("azimuth",  90.65049570, testedEarth.getConstantAzimuth(), 1E-8);
         assertEquals("distance", 2028.9 * NAUTICAL_MILE, distance, 0.05 * NAUTICAL_MILE);
  // From Bennett (1996)
         assertEquals("distance", 3757550.656, distance, Formulas.LINEAR_TOLERANCE);     
   // From Karney's online calculator.
-//      assertEquals("azimuth",  90.65049570, azimuth,  1E-8);
     }
 
     /**
@@ -565,9 +564,8 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT
         testedEarth.setEndGeographicPoint  (48+45.0/60,   5+13.2/60);
         final double distance = testedEarth.getRhumblineLength();
         assertValueEquals("Δλ", 0, 4004.3 / 60, 1E-11, true);
-        assertValueEquals("C",  0,   90.0,      1E-4, true);
+        assertEquals("azimuth",  90.00000000, testedEarth.getConstantAzimuth(), 1E-8);
         assertEquals("distance", 2649.9 * NAUTICAL_MILE, distance, 0.1 * NAUTICAL_MILE);
   // From Bennett (1996)
         assertEquals("distance", 4907757.375, distance, Formulas.LINEAR_TOLERANCE);     
   // From Karney's online calculator.
-//      assertEquals("azimuth",  90.00000000, azimuth,  1E-8);
     }
 }
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticCalculatorTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticCalculatorTest.java
index cd49677..5a309fb 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticCalculatorTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticCalculatorTest.java
@@ -573,6 +573,7 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
         c.setStartGeographicPoint(10+18.4/60,  37+41.7/60);
         c.setEndGeographicPoint  (53+29.5/60, 113+17.1/60);
         assertEquals(8344561, c.getRhumblineLength(), 1);
+        assertEquals(54.8682, c.getConstantAzimuth(), 1E-4);
     }
 
     /**
@@ -585,6 +586,7 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
         c.setStartGeographicPoint(-52-47.8/60, -97-31.6/60);
         c.setEndGeographicPoint  (-53-10.8/60, -41-34.6/60);
         assertEquals(3745332, c.getRhumblineLength(), 1);
+        assertEquals(90.6521, c.getConstantAzimuth(), 1E-4);
     }
 
     /**
@@ -597,5 +599,6 @@ public strictfp class GeodeticCalculatorTest extends TestCase {
         c.setStartGeographicPoint(48+45.0/60, -61-31.1/60);
         c.setEndGeographicPoint  (48+45.0/60,   5+13.2/60);
         assertEquals(4892987, c.getRhumblineLength(), 1);
+        assertEquals(90, c.getConstantAzimuth(), STRICT);
     }
 }


Mime
View raw message