【python】ランドマーク名でジオコーディング(geopy)

地図上に何かをプロットする場合、緯度経度が必要です。
詳しい住所があれば、国土地理院が提供するAPI等で緯度経度に変換ができるが、ランドマーク名(駅名や施設名、公園名など)しかない場合、どう緯度経度に変換するか、悩んでおったのです。(Google maps APIがあるが、有料なので)

たとえば、こんな具合のリストの項目を地図上にプロットしたい場合など。

緯度経度を出したいリストをExcelで整理した

ひとつひとつ、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列に経度を記入していきます。

ランドマーク名はB列、緯度が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が経由して緯度経度を取得できるのである」と書いています。

GeoPyの仕組み

今回の例では、OpenStreetMapの無料サービスであるNominatimを使っていますが、たとえばGoogleMapsAPIの有料APIキーを持っていれば、そこにアクセスすることもできる…という訳です。pythonとジオコーディングサービスの橋渡しをしているのがGeoPy、というわけなのですね。なるほど。

※下記の環境で動作させました。
・Jupyterlab notebook Version 3.2.9-1
・Microsoft Windows [Version 10.0.19044.2251]

コメント