This is to calculate from two sets of points (Latitude, and Longitude) and distance based on the Earth's diameter/radius.
Here is the Haversine Formula followed by the java code. I've added Miles, KM, Meters, CM, Feet and Yards methods as well.
Here is the Haversine Formula followed by the java code. I've added Miles, KM, Meters, CM, Feet and Yards methods as well.
Haversine formula: | a = sin²(Δφ/2) + cos(φ1).cos(φ2).sin²(Δλ/2) c = 2.atan2(√a, √(1−a)) d = R.c |
where | φ is latitude, λ is longitude, R is earth’s radius (mean radius = 6,371km) |
note that angles need to be in radians to pass to trig functions! |
/**
* This is the implementation Haversine Distance Algorithm between two places
* @author amitapollo
* R = earth’s radius (mean radius = 6372.8km)
Δlat = lat2 − lat1
Δlong = long2 − long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c * (distance converstion factor*)
*
* * - km, mi, m, yds
*/
import java.lang.Math.*;
public class Haversine {
/**
* @param args
* arg 1- latitude 1
* arg 2 - longitude 1
* arg 3 - latitude 2
* arg 4 - longitude 2
*/
public static final double RKilometers = 6372.8; // In kilometers
public static final double RMiles = 10256.0; // In miles
//returns kilometers between two sets of points (lat, lon)
public static double haversineKilometers(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return RKilometers * c;
}
//returns meters between two sets of points (lat, lon)
public static double haversineMeters(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return RKilometers * c * 1000;
}
//returns centimeters between two sets of points (lat, lon)
public static double haversineCentimeters(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return RKilometers * c * 1000 * 100;
}
//returns miles between two sets of points (lat, lon)
public static double haversineMiles(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return RMiles * c;
}
//returns feet between two sets of points (lat, lon)
public static double haversineFeet(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return RMiles * c * 5280;
}
//returns inches between two sets of points (lat, lon)
public static double haversineInches(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return RMiles * c * 5280 * 12;
}
//returns yards between two sets of points (lat, lon)
public static double haversineYards(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return RMiles * c * 1760;
}
//CONVERTS value to Radians
private static Double toRad(Double value) {
return value * Math.PI / 180;
}
}
Your RMiles constant is wrong. You inadvertently divided KM by .62 instead of multiplying by .62. Miles will ALWAYS be less than KM for the same distance, since a mile is larger.
ReplyDelete