Ruby向けのQuadkeyライブラリを作りました

Ruby向けのQuadkeyライブラリを作りました
Photo by NEOM / Unsplash

quadkey gemを作りました。ベースは公式にあるC#のものです。

実は3年ぐらい前に公開しているものなので今更ですが。

Quadkeyとは

緯度経度を使って範囲を指定したいときに使われるGeohashと同じようなものです。

Geohashはその仕組み上、長方形で範囲を表現するので若干使いづらいところがあったんですが、Quadkeyは正方形で範囲を表現するのでGeohashより使いやすいかなと思います。

"Quadkeyとは"
https://docs.microsoft.com/en-us/bingmaps/articles/bing-maps-tile-system より

画像のようなイメージです。

地球全体を4分割、更に4分割という感じでドンドン分割していきます。

例えば、北半球のアメリカの辺りがQuadkeyの0になり、アジアからヨーロッパのあたりが1。みたいな感じです。

東日本のあたりを表すのは133となります。

という感じで桁数が1つ増えると範囲が1つ狭まります。

東京タワー周辺とかを表現する場合は1330021123031133になります。

使い方

READMEに書いてある通りですが、前述の東京タワーを例にしてみます。

緯度、経度、精度(桁数)からQuadkeyを計算する

Quadkey.encode(35.658638, 139.745413, 16)

=> "1330021123031133"

精度を16桁にすると614.4m四方の範囲にになります。

なのでこの場合、東京タワーの周辺614.4m四方あたりが対象になります。

精度に関してはズーム レベルとタイル グリッド | Microsoft Docsを見ると分かりやすいかなと思います。

Quadkeyから緯度、経度、精度を計算する

Quadkey.decode('1330021123031133')

=> [35.66175941929504, 139.7406005859375, 16]

Quadkeyからその周辺8マスのQuadkeyを取得

Quadkey.neighbors('1330021123031133')

=> ["1330021123031130", "1330021123031131", "1330021123120020", "1330021123031132", "1330021123031133", "1330021123120022", "1330021123031310", "1330021123031311", "1330021123120200"]

東京タワーの周辺614.4m四方の更に外の範囲を取得します。

具体的な使い方

例えば、現在地から約150m四方の範囲内にあるお店を調べる場合は以下のようなコードになります。

quadkey = Quadkey.encode(35.658638, 139.745413, 18) # 現在地のQuadkey
shops = Shop.where('quadkey like ?', "#{quadkey}%")

現在地のQuadkeyを取得する際に精度を18にすること152.8m四方の範囲を指定することになります。

そのQuadkeyを使って前方一致でwhereすることでその指定した範囲内にあるお店一覧を習得することが出来ます。

前方一致で検索するのでIndexが効きます。これ大きいですよね。

おわりに

もし測地系の処理をRubyで書いてる場合は是非使ってみてください。

以上、宣伝でした!