Lucene 如何通过GeoHash 查询距离

本文探讨了使用GeoHash进行地理位置距离查询的方法,并通过实例说明了如何根据GeoHash判断两点间的距离,指出GeoHash并不是简单的从前往后匹配字符,而是通过二进制数值的绝对值差来确定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前用Lucene做过位置距离查询的项目,其中Lucene搜索定位距离的原理就是GeoHash,关于GeoHash的介绍看这里GeoHash 介绍,这篇文章要说的是如何根据GeoHash查询距离。

以下面以这幅图来看,图片将经度为0作为X轴的原点,纬度为0作为Y轴的原点,图中为了问题简单化,仅化了3层,实际中3层是不够的。

假设坐标轴正方向表示1,负方向表示0。那么按照GeoHash方法划分区域,则A到J的GeoHash分别为:

位置点GeoHash经度值GeoHash纬度值GeoHash值(经度+维度)
A1 0 01 0 011 00 00
B1 0 00 1 110 01 01
C0 1 10 1 100 11 11
D0 1 11 0 001 10 10
E1 1 01 1 011 11 00
F1 1 11 1 111 11 11
G1 1 11 1 111 11 11
H1 1 10 1 101 11 11
I0 1 00 1 000 11 00
J0 0 01 1 101 01 01

情况1:

  我们看E、F两个点,其中前两层都是11,仅第三层不一致,E、F离得很近。

情况2:

  我们看E、I两个点,第二、三层匹配,仅第一层不一致,E、I却离得很远。同理B、J也一样。

推测结果:

  那么我们可以这样认为,GeoHash匹配距离时,必须从前往后,直到第一个不能匹配为止,匹配的层数越多越相近。

情况3:

  拿着结果1,我们看F、G两个点,三层完全匹配,是不是F、G的距离要比E、F的距离近呢?不是,E、F距离更近。

情况4:

  加速A、B、C、D无限靠近原点,那么A、B、C、D应该离得非常近,但是我们看GeoHash,A、B、C、D并不是按照从前往后匹配的。

分析结果

  GeoHash并不是通过从前往后匹配来判断距离的,推测结果是错误的,那是通过什么呢?下面是我的猜测,具体实现思路还需要看看Lucene的源码。

A、B、C、D四个点,如果按字符串从前往后匹配,那么匹配程度非常低,但是如果把Hash当成一个二进制数,100表示4,而011表示3,通过数的差的绝对值,我们发现,无论是经度还是维度,A、B、C、D之间的差的绝对值都不会大于一。因为A、B、C、D无限靠近原点,即使有Geo划分有无限层,A的维度是1 0 0 0 0 0...(无限0),B的维度是0 1 1 1 1 1...(无限1),那么他们的绝对值仍然不会大于1。同样的,ABCD任意两点的经纬度差绝对值不会大于1。由于都是整数,除了0之外,最小差绝对值就是1。

由此我们可以推论:判断两个点的距离,是通过GeoHash的经纬度Hash分别按照二进制取差,绝对值越小,则距离越近。

至于经度和维度的合并的距离,由于经纬度是完全垂直的,就可以根据平方和(勾股定理)来定了。

如何判断F、G要比E、F远,应该就没有办法,因为这儿划分的层次太少,当划分层次多的时候,经纬度绝对值差E、F自然会比F、G小。所以,分层的大小直接影响到距离的精度。

以上都是自己分析的,不知是否正确,如有错误,欢迎批评指正。

转载于:https://www.cnblogs.com/yhzhtk/p/3548105.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值