グリッドとしても座標表現としても使える 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分割回数 | 経度方向のグリッド辺長(秒) | 経度方向のグリッド辺長(秒) |
1 | 3 | 2 | 162000.000000 | 162000.000000 |
2 | 5 | 5 | 40500.000000 | 20250.000000 |
3 | 8 | 7 | 5062.500000 | 5062.500000 |
4 | 10 | 10 | 1265.625000 | 632.812500 |
5 | 13 | 12 | 158.203125 | 158.203125 |
6 | 15 | 15 | 39.550781 | 19.775391 |
7 | 18 | 17 | 4.943848 | 4.943848 |
8 | 20 | 20 | 1.235962 | 0.617981 |
9 | 23 | 22 | 0.154495 | 0.154495 |
10 | 25 | 25 | 0.038624 | 0.019312 |
11 | 28 | 27 | 0.004828 | 0.004828 |
12 | 30 | 30 | 0.001207 | 0.000603 |
13 | 33 | 32 | 0.000151 | 0.000151 |
14 | 35 | 35 | 0.000038 | 0.000019 |
15 | 38 | 37 | 0.000005 | 0.000005 |
16 | 40 | 40 | 0.000001 | 0.000001 |
Geohash 文字数が奇数であれば、経緯度座標系で正方格子になり、偶数であれば"横長"の格子になります。この"横長"さは、投影のことを考えると多少緩和されます。Geohash を空間インデクスっぽく使うのであれば、グリッドの大きさを基準に考えればよいでしょう。
Geohash6グリッド・Geohash16座標
例えば、旅行スケールの地図データであれば、Geohash 6 文字でグリッドを切れば、それは40秒 x 20秒メッシュですので良い大きさのグリッドとなりそうです。座標表現としては、通常の用途では 10 文字あれば十分でしょうし、かなりの精度を求める場合でも、15、16文字あたりを考えておけば、少なくとも10万分の1秒程度の有効数字を持つことになりそうです。