MongoDBで位置情報お手軽検索。あとついでにPython

MongoDB使ってますかー?便利ですよー?

最近、位置情報を処理するのにこのMongoDBを使っています。何故Mongoかと言うと
「この位置から500m以内の施設情報をヨコセ」
といった検索が超簡単にできるから。

論より証拠。
MongoDBには[緯度、経度]といった配列を含むデータをつっこんでおきます。こんな感じ。
[js]
db.test.save({‘id’:’hoge’, ‘place’:’新宿駅’, ‘loc’:[35.690921, 139.700258]});
db.test.save({‘id’:’hoge’, ‘place’:’スタジオアルタ’, ‘loc’:[35.69271580036533, 139.70121502876282]});
db.test.save({‘id’:’test’, ‘place’:’東京都庁’, ‘loc’:[35.68947430993086, 139.69163417816162]});
db.test.save({‘id’:’test’, ‘place’:’恵比寿駅’, ‘loc’:[35.64669, 139.710106]});
[/js]
…普通のデータ挿入と変わらないですね。
位置情報は「loc」というキーで持たせてあります。

地理空間インデックスを作成します。
[js]
db.test.ensureIndex({loc:’2d’});
[/js]

はい準備OK。検索は
{ loc: {$near: [ 検索基準の緯度, 検索基準の経度 ], $maxDistance: 範囲(単位:度) }}
で行います。

新宿駅から範囲500mの施設を検索
[js]
db.test.find({ loc: {$near: [ 35.690921, 139.700258 ], $maxDistance: 0.0044938568976209516 }})
[/js]

結果:
[js]
> db.test.find({ loc: {$near: [ 35.690921, 139.700258 ], $maxDistance: 0.0044938568976209516 }})
{ "_id" : ObjectId("4f535cc547a123a659ac5605"), "id" : "hoge", "place" : "新宿駅", "loc" : [ 35.690921, 139.700258 ] }
{ "_id" : ObjectId("4f535ccb47a123a659ac5606"), "id" : "hoge", "place" : "スタジオアルタ", "loc" : [ 35.69271580036533, 139.70121502876282 ] }
[/js]

となります。簡単ですね(・∀・)!
で、例によってPythonでやる場合。
※pymongoパッケージが必要です
[py]
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from pymongo import Connection, GEO2D

con = Connection()
db = con.test
db.test.ensure_index([(‘loc’, GEO2D)])

# 範囲を示すmaxDistanceの単位は’度’ ※1度 = 111.263km
KM = 1/111.263

def get_geodata(pos, distance):
"""
指定された位置と範囲にマッチする施設を表示する
"""
query = {‘loc’: {‘$maxDistance’ : KM * distance, ‘$near’ : pos}}
result = [r for r in db.test.find(query)]
if not result:
print u’範囲内に施設はありませんでした。’
else:
for r in result:
print r[‘place’]

# 検索起点を歌舞伎町近辺に設定
pos = [35.69377884112287, 139.70155835151672]

line = ‘-‘ * 30
print u’歌舞伎町から5m以内にある施設 %s’ % line
get_geodata(pos, 0.005)

print u’\n500mにある施設 %s’ % line
get_geodata(pos, 0.5)

print u’\n5km以内にある施設 %s’ % line
get_geodata(pos, 5)

print u’\n10km以内にある施設 %s’ % line
get_geodata(pos, 10)
[/py]

実行結果

簡単ですよね!
というわけで、位置情報検索する際はMongoDB使うと便利だと思うのです(・ω・)ノ

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください