Skip to content

Instantly share code, notes, and snippets.

@2sbsbsb
Created March 21, 2013 20:10
Show Gist options
  • Save 2sbsbsb/5216268 to your computer and use it in GitHub Desktop.
Save 2sbsbsb/5216268 to your computer and use it in GitHub Desktop.
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Parses longitude or latitude to double
*/
public class LongitudeLatitudeUtil {
private static String EXPRESSION = "^(?<deg>[-+0-9]+)[^0-9]+(?<min>[0-9]+)[^0-9]+(?<sec>[0-9.,]+)[^0-9.,ENSW]+(?<pos>[ENSW]*)$";
/**
* Parses the latitude and longitude to double
*
* @param value
* @return
*/
public static double ParseLatLonValue(String value) {
double result = Double.NaN;
/**
* Remove the double quote from both sides if present
*/
if (value.startsWith("\"") && value.endsWith("\"")) {
value = value.substring(1, value.length() - 2).replace("\"\"", "\"");
}
Pattern pattern = Pattern.compile(EXPRESSION);
Matcher matcher = pattern.matcher(value);
double deg = Double.NaN;
double min = Double.NaN;
double sec = Double.NaN;
char pos = '\0';
if (matcher.matches()) {
deg = Double.parseDouble(matcher.group("deg"));
min = Double.parseDouble(matcher.group("min"));
sec = Double.parseDouble(matcher.group("sec"));
pos = matcher.group("pos").charAt(0);
result = parseLatLonValue(deg, min, sec, pos);
}
return result;
}
/**
* @param deg
* @param min
* @param sec
* @param pos
* @return
*/
public static double parseLatLonValue(double deg, double min, double sec, char pos) {
double result = deg + (min / 60) + (sec / 3600);
// North and East are positives and so adjustment for S W
result = ((pos == 'S') || (pos == 'W')) ? -result : result;
return result;
}
/**
* @param value
* @return
*/
private static String parseLatLonValue(double value) {
double absoluteValue = Math.abs(value);
int deg = (int) Math.floor(absoluteValue);
absoluteValue = (absoluteValue - deg) * 60;
int min = (int) Math.floor(absoluteValue);
double seconds = (absoluteValue - min) * 60;
DecimalFormat twoDForm = new DecimalFormat("#.##");
seconds = Double.valueOf(twoDForm.format(seconds));
return deg + "°" + min + "'" + seconds;
}
/**
* @param value
* @return
*/
private static String parseSpaceLatLonValue(double value) {
double absoluteValue = Math.abs(value);
int deg = (int) Math.floor(absoluteValue);
absoluteValue = (absoluteValue - deg) * 60;
int min = (int) Math.floor(absoluteValue);
double seconds = (absoluteValue - min) * 60;
DecimalFormat twoDForm = new DecimalFormat("#.##");
seconds = Double.valueOf(twoDForm.format(seconds));
return deg + " " + min + "' " + seconds + "''";
}
/**
* @param value
* @return
*/
public static String parseSpaceLatitude(double value) {
String direction = value < 0 ? "S" : "N";
String strValue = parseSpaceLatLonValue(value);
return strValue + " " + direction;
}
/**
* @param value
* @return
*/
public static String parseSpaceLongitude(double value) {
String direction = value < 0 ? "W" : "E";
String strValue = parseSpaceLatLonValue(value);
return strValue + " " + direction;
}
/**
* @param value
* @return
*/
public static String parseLatitude(double value) {
String direction = value < 0 ? "S" : "N";
String strValue = parseLatLonValue(value);
return strValue + "\"" + direction;
}
/**
* @param value
* @return
*/
public static String parseLongitude(double value) {
String direction = value < 0 ? "W" : "E";
String strValue = parseLatLonValue(value);
return strValue + "\"" + direction;
}
/**
* @param lat1
* @param lon1
* @param lat2
* @param lon2
* @param unit
* M = Miles K = Kilometer N = NauticalMiles
* @return
*/
public static double distance(double lat1, double lon1, double lat2, double lon2, char unit) {
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
if (unit == 'K') {
dist = dist * 1.609344;
} else if (unit == 'N') {
dist = dist * 0.8684;
}
if (!Double.isNaN(dist) && !Double.isInfinite(dist)) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
dist = Double.valueOf(twoDForm.format(dist));
}
return (dist);
}
private static double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
private static double rad2deg(double rad) {
return (rad * 180.0 / Math.PI);
}
/**
* @param lat1
* @param lon1
* @param lat2
* @param lon2
* @return
*/
public static double[] midPoint(double lat1, double lon1, double lat2, double lon2) {
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
lon1 = Math.toRadians(lon1);
double Bx = Math.cos(lat2) * Math.cos(dLon);
double By = Math.cos(lat2) * Math.sin(dLon);
double latitudeMidPoint = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By));
double longitudeMidPoint = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);
return new double[] { Math.toDegrees(longitudeMidPoint), Math.toDegrees(latitudeMidPoint) };
}
/**
* @param lat1
* @param lon1
* @param lat2
* @param lon2
* @return
*/
public static double[] midPoint(String lat1, String lon1, String lat2, String lon2) {
double lat11 = ParseLatLonValue(lat1);
double lon11 = ParseLatLonValue(lon1);
//
double lat22 = ParseLatLonValue(lat2);
double lon22 = ParseLatLonValue(lon2);
return midPoint(lat11, lon11, lat22, lon22);
}
/**
* NOT TESTED YET
* @param lat1
* @param lon1
* @param lat2
* @param lon2
* @return
*/
public static double bearing(double lat1, double lon1, double lat2, double lon2) {
//
double longitude1 = lon1;
double longitude2 = lon2;
double latitude1 = Math.toRadians(lat1);
double latitude2 = Math.toRadians(lat2);
double longDiff = Math.toRadians(longitude2 - longitude1);
double y = Math.sin(longDiff) * Math.cos(latitude2);
double x = Math.cos(latitude1) * Math.sin(latitude2) - Math.sin(latitude1) * Math.cos(latitude2) * Math.cos(longDiff);
return (Math.toDegrees(Math.atan2(y, x)) + 360) % 360;
}
/**
* @param longitude1
* @param longitude2
* @return if first Point is on west side of 2nd point
*/
public static boolean isWest(double longitude1, double longitude2) {
return longitude1 < longitude2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment