2014-11-14 2 views
1

Посмотрите на этом примере:интеллектуального расстояние вычисления между двумя точками гео в андроиде

public void start(){ 

    //... 

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, TEN_SECONDS, TEN_METERS, this); 
} 


@Override 
public void onLocationChanged(Location location) { 

    if(location.distanceTo(_lastLocation) > TEN_KM_IN_METERS){ 
     actionA(location); 
     _lastLocation = location; 
    } else { 
     actionB(location); 
    } 

} 

Реализация Location#distanceTo(l) является довольно сложной и ресурсоемким. Поэтому я не хочу вызывать эту операцию при каждом обновлении местоположения.

Вопрос: стоит ли надлежащим образом, чтобы избежать ненужныхLocation#distanceTo(l)звонки

Что я пытался до сих пор. По Wiki - Decimal degrees я сделать это таким образом:

private boolean closeTogether(Location a, Location b) { 

    double changeLat = Math.abs(a.getLatitude() - b.getLatitude()); 

    final float myNaiveMax = 0.005; 

    if (changeLat > myNaiveMax) { 
     return false; 
    } 

    double changeLon = Math.abs(a.getLongitude() - b.getLongitude()); 

    if (changeLon > myNaiveMax) { 
     return false; 
    } 

    return true; 
} 

@Override 
public void onLocationChanged(Location location) { 

    if(!closeTogether(location, _lastLocation) && location.distanceTo(_lastLocation) > TEN_KM_IN_METERS){ 
     actionA(location); 
     _lastLocation = location; 
    } else { 
     actionB(location); 
    } 

} 

ответ

2

Я нашел, что Haversine formula очень хорошо для этого. Хорошо работает для моего приложения отслеживания доставки. Вот как я рассчитываю расстояние между двумя точками. Если вы начали :)

/** 
* getDistanceBetweenTwoPoints 
* @param p1 - First point 
* @param p2 - Second point 
* @return distance between the two specified points (as the crow flys) 
*/ 
public static double getDistanceBetweenTwoPoints(PointF p1, PointF p2) { 
    double R = 6371000; // Earth radius 
    double dLat = Math.toRadians(p2.x - p1.x); 
    double dLon = Math.toRadians(p2.y - p1.y); 
    double lat1 = Math.toRadians(p1.x); 
    double lat2 = Math.toRadians(p2.x); 

    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.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
    double d = R * c; 

    return d; 
} 

Редактировать И еще

public static PointF calculateDerivedPosition(PointF point, 
     double range, double bearing) 
{ 
    double EarthRadius = 6371000; // m 

    double latA = Math.toRadians(point.x); 
    double lonA = Math.toRadians(point.y); 
    double angularDistance = range/EarthRadius; 
    double trueCourse = Math.toRadians(bearing); 

    double lat = Math.asin(Math.sin(latA) * Math.cos(angularDistance) + 
      Math.cos(latA) * Math.sin(angularDistance) * Math.cos(trueCourse)); 

    double dlon = Math.atan2(Math.sin(trueCourse) * Math.sin(angularDistance) * Math.cos(latA), 
      Math.cos(angularDistance) - Math.sin(latA) * Math.sin(lat)); 

    double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI; 

    lat = Math.toDegrees(lat); 
    lon = Math.toDegrees(lon); 

    PointF newPoint = new PointF((float) lat, (float) lon); 

    return newPoint; 

} 
+0

благодаря спариванию, именно то, что мне было нужно –