如何计算由经纬度指定的两点之间的距离?
为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。
如何计算由经纬度指定的两点之间的距离?
为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。
当前回答
下面是移植到Java的已接受的答案实现,以备任何人需要。
package com.project529.garage.util;
/**
* Mean radius.
*/
private static double EARTH_RADIUS = 6371;
/**
* Returns the distance between two sets of latitudes and longitudes in meters.
* <p/>
* Based from the following JavaScript SO answer:
* http://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula,
* which is based on https://en.wikipedia.org/wiki/Haversine_formula (error rate: ~0.55%).
*/
public double getDistanceBetween(double lat1, double lon1, double lat2, double lon2) {
double dLat = toRadians(lat2 - lat1);
double dLon = toRadians(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = EARTH_RADIUS * c;
return d;
}
public double toRadians(double degrees) {
return degrees * (Math.PI / 180);
}
其他回答
你可以用Haversine公式计算它,它是:
a = sin²(Δφ/2) + cos φ1 ⋅ cos φ2 ⋅ sin²(Δλ/2)
c = 2 ⋅ atan2( √a, √(1−a) )
d = R ⋅ c
下面给出了一个计算两点之间距离的例子
假设我要计算从新德里到伦敦的距离,那么我该如何使用这个公式:
New delhi co-ordinates= 28.7041° N, 77.1025° E
London co-ordinates= 51.5074° N, 0.1278° W
var R = 6371e3; // metres
var φ1 = 28.7041.toRadians();
var φ2 = 51.5074.toRadians();
var Δφ = (51.5074-28.7041).toRadians();
var Δλ = (0.1278-77.1025).toRadians();
var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // metres
d = d/1000; // km
哈弗辛公式在大多数情况下都是很好的公式,其他答案已经包含了它所以我就不占用空间了。但重要的是要注意,无论使用什么公式(是的,不仅仅是一个)。因为可能的精度范围很大,以及所需的计算时间。公式的选择需要更多的思考,而不是简单的无脑答案。
这个帖子来自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个。
如果你想要驾驶距离/路线(张贴在这里,因为这是谷歌上两点之间距离的第一个结果,但对大多数人来说,驾驶距离更有用),你可以使用谷歌地图距离矩阵服务:
getDrivingDistanceBetweenTwoLatLong(origin, destination) {
return new Observable(subscriber => {
let service = new google.maps.DistanceMatrixService();
service.getDistanceMatrix(
{
origins: [new google.maps.LatLng(origin.lat, origin.long)],
destinations: [new google.maps.LatLng(destination.lat, destination.long)],
travelMode: 'DRIVING'
}, (response, status) => {
if (status !== google.maps.DistanceMatrixStatus.OK) {
console.log('Error:', status);
subscriber.error({error: status, status: status});
} else {
console.log(response);
try {
let valueInMeters = response.rows[0].elements[0].distance.value;
let valueInKms = valueInMeters / 1000;
subscriber.next(valueInKms);
subscriber.complete();
}
catch(error) {
subscriber.error({error: error, status: status});
}
}
});
});
}
function distance($lat1, $lon1, $lat2, $lon2) {
$pi80 = M_PI / 180;
$lat1 *= $pi80; $lon1 *= $pi80; $lat2 *= $pi80; $lon2 *= $pi80;
$dlat = $lat2 - $lat1;
$dlon = $lon2 - $lon1;
$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlon / 2) * sin($dlon / 2);
$km = 6372.797 * 2 * atan2(sqrt($a), sqrt(1 - $a));
return $km;
}
在我的项目中,我需要计算很多点之间的距离,所以我继续尝试优化我在这里找到的代码。平均而言,在不同的浏览器中,我的新实现的运行速度比获得最多好评的答案快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。