Google Colaboratoryを使って、BODIK APIを使ったPythonプログラムを書いてみます。
課題2:地図に表示してみる
問題:BODIK APIを使って、AEDを検索し、結果を地図に表示(マーカーを表示)する。
基本情報
- Pythonで地図を表示する場合、「Leaflet」のPythonライブラリである「folium」ライブラリが使えます。
- Google ColaboratoryでFoliumを使うためには、foliumをインストールする必要があります。
「!pip install folium」でインストールしてください。 - foliumにはいくつかの関数が用意されています。
| folium関数 | 機能 | 例 |
|---|---|---|
| folium.Map | マップを作成する | map = folium.Map(location, zoom_start) |
| folium.Popup | ポップアップを作成する | popup = folium.Popup(text, max_width) |
| folium.Marker | マーカーを作成する | marker = folium.Marker(location, popup).add_to(map) |
| folium.GeoJson | GeoJsonを読み込む | folium.GeoJson(geojson).add_to(map) |
swaggerで試す
最初に、WAPIのswagger(https://wapi.bodik.jp/docs)でAPIを試してみましょう。
AED(GET /aed)のエンドポイントを表示し、「try it out」のボタンを押します。
今回は位置情報が欲しいので、いくつかのパラメータを指定します。

下の方にある青い「Execute」ボタンを押します。
検索結果が表示されます。「Request URL」のところを確認します。

パラメータ部分が変わりました。 select_type=geometry maxResults=10 lat=33.59328962901721 lon=130.35598920962553 distance=2000
pythonで記述
では、Pythonで「BODIK API」を呼び出してみましょう。
緯度と経度を指定して、位置情報を取り出します。
位置情報は、featureの「geometry」に格納されています。
import requests
import json
api_server = 'https://wapi.bodik.jp'
apiname = 'aed'
lat=33.59328962901721
lon=130.35598920962553
distance=2000
url = f'{api_server}/{apiname}?select_type=geometry&lat={lat}&lon={lon}&distance={distance}&maxResults=10'
response = requests.get(url)
data = response.json()
features = data['resultsets']['features']
for feature in features:
properties = feature['properties']
geometry = feature['geometry']
print(json.dumps(geometry, indent=2, ensure_ascii=False))
featureのgeometryは、次のような構造になっています。
「type」が「Point」になっていますので、「coordinates」は位置情報となり、データ型は配列です。
この配列には、緯度(latitude)と経度(longitude)の数値が格納されていますが、「緯度、経度」ではなく、「経度、緯度」になっているので注意が必要です。
geometry = {
'type': 'Point',
'coordinates': [ lon, lat ] # latとlonが逆になっていることに注意する
}
検索結果のgeometryから「緯度、経度」がわかるので、地図上のその場所に印(マーカーといいます)を付ければいいですね。
Pythonで地図を表示するにはどうしたらいいのでしょうか?
pythonで地図を表示
pythonで地図を表示する方法として、LeafletのPythonライブラリ「folium」を使います。
# google colabにfoliumをインストールする(1回でOK) !pip install folium
とりあえず、地図を表示してみましょう。
import folium # 地図の中央の緯度経度を指定する lat = 33.59328962901721 lon = 130.35598920962553 center = [ lat, lon ] # 地図を作成する map = folium.Map(location=center, zoom_start=14) # 地図を表示する map
これだけのコードで地図を表示できました。
地図にマーカーを立てる
地図の指定した場所にマーカーを立てる方法を調べます。
# lat, lonで指定された場所にマーカーを作成する pos = [ lat, lon ] folium.Marker(location=pos).add_to(map)
マーカーをクリックしたときにポップアップを表示したい。
title = 'ポップアップに表示する文字列' mypopup = folium.Popup(title, max_width=300) # lat, lonで指定された場所にマーカーを作成する pos = [ lat, lon ] folium.Marker(location=pos, popup=mypopup).add_to(map)
BODIK APIと組み合わせる
地図を作成し、表示する前に、BODIK APIを呼び出すコードを追加します。
import requests
import json
import folium
# 地図の中央の緯度経度を指定する
lat = 33.59328962901721
lon = 130.35598920962553
center = [ lat, lon ]
# 地図を作成する
map = folium.Map(location=center, zoom_start=14)
# BODIK APIを呼び出す
api_server = 'https://wapi.bodik.jp'
apiname = 'aed'
lat=33.59328962901721
lon=130.35598920962553
distance=2000
url = f'{api_server}/{apiname}?select_type=geometry&lat={lat}&lon={lon}&distance={distance}&maxResults=10'
response = requests.get(url)
data = response.json()
features = data['resultsets']['features']
for feature in features:
properties = feature['properties']
geometry = feature['geometry']
#print(json.dumps(geometry, indent=2, ensure_ascii=False)) # コメントアウトしておく
# 地図を表示する
map
BODIK APIの検索結果から位置情報を取り出し、地図にマーカーを立ててみましょう。
import requests
import json
import folium
# 地図の中央の緯度経度を指定する
lat = 33.59328962901721
lon = 130.35598920962553
center = [ lat, lon ]
# 地図を作成する
map = folium.Map(location=center, zoom_start=14)
# BODIK APIを呼び出す
api_server = 'https://wapi.bodik.jp'
apiname = 'aed'
# APIのURLを組み立てる
url = f'{api_server}/{apiname}?select_type=geometry&lat={lat}&lon={lon}&distance=2000'
# BODIK APIを呼び出す
response = requests.get(url)
data = response.json()
features = data['resultsets']['features']
for feature in features:
properties = feature['properties']
geometry = feature['geometry']
# ポップアップを作成
title = properties['name']
mypopup = folium.Popup(title, max_width=300)
# マーカーを作成
location = geometry['coordinates']
marker_lat = location[1]
marker_lon = location[0]
pos = [ marker_lat, marker_lon ]
folium.Marker(location=pos, popup=mypopup).add_to(map)
# 地図を表示する
map
プログラム(完成版)
コメントとエラー処理を入れて完成です。
Google Colaboratoryの場合、画面出力は最後にないとうまく表示されないので、BODIK API部分だけを例外処理しています。
import requests
import json
import folium
# 地図の中央の緯度経度を指定する
lat = 33.59328962901721
lon = 130.35598920962553
center = [ lat, lon ]
# 地図を作成する
map = folium.Map(location=center, zoom_start=14)
try:
# BODIK APIを呼び出す
api_server = 'https://wapi.bodik.jp'
apiname = 'aed'
# APIのURLを組み立てる
url = f'{api_server}/{apiname}?select_type=geometry&lat={lat}&lon={lon}&distance=2000'
# BODIK APIを呼び出す
response = requests.get(url, timeout=5.0)
# APIの実行結果を確認する
if response is not None and response.status_code == 200:
# 結果をJSONで取得する
data = response.json()
# BODIK APIの検索結果を解析する
if data is not None and 'resultsets' in data:
resultsets = data['resultsets']
if 'features' in resultsets:
features = resultsets['features']
for feature in features:
properties = feature['properties']
geometry = feature['geometry']
# ポップアップを作成
title = properties['name']
mypopup = folium.Popup(title, max_width=300)
# マーカーを作成
location = geometry['coordinates']
marker_lat = location[1]
marker_lon = location[0]
pos = [ marker_lat, marker_lon ]
folium.Marker(location=pos, popup=mypopup).add_to(map)
else:
print('no features', resultsets)
else:
print('no resultsets', data)
else:
print('status_code', response)
except Exception as e:
print('Exception', e)
# 地図を表示する
map
お疲れ様でした。
