根据2个经纬度点,计算这2个经纬度点之间的距离(通过经度纬度得到距离)
球面上任意两点之间的距离计算公式可以参考维基百科上的下述文章。
Great-circle distance
Haversine formula
值得一提的是,维基百科推荐使用Haversine公式,理由是Great-circle distance公式用到了大量余弦函数, 而两点间距离很短时(比如地球表面上相距几百米的两点),余弦函数会得出0.999…的结果, 会导致较大的舍入误差。而Haversine公式采用了正弦函数,即使距离很小,也能保持足够的有效数字。 以前采用三角函数表计算时的确会有这个问题,但经过实际验证,采用计算机来计算时,两个公式的区别不大。 稳妥起见,这里还是采用Haversine公式。
其中
R为地球半径,可取平均值 6371km;
φ1, φ2 表示两点的纬度;
Δλ 表示两点经度的差值。
根据2个经纬度坐标,距离计算函数
下面就是计算球面间两点(lat1, lon1) - (lat2, lon2)之间距离的函数。
复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace HarvenSin
{
class Program
{
///
/// 根据经纬度,计算2个点之间的距离。
///
///
static void Main(string[] args)
{
//39.94607,116.32793 31.24063,121.42575
Console.WriteLine(Distance(39.94607, 116.32793, 31.24063, 121.42575));
}
public static double HaverSin(double theta)
{
var v = Math.Sin(theta / 2);
return v * v;
}
static double EARTH_RADIUS = 6371.0;//km 地球半径 平均值,千米
/// <summary>
/// 给定的经度1,纬度1;经度2,纬度2. 计算2个经纬度之间的距离。
/// </summary>
/// <param name="lat1">经度1</param>
/// <param name="lon1">纬度1</param>
/// <param name="lat2">经度2</param>
/// <param name="lon2">纬度2</param>
/// <returns>距离(公里、千米)</returns>
public static double Distance(double lat1,double lon1, double lat2,double lon2)
{
//用haversine公式计算球面两点间的距离。
//经纬度转换成弧度
lat1 = ConvertDegreesToRadians(lat1);
lon1 = ConvertDegreesToRadians(lon1);
lat2 = ConvertDegreesToRadians(lat2);
lon2 = ConvertDegreesToRadians(lon2);
//差值
var vLon = Math.Abs(lon1 - lon2);
var vLat = Math.Abs(lat1 - lat2);
//h is the great circle distance in radians, great circle就是一个球体上的切面,它的圆心即是球心的一个周长最大的圆。
var h = HaverSin(vLat) + Math.Cos(lat1) * Math.Cos(lat2) * HaverSin(vLon);
var distance = 2 * EARTH_RADIUS * Math.Asin(Math.Sqrt(h));
return distance;
}
/// <summary>
/// 将角度换算为弧度。
/// </summary>
/// <param name="degrees">角度</param>
/// <returns>弧度</returns>
public static double ConvertDegreesToRadians(double degrees)
{
return degrees * Math.PI / 180;
}
public static double ConvertRadiansToDegrees(double radian)
{
return radian * 180.0 / Math.PI;
}
}
}
– lua代码,计算经纬度距离
local function algorithm(longitude1, latitude1, longitude2, latitude2)
local function rad(d)
return d*math.pi/180
end
local function round(n)
return math.floor(n+0.5)
end
local a = rad(latitude1) - rad(latitude2)
local b = rad(longitude1) - rad(longitude2)
local s = 2 * math.asin(math.sqrt(math.pow(math.sin(a / 2), 2) +
math.cos(latitude1) * math.cos(latitude2) * math.pow(math.sin(b / 2), 2)))
s = s * 6371.393
s = round(s * 10000) / 10000
return s
end