网上很多教程类似, 不是很好,精度差别很大
比如这个c#实现:
c#代码
private const double EARTH_RADIUS = 6378.137; //地球半径
private static double rad(double d)
{
return d * Math.PI / 180.0;
}
public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
double radLat1 = rad(lat1);
double radLat2 = rad(lat2);
double a = radLat1 - radLat2;
double b = rad(lng1) - rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) +
Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2)));
s = s * EARTH_RADIUS;
s = Math.Round(s * 10000) / 10000;
return s;
}
local start = {longitude=116.368904, latitude=39.923423}
local tail = {longitude=116.387271, latitude=39.922501}
算出来是:2.0451公里,
高德地图是:1571.37米,
https://lbs.amap.com/api/javascript-api/example/calcutation/calculate-distance-between-two-markers/
通过地球半径粗略算距离,单位也不统一,误差500米左右。
找到一个好一点的介绍的比较详细,写的很不错:
他上面使用js, mysql, java实现,误差相对较小,比较精确,我参考他的实现了lua版本的:
function TestLua:CalDistance()
local start = {longitude=116.368904, latitude=39.923423}
local tail = {longitude=116.387271, latitude=39.922501}
print("[gps距离]"..tostring(self:CalculateLineDistance(start, tail)))
end
function TestLua:CalculateLineDistance(start, tail)
local d1 = 0.01745329251994329;
local d2 = start.longitude;
local d3 = start.latitude;
local d4 = tail.longitude;
local d5 = tail.latitude;
d2 = d2*d1;
d3 = d3*d1;
d4 = d4*d1;
d5 = d5*d1;
local d6 = math.sin(d2);
local d7 = math.sin(d3);
local d8 = math.cos(d2);
local d9 = math.cos(d3);
local d10 = math.sin(d4);
local d11 = math.sin(d5);
local d12 = math.cos(d4);
local d13 = math.cos(d5);
local arrayOfDouble1 = {};
local arrayOfDouble2 = {};
arrayOfDouble1[0]=(d9 * d8);
arrayOfDouble1[1]=(d9 * d6);
arrayOfDouble1[2]=(d7);
arrayOfDouble2[0]=(d13 * d12);
arrayOfDouble2[1]=(d13 * d10);
arrayOfDouble2[2]=(d11);
local d14 = math.sqrt((arrayOfDouble1[0] - arrayOfDouble2[0]) * (arrayOfDouble1[0] - arrayOfDouble2[0]) +
(arrayOfDouble1[1] - arrayOfDouble2[1]) * (arrayOfDouble1[1] - arrayOfDouble2[1]) +
(arrayOfDouble1[2] - arrayOfDouble2[2]) * (arrayOfDouble1[2] - arrayOfDouble2[2]));
return(math.asin(d14 / 2.0) * 12742001.579854401);
end