最近在做计算公交站的地铁换乘线路的需求,发现python计算两个POI的球面距离实在是太慢了,偶然想到了一个优化的方法,就是根据经纬度估算距离,减少一些不必要的计算,经测试性能提升了30%左右。

以下距离估算引用自 Geohash距离估算, geohash部分略过了

##纬度相等的情况下, 经度

- 每隔0.00001度,距离相差约1米
- 每隔0.0001度,距离相差约10米
- 每隔0.001度,距离相差约100米
- 每隔0.01度,距离相差约1000米
- 每隔0.1度,距离相差约10000米

##经度相等的情况下, 纬度

- 每隔0.00001度,距离相差约1.1米
- 每隔0.0001度,距离相差约11米
- 每隔0.001度,距离相差约111米
- 每隔0.01度,距离相差约1113米
- 每隔0.1度,距离相差约11132米

但是当我在想明白这个是怎么计算出来的时候我发现这个有问题,纬度不同的情况下经度变化1度,距离差是不确定的,跟纬度有关。

先说下这个估算的原理吧。

在经度相同的情况下,纬度变化导致的距离变化正比于纬度变化的度数,值为子午线长度 / 360 * 纬度变化的度数,即:

39940.67/360 = 110.94630555555555 km

也就是每隔1度,距离相差约110946米,说明经度相同情况下上面的推论是正确的。

但纬度相同的情况下就不成立了,是因为不同的纬度对应的圆周周长不同,赤道是最长的,如果在赤道上的话,经度每隔1度,距离变化为:

40075.36 / 360 = 111.32044444444445 km

如果不是赤道的话,需要再乘以cosΘ(Θ为纬度),赤道的话纬度为0,余弦值为1,也满足这个公式。

按照中国的经纬度边界计算(最西端约东经73.5度,最东为东经135度多,北端北纬53度多,南端北纬4度),纬度相同情况下,经度每变1度,距离变化在

40075.36 / 360 cos(53°) - 40075.36 / 360 cos(4°)
即 66.99431585062965 - 111.04927343672375 km之间。

我要计算的距离是500米,之前经度和纬度都用的0.01度(差不多对应1000米),纬度相同的情况肯定没问题,经度相同的情况按这个范围看也没有问题,我又蒙对了, :)。