地図上に何かをプロットする場合、緯度経度が必要です。
詳しい住所があれば、国土地理院が提供するAPI等で緯度経度に変換ができるが、ランドマーク名(駅名や施設名、公園名など)しかない場合、どう緯度経度に変換するか、悩んでおったのです。(Google maps APIがあるが、有料なので)
たとえば、こんな具合のリストの項目を地図上にプロットしたい場合など。
ひとつひとつ、googlemapに入力していって調べる手もあるけど、リストが多くなると手間だ。
また、ばーっと調べて、かつ、自動でExcelに記入できる・・・なんて都合の良いことができないかと考えていたのだが、やってみると、あった!pythonを使うと簡単にできたのでした。
今回、やること
- Excelでランドマーク名のリスト
- ランドマークに対応した緯度経度を調べる
- 元のExcelに緯度経度を記入して保存
準備 – geopyとopenpyxlをインストール
今回、二つのlibraryを新しく使うので早速インストール。
▽GeoPy – ランドマーク名から緯度経度を調べることができる
▽openpyxl – pythonコンソール上からExcelファイルの読み込み・書き込みができる
pip install geopy
pip install openpyxl
これだけ。
Excelの読み込み・geopyの準備
Excelを適当な場所に保存して(ここでは「geocoding.xlms」として保存)、パスをコピーしておく。ちなみにファイルをshift+右クリックで出てくる「パスをコピー」を使うと便利。
# -*- coding: utf-8 -*-
import openpyxl
wb = openpyxl.load_workbook(r"C:\geocoding.xlsx")
ws = wb.worksheets[0]
これで読み込み完了。worksheetは1枚目を指定しています。
続いて、geopyの準備もしておきます。
from geopy.geocoders import Nominatim
geolocator = Nominatim(user_agent="test")
GeoPyはユーザー名を指定しないとエラーが出るので、適当に入れておきます。これで準備完了!
Excelからランドマーク名を取り出していくぞ
もう一度確認しておくと、ExcelはBの2~10がランドマーク名。
それぞれ、C列に緯度、D列に経度を記入していきます。
やることとしては・・・
- ExcelのB列の2~10まで繰り返しランドマーク名を取得
- 取得したランドマーク名に対して緯度と経度をそれぞれlat,lonに代入
- lat,lonをそれぞれのランドマークのC、D列に記入
- Excelを保存
です。ただし、「もし対応するランドマーク名が存在せず、緯度経度が取得できない場合は、エラーで泊まらず、空欄にせよ」という例外処理も書いています。
以下がコードです。
for i in range(2,10):
cell_place = "B"+str(i)
val = ws[cell_place].value
if val is None:
lat = None
lon = None
else:
try:
location = geolocator.geocode(val)
lat = location.latitude #緯度
lon = location.longitude #経度
except Exception as e:
lat = None
lon = None
cell_lat = "C"+str(i)
cell_lon = "D"+str(i)
ws[cell_lat]= lat
ws[cell_lon]= lon
wb.save(r"C:\geocoding.xlsx")
早速、実行してみます!
・・・あ、Permission Error。Excelを閉じて実行しないと「変更できないよ~」と言われてしまいます。Excelを閉じて再実行。
いくつかスキップされてしまいましたが、ほぼ埋まりました。たとえば増上寺を調べてみると・・・
ちゃんと表示されておりました。
これらのExcelファイルをQGSIで地図に描画する方法は、こちら。
漏れたところも微修正で
書き込めなかった2カ所についても、ランドマーク名をシンプルに変更するとちゃんと読み込まれました。
ランドマーク名を変更した後は、
wb = openpyxl.load_workbook(r"C:\geocoding.xlsx")
ws = wb.worksheets[0]
をやり直さないと、変更が反映されませんのでご注意下さい。
これは何を使って緯度経度を出しているのか?
GeoPyの公式ページを見てみると、GeoPy自体がジオコーディングをしているわけではなく、「ジオコーディングができるサービスにGeoPyが経由して緯度経度を取得できるのである」と書いています。
今回の例では、OpenStreetMapの無料サービスであるNominatimを使っていますが、たとえばGoogleMapsAPIの有料APIキーを持っていれば、そこにアクセスすることもできる…という訳です。pythonとジオコーディングサービスの橋渡しをしているのがGeoPy、というわけなのですね。なるほど。
※下記の環境で動作させました。
・Jupyterlab notebook Version 3.2.9-1
・Microsoft Windows [Version 10.0.19044.2251]
コメント