Location { public double rhumbAzimuth(Location location) { if (location == null) { throw new IllegalArgumentException( Logger.logMessage(Logger.ERROR, "Location", "rhumbAzimuth", "missingLocation")); } double lat1 = Math.toRadians(this.latitude); double lon1 = Math.toRadians(this.longitude); double lat2 = Math.toRadians(location.latitude); double lon2 = Math.toRadians(location.longitude); if (lat1 == lat2 && lon1 == lon2) { return 0; } double dLon = lon2 - lon1; double dPhi = Math.log(Math.tan(lat2 / 2.0 + Math.PI / 4) / Math.tan(lat1 / 2.0 + Math.PI / 4)); if (Math.abs(dLon) > Math.PI) { dLon = dLon > 0 ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon); } double azimuthRadians = Math.atan2(dLon, dPhi); return Double.isNaN(azimuthRadians) ? 0 : Math.toDegrees(azimuthRadians); } Location();  Location(double latitude, double longitude);  Location(Location location); static Location fromDegrees(double latitudeDegrees, double longitudeDegrees); static Location fromRadians(double latitudeRadians, double longitudeRadians); static Location fromTimeZone(TimeZone timeZone); static double normalizeLatitude(double degrees); static double normalizeLongitude(double degrees); static double clampLatitude(double degrees); static double clampLongitude(double degrees); static boolean locationsCrossAntimeridian(List<? extends Location> locations); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString(); Location set(double latitude, double longitude); Location set(Location location); Location interpolateAlongPath(Location endLocation, @WorldWind.PathType int pathType, double amount,
                                         Location result); double greatCircleAzimuth(Location location); double greatCircleDistance(Location location); Location greatCircleLocation(double azimuthDegrees, double distanceRadians, Location result); double rhumbAzimuth(Location location); double rhumbDistance(Location location); Location rhumbLocation(double azimuthDegrees, double distanceRadians, Location result); double linearAzimuth(Location location); double linearDistance(Location location); Location linearLocation(double azimuthDegrees, double distanceRadians, Location result); public double latitude; public double longitude; }
@Test public void testRhumbAzimuth() throws Exception { Location lax = Location.fromRadians(0.592539, -2.066470); Location jfk = Location.fromRadians(0.709185, -1.287762); final double courseRadians = 1.384464; double azimuth = lax.rhumbAzimuth(jfk); assertEquals("lax to jfk", courseRadians, Math.toRadians(azimuth), 1e-6); }
@Test public void testRhumbAzimuth_AlongEquator() throws Exception { Location origin = new Location(0, 0); Location east = new Location(0, 1); Location west = new Location(0, -1); double azimuthEast = origin.rhumbAzimuth(east); double azimuthWest = origin.rhumbAzimuth(west); assertEquals("expecting 90", 90d, azimuthEast, 0); assertEquals("expecting -90", -90d, azimuthWest, 0); }
@Test public void testRhumbAzimuth_AlongMeridian() throws Exception { Location begin = new Location(0, 0); Location north = new Location(1, 0); Location south = new Location(-1, 0); double azimuthNorth = begin.rhumbAzimuth(north); double azimuthSouth = begin.rhumbAzimuth(south); assertEquals("expecting 0", 0d, azimuthNorth, 0); assertEquals("expecting 180", 180d, azimuthSouth, 0); }
@Test public void testRhumbAzimuth_FromPoles() throws Exception { Location northPole = new Location(90, 0); Location southPole = new Location(-90, 0); Location end = new Location(0, 0); double azimuthNorth = southPole.rhumbAzimuth(end); double azimuthSouth = northPole.rhumbAzimuth(end); assertEquals("expecting 0", 0d, azimuthNorth, 0); assertEquals("expecting 180", 180d, azimuthSouth, 0); }
@Test public void testRhumbAzimuth_AcrossDateline() throws Exception { Location end = new Location(45d, 165d); Location begin = new Location(45d, -165d); double azimuth = begin.rhumbAzimuth(end); assertEquals("expecting -90", -90d, azimuth, 0); }
@Test public void testRhumbAzimuth_CoincidentLocations() throws Exception { Location begin = new Location(34.2, -119.2); Location end = new Location(34.2, -119.2); double azimuth = begin.rhumbAzimuth(end); assertEquals("expecting zero", 0d, azimuth, 0); }
@Ignore("NaN behavior TBD") @Test public void testRhumbAzimuth_WithNaN() throws Exception { Location begin = new Location(Double.NaN, Double.NaN); Location end = new Location(34.2, -119.2); double azimuth = begin.rhumbAzimuth(end); assertTrue("expecting NaN", Double.isNaN(azimuth)); }
@Test(expected = IllegalArgumentException.class) public void testRhumbAzimuth_WithNull() throws Exception { PowerMockito.mockStatic(Logger.class); Location begin = new Location(34.2, -119.2); begin.rhumbAzimuth(null); fail("Expected an IllegalArgumentException to be thrown."); }