Location { public double greatCircleDistance(Location location) { if (location == null) { throw new IllegalArgumentException( Logger.logMessage(Logger.ERROR, "Location", "greatCircleDistance", "missingLocation")); } double lat1Radians = Math.toRadians(this.latitude); double lon1Radians = Math.toRadians(this.longitude); double lat2Radians = Math.toRadians(location.latitude); double lon2Radians = Math.toRadians(location.longitude); if (lat1Radians == lat2Radians && lon1Radians == lon2Radians) { return 0; } double a = Math.sin((lat2Radians - lat1Radians) / 2.0); double b = Math.sin((lon2Radians - lon1Radians) / 2.0); double c = a * a + Math.cos(lat1Radians) * Math.cos(lat2Radians) * b * b; double distanceRadians = 2.0 * Math.asin(Math.sqrt(c)); return Double.isNaN(distanceRadians) ? 0 : distanceRadians; } 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 testGreatCircleDistance() throws Exception { Location begin = Location.fromDegrees(90.0, 45.0); Location end = Location.fromDegrees(36.0, 180.0); double distance = Math.toDegrees(begin.greatCircleDistance(end)); assertEquals("known spherical distance", 54.0, distance, TOLERANCE); }
@Test public void testGreatCircleDistance_AlongEquator() throws Exception { Location origin = new Location(); double eastToDateLine = origin.greatCircleDistance(new Location(0, 180)); assertEquals("prime meridian to dateline east", Math.toRadians(180), eastToDateLine, TOLERANCE); double westToDateLine = origin.greatCircleDistance(new Location(0, -180)); assertEquals("prime meridian to dateline west ", Math.toRadians(180), westToDateLine, TOLERANCE); Location west = new Location(0, -22.5); double sideToSide = west.greatCircleDistance(new Location(0, 22.5)); assertEquals("22.5 east to 22.5 west", Math.toRadians(45), sideToSide, TOLERANCE); }
@Test public void testGreatCircleDistance_AcrossMeridian() throws Exception { Location west = new Location(0, -22.5); Location east = new Location(0, 22.5); double sideToSide = west.greatCircleDistance(east); assertEquals("22.5 east to 22.5 west", Math.toRadians(45), sideToSide, TOLERANCE); }
@Test public void testGreatCircleDistance_AcrossDateline() throws Exception { Location west = new Location(0, -157.5); Location east = new Location(0, 157.5); double sideToSide = west.greatCircleDistance(east); assertEquals("157.5 east to 157.5 west", Math.toRadians(45), sideToSide, TOLERANCE); }
@Test public void testGreatCircleDistance_AlongMeridians() throws Exception { Location origin = new Location(); double northToPole = origin.greatCircleDistance(new Location(90, 0)); assertEquals("equator to north pole", Math.toRadians(90), northToPole, TOLERANCE); double southToPole = origin.greatCircleDistance(new Location(-90, 0)); assertEquals("equator to south pole", Math.toRadians(90), southToPole, TOLERANCE); Location southPole = new Location(-90, 0); Location northPole = new Location(90, 0); double poleToPole = southPole.greatCircleDistance(northPole); assertEquals("south pole to north pole", Math.toRadians(180), poleToPole, TOLERANCE); Location south = new Location(-22.5, 0); Location north = new Location(22.5, 0); double southToNorth = south.greatCircleDistance(north); assertEquals("22.5 deg south to 22.5 north", Math.toRadians(45), southToNorth, TOLERANCE); }
@Test(expected = IllegalArgumentException.class) public void testGreatCircleDistance_WithNull() throws Exception { PowerMockito.mockStatic(Logger.class); Location begin = new Location(34.2, -119.2); begin.greatCircleDistance(null); fail("Expected an IllegalArgumentException to be thrown."); }
@Ignore("NaN behavior TBD") @Test public void testGreatCircleDistance_WithNaN() throws Exception { Location location = new Location(Double.NaN, Double.NaN); double nanDistance = location.greatCircleDistance(new Location(34.2, -119.2)); assertTrue("expecting NaN", Double.isNaN(nanDistance)); }