如何计算由经纬度指定的两点之间的距离?
为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。
如何计算由经纬度指定的两点之间的距离?
为了澄清,我想用千米来表示距离;这些点使用WGS84系统,我想了解可用方法的相对准确性。
当前回答
下面是一个Scala实现:
def calculateHaversineDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double = {
val long2 = lon2 * math.Pi / 180
val lat2 = lat2 * math.Pi / 180
val long1 = lon1 * math.Pi / 180
val lat1 = lat1 * math.Pi / 180
val dlon = long2 - long1
val dlat = lat2 - lat1
val a = math.pow(math.sin(dlat / 2), 2) + math.cos(lat1) * math.cos(lat2) * math.pow(math.sin(dlon / 2), 2)
val c = 2 * math.atan2(Math.sqrt(a), math.sqrt(1 - a))
val haversineDistance = 3961 * c // 3961 = radius of earth in miles
haversineDistance
}
其他回答
下面是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
下面是Haversine公式的typescript实现
static getDistanceFromLatLonInKm(lat1: number, lon1: number, lat2: number, lon2: number): number {
var deg2Rad = deg => {
return deg * Math.PI / 180;
}
var r = 6371; // Radius of the earth in km
var dLat = deg2Rad(lat2 - lat1);
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;
}
如果你正在使用python; PIP安装地质
from geopy.distance import geodesic
origin = (30.172705, 31.526725) # (latitude, longitude) don't confuse
destination = (30.288281, 31.732326)
print(geodesic(origin, destination).meters) # 23576.805481751613
print(geodesic(origin, destination).kilometers) # 23.576805481751613
print(geodesic(origin, destination).miles) # 14.64994773134371
这是一个简单的PHP函数,它将给出一个非常合理的近似值(误差小于+/-1%)。
<?php
function distance($lat1, $lon1, $lat2, $lon2) {
$pi80 = M_PI / 180;
$lat1 *= $pi80;
$lon1 *= $pi80;
$lat2 *= $pi80;
$lon2 *= $pi80;
$r = 6372.797; // mean radius of Earth in km
$dlat = $lat2 - $lat1;
$dlon = $lon2 - $lon1;
$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlon / 2) * sin($dlon / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
$km = $r * $c;
//echo '<br/>'.$km;
return $km;
}
?>
如前所述;地球不是一个球体。它就像马克·麦奎尔决定用来练习的一个很旧很旧的棒球——到处都是凹痕和凸起。简单的计算(像这样)把它当作一个球体。
不同的方法或多或少的精确取决于你在这个不规则的卵形上的位置以及你的点之间的距离(它们越近,绝对误差范围就越小)。你的期望越精确,计算就越复杂。
更多信息:维基百科地理距离
我已经创建了这个小Javascript LatLng对象,可能对某人有用。
var latLng1 = new LatLng(5, 3);
var latLng2 = new LatLng(6, 7);
var distance = latLng1.distanceTo(latLng2);
代码:
/**
* latLng point
* @param {Number} lat
* @param {Number} lng
* @returns {LatLng}
* @constructor
*/
function LatLng(lat,lng) {
this.lat = parseFloat(lat);
this.lng = parseFloat(lng);
this.__cache = {};
}
LatLng.prototype = {
toString: function() {
return [this.lat, this.lng].join(",");
},
/**
* calculate distance in km to another latLng, with caching
* @param {LatLng} latLng
* @returns {Number} distance in km
*/
distanceTo: function(latLng) {
var cacheKey = latLng.toString();
if(cacheKey in this.__cache) {
return this.__cache[cacheKey];
}
// the fastest way to calculate the distance, according to this jsperf test;
// http://jsperf.com/haversine-salvador/8
// http://stackoverflow.com/questions/27928
var deg2rad = 0.017453292519943295; // === Math.PI / 180
var lat1 = this.lat * deg2rad;
var lng1 = this.lng * deg2rad;
var lat2 = latLng.lat * deg2rad;
var lng2 = latLng.lng * deg2rad;
var a = (
(1 - Math.cos(lat2 - lat1)) +
(1 - Math.cos(lng2 - lng1)) * Math.cos(lat1) * Math.cos(lat2)
) / 2;
var distance = 12742 * Math.asin(Math.sqrt(a)); // Diameter of the earth in km (2 * 6371)
// cache the distance
this.__cache[cacheKey] = distance;
return distance;
}
};