geohash和geohash聚合

Geohash原理

GeoHash本質上是空間索引的一種方式,其基本原理是將地球理解爲
一個二維平面,將平面遞歸分解成更小的子塊,每個子塊在一定經緯
度範圍內擁有相同的編碼。以GeoHash方式建立空間索引,可以提高
對空間poi數據進行經緯度檢索的效率。

認識Geohash

GeoHash將二維的經緯度轉換成字符串,比如下圖展示了北京9個區
域的GeoHash字符串,分別是WX4ER,WX4G2、WX4G3等等,每
一個字符串代表了某一矩形區域。也就是說,這個矩形區域內所有的
點(經緯度座標)都共享相同的GeoHash字符串,這樣既可以保護隱
私(只表示大概區域位置而不是具體的點),又比較容易做緩存。
--------------------在這裏插入圖片描述------------------
Geohash編碼中,字符串相似的表示距離相近(特殊情況後文闡

述),這樣可以利用字符串的前綴匹配來查詢附近的POI信息。如下

兩個圖所示,一個在城區,一個在郊區,城區的GeoHash字符串之間

比較相似,郊區的字符串之間也比較相似,而城區和郊區的GeoHash

字符串相似程度要低些。此外,不同的編碼長度,表示不同的範圍區

間,字符串越長,表示的範圍越精確。

在這裏插入圖片描述

GeoHash算法

以經緯度值:(116.389550, 39.928167)進行算法說明,對緯度39.928167進行逼近編碼 (地球緯度區間是[-90,90]

a、 區間[-90,90]進行二分爲[-90,0),[0,90],稱爲左右區間,可以確定39.928167屬於右區間[0,90],給標記爲1

b、 接着將區間[0,90]進行二分爲 [0,45),[45,90],可以確定39.928167屬於左區間 [0,45),給標記爲0

c、 遞歸上述過程39.928167總是屬於某個區間[a,b]。隨着每次迭代區間[a,b]總在縮小,並越來越逼近39.928167

d、 如果給定的緯度x(39.928167)屬於左區間,則記錄0,如果屬於右區間則記錄1,序列的長度跟給定的區間劃分次數有關,如下圖

在這裏插入圖片描述
e、 同理,地球經度區間是[-180,180],可以對經度116.389550進行編碼。通過上述計算, 緯度產生的編碼爲1 1 0 1 0 0 1 0 1 1 0 0 0 1 0,經度產生的編碼爲1 0 1 1 1 0 0 0 1 1 0 0 0 1 1

f、 合併:偶數位放經度,奇數位放緯度,把2串編碼組合生成新串如下圖
在這裏插入圖片描述
g、 首先將11100 11101 00100 01111 0000 01101轉成十進制,對應着28、29、4、15,0,13 十進制對應的base32編碼就是wx4g0e,如下圖.
在這裏插入圖片描述
h、同理,將編碼轉換成經緯度的解碼算法與之相反

GeoHash原理

Geohash其實就是將整個地圖或者某個分割所得的區域進行一次劃

分,由於採用的是base32編碼方式,即Geohash中的每一個字母或者

數字(如wx4g0e中的w)都是由5bits組成(2^5 = 32,base32),這

5bits可以有32中不同的組合(0~31),這樣我們可以將整個地圖區域

分爲32個區域,通過00000 ~ 11111來標識這32個區域。第一次對地圖

劃分後的情況如下圖所示(每個區域中的編號對應於該區域所對應的

編碼)。
在這裏插入圖片描述
Geohash的0、1串序列是經度0、1序列和緯度0、1序列中的數字交替

進行排列的,偶數位對應的序列爲經度序列,奇數位對應的序列爲緯

度序列,在進行第一次劃分時,Geohash0、1序列中的前5個

bits(11100),那麼這5bits中有3bits是表示經度,2bits表示緯度,所

以第一次劃分時,是將經度劃分成8個區段(2^3 = 8),將緯度劃分

爲4個區段(2^2 = 4),這樣就形成了32個區域。如下圖
------在這裏插入圖片描述------
同理,可以按照第一次劃分所採用的方式對第一次劃分所得的32個區

域各自再次劃分。

Geohash特點

Geohash 一個點附近的地方(但不絕對) hash 字符串總是有公共前

綴,並且公共前綴的長度越長,這兩個點距離越近。

GeoHash缺陷

z階曲線

在這裏插入圖片描述
上圖就是 Z 階曲線。這個曲線比較簡單,生成它也比較容易,只需要把每個 Z 首尾相連即可。

在這裏插入圖片描述
Z 階曲線同樣可以擴展到三維空間。只要 Z 形狀足夠小並且足夠密,也能填滿整個三維空間。

如圖所示,我們將二進制編碼的結果填寫到空間中,當將空間劃分爲四塊時候,編碼的順序分別是左下角00,左上角01,右下腳10,右上角11,也就是類似於Z的曲線,當我們遞歸的將各個塊分解成更小的子塊時,編碼的順序是自相似的(分形),每一個子快也形成Z曲線,這種類型的曲線被稱爲Peano空間填充曲線。

這種類型的空間填充曲線的優點是將二維空間轉換成一維曲線(事實上是分形維),對大部分而言,編碼相似的距離也相近,但Peano空間填充曲線最大的缺點就是突變性,有些編碼相鄰但距離卻相差很遠,比如0111與1000,編碼是相鄰的,但距離相差很大。
在這裏插入圖片描述
除Peano空間填充曲線外,還有很多空間填充曲線,如圖所示,其中效果公認較好是Hilbert空間填充曲線,相較於Peano曲線而言,Hilbert曲線沒有較大的突變。但是由於Peano曲線實現更加簡單,在使用的時候配合一定的解決手段,可以很好的滿足大部分需求,因此TD內部Geohash算法採用的是Peano空間填充曲線。
在這裏插入圖片描述

使用注意點

a、 由於GeoHash是將區域劃分爲一個個規則矩形,並對每個矩形進行編碼,這樣在查詢附近POI信息時會導致以下問題,比如紅色的點是我們的位置,綠色的兩個點分別是附近的兩個餐館,但是在查詢的時候會發現距離較遠餐館的GeoHash編碼與我們一樣(因爲在同一個GeoHash區域塊上),而較近餐館的GeoHash編碼與我們不一致。這個問題往往產生在邊界處。
--------------------------在這裏插入圖片描述------------------------
解決的思路很簡單,我們查詢時,除了使用定位點的GeoHash編碼進行匹配外,還使用周圍8個區域的GeoHash編碼,這樣可以避免這個問題。

b、 我們已經知道現有的GeoHash算法使用的是Peano空間填充曲線,這種曲線會產生突變,造成了編碼雖然相似但距離可能相差很大的問題,因此在查詢附近餐館時候,首先篩選GeoHash編碼相似的POI點,然後進行實際距離計算。

c、 GeoHash Base32編碼長度與精度。可以看出,當geohash base32編碼長度爲8時,精度在19米左右,而當編碼長度爲9時,精度在2米左右,編碼長度需要根據數據情況進行選擇。
--------在這裏插入圖片描述--------

Geohash單元聚合器

一個查詢返回的結果集中可能包含很多的點,以至於不能在地圖上全

部單獨顯示。 geohash單元聚合器可以按照你指定的精度計算每個點

的geohash並將相鄰的點聚合到一起。

返回結果是一個個單元格,每個單元格對應一個可以在地圖上展示的 geohash。 通過改變 geohash 的精度,你可以統計全球、某個國家,或者一個城市級別的綜述信息。

聚合結果是稀疏(sparse)的,因爲它只返回包含了文檔集合的單元。 如果你的geohash精度太細,導致生成了太多的結果集,它默認只會返回包含結果最多的10000個單元 – 它們包含了大部分文檔集合。 然後,爲了找出這排在前10000的單元,它還是需要先生成所有的結果集。 你可以通過如下方式控制生成的單元的數目:

  • 使用一個矩形過濾器來限制結果集。
  • 對應該矩形,選擇一個合適的精度。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章