如何计算由经纬度指定的两点之间的距离?

为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。


当前回答

FSharp版本,使用里程:

let radialDistanceHaversine location1 location2 : float = 
                let degreeToRadian degrees = degrees * System.Math.PI / 180.0
                let earthRadius = 3959.0
                let deltaLat = location2.Latitude - location1.Latitude |> degreeToRadian
                let deltaLong = location2.Longitude - location1.Longitude |> degreeToRadian
                let a =
                    (deltaLat / 2.0 |> sin) ** 2.0
                    + (location1.Latitude |> degreeToRadian |> cos)
                    * (location2.Latitude |> degreeToRadian |> cos)
                    * (deltaLong / 2.0 |> sin) ** 2.0
                atan2 (a |> sqrt) (1.0 - a |> sqrt)
                * 2.0
                * earthRadius

其他回答

PIP安装haversine

Python实现

原产地是美国毗连的中心。

from haversine import haversine, Unit
origin = (39.50, 98.35)
paris = (48.8567, 2.3508)
haversine(origin, paris, unit=Unit.MILES)

要得到以千米为单位的答案,只需设置unit= unit。千米(这是默认值)。

这里有一个用PHP http://www.geodatasource.com/developers/php计算距离的好例子:

 function distance($lat1, $lon1, $lat2, $lon2, $unit) {

     $theta = $lon1 - $lon2;
     $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) +  cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
     $dist = acos($dist);
     $dist = rad2deg($dist);
     $miles = $dist * 60 * 1.1515;
     $unit = strtoupper($unit);

     if ($unit == "K") {
         return ($miles * 1.609344);
     } else if ($unit == "N") {
          return ($miles * 0.8684);
     } else {
          return $miles;
     }
 }

要计算球体上两点之间的距离,你需要做大圆计算。

如果你需要将距离重新投影到平面上,MapTools中有许多C/ c++库可以帮助你进行地图投影。要做到这一点,你需要不同坐标系的投影字符串。

你可能还会发现MapWindow是一个可视化点的有用工具。此外,由于它是开源的,它是如何使用project.dll库的有用指南,它似乎是核心的开源投影库。

可能有一个更简单、更正确的解决方案:地球的周长在赤道上是40000公里,在格林威治(或任何经度)周期上约为37000公里。因此:

pythagoras = function (lat1, lon1, lat2, lon2) {
   function sqr(x) {return x * x;}
   function cosDeg(x) {return Math.cos(x * Math.PI / 180.0);}

   var earthCyclePerimeter = 40000000.0 * cosDeg((lat1 + lat2) / 2.0);
   var dx = (lon1 - lon2) * earthCyclePerimeter / 360.0;
   var dy = 37000000.0 * (lat1 - lat2) / 360.0;

   return Math.sqrt(sqr(dx) + sqr(dy));
};

我同意它应该被微调,我自己说过它是一个椭球,所以半径乘以余弦值是不同的。但它更准确一点。与谷歌map相比,误差明显减小。

你可以使用CLLocationDistance中的构建来计算这个:

CLLocation *location1 = [[CLLocation alloc] initWithLatitude:latitude1 longitude:longitude1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:latitude2 longitude:longitude2];
[self distanceInMetersFromLocation:location1 toLocation:location2]

- (int)distanceInMetersFromLocation:(CLLocation*)location1 toLocation:(CLLocation*)location2 {
    CLLocationDistance distanceInMeters = [location1 distanceFromLocation:location2];
    return distanceInMeters;
}

在你的例子中,如果你想要公里,只要除以1000。