计算两个GeoLocation之间的距离

时间:2015-06-15 09:43:43

标签: java geolocation distance

我正在尝试计算两个地理位置之间的距离。我遇到的问题如下:我尝试使用像Geocalc 和Haversine公式这样的库,如下所示:

public static final double RKilometers = 6371;

public static double calculationByDistance(double lat1, double lon1, double lat2, double lon2) {
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lon2 - lon1);
    lat1 = Math.toRadians(lat1);
    lat2 = Math.toRadians(lat2);

    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.asin(Math.sqrt(a));
    return RKilometers * c;
}

但是我对所有这些选项都得到了相同的错误值。对于短距离它可以很好地工作,但是对于长距离它不会。

这是我做的测试:

//distance between Barrow Island(Australia) and Tavatave(Madagascar)
assertEquals(calculationByDistance(20.82, 115.4, 18.15, 49.4), 6885, 20);
//get 6875.965169284442

//here is the problem
//distance between Rio Grande and Glasgow
assertEquals(calculationByDistance(32.05, 52.11, 55.83, 4.25), 10744, 20);
//get 4522.502442756569

有人知道我的错误在哪里吗?谢谢!

4 个答案:

答案 0 :(得分:2)

我很久以前就有这个代码,我甚至不记得我是自己写的还是从某人那里得到的。据我记得它给出了一个很好的估计,你可以尝试一下,看看它是否适合你。 (欢迎编辑)

public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
        double earthRadius = 3958.75;  //this is in miles I believe
        double dLat = Math.toRadians(lat2-lat1);
        double dLng = Math.toRadians(lng2-lng1);
        double sindLat = Math.sin(dLat / 2);
        double sindLng = Math.sin(dLng / 2);
        double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
                * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        double dist = earthRadius * c;

        return dist;
}

答案 1 :(得分:1)

我发现了错误。问题是纬度和纵向的值是错误的。我从Wolframalpha那里获取数据,他们没有显示价值观的迹象。我的测试的权利值是:

assertEquals(calculationByDistance(-32.05, 52.11, 55.83, -4.25), 10744, 20); 

感谢您的时间!!!抱歉这个愚蠢的错误:)

答案 2 :(得分:1)

public static float distFrom(float lat1, float lng1, float lat2, float lng2) 
{
    // Earth Radius in meters

    double earthRadius = 6371000; 
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
               Math.cos(Math.toRadians(lat1)) *
               Math.cos(Math.toRadians(lat2)) *
               Math.sin(dLng/2) * Math.sin(dLng/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    float dist = (float) (earthRadius * c);

    System.out.println("Distance is : " + dist);
    return dist; // distance in meters
}

答案 3 :(得分:0)

很难向您推荐任何代码段或现有工具和服务。仅仅因为计算距离取决于某项任务。地图投影和相应的公式有很多种。

例如,如果您使用Google地图,则可以考虑高度差异进行更精确的计算。例如,OpenStreetMap不提供(至少几年前)任何高度信息,因此您的精度可能会有所不同(比较使用OpenStreetMap为东欧和旧金山的城市提供的精确度) ,例如)。

我对https://code.google.com/p/simplelatlng/感到满意。它非常简单,使您无需编写样板代码。

对于长距离,特定的Web服务可以做得很好(特别是当服务聚合来自其他几个服务的数据时)。