如何计算两个GPS坐标之间的距离(使用经纬度)?
当前回答
下面是我在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来生成距离。
基于Roman Makarov对这个线程的回复的Java版本的Haversine算法
public class HaversineAlgorithm {
static final double _eQuatorialEarthRadius = 6378.1370D;
static final double _d2r = (Math.PI / 180D);
public static int HaversineInM(double lat1, double long1, double lat2, double long2) {
return (int) (1000D * HaversineInKM(lat1, long1, lat2, long2));
}
public static double HaversineInKM(double lat1, double long1, double lat2, double long2) {
double dlong = (long2 - long1) * _d2r;
double dlat = (lat2 - lat1) * _d2r;
double a = Math.pow(Math.sin(dlat / 2D), 2D) + Math.cos(lat1 * _d2r) * Math.cos(lat2 * _d2r)
* Math.pow(Math.sin(dlong / 2D), 2D);
double c = 2D * Math.atan2(Math.sqrt(a), Math.sqrt(1D - a));
double d = _eQuatorialEarthRadius * c;
return d;
}
}
计算两个坐标之间的纬度和经度的距离,包括一个Javascript实现。
西部和南部的位置是负的。 记住,分和秒是60度,所以S31 30'是-31.50度。
别忘了把角度转换成弧度。许多语言都有这个功能。或者它是一个简单的计算:弧度=角度* PI / 180。
function degreesToRadians(degrees) {
return degrees * Math.PI / 180;
}
function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
var earthRadiusKm = 6371;
var dLat = degreesToRadians(lat2-lat1);
var dLon = degreesToRadians(lon2-lon1);
lat1 = degreesToRadians(lat1);
lat2 = degreesToRadians(lat2);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadiusKm * c;
}
下面是一些用法的例子:
distanceInKmBetweenEarthCoordinates(0,0,0,0) // Distance between same
// points should be 0
0
distanceInKmBetweenEarthCoordinates(51.5, 0, 38.8, -77.1) // From London
// to Arlington
5918.185064088764
在Python中,你可以使用geopy库使用WGS84椭球来计算测地线距离:
from geopy.distance import geodesic
newport_ri = (41.49008, -71.312796)
cleveland_oh = (41.499498, -81.695391)
print(geodesic(newport_ri, cleveland_oh).km)
推荐文章
- 如何在JavaScript中指定Math.log()的基?
- 为什么使用softmax而不是标准归一化?
- 圆线段碰撞检测算法?
- 对于有符号的数,为什么更喜欢2的补数而不是大小?
- 一个用于膨胀/收缩(抵消,缓冲)多边形的算法
- 圆-矩形碰撞检测(相交)
- 在ImageView中使用“animated circle”来加载东西
- 如何在Python中使用空圆圈做散点图?
- 为什么Python的无穷散列中有π的数字?
- 四舍五入BigDecimal *总是*有两位小数点后
- 从数字中移除无关紧要的尾随零?
- navigator。gelocation。getcurrentposition有时有效有时无效
- 负数的Mod快把我的脑子都融化了
- 如何计算圆周长上的一点?
- 如何确保整数的除法总是四舍五入?