Updated Compat library and cleaned up code
Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
This commit is contained in:
@@ -35,72 +35,72 @@ import com.google.android.maps.MapView;
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public class GeoUtils {
|
||||
|
||||
|
||||
public static final int EARTH_RADIUS_KM = 6371;
|
||||
public static final double MILLION = 1000000;
|
||||
|
||||
/**
|
||||
* Calculates the bearing from the user location to the destination location, or returns the bearing for north if there is no destination.
|
||||
* This method is awesome for making a compass point toward the destination rather than North.
|
||||
* @param user location
|
||||
* @param dest location
|
||||
* @param bearing Degrees East from compass
|
||||
* @return Degrees East of dest location
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public static final double MILLION = 1000000;
|
||||
|
||||
/**
|
||||
* computes the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East
|
||||
* @param lat1 source lat
|
||||
* @param lon1 source lon
|
||||
* @param lat2 destination lat
|
||||
* @param lon2 destination lon
|
||||
* @return the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East of true north
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static double bearing(final double lat1, final double lon1, final double lat2, final double lon2) {
|
||||
final double lat1Rad = Math.toRadians(lat1);
|
||||
final double lat2Rad = Math.toRadians(lat2);
|
||||
final double deltaLonRad = Math.toRadians(lon2 - lon1);
|
||||
final double y = Math.sin(deltaLonRad) * Math.cos(lat2Rad);
|
||||
final double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) - Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad);
|
||||
return radToBearing(Math.atan2(y, x));
|
||||
}
|
||||
|
||||
/**
|
||||
* computes the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East of true north
|
||||
* @param p1 source geopoint
|
||||
* @param p2 destination geopoint
|
||||
* @return the bearing of p2 in relationship from p1 in degrees East
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static Double bearing(final GeoPoint p1, final GeoPoint p2) {
|
||||
final double lat1 = p1.getLatitudeE6() / MILLION;
|
||||
final double lon1 = p1.getLongitudeE6() / MILLION;
|
||||
final double lat2 = p2.getLatitudeE6() / MILLION;
|
||||
final double lon2 = p2.getLongitudeE6() / MILLION;
|
||||
return bearing(lat1, lon1, lat2, lon2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the bearing from the user location to the destination location, or returns the bearing for north if there is no destination.
|
||||
* This method is awesome for making a compass point toward the destination rather than North.
|
||||
* @param user location
|
||||
* @param dest location
|
||||
* @param bearing Degrees East from compass
|
||||
* @return Degrees East of dest location
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public static float calculateBearing(final GeoPoint user, final GeoPoint dest, float bearing) {
|
||||
|
||||
if( (user == null) || (dest == null) )
|
||||
|
||||
if( user == null || dest == null )
|
||||
return bearing;
|
||||
|
||||
float heading = bearing(user, dest).floatValue();
|
||||
|
||||
bearing = (360 - heading) + bearing;
|
||||
|
||||
|
||||
final float heading = bearing(user, dest).floatValue();
|
||||
|
||||
bearing = 360 - heading + bearing;
|
||||
|
||||
if (bearing > 360)
|
||||
return bearing - 360;
|
||||
|
||||
|
||||
return bearing;
|
||||
}
|
||||
|
||||
/**
|
||||
* computes the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East
|
||||
* @param lat1 source lat
|
||||
* @param lon1 source lon
|
||||
* @param lat2 destination lat
|
||||
* @param lon2 destination lon
|
||||
* @return the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East of true north
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static double bearing(final double lat1, final double lon1, final double lat2, final double lon2) {
|
||||
double lat1Rad = Math.toRadians(lat1);
|
||||
double lat2Rad = Math.toRadians(lat2);
|
||||
double deltaLonRad = Math.toRadians(lon2 - lon1);
|
||||
double y = Math.sin(deltaLonRad) * Math.cos(lat2Rad);
|
||||
double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) - Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad);
|
||||
return radToBearing(Math.atan2(y, x));
|
||||
}
|
||||
|
||||
/**
|
||||
* computes the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East of true north
|
||||
* @param p1 source geopoint
|
||||
* @param p2 destination geopoint
|
||||
* @return the bearing of p2 in relationship from p1 in degrees East
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static Double bearing(final GeoPoint p1, final GeoPoint p2) {
|
||||
double lat1 = p1.getLatitudeE6() / MILLION;
|
||||
double lon1 = p1.getLongitudeE6() / MILLION;
|
||||
double lat2 = p2.getLatitudeE6() / MILLION;
|
||||
double lon2 = p2.getLongitudeE6() / MILLION;
|
||||
return bearing(lat1, lon1, lat2, lon2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a geopoint x meters away of the geopoint supplied. The new geopoint
|
||||
/**
|
||||
* Calculates a geopoint x meters away of the geopoint supplied. The new geopoint
|
||||
* shares the same latitude as geopoint point, this way they are on the same latitude arc.
|
||||
*
|
||||
* @param point central geopoint
|
||||
* @param point central geopoint
|
||||
* @param distance in meters from the geopoint
|
||||
* @return geopoint that is x meters away from the geopoint supplied
|
||||
* @author ricky barrette
|
||||
@@ -108,11 +108,11 @@ public class GeoUtils {
|
||||
public static GeoPoint distanceFrom(final GeoPoint point, double distance){
|
||||
//convert meters into kilometers
|
||||
distance = distance / 1000;
|
||||
|
||||
|
||||
// convert lat and lon of geopoint to radians
|
||||
double lat1Rad = Math.toRadians((point.getLatitudeE6() / 1e6));
|
||||
double lon1Rad = Math.toRadians((point.getLongitudeE6() / 1e6));
|
||||
|
||||
final double lat1Rad = Math.toRadians(point.getLatitudeE6() / 1e6);
|
||||
final double lon1Rad = Math.toRadians(point.getLongitudeE6() / 1e6);
|
||||
|
||||
/*
|
||||
* kilometers = acos(sin(lat1Rad)sin(lat2Rad)+cos(lat1Rad)cos(lat2Rad)cos(lon2Rad-lon1Rad)6371
|
||||
*
|
||||
@@ -123,36 +123,55 @@ public class GeoUtils {
|
||||
* NOTE: sec(x) = 1/cos(x)
|
||||
*
|
||||
* NOTE: that lat2Rad is = lat1Rad because we want to keep the new geopoint on the same lat arc
|
||||
* therefore i saw no need to create a new variable for lat2Rad,
|
||||
* therefore i saw no need to create a new variable for lat2Rad,
|
||||
* and simply inputed lat1Rad in place of lat2Rad in the equation
|
||||
*
|
||||
* NOTE: this equation has be tested in the field against another gps device, and the distanceKm() from google
|
||||
* and has been proven to be damn close
|
||||
*/
|
||||
double lon2Rad = lon1Rad + Math.acos( Math.cos((distance/6371)) * (1 / Math.cos(lat1Rad))
|
||||
* (1 / Math.cos(lat1Rad)) - Math.tan(lat1Rad) * Math.tan(lat1Rad));
|
||||
|
||||
final double lon2Rad = lon1Rad + Math.acos( Math.cos(distance/6371) * (1 / Math.cos(lat1Rad))
|
||||
* (1 / Math.cos(lat1Rad)) - Math.tan(lat1Rad) * Math.tan(lat1Rad));
|
||||
|
||||
//return a geopoint that is x meters away from the geopoint supplied
|
||||
return new GeoPoint(point.getLatitudeE6(), (int) (Math.toDegrees(lon2Rad) * 1e6));
|
||||
}
|
||||
|
||||
/**
|
||||
* computes the distance between to lat1/lon1 and lat2/lon2 based on the curve of the earth
|
||||
* @param lat1 source lat
|
||||
* @param lon1 source lon
|
||||
* @param lat2 destination lat
|
||||
* @param lon2 destination lon
|
||||
* @return the distance between to lat1/lon1 and lat2/lon2
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static double distanceKm(final double lat1, final double lon1, final double lat2, final double lon2) {
|
||||
double lat1Rad = Math.toRadians(lat1);
|
||||
double lat2Rad = Math.toRadians(lat2);
|
||||
double deltaLonRad = Math.toRadians(lon2 - lon1);
|
||||
return Math.acos(Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad)) * EARTH_RADIUS_KM;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* computes the distance between to lat1/lon1 and lat2/lon2 based on the curve of the earth
|
||||
* @param lat1 source lat
|
||||
* @param lon1 source lon
|
||||
* @param lat2 destination lat
|
||||
* @param lon2 destination lon
|
||||
* @return the distance between to lat1/lon1 and lat2/lon2
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static double distanceKm(final double lat1, final double lon1, final double lat2, final double lon2) {
|
||||
final double lat1Rad = Math.toRadians(lat1);
|
||||
final double lat2Rad = Math.toRadians(lat2);
|
||||
final double deltaLonRad = Math.toRadians(lon2 - lon1);
|
||||
return Math.acos(Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad)) * EARTH_RADIUS_KM;
|
||||
}
|
||||
|
||||
/**
|
||||
* computes the distance between to p1 and p2 based on the curve of the earth
|
||||
* @param p1
|
||||
* @param p2
|
||||
* @return the distance between to p1 and p2
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static double distanceKm(final GeoPoint p1, final GeoPoint p2) {
|
||||
//if we are handed a null, return -1 so we don't break
|
||||
if(p1 == null || p2 == null)
|
||||
return -1;
|
||||
|
||||
final double lat1 = p1.getLatitudeE6() / MILLION;
|
||||
final double lon1 = p1.getLongitudeE6() / MILLION;
|
||||
final double lat2 = p2.getLatitudeE6() / MILLION;
|
||||
final double lon2 = p2.getLongitudeE6() / MILLION;
|
||||
return distanceKm(lat1, lon1, lat2, lon2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts distance into a human readbale string
|
||||
* @param distance in kilometers
|
||||
* @param returnMetric true if metric, false for US
|
||||
@@ -160,8 +179,8 @@ public class GeoUtils {
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public static String distanceToString(double distance, final boolean returnMetric) {
|
||||
DecimalFormat threeDForm = new DecimalFormat("#.###");
|
||||
DecimalFormat twoDForm = new DecimalFormat("#.##");
|
||||
final DecimalFormat threeDForm = new DecimalFormat("#.###");
|
||||
final DecimalFormat twoDForm = new DecimalFormat("#.##");
|
||||
|
||||
if (returnMetric) {
|
||||
if (distance < 1) {
|
||||
@@ -177,12 +196,12 @@ public class GeoUtils {
|
||||
}
|
||||
return twoDForm.format(distance) + " mi";
|
||||
}
|
||||
|
||||
/**
|
||||
* a convince method for testing if 2 circles on the the surface of the earth intersect.
|
||||
* we will use this method to test if the users accuracy circle intersects a marked locaton's radius
|
||||
|
||||
/**
|
||||
* a convince method for testing if 2 circles on the the surface of the earth intersect.
|
||||
* we will use this method to test if the users accuracy circle intersects a marked locaton's radius
|
||||
* if ( (accuracyCircleRadius + locationRadius) - fudgeFactor) > acos(sin(lat1Rad)sin(lat2Rad)+cos(lat1Rad)cos(lat2Rad)cos(lon2Rad-lon1Rad)6371
|
||||
* @param userPoint
|
||||
* @param userPoint
|
||||
* @param accuracyRadius in KM
|
||||
* @param locationPoint
|
||||
* @param locationRadius in KM
|
||||
@@ -191,31 +210,12 @@ public class GeoUtils {
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public static boolean isIntersecting(final GeoPoint userPoint, final float accuracyRadius, final GeoPoint locationPoint, final float locationRadius, final float fudgeFactor){
|
||||
if(((accuracyRadius + locationRadius) - fudgeFactor) > distanceKm(locationPoint, userPoint))
|
||||
if(accuracyRadius + locationRadius - fudgeFactor > distanceKm(locationPoint, userPoint))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* computes the distance between to p1 and p2 based on the curve of the earth
|
||||
* @param p1
|
||||
* @param p2
|
||||
* @return the distance between to p1 and p2
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static double distanceKm(final GeoPoint p1, final GeoPoint p2) {
|
||||
//if we are handed a null, return -1 so we don't break
|
||||
if(p1 == null || p2 == null)
|
||||
return -1;
|
||||
|
||||
double lat1 = p1.getLatitudeE6() / MILLION;
|
||||
double lon1 = p1.getLongitudeE6() / MILLION;
|
||||
double lat2 = p2.getLatitudeE6() / MILLION;
|
||||
double lon2 = p2.getLongitudeE6() / MILLION;
|
||||
return distanceKm(lat1, lon1, lat2, lon2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* determines when the specified point is off the map
|
||||
* @param point
|
||||
* @return true is the point is off the map
|
||||
@@ -226,58 +226,57 @@ public class GeoUtils {
|
||||
return false;
|
||||
if (point == null)
|
||||
return false;
|
||||
GeoPoint center = map.getMapCenter();
|
||||
double distance = GeoUtils.distanceKm(center, point);
|
||||
double distanceLat = GeoUtils.distanceKm(center, new GeoPoint((center.getLatitudeE6() + (int) (map.getLatitudeSpan() / 2)), center.getLongitudeE6()));
|
||||
double distanceLon = GeoUtils.distanceKm(center, new GeoPoint(center.getLatitudeE6(), (center.getLongitudeE6() + (int) (map.getLongitudeSpan() / 2))));
|
||||
if (distance > distanceLat || distance > distanceLon){
|
||||
return true;
|
||||
}
|
||||
final GeoPoint center = map.getMapCenter();
|
||||
final double distance = GeoUtils.distanceKm(center, point);
|
||||
final double distanceLat = GeoUtils.distanceKm(center, new GeoPoint(center.getLatitudeE6() + map.getLatitudeSpan() / 2, center.getLongitudeE6()));
|
||||
final double distanceLon = GeoUtils.distanceKm(center, new GeoPoint(center.getLatitudeE6(), center.getLongitudeE6() + map.getLongitudeSpan() / 2));
|
||||
if (distance > distanceLat || distance > distanceLon)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* computes a geopoint the is the central geopoint between p1 and p1
|
||||
* @param p1 first geopoint
|
||||
* @param p2 second geopoint
|
||||
* @return a MidPoint object
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public static MidPoint midPoint(final GeoPoint p1, final GeoPoint p2) {
|
||||
int minLatitude = (int)(+81 * 1E6);
|
||||
int maxLatitude = (int)(-81 * 1E6);
|
||||
int minLongitude = (int)(+181 * 1E6);
|
||||
int maxLongitude = (int)(-181 * 1E6);
|
||||
List<Point> mPoints = new ArrayList<Point>();
|
||||
int latitude = p1.getLatitudeE6();
|
||||
int longitude = p1.getLongitudeE6();
|
||||
if (latitude != 0 && longitude !=0) {
|
||||
minLatitude = (minLatitude > latitude) ? latitude : minLatitude;
|
||||
maxLatitude = (maxLatitude < latitude) ? latitude : maxLatitude;
|
||||
minLongitude = (minLongitude > longitude) ? longitude : minLongitude;
|
||||
maxLongitude = (maxLongitude < longitude) ? longitude : maxLongitude;
|
||||
mPoints.add(new Point(latitude, longitude));
|
||||
}
|
||||
|
||||
latitude = p2.getLatitudeE6();
|
||||
longitude = p2.getLongitudeE6();
|
||||
if (latitude != 0 && longitude !=0) {
|
||||
minLatitude = (minLatitude > latitude) ? latitude : minLatitude;
|
||||
maxLatitude = (maxLatitude < latitude) ? latitude : maxLatitude;
|
||||
minLongitude = (minLongitude > longitude) ? longitude : minLongitude;
|
||||
maxLongitude = (maxLongitude < longitude) ? longitude : maxLongitude;
|
||||
mPoints.add(new Point(latitude, longitude));
|
||||
}
|
||||
return new MidPoint(new GeoPoint((maxLatitude + minLatitude)/2, (maxLongitude + minLongitude)/2 ), minLatitude, minLongitude, maxLatitude, maxLongitude);
|
||||
}
|
||||
|
||||
/**
|
||||
* converts radians to bearing
|
||||
* @param rad
|
||||
* @return bearing
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static double radToBearing(final double rad) {
|
||||
return (Math.toDegrees(rad) + 360) % 360;
|
||||
}
|
||||
|
||||
/**
|
||||
* computes a geopoint the is the central geopoint between p1 and p1
|
||||
* @param p1 first geopoint
|
||||
* @param p2 second geopoint
|
||||
* @return a MidPoint object
|
||||
* @author ricky barrette
|
||||
*/
|
||||
public static MidPoint midPoint(final GeoPoint p1, final GeoPoint p2) {
|
||||
int minLatitude = (int)(+81 * 1E6);
|
||||
int maxLatitude = (int)(-81 * 1E6);
|
||||
int minLongitude = (int)(+181 * 1E6);
|
||||
int maxLongitude = (int)(-181 * 1E6);
|
||||
final List<Point> mPoints = new ArrayList<Point>();
|
||||
int latitude = p1.getLatitudeE6();
|
||||
int longitude = p1.getLongitudeE6();
|
||||
if (latitude != 0 && longitude !=0) {
|
||||
minLatitude = minLatitude > latitude ? latitude : minLatitude;
|
||||
maxLatitude = maxLatitude < latitude ? latitude : maxLatitude;
|
||||
minLongitude = minLongitude > longitude ? longitude : minLongitude;
|
||||
maxLongitude = maxLongitude < longitude ? longitude : maxLongitude;
|
||||
mPoints.add(new Point(latitude, longitude));
|
||||
}
|
||||
|
||||
latitude = p2.getLatitudeE6();
|
||||
longitude = p2.getLongitudeE6();
|
||||
if (latitude != 0 && longitude !=0) {
|
||||
minLatitude = minLatitude > latitude ? latitude : minLatitude;
|
||||
maxLatitude = maxLatitude < latitude ? latitude : maxLatitude;
|
||||
minLongitude = minLongitude > longitude ? longitude : minLongitude;
|
||||
maxLongitude = maxLongitude < longitude ? longitude : maxLongitude;
|
||||
mPoints.add(new Point(latitude, longitude));
|
||||
}
|
||||
return new MidPoint(new GeoPoint((maxLatitude + minLatitude)/2, (maxLongitude + minLongitude)/2 ), minLatitude, minLongitude, maxLatitude, maxLongitude);
|
||||
}
|
||||
|
||||
/**
|
||||
* converts radians to bearing
|
||||
* @param rad
|
||||
* @return bearing
|
||||
* @author Google Inc.
|
||||
*/
|
||||
public static double radToBearing(final double rad) {
|
||||
return (Math.toDegrees(rad) + 360) % 360;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user