地理距离排序,范围查找

参考文章:地理空间距离计算优化

首先,这篇文章讲述了两种地理模型,一种是球体,一种是椭球体。一般网站对精度没有太大的需求,对于网站用户而言,只要得到一个大概结果就可以了,因此下面内容将选用球体展开讲述。

查找附近的点,即需要对数据库中的点与当地点的距离排序。

1.在一个球体上,求任意两点A和B的距离,相当于求一个弧长,公式为:

d = (θ / 360) * (2 * π * r) = θ * π * r / 180

注:周长是弧长的360/θ倍。

只要求出夹角θ,就能求出弧长,即求出距离。

2.然后需要将一个点的经纬度转换为r=1的空间坐标,公式为:

x = r * cos b * cos a = cos b * cos a

y = r * cos b * sin a = cos b * sin a

z = r * sin b = sin b

注:经度和纬度的意义为,先绕x轴旋转的度数为纬度值,再绕z轴旋转的度数为经度值。

计算出A和B的空间坐标分别为(x1, y1, z1)和(x2, y2, z2)。

3.然后再求空间两向量的夹角,公式为:

cosθ = (OA * OB) / (|OA| * |OB|) = (x1 * x2 + y1 * y2 + z1 * z2) / (r * r) = x1 * x2 + y1 * y2 + z1 * z2

最后使用arccos求出夹角θ,那么A和B的弧长,即距离求得。

4.但是,对于所需的距离排序,是否真的需要求出两个点的距离?

假设θ1 < θ2,那么θ1 * π * r / 180 < θ2 * π * r / 180,即d1 < d2。

注:这里的r是地球半径,并不是1。

显然是不需要求出距离的,使用夹角排序代替距离排序。

5.接着是否需要求出两个点代表的向量夹角?

假设cos θ1 < cos θ2,那么arccos(cos θ1) > arccos(cos θ2),即θ1 > θ2。

注:函数y = arccos x, y∈[0, π]的单调性为减函数,证明略。

夹角也是不需要求出的,使用cos θ的排序代替夹角的排序,也间接代替了距离排序。

6.对于范围查找,如查找方圆5公里内。

由于上述公式中,使用cos θ排序代替距离排序,是不能计算出范围进行排除的。

由于已经排序好,就可以使用二分法计算,比较,排除,但SQL如何实现二分法,这是一个疑问。

注:个人感觉可以不做统计,即无具体分页,只有下一页,也无总数显示。这样,每次读取的有序数据,在业务层进行距离比较,然后排除。

有了限定范围的数值,就可以在排序之前进行剪枝,从而减少排序时计算和比较的次数。

剪枝的方法有矩形排除,目前我还研究着是否有更有效率的剪枝方法,其中想到一个方向,就是相加。

不过这个方法只研究在平面上,思路是这样的,平面上任意一个点A(x, y),那么x + y与|OA|的关系。

我们知道x = |OA| * cos a,y = |OA| * sin a。

那么x + y = |OA| * sina + |OA| * cos a = |OA| * √2 * sin(a - 45)。

从公式中看出,当a为45度时,sin(a - 45)取最大值即为1,x + y的最大值为|OA| * √2。

假设我要搜索的范围为10,那么x + y的最大值为10 * √2,使用x + y <= 10 * √2进行前枝,把不符合该不等式的点排除。

进一步,|AB|与固定点B(a, b),任意点A(x, y)的关系,(x - a) + (y - b) <= L * √2,L是给定的已知值。

那么x + y <= L * √2 + a + b,其中x + y可以预先计算存入数据库,L * √2 + a + b是查询前计算出来,这个比较的效率是非常高的。

这种假想的剪枝方法是否适用于地理范围查找,尚在研究中。

到这里,不知道我的思路是否正确,因为这篇文章《地理空间距离计算优化》里并没有讲述到,希望有人能帮我参详一下,查了很多资料也没查找到。

文章只是讲到了一个计算距离的公式优化。

优化1:

对于公式cosθ = x1 * x2 + y1 * y2 + z1 * z2,要计算出夹角θ,就得计算出cosθ,由于cosθ运算比较耗时,文章给出了优化方案。

我们知道sinθ ^ 2 + cosθ ^ 2 = 1,那么公式就变为sinθ = √(1 - (x1 * x2 + y1 * y2 + z1 * z2))。

再者,这种优化方案适用于θ角非常小的情况下,sinθ ≈ θ,即√(1 - (x1 * x2 + y1 * y2 + z1 * z2)) ≈ θ。

优化2:

这种优化方案也是适用于θ角非常小的情况下,使用平面距离公式代替球面弧长公式。

优化3:

采用多项式来拟合cos三角函数,达到消除消除cos三角函数的目的。

关于地理距离排序的其它方法,还有geohash。

这个方法就像我们的居住地址一样,生成一个什么省什么市什么村的地址串。

相关文章:《如何实现按距离排序、范围查找》,《GeoHash核心原理解析

原文地址:https://www.cnblogs.com/hvicen/p/6471387.html