索引技術-GeoHash

要點

GeoHash演算法介紹。

GeoHash應用場景及存在的問題。

概述

GeoHash是一種地理位置編碼方法,它將地理位置編碼為一個由字母和數字組成的短字串。其思想是,不斷地將經緯度地址進行二分,直到最小範圍,並使用二進位制表示,最後將二進位制的地址,按Base32進行編碼。大多數情況下,兩個地址編碼公共字首越長,則表示兩個地址距離越近。

GeoHash的應用場景,主要有:

根據指定地理位置搜尋周邊。

給定地理位置範圍內搜尋。

編碼演算法

以座標(112。084637,28。103151)為例進行說明,其中,經度取8bit位,緯度取7bit位。編碼過程如下圖所示:

索引技術-GeoHash

GeoHash編碼演算法

1、生成緯度的二進位制編碼,如果位於座標左區間則編碼為0,位於右區間則編碼為1。

將緯度進行二分,分成[-90, 0)和[0, 90]兩個區間,28。103151位於區間[0,90],因此編碼為1。

對[0, 90]進行二分,分為[0, 45)和[45, 90]兩個區間,28。103151位於區間[0, 45),因此編碼為0。

遞迴上述過程,直到區間逼近28。103151,經過多次劃分,最終生成的編碼為:1010 011。

2、同上述規則生成經度的編碼為:1100 1111。

3、將緯度編碼和經度編碼合併編碼,規則是,經度在前,緯度在後,逐位相間組合,生成新串:1110 0100 1011 111。

4、將合併後的二進位制串轉換成十進位制整數,每5個bit位為一組,對應的十進位制數為:28,17,31。

5、根據Base32規則,再進行Base32編碼,GeoHash編碼為:wjz。

Base32規則為:0-9對應字母‘0’-‘9’,10-31對應‘b’-‘z’,去掉a、i、l和o。對應關係如下:

索引技術-GeoHash

Base32編碼表

精度問題

GeoHash編碼中每一位都表示一個長度範圍。因此,計算精度與編碼長度有直接關係,其對應關係如下圖所示:

索引技術-GeoHash

計算精度與編碼長度對應表

存在的問題

GeoHash的二進位制編碼填充空間中,編碼的順序為左下角00,左上角01,右下腳10,右上角11,其遍歷曲線如下圖:

索引技術-GeoHash

GeoHash遍歷曲線圖

考慮到,GeoHash編碼有跳變的問題,如:從0111至1000 。因此,在使用GeoHash做空間索引時,可能會存在以下問題:

邊界問題

GeoHash實際上,是將區域劃分成矩形區域,並對其編碼。相鄰的兩個位置,不一定擁有一個較長的公共字首,通常在劃分的邊界上會出現該問題。如:表中0010和1000相鄰,但沒有較長公共字首。解決方案是,將搜尋區域擴充套件到目標位置的周圍8個區域。

非線性問題

由於GeoHash編碼是二進位制編碼生成。因此,相鄰的二進位制位之間,距離並不一定是最近的,如表中0111和1000二進位制相鄰,但距離並不是最近的。解決方案是,搜尋到相鄰結點後,需要再進一步計算實際距離。

參考

https://en。wikipedia。org/wiki/Geohash