• 地理距离排序,范围查找


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

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

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

    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核心原理解析

  • 相关阅读:
    Qt 让QLabel自适应text的大小,并且自动换行(转)
    /usr/local/lib/libz.a: could not read symbols: Bad value(64 位 Linux)
    HDU 3605 Escape(最大流)
    HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
    HDU 2883 kebab (最大流)
    SPOJ 10606. Balanced Numbers (数位DP)
    HDU 3338 Kakuro Extension(最大流)
    HDU 3081 Marriage Match II (最大流+二分+并查集)
    HDU 2732 Leapin' Lizards(最大流)
    HDU 3709 Balanced Number ZOJ 3416 Balanced Number(数位DP)
  • 原文地址:https://www.cnblogs.com/hvicen/p/6471387.html
Copyright © 2020-2023  润新知