0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OSRMをDockerで動かす:OSMデータ取得からAPI確認・Folium可視化まで

Posted at

はじめに

経路探索やルート最適化を扱うとき、単純なユークリッド距離(直線距離)ではなく、
実際の「道路距離」や「所要時間」を使いたいケースが多くあります。

例えば以下のような場面です:

  • 配送ルートの最適化
  • 観光ルートの提案
  • 移動時間のシミュレーション

このような現実的な距離・時間を取得できるオープンソースのルーティングエンジンが
OSRM(Open Source Routing Machine) です。

OSRM は OpenStreetMap のデータを利用し、
REST API として距離や所要時間を簡単に取得できるようになります。

本記事では、Windows 11 環境を例に以下の手順をハンズオン形式で実施します:

  1. Docker と OSM データを準備する
  2. OSRM の前処理を実行する
  3. OSRM サーバを起動して API を確認する
  4. Folium でルートを可視化する

これにより、「道路距離・所要時間を扱える環境」をローカルに構築し、
地図上にルートを描画して確認する
ことがゴールとなります。

環境準備

本記事では以下の環境を前提とします:

  • Windows 11
  • Docker Desktop(インストール済み)
  • Git Bash(コマンド実行に使用)
  • Python(インストール済み、後半で可視化に使用)

Docker Desktop のインストール手順や動作確認(hello-world)は本記事では省略します。
インストールがまだの場合は、公式サイト を参照してください。

OSMデータの取得

OSRM を動かすには、OpenStreetMap (OSM) の地図データが必要です。
これは Geofabrik から地域ごとに入手できます。

データの選択

  • 日本全体のデータもありますが、サイズが大きく処理に時間がかかります。
  • まずは軽量で扱いやすい 関東地方のデータ を使用します。

ダウンロード先:
Geofabrik - Kanto

ファイル名:

  • kanto-latest.osm.pbf

保存先ディレクトリ

本記事では以下のディレクトリに保存したとします:

例:
project_dir/osrm/kanto-latest.osm.pbf

これで OSM データの準備が整いました。

OSRMの前処理

OSM データをそのままでは利用できないため、
OSRM で使える形式に変換する「前処理」を行います。

この処理は以下の 3 ステップです:

  1. extract:OSM データを抽出
  2. partition:データを分割
  3. customize:探索用の重み付けを設定

前処理コマンド(Git Bash)

作業ディレクトリ:project_dir
保存先:project_dir/osrm/kanto-latest.osm.pbf

# OSRM イメージを取得(初回のみ)
docker pull osrm/osrm-backend

# extract
WINPWD="$(pwd -W)"
MSYS_NO_PATHCONV=1 docker run --rm -t \
  -v "$WINPWD/osrm:/data" \
  osrm/osrm-backend \
  osrm-extract -p /opt/car.lua /data/kanto-latest.osm.pbf

# partition
MSYS_NO_PATHCONV=1 docker run --rm -t \
  -v "$WINPWD/osrm:/data" \
  osrm/osrm-backend \
  osrm-partition /data/kanto-latest.osrm

# customize
MSYS_NO_PATHCONV=1 docker run --rm -t \
  -v "$WINPWD/osrm:/data" \
  osrm/osrm-backend \
  osrm-customize /data/kanto-latest.osrm

※ Git Bash ではパスの自動変換を防ぐため、先頭に
MSYS_NO_PATHCONV=1 を付けています。

生成されるファイル

処理が完了すると、project_dir/osrm/ 配下に以下のようなファイルが生成されます。

  • kanto-latest.osrm
  • kanto-latest.osrm.partition
  • kanto-latest.osrm.cells
  • その他、補助ファイル(.geometry など)

これらが揃っていれば、OSRM サーバを起動できる状態になっています。

サーバ起動とAPI確認

前処理が完了したら、OSRM サーバを起動して API が利用できるか確認します。

サーバの起動

以下のコマンドで OSRM サーバを起動します。
標準ではポート 5000 を使用します。

