施設名から経緯度を一括自動取得する方法
今さら感のある話題ですが、経緯度の公開されていない放射線量の自治体公開データから、住所や経緯度を一括で取得するやり方の説明をします。使用言語は Python です。Python 以外の言語でも、同じやり方でできるはず。1600 箇所の可視化、4400 箇所の可視化のときに使った方法です。
福島県が経緯度を公開してくれれば良かったのですが、例えばこの PDFのように、施設名しか公開してくれませんでした。そのときの文句は「4 月 19 日に福島県災害対策本部原子力班と電話した内容」に書きました。
1. 「iタウンページ」で住所を取得
NTT の提供するiタウンページを使用すると、施設名から住所を取得できます。例えば福島市立御山小学校の場合だと、こんな感じで検索すれば住所が表示されます。同名の小学校が存在する可能性もあるので、「福島県」や「福島市立」などを入れておくと正確に取得できます。
2. Google Maps で経緯度を取得
次に、取得した住所から経緯度に直すには Google Maps を使います。御山小学校の場合は住所が「福島県福島市御山字長滝1-1」ですので、これを引数に渡してこんな感じで情報を取ります。そうすると、うまく見つかった場合には「140.4585484, 37.7786954」という数値が取得できます。検索が失敗する場合もあります。
3. 使った Python Script
まずは元の PDF を Acrobat なりで開いた後に少し手を加えて、次のような CSV を作ります。
http://www.pref.fukushima.jp/j/schoolmonitamatome.pdf ,,,,,※測定値(μSv/h) 市町村,No.,区分,調査地点,調査月日,1m高さ,1cm高さ 福島市,1,公立小学校,福島市立御山小学校,2011/04/05,4.9,6.3 福島市,2,公立小学校,福島市立三河台小学校,2011/04/05,3.3,4.1 福島市,3,公立小学校,福島市立松川小学校,2011/04/05,2.3,2.7 福島市,4,公立小学校,福島市立下川崎小学校,2011/04/05,4.2,4.9 福島市,5,公立小学校,福島市立水原小学校,2011/04/05,2.1,2.7 福島市,6,公立小学校,福島市立金谷川小学校,2011/04/05,3.1,3.8
これを、次の Python script で読み込みます*1。
# -*- coding: utf-8 -*- import codecs import urllib2 import os f = codecs.open('school.csv', 'r', 'utf') for line in f.readlines()[3:]: name = line.split(',')[3] town = line.split(',')[0] if name.find(u'市立') >= 0: split_name = name.replace(u'市立', u'市立 ').split(' ') elif name.find(u'町立') >= 0: split_name = name.replace(u'町立', u'町立 ').split(' ') elif name.find(u'村立') >= 0: split_name = name.replace(u'村立', u'村立 ').split(' ') else: split_name = (name, '') try: url = u'http://itp.ne.jp/result/?kw=' + urllib2.quote(u'福島県'.encode('shift_jis')) + '+' + urllib2.quote(town.encode('shift_jis')) + '+' + urllib2.quote(split_name[0].encode('shift_jis')) + '+' + urllib2.quote(split_name[1].encode('shift_jis')) except: print name continue fp = urllib2.urlopen(url) html = fp.read() tmp = open('tmp.txt', 'w') tmp.write(html) tmp = codecs.open('tmp.txt', 'r', 'shift-jis') flag = False for tmpline in tmp.readlines(): if tmpline.find('class="icn"') >= 0: address = tmpline.split(u' ')[1].split('<a')[0] flag = True break if not flag: print name continue url = u"http://maps.google.com/maps/geo?q=" + address + u"+" + u"+福島県+日本&output=json&sensor=false" fp = urllib2.urlopen(url.encode("utf-8")) html = fp.read() for v in html.split("\n"): if v.find("coordinates") >= 0: break try: lng, lat = v.split("[ ")[1].split(", 0 ]")[0].split(", ") lng, lat = float(lng), float(lat) except: lng, lat = float('nan'), float('nan') print "%s\t%s\t%f\t%f" % (name, address, lat, lng)
そうすると、次のような出力が得られます。このやり方で 4400 箇所の 9 割以上は自動で経緯度の取得ができました。残った地点は、有志の皆さんのご協力で手入力で頑張りました。
福島市立御山小学校 福島県福島市御山字長滝1−1 37.778695 140.458548 福島市立三河台小学校 福島県福島市三河南町17−7 37.757742 140.453800 福島市立松川小学校 福島県福島市松川町字南諏訪原31−1 37.656167 140.464370 福島市立下川崎小学校 福島県福島市松川町沼袋字戸ノ内832−3 37.644727 140.500220 福島市立水原小学校 福島県福島市松川町水原字戸ノ内31 37.665687 140.420651 福島市立金谷川小学校 福島県福島市松川町浅川字陳場21 37.683573 140.465394
*1:当時、急いで勢い任せで書いたのを記事用にちょこっと修正しただけなので、もっと綺麗に書けます。