こんにちはマダラです。
今回はpythonライブラリでも人気のpandasを利用して、OSM(オープンストリートマップ)をデータフレームとして扱っていきます。
たまたまオープンストリートマップを使う機会があり、その際に有用な情報ソースがstackoverflowの英語記事だけだったので、日本語で紹介すればニーズがあるのではと思ったのでしたw
研究でOSMを使う人も多いと思いので、誰かの役に立てばと思います。
OSMのデータをダウンロードする
まずはOSMのデータをダウンロードします。
下記からダウンロードすることができます。
全世界のplanetデータや日本だけのデータ、関東地方レベルのサイズのデータまでダウンローデできます。
このサイトで、.osm.bz2の拡張子のデータをダウンロードしてください。
ダウンロードしたファイルを解凍すればosm拡張子の生データを得ることができます。
このosmの状態だとすこぶる使いづらいので、pandasで扱える形にしていきたいと思います。
osm生データをpandasのデータフレームに変換する
それでは本題のosmをpandasに扱える形にしていきましょう。
といってもコードはほとんどコピペです笑
今回は関東のosmデータを取ってきたのでkanto-latest.osmですが、その部分を皆さんの取ってきたosmファイルのパスに変更してください
import osmium as osm
import pandas as pd
class OSMHandler(osm.SimpleHandler):
def __init__(self):
osm.SimpleHandler.__init__(self)
self.osm_data = []
def tag_inventory(self, elem, elem_type):
for tag in elem.tags:
lon_lat=["none","none"]
if elem_type=="node":
lon_lat = str(elem.location).split('/')
self.osm_data.append([elem_type,
elem.id,
lon_lat[1],
lon_lat[0],
elem.version,
elem.visible,
pd.Timestamp(elem.timestamp),
#elem.uid,
#elem.user,
elem.changeset,
len(elem.tags),
tag.k,
tag.v
])
def node(self, n):
self.tag_inventory(n, "node")
def way(self, w):
self.tag_inventory(w, "way")
def relation(self, r):
self.tag_inventory(r, "relation")
osmhandler = OSMHandler()
osmhandler.apply_file("kanto-latest.osm")
data_colnames = ['type', 'id','latitude', 'longitude', 'version', 'visible', 'timestamp', 'chgset', 'len_tags', 'tagkey', 'tagvalue']
df = pd.DataFrame(osmhandler.osm_data, columns=data_colnames)
処理が終われば、df.head()で確認してみましょう。
なお、データの処理数が大きすぎるのかjsonで一度に保存しようとしたらエラーになりました。
pcのメモリが足りないのか、pandasの仕様か知りませんが(調べる気もない)、小分けに出力すれば通りました。
ではでは。