如何计算两个GPS坐标之间的距离(使用经纬度)?
当前回答
计算两个坐标之间的纬度和经度的距离,包括一个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
其他回答
在SQL Server 2008中使用地理类型非常容易做到这一点。
SELECT geography::Point(lat1, lon1, 4326).STDistance(geography::Point(lat2, lon2, 4326))
-- computes distance in meters using eliptical model, accurate to the mm
4326是WGS84椭球地球模型的SRID
下面是c#语言(用纬度和弧度表示):
double CalculateGreatCircleDistance(double lat1, double long1, double lat2, double long2, double radius)
{
return radius * Math.Acos(
Math.Sin(lat1) * Math.Sin(lat2)
+ Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(long2 - long1));
}
如果你的纬度和长度是用角度表示的,那么除以180/PI就可以转换成弧度。
这是我在Elixir中的实现
defmodule Geo do
@earth_radius_km 6371
@earth_radius_sm 3958.748
@earth_radius_nm 3440.065
@feet_per_sm 5280
@d2r :math.pi / 180
def deg_to_rad(deg), do: deg * @d2r
def great_circle_distance(p1, p2, :km), do: haversine(p1, p2) * @earth_radius_km
def great_circle_distance(p1, p2, :sm), do: haversine(p1, p2) * @earth_radius_sm
def great_circle_distance(p1, p2, :nm), do: haversine(p1, p2) * @earth_radius_nm
def great_circle_distance(p1, p2, :m), do: great_circle_distance(p1, p2, :km) * 1000
def great_circle_distance(p1, p2, :ft), do: great_circle_distance(p1, p2, :sm) * @feet_per_sm
@doc """
Calculate the [Haversine](https://en.wikipedia.org/wiki/Haversine_formula)
distance between two coordinates. Result is in radians. This result can be
multiplied by the sphere's radius in any unit to get the distance in that unit.
For example, multiple the result of this function by the Earth's radius in
kilometres and you get the distance between the two given points in kilometres.
"""
def haversine({lat1, lon1}, {lat2, lon2}) do
dlat = deg_to_rad(lat2 - lat1)
dlon = deg_to_rad(lon2 - lon1)
radlat1 = deg_to_rad(lat1)
radlat2 = deg_to_rad(lat2)
a = :math.pow(:math.sin(dlat / 2), 2) +
:math.pow(:math.sin(dlon / 2), 2) *
:math.cos(radlat1) * :math.cos(radlat2)
2 * :math.atan2(:math.sqrt(a), :math.sqrt(1 - a))
end
end
你可以在f#的fssnip中找到这个实现(有一些很好的解释)
以下是重要的部分:
let GreatCircleDistance<[<Measure>] 'u> (R : float<'u>) (p1 : Location) (p2 : Location) =
let degToRad (x : float<deg>) = System.Math.PI * x / 180.0<deg/rad>
let sq x = x * x
// take the sin of the half and square the result
let sinSqHf (a : float<rad>) = (System.Math.Sin >> sq) (a / 2.0<rad>)
let cos (a : float<deg>) = System.Math.Cos (degToRad a / 1.0<rad>)
let dLat = (p2.Latitude - p1.Latitude) |> degToRad
let dLon = (p2.Longitude - p1.Longitude) |> degToRad
let a = sinSqHf dLat + cos p1.Latitude * cos p2.Latitude * sinSqHf dLon
let c = 2.0 * System.Math.Atan2(System.Math.Sqrt(a), System.Math.Sqrt(1.0-a))
R * c
这取决于你需要它有多准确。如果你需要精确到毫米的精度,最好看看使用椭球的算法,而不是球体,比如Vincenty的算法。
推荐文章
- 如何计算线段的法向量?
- Numpy Max vs amax vs maximum
- 从IP地址获取位置
- 这是在Android中获取用户位置的好方法
- 如何在JavaScript中指定Math.log()的基?
- 为什么使用softmax而不是标准归一化?
- 圆线段碰撞检测算法?
- 对于有符号的数,为什么更喜欢2的补数而不是大小?
- 一个用于膨胀/收缩(抵消,缓冲)多边形的算法
- 圆-矩形碰撞检测(相交)
- 在ImageView中使用“animated circle”来加载东西
- 如何在Python中使用空圆圈做散点图?
- 为什么Python的无穷散列中有π的数字?
- 四舍五入BigDecimal *总是*有两位小数点后
- 从数字中移除无关紧要的尾随零?