横浜市の地域防災拠点データ

横浜市の地域防災拠点データは、オープンデータとして提供されています。
http://www.city.yokohama.lg.jp/somu/org/kikikanri/data/

データはXML形式で提供されています。提供されている内容は
– 拠点名
– 区名
– 住所
– 拠点の機能

の4つでです。
このデータをXMLをパースし、地図にプロットするためには位置情報が必要になります。
住所から座標を取得するために、GoogleのAPIを利用します。

GoogleAPIを利用するには、APIキーの取得が必要です。

XMLとGooleAPIで入手した位置情報をJSON形式にしてファイルに保存します。
コードは以下のようになります。

from bs4 import BeautifulSoup
import requests
import json
import time

base_param = {
'key' :'APIキー',
'language':'JP'
}
geourl = 'https://maps.googleapis.com/maps/api/geocode/json'

CITY = '横浜市'

def create_address(ward,address):
return CITY + ward + address

def call_geo_api(address):
base_param['address'] = address
geo_response = requests.get(geourl,base_param)
if (geo_response.status_code == 200):
geo_results = geo_response.json()
lat = geo_results['results'][0]['geometry']['location']['lat']
lng = geo_results['results'][0]['geometry']['location']['lng']
return lat, lng

url = requests.get('http://www.city.yokohama.lg.jp/somu/org/kikikanri/data/shelter.xml')
url.encoding = url.apparent_encoding
bsObj = BeautifulSoup( url.text,'lxml')

shelter_list = bsObj.findAll('shelter')

data = {}
shelter_t = []
for shelter in shelter_list:
    info ={}
    info['name'] = shelter.find('name').get_text()
    info['ward'] = shelter.find('ward').get_text()
    info['address'] = shelter.find('address').get_text()
    info['notes'] = shelter.find('notes').get_text()

    lat,lng = call_geo_api(create_address(info['ward'] , info['address']))
    info['lat'] = lat
    info['lng'] = lng

    print(info)
    shelter_t.append(info)
    time.sleep(1)

data['results'] = shelter_t
f = open('result.json','w')
json.dump(data,f,ensure_ascii=False)
f.close()

地図へのプロット

地図へプロットは、GoogleMapを使用しても良いのですが、今回はpythonの
地図表示ライブラリfoliumを使用します。

先程、保存したJSONデータを読み込み、プロットします。foliumはとてもシンプルに
プログラミングができます。pythonプログラマーならGoogleMapは使わずに
foliumを使ってみましょう。

foliumのイストールは、pipコマンドで行います。

pip install folium

コードと実行結果は以下のようになります。

import json
import folium

f = open('result.json','r')
data = json.load(f)
f.close()

map_1 = folium.Map(location =[ 35.469716 , 139.629184],
zoom_start=14,
)

for shelter in data['results']:
    popup_text = '{0}:{1}'.format(shelter['name'],shelter['notes'])
    folium.Marker( [ shelter['lat'], shelter['lng']] ,
    popup=popup_text,
    icon=folium.Icon(color='red',icon='info-sign')).add_to(map_1)
map_1

実行結果

 
GoogleMapと同様に拡大・縮小、マーカー指定などの機能が使えます。