如何计算由经纬度指定的两点之间的距离?
为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。
如何计算由经纬度指定的两点之间的距离?
为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。
当前回答
计算距离——尤其是大距离——的主要挑战之一是解释地球的曲率。如果地球是平的,计算两点之间的距离就会像计算直线一样简单!哈弗辛公式包括一个常数(下面是R变量),它表示地球的半径。根据你是用英里还是公里来测量,它分别等于3956英里或6367公里。 基本公式是:
Dlon = lon2 - lon1 dat = lat2 - lat1 = (sin (dlat / 2)) ^ 2 + cos (lat1) * cos (lat2) * (sin (dlon / 2)) ^ 2 C = 2 * atan2(√(a),√(1-a)) distance = R * c(其中R为地球半径) R = 6367公里OR 3956英里
lat1, lon1: The Latitude and Longitude of point 1 (in decimal degrees)
lat2, lon2: The Latitude and Longitude of point 2 (in decimal degrees)
unit: The unit of measurement in which to calculate the results where:
'M' is statute miles (default)
'K' is kilometers
'N' is nautical miles
样本
function distance(lat1, lon1, lat2, lon2, unit) {
try {
var radlat1 = Math.PI * lat1 / 180
var radlat2 = Math.PI * lat2 / 180
var theta = lon1 - lon2
var radtheta = Math.PI * theta / 180
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
dist = Math.acos(dist)
dist = dist * 180 / Math.PI
dist = dist * 60 * 1.1515
if (unit == "K") {
dist = dist * 1.609344
}
if (unit == "N") {
dist = dist * 0.8684
}
return dist
} catch (err) {
console.log(err);
}
}
其他回答
下面是VB的实现。NET,这个实现将根据您传递的Enum值以KM或Miles为单位给您结果。
Public Enum DistanceType
Miles
KiloMeters
End Enum
Public Structure Position
Public Latitude As Double
Public Longitude As Double
End Structure
Public Class Haversine
Public Function Distance(Pos1 As Position,
Pos2 As Position,
DistType As DistanceType) As Double
Dim R As Double = If((DistType = DistanceType.Miles), 3960, 6371)
Dim dLat As Double = Me.toRadian(Pos2.Latitude - Pos1.Latitude)
Dim dLon As Double = Me.toRadian(Pos2.Longitude - Pos1.Longitude)
Dim a As Double = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(Me.toRadian(Pos1.Latitude)) * Math.Cos(Me.toRadian(Pos2.Latitude)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2)
Dim c As Double = 2 * Math.Asin(Math.Min(1, Math.Sqrt(a)))
Dim result As Double = R * c
Return result
End Function
Private Function toRadian(val As Double) As Double
Return (Math.PI / 180) * val
End Function
End Class
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2,units) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
var miles = d / 1.609344;
if ( units == 'km' ) {
return d;
} else {
return miles;
}}
查克的解决方案,也适用于英里。
下面是Erlang实现
lat_lng({Lat1, Lon1}=_Point1, {Lat2, Lon2}=_Point2) ->
P = math:pi() / 180,
R = 6371, % Radius of Earth in KM
A = 0.5 - math:cos((Lat2 - Lat1) * P) / 2 +
math:cos(Lat1 * P) * math:cos(Lat2 * P) * (1 - math:cos((Lon2 - Lon1) * P))/2,
R * 2 * math:asin(math:sqrt(A)).
哈弗辛公式在大多数情况下都是很好的公式,其他答案已经包含了它所以我就不占用空间了。但重要的是要注意,无论使用什么公式(是的,不仅仅是一个)。因为可能的精度范围很大,以及所需的计算时间。公式的选择需要更多的思考,而不是简单的无脑答案。
这个帖子来自nasa的一个人,是我在讨论这些选项时发现的最好的一个
http://www.cs.nyu.edu/visual/home/proj/tiger/gisfaq.html
例如,如果您只是在100英里半径内按距离对行进行排序。地平公式比哈弗辛公式快得多。
HalfPi = 1.5707963;
R = 3956; /* the radius gives you the measurement unit*/
a = HalfPi - latoriginrad;
b = HalfPi - latdestrad;
u = a * a + b * b;
v = - 2 * a * b * cos(longdestrad - longoriginrad);
c = sqrt(abs(u + v));
return R * c;
注意这里只有一个余弦和一个平方根。在哈弗辛公式中有9个。
这个链接可能对你有帮助,因为它详细介绍了使用哈弗辛公式来计算距离。
摘录:
这个脚本计算两点之间的大圆距离 也就是说,在地球表面上的最短距离-使用 “半正矢”公式。
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}