OSM(オープンストリートマップ)のデータをPythonライブラリpandasで扱う | COMMONS NOTE

OSM(オープンストリートマップ)のデータをPythonライブラリpandasで扱う

こんにちはマダラです。

今回はpythonライブラリでも人気のpandasを利用して、OSM(オープンストリートマップ)をデータフレームとして扱っていきます。

たまたまオープンストリートマップを使う機会があり、その際に有用な情報ソースがstackoverflowの英語記事だけだったので、日本語で紹介すればニーズがあるのではと思ったのでしたw

研究でOSMを使う人も多いと思いので、誰かの役に立てばと思います。

OSMのデータをダウンロードする

まずはOSMのデータをダウンロードします。
下記からダウンロードすることができます。

http://download.geofabrik.de/asia.html?fbclid=IwAR2yy_2wwUVZVWDpxTQz1DB1DaENFDOoe4GbZM2OWq5NUUw08Pb271GbyQ4

全世界の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の仕様か知りませんが(調べる気もない)、小分けに出力すれば通りました。

ではでは。