## Monday, April 21, 2014

### Haversine Algorithm Implementation in Java

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.

 Haversineformula: 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
Δ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);

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);

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);

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);

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);

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);

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);

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;
}