计算两个地理位置之间的距离

86

请帮忙解决这个问题。

现在我有两个数组,分别包含附近地点的纬度和经度,以及用户位置的纬度和经度,现在我想计算用户位置与附近地点之间的距离,并在列表视图中显示它们。

我知道有一种计算距离的方法:

public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results);

现在的问题是如何在这个方法中传递这两个具有附近纬度和经度的数组,并获取距离数组。


请查看此链接:https://dev59.com/z1bTa4cB1Zd3GeqP-m5t#5739789希望这能对您有所帮助。 - Dinesh Sharma
谢谢您的回复,但我想使用上述方法来计算距离。 - Sunny
请澄清,从技术上讲,您只给了我们一个方法签名,这并不足以知道方法文档在哪里可以找到。尝试添加包含类的信息。 - Marmoy
停止使用distanceTo,因为它返回错误的值:http://stackoverflow.com/questions/30664031/stop-using-distanceto-of-location-it-retourns-wrong-values - Karamsa
@Karamsa,但是在你的链接中描述它是正常工作的。 - CoolMind
Google Distance Matrix API是计算两个地理位置之间距离的正确选择吗? - K Pradeep Kumar Reddy
8个回答

211

http://developer.android.com/reference/android/location/Location.html

查看 distanceTo 方法:

返回此位置和给定位置之间的大约距离(以米为单位)。 距离使用 WGS84 椭球体定义。

或者使用 distanceBetween 方法:

计算两个位置之间的大约距离(以米为单位),以及它们之间最短路径的初始和终止方位角。距离和方位角使用 WGS84 椭球体定义。

您可以通过经度和纬度创建一个 Location 对象:

Location locationA = new Location("point A");

locationA.setLatitude(latA);
locationA.setLongitude(lngA);

Location locationB = new Location("point B");

locationB.setLatitude(latB);
locationB.setLongitude(lngB);

float distance = locationA.distanceTo(locationB);
或者
private double meterDistanceBetweenPoints(float lat_a, float lng_a, float lat_b, float lng_b) {
    float pk = (float) (180.f/Math.PI);

    float a1 = lat_a / pk;
    float a2 = lng_a / pk;
    float b1 = lat_b / pk;
    float b2 = lng_b / pk;

    double t1 = Math.cos(a1) * Math.cos(a2) * Math.cos(b1) * Math.cos(b2);
    double t2 = Math.cos(a1) * Math.sin(a2) * Math.cos(b1) * Math.sin(b2);
    double t3 = Math.sin(a1) * Math.sin(b1);
    double tt = Math.acos(t1 + t2 + t3);
   
    return 6366000 * tt;
}

3
不,它返回位移(两点之间的最短距离)。 - Zeeshan Chaudhry
2
小错误,这不是圆周率...应该是3.14159或使用Math.PI(还有Math类而不是弃用的FloatMath)。57个赞,没人注意到吗?:D - snachmsm
有人能确认一下 locationA.distanceTo(locationB) 是否考虑了海拔高度吗? - Squirrel5853
2
第二个代码块是用来干什么的?为什么不直接使用 Location.distanceBetween() - spaaarky21
使用Google Distance Matrix API计算距离和使用上述代码计算距离有什么区别? - K Pradeep Kumar Reddy
显示剩余4条评论

18

尝试这段代码。在这里我们有两个经纬度值并且选定的位置.distanceTo(附近的位置)函数返回这些位置之间的距离(以米为单位)。

Location selected_location = new Location("locationA");
            selected_location.setLatitude(17.372102);
            selected_location.setLongitude(78.484196);
Location near_locations = new Location("locationB");
            near_locations.setLatitude(17.375775);
            near_locations.setLongitude(78.469218);
double distance = selected_location.distanceTo(near_locations);

这里的 "distance" 是位置A和位置B之间的距离(以为单位)


3
    private static Double _MilesToKilometers = 1.609344;
    private static Double _MilesToNautical = 0.8684;


    /// <summary>
    /// Calculates the distance between two points of latitude and longitude.
    /// Great Link - http://www.movable-type.co.uk/scripts/latlong.html
    /// </summary>
    /// <param name="coordinate1">First coordinate.</param>
    /// <param name="coordinate2">Second coordinate.</param>
    /// <param name="unitsOfLength">Sets the return value unit of length.</param>
    public static Double Distance(Coordinate coordinate1, Coordinate coordinate2, UnitsOfLength unitsOfLength)
    {

        double theta = coordinate1.getLongitude() - coordinate2.getLongitude();
        double distance = Math.sin(ToRadian(coordinate1.getLatitude())) * Math.sin(ToRadian(coordinate2.getLatitude())) +
                       Math.cos(ToRadian(coordinate1.getLatitude())) * Math.cos(ToRadian(coordinate2.getLatitude())) *
                       Math.cos(ToRadian(theta));

        distance = Math.acos(distance);
        distance = ToDegree(distance);
        distance = distance * 60 * 1.1515;

        if (unitsOfLength == UnitsOfLength.Kilometer)
            distance = distance * _MilesToKilometers;
        else if (unitsOfLength == UnitsOfLength.NauticalMiles)
            distance = distance * _MilesToNautical;

        return (distance);

    }

3

只有一个用户位置,所以您可以迭代附近地点列表并调用 distanceTo() 函数以获取距离,如果愿意,可以将其存储在数组中。

据我了解,distanceBetween() 用于远距离地点,其输出是WGS84椭球体。


你能否建议哪一个提供了准确的距离? - Paresh Mayani

1

distanceTo将给出两个给定位置之间的距离(以米为单位),例如target.distanceTo(destination)。

distanceBetween也会给出距离,但它将在float数组中存储距离(results[0])。文档说,如果results的长度大于等于2,则初始方位角存储在results[1]中。如果results的长度大于等于3,则最终方位角存储在results[2]中。

希望这可以帮助你。

我使用distanceTo来获取从点A到B的距离,我认为这是正确的方法。


什么是轴承? - Houman

0
public double distance(Double latitude, Double longitude, double e, double f) {
        double d2r = Math.PI / 180;

        double dlong = (longitude - f) * d2r;
        double dlat = (latitude - e) * d2r;
        double a = Math.pow(Math.sin(dlat / 2.0), 2) + Math.cos(e * d2r)
                * Math.cos(latitude * d2r) * Math.pow(Math.sin(dlong / 2.0), 2)
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double d = 6367 * c;
                return d;

    }

0
我想要自己实现这个,结果我阅读了维基百科上大圆距离公式页面,因为没有任何代码是足够可读的作为基础来使用。
C# 示例
    /// <summary>
    /// Calculates the distance between two locations using the Great Circle Distance algorithm
    /// <see cref="https://en.wikipedia.org/wiki/Great-circle_distance"/>
    /// </summary>
    /// <param name="first"></param>
    /// <param name="second"></param>
    /// <returns></returns>
    private static double DistanceBetween(GeoLocation first, GeoLocation second)
    {
        double longitudeDifferenceInRadians = Math.Abs(ToRadians(first.Longitude) - ToRadians(second.Longitude));

        double centralAngleBetweenLocationsInRadians = Math.Acos(
            Math.Sin(ToRadians(first.Latitude)) * Math.Sin(ToRadians(second.Latitude)) +
            Math.Cos(ToRadians(first.Latitude)) * Math.Cos(ToRadians(second.Latitude)) *
            Math.Cos(longitudeDifferenceInRadians));

        const double earthRadiusInMeters = 6357 * 1000;

        return earthRadiusInMeters * centralAngleBetweenLocationsInRadians;
    }

    private static double ToRadians(double degrees)
    {
        return degrees * Math.PI / 180;
    }

0

只需使用 .distanceTo 方法。 例如:

private fun getDistance(locationA:Location, locationB:Location){

    val distance = locationA.distanceTo(locationB)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接