android - Representing and comparing geographic locations in Java -
i'm trying figure out how represent geographic locations, , can't seem find relevant classes in se documentation.
i this:
location loca = new location(aa.aaaaaaa, bb.bbbbbbb); //lat/long coordinates location locb = ..... int meters = loca.distanceto(locb);
ideally want android location since of location data sent android devices anyway. understanding contains information accuracy, latitude , speed, useful (but not required).
i have idea of how implement myself, open source alternative save me time.
it extremely helpful if ip/location lookup. guess that's whole other issue.
here method calculate distance between 2 points, taken android location
class small modification. looks little bit complicated--this because uses vincenty's formulae perform iterative calculations on wgs84 ellipsoid:
/** distance between 2 geographic points on earth, in km **/ public static double geodistance(geopoint gp1, geopoint gp2) { // based on http://www.ngs.noaa.gov/pubs_lib/inverse.pdf // using "inverse formula" (section 4) int maxiters = 20; // convert lat/long radians double lat1 = gp1.getlat() * math.pi / 180.0; double lat2 = gp2.getlat() * math.pi / 180.0; double lon1 = gp1.getlon() * math.pi / 180.0; double lon2 = gp2.getlon() * math.pi / 180.0; double = 6378.137; // wgs84 major axis double b = 6356.7523142; // wgs84 semi-major axis double f = (a - b) / a; double asqminusbsqoverbsq = (a * - b * b) / (b * b); double l = lon2 - lon1; double = 0.0; double u1 = math.atan((1.0 - f) * math.tan(lat1)); double u2 = math.atan((1.0 - f) * math.tan(lat2)); double cosu1 = math.cos(u1); double cosu2 = math.cos(u2); double sinu1 = math.sin(u1); double sinu2 = math.sin(u2); double cosu1cosu2 = cosu1 * cosu2; double sinu1sinu2 = sinu1 * sinu2; double sigma = 0.0; double deltasigma = 0.0; double cossqalpha = 0.0; double cos2sm = 0.0; double cossigma = 0.0; double sinsigma = 0.0; double coslambda = 0.0; double sinlambda = 0.0; double lambda = l; // initial guess (int iter = 0; iter < maxiters; iter++) { double lambdaorig = lambda; coslambda = math.cos(lambda); sinlambda = math.sin(lambda); double t1 = cosu2 * sinlambda; double t2 = cosu1 * sinu2 - sinu1 * cosu2 * coslambda; double sinsqsigma = t1 * t1 + t2 * t2; // (14) sinsigma = math.sqrt(sinsqsigma); cossigma = sinu1sinu2 + cosu1cosu2 * coslambda; // (15) sigma = math.atan2(sinsigma, cossigma); // (16) double sinalpha = (sinsigma == 0) ? 0.0 : cosu1cosu2 * sinlambda / sinsigma; // (17) cossqalpha = 1.0 - sinalpha * sinalpha; cos2sm = (cossqalpha == 0) ? 0.0 : cossigma - 2.0 * sinu1sinu2 / cossqalpha; // (18) double usquared = cossqalpha * asqminusbsqoverbsq; // defn = 1 + (usquared / 16384.0) * // (3) (4096.0 + usquared * (-768 + usquared * (320.0 - 175.0 * usquared))); double b = (usquared / 1024.0) * // (4) (256.0 + usquared * (-128.0 + usquared * (74.0 - 47.0 * usquared))); double c = (f / 16.0) * cossqalpha * (4.0 + f * (4.0 - 3.0 * cossqalpha)); // (10) double cos2smsq = cos2sm * cos2sm; deltasigma = b * sinsigma * // (6) (cos2sm + (b / 4.0) * (cossigma * (-1.0 + 2.0 * cos2smsq) - (b / 6.0) * cos2sm * (-3.0 + 4.0 * sinsigma * sinsigma) * (-3.0 + 4.0 * cos2smsq))); lambda = l + (1.0 - c) * f * sinalpha * (sigma + c * sinsigma * (cos2sm + c * cossigma * (-1.0 + 2.0 * cos2sm * cos2sm))); // (11) double delta = (lambda - lambdaorig) / lambda; if (math.abs(delta) < 1.0e-12) { break; } } return b * * (sigma - deltasigma); }
geopoint
class looks following:
/** * immutable point in geo coordinates (latitude, longitude) accuracy in km */ public class geopoint { private final double lat; private final double lon; private final double accuracy; /** * new geo point without accuracy */ public geopoint(double lat, double lon){ this(lat, lon, -1d); } /** * new geo point specified accuracy * @param accuracy accuracy in km */ public geopoint(double lat, double lon, double accuracy){ this.lat = lat; this.lon = lon; this.accuracy = accuracy < 0 ? -1d : accuracy; } public double getlat(){ return this.lat; } public double getlon(){ return this.lon; } /** * @return accuracy in km. if < 0, accuracy not defined */ public double getaccuracy(){ return this.accuracy; } @override public string tostring(){ return "lat = " + this.lat + "; lon = " + this.lon + (this.accuracy < 0 ? "" : ("; accuracy = " + this.accuracy)); } @override public boolean equals(object o) { if (this == o) return true; if (!(o instanceof geopoint) || o == null) return false; geopoint g = (geopoint) o; return g.lat == this.lat && g.lon == this.lon && g.accuracy == this.accuracy; } }
Comments
Post a Comment