ソフトウェアを研究・検証していると、以下の処理をしたいと思うことが多いかと思います。
- 住所を緯度経度に変換(ジオコーディング)
- 緯度経度から住所に変換(逆ジオコーディング)
一般的には Google Maps API や OpenStreetMap (OSM) の公開 Nominatim サーバー を利用します。Google Maps API は無料枠を超えると有料です。一方、OSM の公開サーバーは無料で使えますが、公式の利用ポリシーにより 最大 1 リクエスト/秒、アプリ固有の User-Agent/Referer の付与、OSM へのアトリビューション、バルク用途の非推奨 といった制限があり、検証で大量に繰り返す用途や商用の継続運用には適しません[1]
しかし、検証などで複数回リクエストをおくって、多くの情報を抽出したくなることが多いと思います。
そこで、リクエスの制限を気にせずに情報を抽出する方法として、自分の環境にNominatimの環境をセルフホストすることで実現できます。
今回は、自環境にNominatim API をセルフホストしてみます。
セルフホストは docker 環境で構築するとします。Nominatimでは高品質なdocker image が提供されているのですが、自分が使いやすいようにdockerfileを修正しています。
Dockerfileはこちらホスティングしてます。
以下の方法で、Nominatimをセルフホストすることができます。
これまで、有料でったりして諦めていた検証が比較的自由にできるのでおすすめです。
環境構築
$ git clone https://github.com/hisashi-ito/nominatim-docker.git
$ cd nominatim-docker/docker
# image だけ先にビルドします
$ ./build.sh
# docker を起動します
$ ./launch.sh
Nominatim のビルドとAPIの起動
/app/start.sh
を実行すると、DB取得、DB登録、APIの起動まで全て行います。
今回の実験では日本のデータベースをダウンロードしました。容量は数GB程度で、API 起動までにかかった時間は私の環境では約 55 分でした。
$ sudo docker exec -it nominatim-v1.0.0 bash
# cd /app
# nohup ./start.sh &> ./start.txt &
動作確認
venv で仮想環境を作成し、その中で動作確認を行います
$ sudo docker exec -it nominatim-v1.0.0 bash
# apt install python3.12-venv
# cd /opt/src
# python3 -m venv myenv
# source myenv/bin/activate
# python3 ./geo.py
皇居: 35.68384665 139.75068590345364
皇居: 皇居, 1, 千代田, 千代田区, 東京都, 100-0001, 日本
Sample (geo.py)
from geopy.geocoders import Nominatim
geo = Nominatim(
user_agent="nominatim/1.0",
scheme="http",
domain="localhost:8080"
)
# geocoding
loc = geo.geocode("皇居", language="ja", country_codes="jp")
print("皇居:",loc.latitude, loc.longitude)
# 逆geocoding
rev = geo.reverse((loc.latitude, loc.longitude), language="ja")
print("皇居:", rev.address)
[1] Nominatim 利用ポリシー
https://operations.osmfoundation.org/policies/nominatim/