Hatena::ブログ(Diary)

Relevant, Timely, and Accurate

 | 

2008-06-03

グリッドとしても座標表現としても使える Geohash

自由に使える経緯度の符号化法 Geohash がグリッドとしても座標表現としても使えてうれしいです。

Geohash とは?

Geohash (http://en.wikipedia.org/wiki/Geohash) が色々と使われているようです(http://zcologia.com/news/759/geohash-and-bigtable/) 。

この Geohash、ビット列を経度・緯度の順に交代に2分割するように解釈し、BASE32 で符号化するもので、Wikipedia の短い記事で仕様が完結しており、自由に使えます。

この Geohash、よく考えられていると思います。Geohash は点を表現するものですが、その点と同じ Geohash を持つ面のグリッドであると解釈することも簡単です。グリッドと座標の表現を、Geohash 一つで済ますことができます。

Geohash のグリッドの大きさ=座標の分解能は?

Geohash 1文字が空間を5回2分割するので、グリッドの大きさはあまり選べないのですが、その大きさがなかなか都合が良いのです。次のプログラムで調べてみました。

(1..16).map {|i|
  lng_bit = (5 * i / 2.0).ceil
  lat_bit = (5 * i / 2.0).floor
  lng_grid_size = sprintf("%6.6f", 360.0 * 60 * 60 / 2 ** lng_bit)
  lat_grid_size = sprintf("%6.6f", 180.0 * 60 * 60 / 2 ** lat_bit)
  [i, lng_bit, lat_bit, lng_grid_size, lat_grid_size]
}.each do |r|
  print "|#{r.join('|')}|\n"
end

その結果は、次のとおりになります:

Geohash文字数経度方向の2分割回数緯度方向の2分割回数経度方向のグリッド辺長(秒)経度方向のグリッド辺長(秒)
132162000.000000162000.000000
25540500.00000020250.000000
3875062.5000005062.500000
410101265.625000632.812500
51312158.203125158.203125
6151539.55078119.775391
718174.9438484.943848
820201.2359620.617981
923220.1544950.154495
1025250.0386240.019312
1128270.0048280.004828
1230300.0012070.000603
1333320.0001510.000151
1435350.0000380.000019
1538370.0000050.000005
1640400.0000010.000001

Geohash 文字数が奇数であれば、経緯度座標系で正方格子になり、偶数であれば"横長"の格子になります。この"横長"さは、投影のことを考えると多少緩和されます。Geohash を空間インデクスっぽく使うのであれば、グリッドの大きさを基準に考えればよいでしょう。

Geohash6グリッド・Geohash16座標

例えば、旅行スケールの地図データであれば、Geohash 6 文字でグリッドを切れば、それは40秒 x 20秒メッシュですので良い大きさのグリッドとなりそうです。座標表現としては、通常の用途では 10 文字あれば十分でしょうし、かなりの精度を求める場合でも、15、16文字あたりを考えておけば、少なくとも10万分の1秒程度の有効数字を持つことになりそうです。

 | 
Connection: close