android中两个地理位置之间的智能计算距离

时间:2014-11-14 15:45:33

标签: android geolocation battery-saver

看看这个例子:

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)的实现非常复杂且占用大量CPU资源。所以我不想在每个位置更新上调用此操作。

问题:是否有任何正确的方法可以避免不必要的 Location#distanceTo(l) 来电

到目前为止我尝试了什么。根据{{​​3}}我这样做:

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

}

1 个答案:

答案 0 :(得分: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;

}