如何计算两个GPS坐标之间的距离(使用经纬度)?
当前回答
我需要在PowerShell中实现这个,希望它可以帮助其他人。 关于这种方法的一些注意事项
Don't split any of the lines or the calculation will be wrong To calculate in KM remove the * 1000 in the calculation of $distance Change $earthsRadius = 3963.19059 and remove * 1000 in the calculation of $distance the to calulate the distance in miles I'm using Haversine, as other posts have pointed out Vincenty's formulae is much more accurate Function MetresDistanceBetweenTwoGPSCoordinates($latitude1, $longitude1, $latitude2, $longitude2) { $Rad = ([math]::PI / 180); $earthsRadius = 6378.1370 # Earth's Radius in KM $dLat = ($latitude2 - $latitude1) * $Rad $dLon = ($longitude2 - $longitude1) * $Rad $latitude1 = $latitude1 * $Rad $latitude2 = $latitude2 * $Rad $a = [math]::Sin($dLat / 2) * [math]::Sin($dLat / 2) + [math]::Sin($dLon / 2) * [math]::Sin($dLon / 2) * [math]::Cos($latitude1) * [math]::Cos($latitude2) $c = 2 * [math]::ATan2([math]::Sqrt($a), [math]::Sqrt(1-$a)) $distance = [math]::Round($earthsRadius * $c * 1000, 0) #Multiple by 1000 to get metres Return $distance }
其他回答
这段Lua代码改编自维基百科和Robert Lipe的GPSbabel工具:
local EARTH_RAD = 6378137.0
-- earth's radius in meters (official geoid datum, not 20,000km / pi)
local radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0;
-- earth's radius in miles
local multipliers = {
radians = 1, miles = radmiles, mi = radmiles, feet = radmiles * 5280,
meters = EARTH_RAD, m = EARTH_RAD, km = EARTH_RAD / 1000,
degrees = 360 / (2 * math.pi), min = 60 * 360 / (2 * math.pi)
}
function gcdist(pt1, pt2, units) -- return distance in radians or given units
--- this formula works best for points close together or antipodal
--- rounding error strikes when distance is one-quarter Earth's circumference
--- (ref: wikipedia Great-circle distance)
if not pt1.radians then pt1 = rad(pt1) end
if not pt2.radians then pt2 = rad(pt2) end
local sdlat = sin((pt1.lat - pt2.lat) / 2.0);
local sdlon = sin((pt1.lon - pt2.lon) / 2.0);
local res = sqrt(sdlat * sdlat + cos(pt1.lat) * cos(pt2.lat) * sdlon * sdlon);
res = res > 1 and 1 or res < -1 and -1 or res
res = 2 * asin(res);
if units then return res * assert(multipliers[units])
else return res
end
end
计算两个坐标之间的纬度和经度的距离,包括一个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)
对于java
public static double degreesToRadians(double degrees) {
return degrees * Math.PI / 180;
}
public static double distanceInKmBetweenEarthCoordinates(Location location1, Location location2) {
double earthRadiusKm = 6371;
double dLat = degreesToRadians(location2.getLatitude()-location1.getLatitude());
double dLon = degreesToRadians(location2.getLongitude()-location1.getLongitude());
double lat1 = degreesToRadians(location1.getLatitude());
double lat2 = degreesToRadians(location2.getLatitude());
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return earthRadiusKm * c;
}
在我的项目中,我需要计算很多点之间的距离,所以我继续尝试优化我在这里找到的代码。平均而言,在不同的浏览器中,我的新实现的运行速度比获得最多好评的答案快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
def distance(lat1, lon1, lat2, lon2):
p = 0.017453292519943295
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))
为了完整起见:维基上的Haversine。
推荐文章
- 如何在JavaScript中指定Math.log()的基?
- 为什么使用softmax而不是标准归一化?
- 圆线段碰撞检测算法?
- 对于有符号的数,为什么更喜欢2的补数而不是大小?
- 一个用于膨胀/收缩(抵消,缓冲)多边形的算法
- 圆-矩形碰撞检测(相交)
- 在ImageView中使用“animated circle”来加载东西
- 如何在Python中使用空圆圈做散点图?
- 为什么Python的无穷散列中有π的数字?
- 四舍五入BigDecimal *总是*有两位小数点后
- 从数字中移除无关紧要的尾随零?
- navigator。gelocation。getcurrentposition有时有效有时无效
- 负数的Mod快把我的脑子都融化了
- 如何计算圆周长上的一点?
- 如何确保整数的除法总是四舍五入?