Bike Router について
Bike Routerは、OSMベースのセルフホスト可能な自転車ルートプランナーで、Web UI、API、コマンドラインを備えています。ルートエンジンのデータと不確実性を明示し、曖昧な地名やルート情報を推測しません。
主な機能
- 01OSMベースの自転車ルート検索
- 02複数のルート・ジオコーディングプロバイダー
- 03ルートの評価と説明
- 04GeoJSONとGPXへのエクスポート
- 05Webプランナー、API、コマンドライン
活用シーン
- 01出発地、目的地、車種を指定したルート計画
- 02曖昧な地名を確認してからルート検索
- 03ルート候補と地図メタデータの比較
- 04計画したルートのGeoJSONまたはGPX出力
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
bike-routing-agent
OSM ベースの自転車ルート検索サービスです。型付けされたプロバイダーに依存しないドメインモデル、openrouteservice API クライアントとルーティングアダプター一式、そして検証済みのルートリクエストを、説明可能でエクスポート可能なサイクリングルートに変換する LangGraph ワークフローを備えています。
LLM を使用する場合、自由形式のテキストを解析したり、確認の質問をしたり、選択したルートを説明したりできます。座標、ジオメトリ、標高、ルートの適性を生成することはありません。これらはすべて、OSM 由来のルーティングエンジンから取得されます。
簡単インストール(プログラミング不要)
Releases ページから pybikerouter-easy-<version>.zip をダウンロードして解凍し、Docker Desktop をインストールして、お使いのコンピューター用の Start ファイルをダブルクリックします。初回起動時に尋ねられるのは、走行する場所だけです。そのエリアの地図データがダウンロードされ、プランナーがブラウザーで開きます。わかりやすい言葉での手順はこちらをご覧ください:docs/easy-install.md(ダウンロード内の START-HERE.txt もご覧ください)。
ドキュメント
ドキュメント一式は docs/ にあります。
| ドキュメント | 内容 |
|---|---|
| アーキテクチャ | グラフノード、状態、分岐、終端ステータス、エラーモデル |
| API | エンドポイントの契約、レスポンスステータス、成果物の配信 |
| 設定 | すべての環境変数、検証ルール、デプロイに関する注意事項 |
| プロバイダー | プロトコル、ORS クライアント/アダプターの動作、ジオコーダー、BRouter/Valhalla アダプター、バックエンドの追加 |
| バックエンドの比較 | 自転車の種類ごとに測定した ORS と BRouter の動作、両エンジンの併用 |
| ジオコーディング | Nominatim と Pelias の比較、信頼度/曖昧さの扱い、調整 |
| スコアリングとエクスポート | スコア計算、不確実性の方針、説明のルール、GeoJSON/GPX |
| 言葉からプランを作成 | 走行内容を一文で説明すると、オプションの LLM が構造化リクエストに変換します(座標には変換しません) |
| 天気 | 出発時刻におけるルート沿いの予報:気温、雨、走行方向に対する風(無料、API キー不要のプロバイダー) |
| セルフホスト可能なスタック | 1 つの OSM 抽出データからルーティングやジオコーディングをローカルで実行する方法。ハードウェア要件と小型 PC の選択肢 |
| テスト | テストの構成、モックの規約、ライブテスト、CI |
| ウェブプランナー | 旅行に立ち寄り先を追加する方法。地図上の地点をクリックし、ルートのどこに追加するかを選択できます |
| iPhone/Tailscale | tailnet 経由でホーム画面アプリとして iPhone からプランナーを使う方法 |
| ロードマップ | 計画中の作業と明示的な対象外項目 |
アーキテクチャ
FastAPI
|
v
LangGraph RouteAgentState
|
+--> parse_request (structured input first; LLM extraction is an injectable dependency)
+--> validate_request (Pydantic)
+--> geocode_locations (Nominatim by default, public or self-hosted; ambiguity -> clarification, never a guess)
+--> route_with_provider (openrouteservice; engine-neutral RoutingRequest in, RouteCandidate out)
+--> score_candidates (deterministic distance/elevation/warning scoring)
+--> explain_and_export (facts-only explanation + GeoJSON/GPX export)
|
v
JSON response + GeoJSON/GPX artifacts
グラフの分岐:
START -> parse_request
-> validate_request -> (invalid | awaiting_clarification) -> END
-> geocode_locations -> (awaiting_clarification | provider_failure) -> END
-> route_with_provider -> (no_route | provider_failure) -> END
-> score_candidates -> (no_route) -> END
-> explain_and_export -> END
すべての経路は明示的な status で終了します。検証とジオコーディングの両方が成功しない限り、グラフがルーティングプロバイダーを呼び出すことはありません。また、終端ステータスなしで処理を返すこともありません。
セットアップ
Python 3.11 以降と Poetry が必要です。
poetry install
cp .env.example .env
poetry install は、ランタイム依存関係と開発依存関係の両方を含む、プロジェクト内の仮想環境(.venv/、poetry.toml を参照)を作成します。仮想環境内でコマンドを実行するには poetry run <command> を使うか、poetry shell で直接有効化してください。
.env を編集し、ORS_API_KEY に有効な openrouteservice API キーを設定します。
環境変数
| 変数 | 用途 | デフォルト |
|---|---|---|
ORS_API_KEY | openrouteservice API キー | (ライブ経路検索に必要) |
ORS_BASE_URL | openrouteservice のベース URL | https://api.openrouteservice.org |
ORS_TIMEOUT_S | ORS リクエストのタイムアウト(秒) | 10.0 |
ORS_MAX_RETRIES | タイムアウト/5xx 発生時の再試行回数 | 2 |
GEOCODER_PROVIDER | ジオコーダーのバックエンド:nominatim(パブリックまたはセルフホスト)または pelias(ORS_BASE_URL の背後に Pelias API が必要です。docs/geocoding.md を参照。起動時にパブリック ORS URL は拒否されます) | nominatim |
GEOCODER_BASE_URL | Nominatim のベース URL(GEOCODER_PROVIDER=pelias の場合は無視されます) | https://nominatim.openstreetmap.org |
GEOCODER_TIMEOUT_S | ジオコーダーのリクエストタイムアウト | 5.0 |
GEOCODER_USER_AGENT | Nominatim の利用ポリシーで必要です | bike-routing-agent/0.1 |
GEOCODER_CACHE_TTL_S | メモリ内ジオコードキャッシュの TTL | 3600 |
GEOCODER_AMBIGUITY_MARGIN | 上位 2 件の結果が「曖昧」と判定される信頼度の差 | 0.05 |
GEOCODER_MIN_CONFIDENCE | 上位の結果を自動的に採用するための最小信頼度 | 0.3 |
VALHALLA_BASE_URL | セルフホスト Valhalla(meili)サーバーのベース URL | http://localhost:8002 |
VALHALLA_TIMEOUT_S | Valhalla のリクエストごとのタイムアウト(秒) | 30.0 |
VALHALLA_MAX_RETRIES | Valhalla のタイムアウト/5xx 発生時の再試行回数 | 1 |
EXPORT_DIR | GeoJSON/GPX 成果物を保存するローカルディレクトリ | exports |
DATABASE_URL | PostgreSQL/PostGIS URL:経路履歴を記録し、/v1/history/* を有効にします(docs/persistence.md) | 未設定 |
ARTIFACT_BACKEND | local または database(成果物を PostgreSQL に保存) | local |
LOG_LEVEL | ログレベル | INFO |
API の実行
poetry run uvicorn bike_routing_agent.api:app --reload
アプリは組み込みのウェブ UI(地図ベースの経路プランナー)も
http://localhost:8000/ で提供します。対話型 API ドキュメントは /docs にあります。
コマンドラインインターフェース
パッケージをインストールすると、bike-router コマンドを使用できます(python -m bike_routing_agent.cli でも実行可能です)。コマンドはサブコマンドグループに整理されています。
bike-router route plan --origin "Berlin Hbf" --destination "Potsdam" \
--bike-type gravel --target-distance-km 30 --output plan.json
bike-router serve start --port 8000
bike-router docker up # docker compose -f docker/compose.yaml up -d --build
bike-router docker logs -f
bike-router config show # effective settings, secrets redacted
bike-router config check # validate settings against the environment
bike-router providers list # provider names and bike-type -> ORS profile map
bike-router route plan ... --format text --gpx best.gpx # alternatives, sight stops, exports
bike-router route show plan.json # a saved plan again; `route export` writes any alternative
bike-router poi along --route plan.json # sights near a route, ranked by fame
bike-router brouter needed|info|download # BRouter map tiles (asks before downloading)
bike-router history list|show|stats # past plans (needs DATABASE_URL)
bike-router status show # readiness of every component and the active features
bike-router chat start # plan routes by chatting (docs/chat.md)
API とウェブフォームでできることはすべて CLI からも実行できます。docs/cli.md を参照してください。
route plan --text "50 km gravel loop from Braunschweig" は、オプションの LLM パーサーを使用します(docs/llm-parser.md)。
route plan では、--origin、--destination および繰り返し指定する --via 経由地点に lat,lon のペアまたは地名テキストを指定できます。JSON の結果を出力し、ready の場合は 0、確認が必要な場合またはプロバイダーでエラーが発生した場合は 1、使用方法に誤りがある場合は 2 で終了します。DATABASE_URL が設定されている場合は、経路履歴にも計画を記録します(ベストエフォート。出力に plan_id が含まれます。記録をスキップするには --no-record を指定します)。また、--departure-time に指定した時刻の経路沿いの天気予報を取得します(docs/weather.md)。bike-router db migrate/db status ではスキーマを管理します(docs/persistence.md)。
Docker での実行
コンテナー関連のファイルはすべて docker/ にあります。
cp .env.example .env # set ORS_API_KEY
docker compose -f docker/compose.yaml up --build
ウェブ UI を開くには http://localhost:8000/ にアクセスしてください。経路の成果物は名前付きボリューム pybikerouter-exports に保存されます。オプションのローカル経路検索/ジオコーディングスタックについては、docs/self-hosted.md を参照してください。必要な要件や、小規模なマシンで片方だけを実行する方法も記載されています。
リクエストの例
curl -X POST http://localhost:8000/v1/route/plan \
-H 'Content-Type: application/json' \
-d '{
"origin": "Braunschweig Hauptbahnhof",
"destination": "Wolfenbüttel",
"constraints": {
"bike_type": "gravel",
"avoid_high_traffic_roads": true,
"max_ascent_m": 500
}
}'
レスポンスの例
{
"status": "ready",
"route": {
"provider": "ors",
"provider_profile": "cycling-regular",
"geometry_geojson": {"type": "LineString", "coordinates": []},
"metrics": {
"distance_m": 12500,
"duration_s": 2700,
"ascent_m": 85,
"descent_m": 90,
"surface_coverage": {},
"unknown_surface_fraction": null
},
"score": 0.91,
"score_breakdown": {"distance_fit": 1.0, "elevation_fit": 1.0, "warning_penalty": 0.0},
"warnings": [],
"provenance": {"provider": "ors", "profile": "cycling-regular"}
},
"candidates": [
{"provider": "ors", "provider_profile": "cycling-regular", "score": 0.91},
{"provider": "brouter", "provider_profile": "trekking", "score": 0.84}
],
"explanation": "...",
"artifacts": {
"geojson_url": "/v1/routes/<id>.geojson",
"gpx_url": "/v1/routes/<id>.gpx"
},
"clarification": [],
"errors": []
}
origin/destination が曖昧、または解決できない場合、status は awaiting_clarification となり、clarification に選択候補の地名が一覧表示されます。推測に基づいて経路が生成されることはありません。
自転車の種類
constraints.bike_type はエンジンごとのルーティングプロファイルを選択し、デフォルトは
gravel です。対応する値は road、gravel、touring、mountain、city、
ebike、commuter(高速、交通量が少ない道路)、recumbent です。
ORS が提供するサイクリングプロファイルは 4 種類のため、たとえば ebike は
cycling-electric を使い、commuter は cycling-regular を使います。
セルフホストの BRouter プロバイダーでは、さらに細かく区別されます。
gravel、touring、mountain、city、commuter、recumbent にはそれぞれ独自のプロファイルが割り当てられ、
road と ebike は fastbike を共有します(BRouter に電動アシストのコストモデルはありません)。
詳しくはdocs/configuration.mdを参照してください。
Make ターゲット
make を実行すると、日常的に使うコマンドが一覧表示されます。これらのコマンドは、プロジェクトの .venv(またはアクティブな環境)を使います。
make install # poetry install
make hooks # the git hooks (commit: lint + types; push: the whole suite)
make run # the API with auto-reload (HOST=127.0.0.1 PORT=8000)
make check # lint + types + tests without coverage, stops at the first failure
make ci # what CI runs: lint, types, tests with the 80 % coverage floor
make test-fast ARGS="tests/nodes -k geocode" # a part of the suite (no coverage floor)
make deploy # build and restart the local container (bike-router deploy up)
リントと型チェック
poetry run ruff check .
poetry run mypy src
どちらも、プッシュとプルリクエストのたびに CI で実行されます(.github/workflows/ci.yml を参照)。
テストの実行
poetry run pytest
カバレッジは実行のたびに計測され、テストスイートは 80% を下回ると失敗します
(tool.pytest.ini_options.addopts の --cov-fail-under=80)。現在の合計カバレッジは 97% で、
すべてのモジュールが 84% 以上です。
実際の外部サービスにアクセスするライブテストには @pytest.mark.live が付けられ、
デフォルトでは除外されます(pyproject.toml の tool.pytest.ini_options.addopts を参照)。
明示的に実行するには、次のようにします。
poetry run pytest -m live
Pre-commit フック
品質チェックは pre-commit を介して、各コミット/プッシュの前に自動実行されます。
poetry install の後、Git フックの両ステージを一度インストールしてください。
poetry run pre-commit install --hook-type pre-commit --hook-type pre-push
コミット時には、空白/EOF/YAML/TOML/マージ競合/大容量ファイルのチェック、
ruff check --fix、mypy src が実行されます。pytest の全テストスイートは、
CI と同様に、git push 時の pre-push ステージでのみ実行されます。
コミットステージを手動で実行するには poetry run pre-commit run --all-files を、
pre-push ステージを実行するには
poetry run pre-commit run --hook-stage pre-push --all-files を使います。
既知の制限事項
- OSM タグの網羅性は地域によって異なります。路面や通行可否のメタデータは 欠落していることが多く、好ましい条件としてではなく、不確実性として扱われます。
- ルーティングエンジン(ORS、Valhalla、BRouter)ごとに、自転車カテゴリを独自の
プロファイルに割り当てます。
config.pyのマッピングは近似的なものであり、 特にグラベル走行ではその傾向が顕著です。 - 標高データ(上り/下り)はプロバイダーによって精度が異なり、常に利用できるとは限りません。
- このサービスが生成するルートは、安全を保証するものではありません。説明では 「利用可能な地図メタデータとの適合性がより高い」のような慎重な表現を使い、 「安全なルート」のような断定は避けています。
- BRouter と Valhalla はエンドツーエンドで接続されていますが、セルフホスト環境でのみ
利用できます(
ROUTING_PROVIDER=brouter/valhalla/all。BRouter は docker/brouter/README.md の compose プロファイルを使用)。 デフォルトのエンジンは引き続き openrouteservice です。 - Pelias ジオコーダーオプションを使うには、
<ORS_BASE_URL>/pelias/v1で Pelias API が 提供されている必要があります。公開 API のapi.openrouteservice.orgも、 標準のセルフホスト ORS も Pelias API を提供しておらず、このアダプターはモックに対してのみ テストされています(docs/geocoding.md を参照)。 ローカルのジオコーダーを使う場合は、セルフホストの Nominatim を使用してください。
リポジトリの構成
src/bike_routing_agent/
├── api.py FastAPI app (POST /v1/route/plan)
├── config.py Settings + provider profile mapping
├── models.py Pydantic v2 domain models
├── state.py LangGraph RouteAgentState
├── graph.py LangGraph wiring
├── errors.py Structured provider/geocoding errors
├── providers/ GeocodeProvider / RoutingProvider adapters
│ (ors_client.py: full ORS client -- directions, export,
│ isochrones, matrix, snap, POIs, Vroom, elevation,
│ Pelias geocoding, health; ors.py: the RoutingProvider;
│ geocoder.py: Nominatim; pelias.py: Pelias on
│ self-hosted ORS)
├── nodes/ One module per graph node
├── scoring/ Deterministic route scoring
├── exporters/ GeoJSON / GPX export
├── frontend/ Static web UI served at /
└── cli/ bike-router command line (route/serve/docker/config/providers)
docker/ Dockerfile + compose.yaml
tests/
├── fixtures/ Sample provider responses
├── nodes/ One test module per graph node
├── providers/ Adapter unit tests (mocked HTTP)
├── graph/ Graph branch tests
├── exporters/ Export format tests
└── live/ Tests marked @pytest.mark.live
docs/ Documentation suite (see docs/README.md)
ライセンス
MIT。詳しくは LICENSE を参照してください。
サードパーティライセンス
このプロジェクトが基盤とする BRouter(MIT)および OpenStreetMap データ(ODbL)への謝辞と、 BRouter のライセンス全文は THIRD_PARTY_LICENSES.md に記載されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。