如何计算两个GPS坐标之间的距离(使用经纬度)?
当前回答
PHP版本:
(删除所有deg2rad()如果您的坐标已经是弧度。)
$R = 6371; // km
$dLat = deg2rad($lat2-$lat1);
$dLon = deg2rad($lon2-$lon1);
$lat1 = deg2rad($lat1);
$lat2 = deg2rad($lat2);
$a = sin($dLat/2) * sin($dLat/2) +
sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
$d = $R * $c;
其他回答
我猜你想让它沿着地球的曲率运动。你的两点和地心在一个平面上。地球的中心是这个平面上的圆心,这两个点(大致)在这个圆的周长上。由此你可以通过求一点到另一点的角度来计算距离。
如果点的高度不一样,或者如果你需要考虑地球不是一个完美的球体,这就有点困难了。
下面是我在Python中使用的Haversine函数:
from math import pi,sqrt,sin,cos,atan2
def haversine(pos1, pos2):
lat1 = float(pos1['lat'])
long1 = float(pos1['long'])
lat2 = float(pos2['lat'])
long2 = float(pos2['long'])
degree_to_rad = float(pi / 180.0)
d_lat = (lat2 - lat1) * degree_to_rad
d_long = (long2 - long1) * degree_to_rad
a = pow(sin(d_lat / 2), 2) + cos(lat1 * degree_to_rad) * cos(lat2 * degree_to_rad) * pow(sin(d_long / 2), 2)
c = 2 * atan2(sqrt(a), sqrt(1 - a))
km = 6367 * c
mi = 3956 * c
return {"km":km, "miles":mi}
我把上面的答案用在Scala程序中
import java.lang.Math.{atan2, cos, sin, sqrt}
def latLonDistance(lat1: Double, lon1: Double)(lat2: Double, lon2: Double): Double = {
val earthRadiusKm = 6371
val dLat = (lat2 - lat1).toRadians
val dLon = (lon2 - lon1).toRadians
val latRad1 = lat1.toRadians
val latRad2 = lat2.toRadians
val a = sin(dLat / 2) * sin(dLat / 2) + sin(dLon / 2) * sin(dLon / 2) * cos(latRad1) * cos(latRad2)
val c = 2 * atan2(sqrt(a), sqrt(1 - a))
earthRadiusKm * c
}
我对函数进行了压缩,以便能够轻松地生成具有两个固定位置之一的函数,并且只需要一对lat/lon来生成距离。
下面是Kotlin的一个变种:
import kotlin.math.*
class HaversineAlgorithm {
companion object {
private const val MEAN_EARTH_RADIUS = 6371.008
private const val D2R = Math.PI / 180.0
}
private fun haversineInKm(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double {
val lonDiff = (lon2 - lon1) * D2R
val latDiff = (lat2 - lat1) * D2R
val latSin = sin(latDiff / 2.0)
val lonSin = sin(lonDiff / 2.0)
val a = latSin * latSin + (cos(lat1 * D2R) * cos(lat2 * D2R) * lonSin * lonSin)
val c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a))
return MEAN_EARTH_RADIUS * c
}
}
一个T-SQL函数,我用来根据中心的距离选择记录
Create Function [dbo].[DistanceInMiles]
( @fromLatitude float ,
@fromLongitude float ,
@toLatitude float,
@toLongitude float
)
returns float
AS
BEGIN
declare @distance float
select @distance = cast((3963 * ACOS(round(COS(RADIANS(90-@fromLatitude))*COS(RADIANS(90-@toLatitude))+
SIN(RADIANS(90-@fromLatitude))*SIN(RADIANS(90-@toLatitude))*COS(RADIANS(@fromLongitude-@toLongitude)),15))
)as float)
return round(@distance,1)
END