本文作者:smallyang,腾讯 IEG 开发工程师
什么是geohash?它的原理是什么?它帮助我们解决了哪些痛点,本文为你娓娓道来。
本文包含以下内容,阅读完需要约10分钟:
我们日常生活中遇到哪些定位的场景
简单复习一下经纬度
geohash原理解析
geohash存在的边界问题
如何解决边界问题
计算两点距离的计算
geohash 在redis中的实现
我们日常生活中遇到哪些定位的场景
我们上下班经常会用APP打车和共享单车,下面2张图,应该都很熟悉,打开定位,查找我附近的车,那么,这个是怎么实现的呢?
我脑海中第一个实现方式是:实时上报经纬度。在数据库里,把经纬度都标记为索引,通过查找对比经纬度的值,来找到附近1km的车子,但是这种做法第一是索引比较多,数值比较大,二是需要循环遍历经纬度,查询会很慢,效率很低。
那么,这些APP是怎么做到,既能精准定位,又能快速查找呢?答案就是 geohash
geohash通过算法将1个定位的经度和纬度2个数值,转换成1个hash字符串。如果2个地方距离越近,那么他们的hash值的前缀越相同。然后通过数据库中like操作符 “ like wtw366%” 快速查找到附近的车。
比如上海腾讯大厦的经纬度是:(31.1688749, 121.3975184)
,那么转换成geohash就是 wtw366ngz5qt
,我们想找附近的车子,可以用:
select * from cart where geohash like 'wtw366%' ;
select * from cart where LEFT(geohash, 6) = 'wtw366';
简单复习一下经纬度
在大致了解什么是geohash之后,我们先来复习一下什么是经纬度(高中学的,可能已经忘记光了(逃)),这对于理解geohash有很大的帮助。
我们将地球铺平开来,会得到下面这个平面图。

以赤道和本初子午线为界,将地球分为经度和纬度。赤道是在0度,本初子午线也在0度。以赤道作为经度X横坐标,以本初子午线作为纬度 Y 竖坐标。

经度(longitude)`和`纬度(latitude)`简称 `lng` 和 `lat
其中,从本初子午线向东划分180度称为东经,用”E”表示:(0, 180];向西划分180度为西经,用“W”表示:[-180, 0)
以赤道为0度,向南北各分出90度,南北极的读数均是90度,北纬用“N”表示 :(0, 90] ,南纬用“S”表示: [-90, 0)
纬线和纬线是角度数值,并不是米。
所以,我们常用十字坐标法来表示经纬度坐标图: