根据两个点经纬度计算距离 地理空间距离计算及优化( 四 )


在得到夹角之后 , 还需要执行函数 , 将其转换成角度 , AB弧长=角AOB*R(R是地球半径) 。
此方法性能如下:
2)进一步优化
美团是本地生活服务 , 我们的业务场景是在一个城市范围内进行距离计算 , 因此夹角AOB往往会比较小 , 这个时候约等于AOB , 因此我们可以将 Math.acos()R 改为Math.sqrt(1 - )*R , 从而完全避免使用三角函数 , 优化后性能如下 。
4.2 简化距离计算公式方法
1)基本思路
我们的业务场景仅仅是在一个城市范围内进行距离计算 , 也就是说两个点之间的距离一般不会超过200多千米 。由于范围小 , 可以认为经线和纬线是垂直的 , 如图所示 , 要求A(116.8 , 39,78)和B(116.9 , 39.68)两点的距离 , 我们可以先求出南北方向距离AM , 然后求出东西方向距离BM , 最后求矩形对角线距离 , 即sqrt(AMAM + BMBM) 。
简化距离计算示意图
南北方向AM = R纬度差Math.PI/180.0;
东西方向BM = R经度差Cos
这种方式仅仅需要计算一次cos函数 。
1
2
3
4
5
6
7
8
9
(,,,,[]a){
=lng1-lng2; //经度差值
=lat1-lat2; //纬度差值
=(lat1+lat2)/2.0; //平均纬度
=(dx)*.0*Math.cos((b)); //东西距离
=.0*(dy); //南北距离
Math.sqrt(Lx*Lx+Ly*Ly); //用平面的矩形对角距离公式计算总距离
}
}
我们对这个方法的有效性和性能进行验证 。
1.1)有效性验证
我们首先检验这种简化是否能满足我们应用的精度 , 如果精度较差将不能用于实际生产环境 。
我们的方法叫 , 的方法叫 。下表是在不同尺度下两个方法的相差情况 。
可以看到两者在百米、千米尺度上几乎没有差别 , 在万米尺度上也仅有分米的差别 , 此外由于我们的业务是在一个城市范围内进行筛选排序 , 所以我们选择了北京左下角和右上角两点进行比较 , 两点相距有260多千米 , 两个方法差别17m 。从精度上看该优化方法能满足我们应用需求 。
1.2)性能验证
2)进一步优化
我们看到这里计算了一次cos这一三角函数 , 如果我们能消除此三角函数 , 那么将进一步提高计算效率 。
如何消除cos三角函数呢?
采用多项式来拟合cos三角函数 , 这样不就可以将三角函数转换为加减乘除了嘛!
首先决定多项式的最高次数 , 次数为1和2显然都无法很好拟合cos函数 , 那么我们选择3先尝试吧 , 注:最高次数不是越多越好 , 次数越高会产生过拟合问题 。
使用mons.math3这一数学工具包来进行拟合 。中国的纬度范围在10~60之间 , 即我们将此区间离散成份作为我们的训练集 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[](,){
er=r.();
=10.0; //中国最低纬度
=60.0; //中国最高纬度
=(-)/();
= new ();
for (inti=0;i