【データの集め方講座】Pythonで地図データを操る-場所の名前から画像作成-
はじめに
ごあいさつ
ご高覧いただきありがとうございます.
ソフトウェアエンジニアのKitaharaです.
本日は地図データの収集方法を解説します!
地図情報を取得すると何がいいのか
今回のテーマの地図情報ですが, 用途はいくつかあります.
例えば, 自社の顧客の所在地をマッピングすることで顧客の潜在的特性を分析することなどが考えられます. 意外かもしれませんが, 住所だけ見ていてもわからないことが地図にすることで分かったりすることがあります. (「バラバラの住所だと思っていたらすべて海の近くだった!」などなど…)
また, 観光地のサイト等で観光場所にピンをさした図があれば非常に便利なものになるでしょう. (今回は地図のhtmlデータの作成もします!)
このように地図データは扱えるとなかなか利便性が高く活用できる幅も広いので興味を持ったらご自身でも動かしてみてください!
使用するものの説明
今回はPythonのライブラリが三つ出てきます
Python
プログラミング言語のひとつです.
Google Colab
Googleが提供するPythonの実行環境です
主要なライブラリがインストールされている状態で使うことができます
Chromeでアクセスするだけで利用することができます
環境構築が不要です
無料で使うことができます
Goecoder
シンプルで確実なgeocodingができるPythonのライブラリです.
機能
場所の名前から情報を検索するFowerd Geocodingと緯度経度から情報を検索するReverse Geocodingができます.
他にも家の住所から検索することやIP Addressから検索する機能もあります
今回使うOpenStreetMapの以外にもGoogole Map等たくさんの提供者がいます
公式ドキュメント
Folium
Pythonで操作したデータをインタラクティブなリーフレットマップに可視化するライブラリ
HTMLデータとして保存する機能をもつ
Selenium
Webブラウザの操作を自動で行うためのフレームワークです
もともとはWebアプリケーションのテスト等で使うことを目的に開発されましたが, 現在ではWebスクレイピング(Webサイトからデータを取得すること)を目的に利用されることも多いです
今回はHTMLデータを画像化するために使います
環境構築
Selenium
まずはGoogle Colabに登録してSeleniumをインストールしましょう.
やり方が分からない方は下記の記事を参考にしてみてください.
Geocoder & Folium
下記のコードをGoogle Colubで実行してください
# Google Colubでコマンドを打つときは「!」を先頭に付ける
!pip install geocoder
!pip install folium
これで今回使うライブラリはすべて揃いました!
Geocoderの仕様を知る
本題に行く前にGeocoderの仕様を少しだけ説明します.
Forwerd Geocoding
Geocoderでは場所の名前から情報を検索するFowerd Geocodingと緯度経度から情報を検索するReverse Geocodingができます. このFowerd Geocodingですが, 常に一つの結果を返します.
例えば, 東京駅を検索した場合は以下の様な出力が得られます.
import geocoder
# 東京駅の住所を検索
g = geocoder.osm('東京駅')
print(g.address)
### return
# 東京駅丸の内駅舎, 1, 丸の内中央広場, 丸の内1, 丸の内, 千代田区, 東京都, 100-0005, 日本
はい, 確かに一つのようです. しかし現実として, 一つに定まらない場所が存在するのも事実です. 例えば, 「稲荷神社」は全国各地にあるように思えます.
その場合においてもGeocoderは出力を一つ返します.
import geocoder
g = geocoder.osm('稲荷神社')
print(g.address)
### return
# 稲荷神社, 水門町, 東区, 岡山市, 岡山県, 日本
Geocoderのドキュメントによると提供者(今回はOpenStreetMap)にとって最も一致する場所なのだそうです.
では, 残りの全国各地の「稲荷神社」のデータは集められないのでしょうか? Geocoderはこの問題を解決する手段を持っています.
import geocoder
# 「稲荷神社」と思われる複数の場所のデータを集める
g = geocoder.osm('稲荷神社', maxRows=100)
for result in g:
print(result.address, result.latlng)
# return
# 稲荷神社, 都営練馬富士見台三丁目アパート, 練馬区, 東京都, 177-0034, 日本 [35.7412303, 139.62044383393018]
# 稲荷神社, 水門町, 東区, 岡山市, 岡山県, 日本 [34.612060400000004, 134.05889265565037]
# 稲荷神社, 上福田, 大仙市, 秋田県, 日本 [39.48857425, 140.54156666419016]
# ...
折角なので今回はこの稲荷神社の場所を可視化してみることにします.
Reverse Geocoding
Geocoderの他の記事はForwerd Geocodingが多かったのですが, Reverse Geocodingもできます.
具体的には以下のように記述します.
g = geocoder.osm([43.6773098, 142.4592705091312], method='reverse')
for i in g:
print(type(i))
print(i)
print(type(str(i)))
l=str(i)[1:-1].replace(',','').split() # 文字列を整形してリストに変換
print(l)
# return
# <class 'geocoder.osm.OsmResult'>
# [南十三号, 東神楽町, 上川郡(石狩国), 上川総合振興局, 北海道, 071-1562, 日本]
# <class 'str'>
# ['南十三号', '東神楽町', '上川郡(石狩国)', '上川総合振興局', '北海道', '071-1562', '日本']
こちらも便利なのですが, 別の機会に使うこととします.
Foliumの使い方を学ぶ
次はFoliumです.
Foliumを使う時はまずmapを作成して次に表示します.
import folium
# mapを作成
map = folium.Map(
location=[45.5236, -122.6750],, # 緯度経度を入力
zoom_start=13 # 地図がどのぐらい拡大しているかを指定する
)
# mapを表示
map
# mapを保存
map.save('index.html)
地図データを使って可視化するためにmapにピンをさしたいときがあると思います. ピンは以下のようにして追加していきます.
folium.Marker(
location=[latitude, longtude], # 緯度経度を入力
popup=name, # ポップアップするときに表示する名前を入力
icon=folium.Icon( #iconを入力
color='red',
icon='info-sign'
)
).add_to(map) # どのマップデータにピンをさすのかを指定
ピンのアイコンはこのサイトから選べるようです.
色々あるので工夫のし甲斐がありますね!
seleniumでスクリーンショットを取る
自動でスクリーンショットを取る方法と言われると難しそうですが, seleniumでは簡潔に記述することが可能です.
from selenium import webdriver
import os
import time
options = webdriver.ChromeOptions()
options.add_argument('--headless') # headlessモードを使用する
options.add_argument('--no-sandbox') # sandboxモードを解除する(クラッシュの回避)
options.add_argument('--disable-dev-shm-usage') # /dev/shmパーティションの使用を禁止にする(クラッシュの回避)
options.add_argument('--disable-extensions') # 拡張機能を無効にする
map_file_name = 'map.html'
map_url = 'file://{0}/{1}'.format(os.getcwd(), map_file_name)
driver.get(map_url) # データを取得
time.sleep(5)
driver.save_screenshot('inari.png')
さて, ここまででデータの取得から可視化の方法まで一通りできたので次は実際に一連の動作を一気に動かしてみましょう!
GeocoderとFoliumとSeleniumで稲荷神社の場所を可視化
早速コードを書いていきましょう.
(Geocoderは住所の出力にクセがあり, データの整形をしているので若干コードが長くなっています.)
import geocoder
import folium
# 稲荷神社の場所と名前をリストに保存
g = geocoder.osm('稲荷神社', maxRows=1000)
inari_latlng_list = []
address_name_list = []
for result in g:
# Geocoderの出力を整形した後にリストに追加
inari_latlng_list.append(result.latlng)
address_list = result.address.split()
address = ''
for i in range(1,len(address_list)-2):
tmp = address_list[i].replace(',','')
address = address +' '+ tmp
address_name_list.append(address)
print('稲荷神社の数:',len(inari_latlng_list))
# mapの作成
center_lat=38.50000
center_lon=141.00000
f = folium.Figure(width=1000, height=500)
map = folium.Map(location=[center_lat, center_lon], zoom_start=5)
# 稲荷神社の場所にピンをさす
for i in range(len(inari_latlng_list)):
latitude = inari_latlng_list[i][0]
longtude = inari_latlng_list[i][1]
name = address_name_list[i]
folium.Marker(
location=[latitude, longtude],
popup=name,
icon=folium.Icon(
color='red',
icon='info-sign'
)
).add_to(map)
実行ができたらGoogle Colabの左側にあるファイルのアイコンを押してみてください. 現在のディレクトリに存在するファイルを見ることができます.
map.htmlが生成できていることを確認したら以下のコードを実行してみましょう.
from selenium import webdriver
import os
import time
options = webdriver.ChromeOptions()
options.add_argument('--headless') # headlessモードを使用する
options.add_argument('--no-sandbox') # sandboxモードを解除する(クラッシュの回避)
options.add_argument('--disable-dev-shm-usage') # /dev/shmパーティションの使用を禁止にする(クラッシュの回避)
options.add_argument('--disable-extensions') # 拡張機能を無効にする
map_file_name = 'map.html'
map_url = 'file://{0}/{1}'.format(os.getcwd(), map_file_name)
driver = webdriver.Chrome('chromedriver', options=options) # Driverを起動
driver.get(map_url) # データを取得
time.sleep(5)
driver.save_screenshot('inari.png')
driver.quit()
先程と同じファイルのアイコンをクリックしてみてinari.pngがあれば成功です. ダウンロードして確認してみてください.
稲荷神社の場所を可視化することができました!
稲荷神社は全国どこにでもあるものとおもっていましたが, 意外と一定の地域に集中しているようです.
おわりに
今回はPythonを使って地図情報を取得・可視化する方法を解説しました!
参考になったという方はぜひハートボタンを押していってください!
モチベーションが上がります!
記事内で不明な点等ございましたら気軽にご連絡ください.
Twitter: @kitahara_dev
email: kitahara.main1@gmail.com
参考文献
この記事が気に入ったらサポートをしてみませんか?