如何计算由经纬度指定的两点之间的距离?
为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。
如何计算由经纬度指定的两点之间的距离?
为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。
当前回答
我通过简化公式来简化计算。
下面是Ruby版本:
include Math
earth_radius_mi = 3959
radians = lambda { |deg| deg * PI / 180 }
coord_radians = lambda { |c| { :lat => radians[c[:lat]], :lng => radians[c[:lng]] } }
# from/to = { :lat => (latitude_in_degrees), :lng => (longitude_in_degrees) }
def haversine_distance(from, to)
from, to = coord_radians[from], coord_radians[to]
cosines_product = cos(to[:lat]) * cos(from[:lat]) * cos(from[:lng] - to[:lng])
sines_product = sin(to[:lat]) * sin(from[:lat])
return earth_radius_mi * acos(cosines_product + sines_product)
end
其他回答
在我的项目中,我需要计算很多点之间的距离,所以我继续尝试优化我在这里找到的代码。平均而言,在不同的浏览器中,我的新实现的运行速度比获得最多好评的答案快2倍。
function distance(lat1, lon1, lat2, lon2) {
var p = 0.017453292519943295; // Math.PI / 180
var c = Math.cos;
var a = 0.5 - c((lat2 - lat1) * p)/2 +
c(lat1 * p) * c(lat2 * p) *
(1 - c((lon2 - lon1) * p))/2;
return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}
您可以在这里使用我的jsPerf并查看结果。
最近我需要在python中做同样的事情,所以这里是一个python实现:
from math import cos, asin, sqrt, pi
def distance(lat1, lon1, lat2, lon2):
p = pi/180
a = 0.5 - cos((lat2-lat1)*p)/2 + cos(lat1*p) * cos(lat2*p) * (1-cos((lon2-lon1)*p))/2
return 12742 * asin(sqrt(a)) #2*R*asin...
为了完整起见:维基百科上的Haversine。
数学有问题,LUA的学位…如果有人知道修复,请清理这段代码!
与此同时,这里有一个Haversine在LUA中的实现(与Redis一起使用!)
function calcDist(lat1, lon1, lat2, lon2)
lat1= lat1*0.0174532925
lat2= lat2*0.0174532925
lon1= lon1*0.0174532925
lon2= lon2*0.0174532925
dlon = lon2-lon1
dlat = lat2-lat1
a = math.pow(math.sin(dlat/2),2) + math.cos(lat1) * math.cos(lat2) * math.pow(math.sin(dlon/2),2)
c = 2 * math.asin(math.sqrt(a))
dist = 6371 * c -- multiply by 0.621371 to convert to miles
return dist
end
干杯!
你也可以使用像geolib这样的模块:
安装方法:
$ npm install geolib
使用方法:
import { getDistance } from 'geolib'
const distance = getDistance(
{ latitude: 51.5103, longitude: 7.49347 },
{ latitude: "51° 31' N", longitude: "7° 28' E" }
)
console.log(distance)
文档: https://www.npmjs.com/package/geolib
在其他答案中,r中的实现是缺失的。
用地质圈包中的distm函数计算两点之间的距离非常简单:
distm(p1, p2, fun = distHaversine)
地点:
p1 = longitude/latitude for point(s)
p2 = longitude/latitude for point(s)
# type of distance calculation
fun = distCosine / distHaversine / distVincentySphere / distVincentyEllipsoid
由于地球不是完美的球形,所以椭球体的文森提公式可能是计算距离的最佳方法。因此,在地质圈包中,您可以使用:
distm(p1, p2, fun = distVincentyEllipsoid)
当然,你不一定要使用geosphere包,你也可以用一个函数来计算以R为基底的距离:
hav.dist <- function(long1, lat1, long2, lat2) {
R <- 6371
diff.long <- (long2 - long1)
diff.lat <- (lat2 - lat1)
a <- sin(diff.lat/2)^2 + cos(lat1) * cos(lat2) * sin(diff.long/2)^2
b <- 2 * asin(pmin(1, sqrt(a)))
d = R * b
return(d)
}
//JAVA
public Double getDistanceBetweenTwoPoints(Double latitude1, Double longitude1, Double latitude2, Double longitude2) {
final int RADIUS_EARTH = 6371;
double dLat = getRad(latitude2 - latitude1);
double dLong = getRad(longitude2 - longitude1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(getRad(latitude1)) * Math.cos(getRad(latitude2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return (RADIUS_EARTH * c) * 1000;
}
private Double getRad(Double x) {
return x * Math.PI / 180;
}