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
お疲れ様でした。