Geohash是地址码,编码一个二维的纬度和经度为一维字符串。例如,北海公园的代码是wx4g0ec1。

Geohash原理和算法

在的情况下,(39.92324,116.3906),介绍了Geohash编码算法。

首先,纬度范围(- 90, 90)被均匀地划分为两个区间(- 90, 0)和(0, 90)。如果目标纬度位于前间隔,编码是0,否则编码是1。因为39.92324是属于(0, 90),编码是1,那么(0, 90)分(0, 45)、(45, 90)两个区间,和39.92324(0, 45),所以代码0。以此类推,直到满足要求的精度,纬度的代码是1011100011000111 1001。



纬度范围
区间划分0
区间划分1
39.92324属


(- 90, 90)
(- 90, 0)
(0, 90)
一


(0, 90)
(0, 45)
(45, 90)
零


(0, 45)
(0,22.5)
(22.5,45)
一


(22.5,45)
(22.5,33.75)
(33.75,45)
一


(33.75,45)
(33.75,39.375)
(39.375,45)
一


(39.375,45)
(39.375,42.1875)
(42.1875,45)
零


(39.375,42.1875)
(39.375,40.7812)
(40.7812,42.1875)
零


(39.375,40.7812)
(39.375,40.0781)
(40.0781,40.7812)
零


(39.375,40.0781)
(39.375,39.7265)
(39.7265,40.0781)
一


(39.7265,40.0781)
(39.7265,39.9023)
(39.9023,40.0781)
一


(39.9023,40.0781)
(39.9023,39.9902)
(39.9902,40.0781)
零


(39.9023,39.9902)
(39.9023,39.9462)
(39.9462,39.9902)
零


(39.9023,39.9462)
(39.9023,39.9243)
(39.9243,39.9462)
零


(39.9023,39.9243)
(39.9023,39.9133)
(39.9133,39.9243)
一


(39.9133,39.9243)
(39.9133,39.9188)
(39.9188,39.9243)
一


(39.9188,39.9243)
(39.9188,39.9215)
(39.9215,39.9243)
一




同样的算法也使用经度。(- 180, 180)依次细分,116.3906的编码为1101001011000100 0100。



经度范围
区间划分0
区间划分1
116.3906属


(- 180, 180)
(- 180, 0)
(0, 180)
一


(0, 180)
(0, 90)
(90, 180)
一


(90, 180)
(90, 135)
(135, 180)
零


(90, 135)
(90,112.5)
(112.5,135)
一


(112.5,135)
(112.5,123.75)
(123.75,135)
零


(112.5,123.75)
(112.5,118.125)
(118.125,123.75)
零


(112.5,118.125)
(112.5,115.312)
(115.312,118.125)
一


(115.312,118.125)
(115.312,116.718)
(116.718,118.125)
零


(115.312,116.718)
(115.312,116.015)
(116.015,116.718)
一


(116.015,116.718)
(116.015,116.367)
(116.367,116.718)
一


(116.367,116.718)
(116.367,116.542)
(116.542,116.718)
零


(116.367,116.542)
(116.367,116.455)
(116.455,116.542)
零


(116.367,116.455)
(116.367,116.411)
(116.411,116.455)
零


(116.367,116.411)
(116.367,116.389)
(116.389,116.411)
一


(116.389,116.411)
(116.389,116.400)
(116.400,116.411)
零


(116.389,116.400)
(116.389,116.394)
(116.394,116.400)
零




接下来,我们结合经度和纬度编码,奇数是纬度,偶数是经度,得到编码111001110100100, 011110000001101,0101100001。

最后,这32个字母的0-9,B-Z(I,L,O)与32个字母编码,和(39.92324,116.3906)码是wx4g0ec1。



十进制系统
零
一
二
三
四
五
六
七
八
九
十
十一
十二
十三
十四
十五


Base32
零
一
二
三
四
五
六
七
八
九
B
C
D
E
F
G


十进制系统
十六
十七
十八
十九
二十
二十一
二十二
二十三
二十四
Twenty-five
二十六
二十七
二十八
二十九
三十
三十一


Base32
H
J
K
M
n
P
Q
R
S
T
u
v
W
X
Y
Z




解码算法与编码算法相反。首先,我们将解码Base32先单独的经度和纬度。最后,我们可以细分的经度和纬度,根据二进制编码。但由于Geohash代表间隔,码长越长,更准确的是,但它是不可能完全一致的地址译码。

应用Geohash:附近的地址搜索

最好使用Geohash的搜索附近的地址。但是,我们可以从Geohash编码算法的一个缺点:看在网格边界两侧的点非常接近,但编码是完全不同的。在实际应用中,这个问题可以通过搜索8格围绕当前电网的同时解决了。

最后,让我们在这两个问题在本文开头提出一看:速度慢,缓存命中率降低。使用Geohash与字符串的前缀匹配查询附近的位置:

复制代码代码如下:SELECT * FROM地方Geohash like'wx4g0 %;

前缀匹配可以利用在Geohash列的索引,那么查询速度不会太慢。此外,即使用户坐标稍有变化,它们也可以被编码成相同Geohash。这样可以确保每次执行相同的SQL语句时,缓存命中率将大大提高。