Geohash

Geohash 是一個可將二維座標編碼為一個字串的演算法

Geohash 是一個可將二維座標編碼為一個字串的演算法,可應用於快速搜索特定位置鄰近的服務。雖其名為 hash,但它並不是一個不可逆的雜湊演算法,其字串是可以跟原始範圍進行雙向轉換的。

基本概念

對於任何二維平面,我們可以將其切分為均等的四個象限,並依序給予編號 0~3,即二進制 00-10

01 | 11
---+---
00 | 10

並且對所有的象限可以再進一步的各自的四個象限,亦依照同樣的邏輯給予編號,其編號就直接作為後綴補在原本的編號後面:

左上 01                  右上 11
01 01 | 01 11 || 11 01 | 11 11
------+-------||-------+------
01 00 | 11 10 || 11 00 | 11 10
==============++==============
00 01 | 00 11 || 10 01 | 10 11
------+-------||-------+------
00 00 | 00 10 || 10 00 | 10 10
左下 00                  右下 10

以此概念重複將每個區域切分,就可以將平面切成非常多的十分小的區域,並且就可以將地點用對應的編碼去進行表示,例如上圖原點右上第一區的座標即為 1100

應用到地理資訊上

基於上述的概念將整個地球座標編列進來之後可以得到這樣的圖:

fig_1.jpg Credit: Petrov et al. Geohash-EAS - a Modified Geohash Geocoding System with Equal-Area Spaces

這邊注意到雖然原始概念上是以 4 象限去切分區域,Geohash 卻不是以 16 或 64 為基數、而是以 32 的基數去切分區域,對應上圖可觀察到在第二級切分後有多一刀只切一半的現象;這個用意是方便將座標進行 base32 編碼1,並且每個字母直接對應到區域中的某個相對位置。

承接第一節所述,我們可以以同樣的規則將每個區域去細分,即: fig_2.jpg Credit: Petrov et al. Geohash-EAS - a Modified Geohash Geocoding System with Equal-Area Spaces

以此類推,即可將地表上所有的座標歸類到某一編碼當中,例如法國大約就在 u0 的位置。當我們用愈多字母(Geohash length)表示位置,其所匡到的面積就愈小、對應的座標就可以愈加精準,例如長度為 2 時大約可以匡列到 1252 x 624 公里的面積,但到長度為 9 時則約 5 x 5 公尺

如果想查 Geohash 跟經緯度的轉換,可以利用 Movable Type Scripts 這個網站。

特性

在上面的例子中可以注意到,由於是將地理區域往下去做細分,故當兩個 Geohash 共用了愈長的前綴,則兩者的地理位置愈接近。如 wsqqmpw2f (台北車站)及 wsqqmpc9q (北門)共用了 5 碼(wsqqmp),而實際上距離 600 公尺。

但事實上,兩個相近的點卻不一定有相似的前綴,主因為這個編碼模式是依照象限去切分,若某地剛好就位於軸線附近時,則兩個相近的地點有可能發生其前綴差異很大的狀況。例如剛好處在經度 0/45/90/135 度、緯度 0/45 度等交界附近的地區,就會發生距離很近、但連第一碼都不共用的狀況。

  1. 注意 Geohash 使用的 base32 並非使用 RFC 4648 版本的表格。其對照表可參考 Wikipedia,基本上是一個數字完才接字母、且不使用 ailo 的版本,應該是不想要英文跟數字看起來混淆所以這樣設計。