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 8c9cf96207da217856e66429d731a211efea8e4e Author: Martin Desruisseaux AuthorDate: Fri Aug 9 11:17:15 2019 +0200 Add tests for the spherical case of rhumb line. --- .../apache/sis/referencing/GeodeticCalculator.java | 11 ++++--- .../sis/referencing/GeodesicsOnEllipsoidTest.java | 3 ++ .../sis/referencing/GeodeticCalculatorTest.java | 36 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) 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 2c54093..48ed79b 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 @@ -621,14 +621,15 @@ public class GeodeticCalculator { * Inverse of Gudermannian function is log(tan(π/4 + φ/2)). * The loxodrome formula involves the following difference: * - * ΔG = log(tan(π/4 + φ₁/2)) - log(tan(π/4 + φ₂/2)) + * ΔΨ = log(tan(π/4 + φ₁/2)) - log(tan(π/4 + φ₂/2)) * = log(tan(π/4 + φ₁/2) / tan(π/4 + φ₂/2)) + * α = atan2(Δλ, ΔΨ) * - * Note that ΔG=0 if φ₁=φ₂, which implies cos(α)=0. + * Note that ΔΨ=0 if φ₁=φ₂, which implies cos(α)=0. + * Code below replaces cos(α) by ΔΨ/hypot(Δλ, ΔΨ). */ - final double ΔG = log(tan(PI/4 + φ1/2) / tan(PI/4 + φ2/2)); - final double α = atan(Δλ / ΔG); - factor = Δφ / cos(α); + final double ΔΨ = log(tan(PI/4 + φ2/2) / tan(PI/4 + φ1/2)); + factor = Δφ / ΔΨ * hypot(Δλ, ΔΨ); } rhumblineLength = authalicRadius * 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 7344e19..f52f0b0 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 @@ -510,6 +510,7 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT * Tests {@link GeodesicsOnEllipsoid#getRhumblineLength()} using the example 1 given in Bennett (1996) appendix. */ @Test + @Override public void testRhumblineLength() { createTracked(); verifyParametersForWGS84(); @@ -536,6 +537,7 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT * Tests {@link GeodesicsOnEllipsoid#getRhumblineLength()} using the example 3 given in Bennett (1996) appendix. */ @Test + @Override public void testRhumblineNearlyEquatorial() { createTracked(); verifyParametersForWGS84(); @@ -552,6 +554,7 @@ public final strictfp class GeodesicsOnEllipsoidTest extends GeodeticCalculatorT * Tests {@link GeodesicsOnEllipsoid#getRhumblineLength()} using the example 4 given in Bennett (1996) appendix. */ @Test + @Override public void testRhumblineEquatorial() { createTracked(); verifyParametersForWGS84(); 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 6040529..11413a2 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 @@ -562,4 +562,40 @@ public strictfp class GeodeticCalculatorTest extends TestCase { boolean isFailure(final double[] expected) { return true; } + + /** + * Tests {@link GeodesicsOnEllipsoid#getRhumblineLength()} using points given by Bennett (1996). + * This is an anti-regression test since the result was computed by SIS for the spherical case. + */ + @Test + public void testRhumblineLength() { + final GeodeticCalculator c = create(false); + 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); + } + + /** + * Tests {@link GeodesicsOnEllipsoid#getRhumblineLength()} using points given by Bennett (1996). + * This is an anti-regression test since the result was computed by SIS for the spherical case. + */ + @Test + public void testRhumblineNearlyEquatorial() { + final GeodeticCalculator c = create(false); + 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); + } + + /** + * Tests {@link GeodesicsOnEllipsoid#getRhumblineLength()} using points given by Bennett (1996). + * This is an anti-regression test since the result was computed by SIS for the spherical case. + */ + @Test + public void testRhumblineEquatorial() { + final GeodeticCalculator c = create(false); + 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); + } }