WINPWD="$(pwd -W)"
MSYS_NO_PATHCONV=1 docker run --rm -t \
  -p 5000:5000 \
  -v "$WINPWD/osrm:/data" \
  osrm/osrm-backend \
  osrm-routed --algorithm mld /data/kanto-latest.osrm

ターミナルに running and waiting for requests のようなメッセージが表示されれば、
OSRM サーバは起動中です。

API の確認

別のターミナルを開いて、curl コマンドで API を叩いてみます。

curl "http://127.0.0.1:5000/route/v1/driving/139.7671,35.6812;139.7020,35.6896?overview=false"

返ってきた JSON に distance(距離, メートル単位)や
duration(所要時間, 秒単位)が含まれていれば成功です。

レスポンス確認

東京駅 → 渋谷駅を例に実行すると、以下のようなレスポンスが返る:

{"code":"Ok","routes":[{"legs":[{"steps":[],"distance":7045.2,"duration":475.8}],"distance":7045.2,"duration":475.8}],"waypoints":[...]}

このように、直線距離ではなく「実際の道路距離」と「所要時間」を取得できることが確認できます。

Foliumでルート可視化

OSRM の API から取得した経路を、Folium(Leaflet ベースの Python ライブラリ)で HTML 地図に描画して確認します。

Foliumスクリプト(距離・時間をポリラインに表示)

  • 東京駅 → 渋谷駅の 2 点を固定
  • 返ってきた GeoJSON 形状([lon, lat])を Folium 用 [lat, lon] に変換
  • 距離(km)と所要時間(分)を 線のツールチップ に表示
  • 地図上のマーカーは開始(緑)・終了(赤)のみ
import requests
import folium

# --- 地点 ---
points = [(35.6812, 139.7671), (35.6896, 139.7020)]  # 東京駅 → 渋谷駅

# --- OSRMサーバ設定 ---
server = "http://127.0.0.1:5000"
profile = "driving"

coords = ";".join(f"{lon},{lat}" for lat, lon in points)
url = f"{server}/route/v1/{profile}/{coords}?overview=full&geometries=geojson"

resp = requests.get(url)
resp.raise_for_status()
data = resp.json()

route = data["routes"][0]
geometry = route["geometry"]["coordinates"]
line = [(lat, lon) for lon, lat in geometry]

distance_km = round(route["distance"] / 1000, 2)
duration_min = round(route["duration"] / 60, 1)

# --- Foliumで地図作成 ---
m = folium.Map(location=points[0], zoom_start=13)

# 経路ポリラインに情報を付与
folium.PolyLine(
    line,
    color="blue",
    weight=5,
    opacity=0.8,
    tooltip=f"距離: {distance_km} km / 所要時間: {duration_min}"
).add_to(m)

# 開始・終了点のマーカー
folium.Marker(points[0], popup="Start: 東京駅", icon=folium.Icon(color="green")).add_to(m)
folium.Marker(points[-1], popup="End: 渋谷駅", icon=folium.Icon(color="red")).add_to(m)

m.save("osrm_route_min.html")
print(f"[OK] 保存しました → osrm_route.html")

実行結果

  • カレントディレクトリに HTML(例:osrm_route.html)が生成される
  • ブラウザで開くと、ルートが描画され、線をホバーすると距離・時間が確認できる

48d5a43c0d9db43b55f5-1.png

まとめ

ここまでの手順で以下を実施しました:

  1. OSM データを取得(関東地方のデータを使用)
  2. OSRM の前処理(extract → partition → customize)
  3. OSRM サーバを起動して API から道路距離・所要時間を取得
  4. Folium でルートを可視化

これにより、「道路距離・所要時間を扱える環境」 がローカルで構築できました。

次のステップとしては以下のような発展が考えられます:

  • /table エンドポイントを利用して 距離・時間の行列 を取得
  • Python で TSP(巡回セールスマン問題)やルート最適化 に応用
  • Web アプリ(Flask / Streamlit など)と組み合わせて インタラクティブなルート検索ツール を作成
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?