OpenStreetMap(OSM)の道路属性を使い、5種類の自転車経路を比較するWebアプリです。既存道路の自転車設備をどこに追加するかを考える研究も進めています。
Phase 5では20組の出発地・目的地で経路比較と重みの感度分析を実行できます。現状経路を固定した設備配置の試作モデルも用意しています。経路の重みや設備配置の結果は研究用の暫定値です。
GitとPython 3.12を用意し、インターネットに接続してから次を実行します。作業フォルダは任意の場所で構いません。
git clone https://github.com/vxau/bicycle-rule-routing.git
Set-Location bicycle-rule-routing
.\setup.batsetup.batは仮想環境と依存パッケージを用意し、初回のみ.envを作成します。道路データがない場合はOSMから取得します。取得データはGitに含まれないため、別PCでは初回実行時に通信が必要です。
準備が終わったらstart_app.batをダブルクリックします。ローカルサーバーが起動し、ブラウザでhttp://127.0.0.1:8000/が開きます。停止するときは起動したコマンド画面でCtrl+Cを押します。
20組の一括評価はrun_evaluation.bat、設備配置候補と整備前後のCSV保存はrun_placement.batをダブルクリックします。アプリを開くと、既定の1,000 m上限で候補と整備前後の結果が画面に表示されます。
対象地域を変える場合はアプリを停止してからsettings.batをダブルクリックします。.envがメモ帳で開くので、緯度・経度・取得半径を保存して閉じると道路データと20組のODペアを取り直します。PC固有のODペアはGit管理外のdata/input/od_pairs.local.csvに保存され、共有用の東京駅20組より優先されます。設定例は.env.exampleです。取得半径は100〜5000 mですが、狭すぎる地域では20組を選べません。
別PCで更新を受け取るときは、そのPCの作業フォルダでgit pullを実行します。Python環境や道路データはGit管理外なので、必要に応じてsetup.batを再実行してください。
既定の設定は東京駅周辺3,000 mです。data/input/od_pairs.csvに短距離5組、中距離10組、長距離5組の計20組を保存しています。settings.batで地域を変更した場合はod_pairs.local.csvが再生成されます。
.\.venv\Scripts\python.exe -m backend.scripts.generate_od_pairs
.\.venv\Scripts\python.exe -m backend.scripts.evaluate_profiles評価結果はdata/processed/route_comparison.csv(100行)、sensitivity_analysis.csv(900行)、sensitivity_summary.csv(45行)です。感度分析は安全性要素と属性欠損要素をそれぞれ0.5倍、1倍、2倍に変えた9条件です。CSVはExcelで開けるUTF-8 BOM付きです。
既定の整備延長上限は1,000 mです。別の上限を使う場合は次のように実行します。
.\.venv\Scripts\python.exe -m backend.scripts.optimize_facilities --budget-m 1500data/processed/facility_candidates.csvに区間ID、端点座標、長さ、20組の経路での通過回数、削減見込み、選択結果を出力します。facility_placement_comparison.csvには20組それぞれの整備前後の経路距離、設備なし区間の通行距離、経路変更の有無を出力します。facility_placement_summary.jsonには予算と全体の集計を出力します。画面では選定区間を橙、未選定候補を灰で表示し、20組の比較を開いて確認できます。
cycleway=noなど設備がないことをOSMに明記した区間だけを候補にします。タグがない区間は設備がないと判断しません。20組は実測交通量ではありません。選んだ区間に設備ができたと仮定して経路を再計算しますが、施工箇所の確定には現地調査と需要・費用データが必要です。数理モデルと検証課題は設備配置の研究設計に記載しています。
- OSMから小範囲の自転車道路ネットワークを取得
- GraphML、GeoJSON、CSV、JSONとして保存
- 道路数、道路延長、信号等の基礎集計
- 自転車関連タグの記録率・不明率の集計
- FastAPIのヘルスチェックAPI
- HTML/CSS/JavaScriptとLeafletによる道路地図
- API接続状態と取得道路数の表示
- 地図上の2点を結ぶプロファイル別経路
- 経路上の幹線道路率、自転車レーン率、信号数、属性不明率
- 距離最短、ルール遵守、安全性、情報信頼性、バランスの5プロファイル
- 5ルートの色分け表示、指標比較表、選択ルートの強調表示
- 道路種別、自転車設備、属性欠損を用いた暫定コストによるルート選定
- 自動テストと再現可能な確認コマンド
本システムは研究用の注意喚起支援であり、交通違反を法的に判定するものではありません。
アプリの地図で「設備調査」を選ぶと、取得地域の全道路を「設備あり」(緑)、「明示的になし」(赤)、「不明」(灰の破線)で表示します。各分類のチェックを外して絞り込めるため、不明な道路だけを表示して調査対象を選べます。
- 道路をクリックし、道路名・区間ID・方向別の
cycleway/cycleway:left/cycleway:right/cycleway:bothを確認します。 - 「調査リストに追加」で対象を選びます。一覧の道路名から地図へ戻れ、「削除」で選択を外せます。
- 「調査CSVを保存」を押し、Excel等で確認結果(あり・なし・不明)、確認日、根拠となる資料URL・写真の識別子、幅員、メモを記入します。確認前の欄は空欄です。
- 記録を点検して、設備なしと確認できた区間を整備候補へ追加するか検討します。CSVを保存しただけでは、OSMデータや配置計算は変更されません。
選択は同じブラウザに保存されます。道路データが変わった場合は再選択を求めます。ブラウザ保存が使えない場合は画面で案内されるので、ページを閉じる前にCSVを保存してください。
分類・集計APIは GET /api/facilities です。元のGraphMLを使うため、既に道路データがあれば再取得は不要です。全道路を端点・エッジキーでまとめ、往復を二重計上せず、方向別の長さの最大値を使います。この全道路の延長と、20組のODの通行距離合計は集計対象が異なります。
判定は既存の配置モデルと共通で、左右別タグも参照します。記録値の no / none を明示的な設備なしとし、それ以外の記録値を「設備あり」に分類する暫定ルールです。共用レーン等も含むため、専用レーンの存在や整備可能性を保証しません。タグ欠損と往復で判定が異なる区間は「不明」に分類し、元のタグを確認できるようにしています。
「経路比較」に戻すと、出発地・目的地の選択と従来の5ルート比較・整備候補表示を利用できます。
学生が各部分を説明しやすいよう、初期段階では構成を小さくしています。
| 役割 | 使用技術 |
|---|---|
| API・静的ファイル配信 | Python 3.10〜3.12、FastAPI、Uvicorn |
| OSM取得・道路グラフ | OSMnx、NetworkX |
| 地理データ処理 | GeoPandas、Shapely |
| 画面 | HTML、CSS、JavaScript |
| 地図 | Leaflet、OpenStreetMapタイル |
| テスト | pytest、FastAPI TestClient |
React、TypeScript、Vite、npm、Docker、データベース、認証、UIライブラリは使用していません。
OpenStreetMap / Overpass API
↓
OSMnxで network_type="bike" の道路グラフを取得
↓
GraphML保存・GeoDataFrame変換
↓
GeoJSON出力・タグ欠損率集計
↓
FastAPIがAPIと静的画面を配信
↓
Leafletが道路GeoJSONを地図上に描画
↓
地図で2点選択 → 最寄りノード → NetworkXプロファイル別経路
↓
5種類の経路GeoJSON・距離・道路属性指標を比較表示
bicycle-rule-routing/
├─ backend/
│ ├─ app/
│ │ ├─ main.py # FastAPIと静的ファイル配信
│ │ ├─ osm_analysis.py # OSMタグの分類・集計
│ │ └─ routing.py # プロファイル別経路・経路指標・暫定コスト
│ ├─ scripts/
│ │ └─ fetch_osm_sample.py # OSM取得・保存・集計
│ ├─ tests/ # 自動テスト
│ └─ requirements.txt
├─ frontend/
│ ├─ index.html
│ ├─ styles.css
│ └─ app.js
├─ data/
│ ├─ raw/ # GraphML
│ ├─ exports/ # GeoJSON
│ └─ processed/ # 集計CSV・JSON
├─ docs/
│ ├─ environment-report.md
│ ├─ rule-tag-mapping.md # 交通ルールとOSMタグ対応表
│ └─ work-log.md
├─ .cache/ # pip・OSMnxキャッシュ(Git対象外)
├─ .venv/ # Python仮想環境(Git対象外)
├─ .env.example
└─ README.md
PowerShellでプロジェクトへ移動します。別PCでの初回準備は上のsetup.batを使ってください。
Set-Location 'C:\path\to\bicycle-rule-routing'既に作成済みの仮想環境を使う場合、activateは不要です。常に仮想環境のPythonを直接指定できます。
.\.venv\Scripts\python.exe --version手動で環境を作り直す場合は、pipキャッシュをプロジェクト内へ向けてから依存関係を入れます。
python -m venv .venv
$env:PIP_CACHE_DIR = (Join-Path (Get-Location) '.cache\pip')
.\.venv\Scripts\python.exe -m pip install --upgrade pip
.\.venv\Scripts\python.exe -m pip install -r backend\requirements.txtシステム全体のPATHやPowerShell実行ポリシーは変更しません。
設定例をコピーします。
Copy-Item .env.example .env.envの緯度・経度・取得半径・表示名を対象地域へ変更します。
OSM_CENTER_LAT=35.681236
OSM_CENTER_LON=139.767125
OSM_DISTANCE_METERS=500
OSM_PLACE_LABEL=Tokyo Station取得半径は100〜5000 mに制限しています。最初は500〜1000 m程度を推奨します。
プロジェクト直下で次を実行します。
.\.venv\Scripts\python.exe -m backend.scripts.fetch_osm_sampleスクリプトはnetwork_type="bike"で自転車が利用できるとOSMnxが判断した道路を取得し、次を出力します。
| 出力 | 内容 |
|---|---|
data/raw/sample_bike.graphml |
道路グラフ本体 |
data/exports/sample_nodes.geojson |
交差点・道路ノード |
data/exports/sample_edges.geojson |
地図表示用道路区間 |
data/processed/tag_coverage.csv |
道路延長で重み付けしたタグ集計 |
data/processed/summary.json |
ノード数・エッジ数・道路延長等 |
OSMnxの通信キャッシュは.cache/osmnxへ保存します。同じ条件で再実行した場合はキャッシュを利用します。
通常はstart_app.batをダブルクリックします。手動で起動する場合は次を実行します。
.\.venv\Scripts\python.exe -m uvicorn backend.app.main:app --host 127.0.0.1 --port 8000ブラウザでhttp://127.0.0.1:8000/を開きます。
- APIが正常なら「API: 接続済み」
- GeoJSONがある場合は「道路データ: ○○区間を表示」
- 道路GeoJSONを緑色で地図上に表示
- 地図を2回クリックすると、5種類の経路を色分けして表示
- 比較表の行を選ぶと、対応する経路を地図上で強調表示
- 各経路の距離、道路区間数、幹線道路率、自転車レーン率、信号数、属性不明率、プロファイル仮コストを表示
ヘルスチェックAPIはhttp://127.0.0.1:8000/api/healthです。
最短経路APIは次の形式です。
GET /api/routes/shortest
?start_lat=35.6812
&start_lon=139.7671
&end_lat=35.6900
&end_lon=139.7800
GraphMLは初回の経路要求時に読み込み、同じサーバープロセス内では再利用します。
Phase 4の比較APIは同じ座標パラメータを使います。
GET /api/routes/compare
?start_lat=35.6812
&start_lon=139.7671
&end_lat=35.7000
&end_lon=139.7900
返却するプロファイルは次の5種類です。重みは研究途中の仮値であり、現時点では優劣や安全性を保証しません。
| プロファイル | 現段階での扱い |
|---|---|
| 距離最短 | 道路延長だけを使用する比較基準 |
| ルール遵守優先 | 明示的な通行禁止を除外し、情報不足区間を抑制 |
| 安全性優先 | 幹線道路と自転車設備のない区間を強く抑制 |
| OSMデータ充足度優先 | 評価用OSM属性が多く記録された区間を優先 |
| バランス型 | 道路種別、自転車設備、情報不足を組み合わせる |
.\.venv\Scripts\python.exe -m pytest backend\tests -v
.\.venv\Scripts\python.exe -m pip check設備調査のCSV・選択復元に関するJavaScriptテストは、Node.jsがある環境で node --test frontend/tests/facility-survey.test.cjs を実行できます。Node.jsはアプリの起動には不要です。
任意のブラウザ検証にはPlaywrightとChromiumを使います。リポジトリ直下で .venv/bin/python -m backend.tests.serve_survey_fixture を起動し、別ターミナルで node frontend/tests/facility-survey.browser.cjs を実行します。このサーバーは8001番ポートで検証用の架空道路を配信し、研究データは変更しません。Chromiumの場所は CHROMIUM_PATH で指定できます。Leafletの取得にはTLS検証を維持してください。必要に応じて、検証済みのLeaflet 1.9.4のJS/CSSを保存したディレクトリを LEAFLET_ASSET_DIR に指定してネットワークに依存せず画面操作を確認できます。背景タイルはこのテストの対象外です。
東京駅周辺・半径3,000 mの現在の研究用データ(2026年10月16日取得)は次のとおりです。
| 指標 | 結果 |
|---|---|
| ノード数 | 12,993 |
| 有向エッジ数 | 28,305 |
| 有向エッジ総延長 | 1,375.242 km |
| 重複方向をまとめた街路総延長 | 983.868 km |
| 信号ノード | 1,032 |
| 一時停止ノード | 1 |
| crossing情報を持つノード | 110 |
代表的な道路タグの記録率は次のとおりです。割合は道路区間数ではなく道路延長で重み付けしています。
| タグ | 記録率 | 不明率 |
|---|---|---|
cycleway |
3.28% | 96.72% |
cycleway:left |
7.35% | 92.65% |
maxspeed |
23.04% | 76.96% |
lanes |
33.47% | 66.53% |
width |
1.35% | 98.65% |
surface |
63.45% | 36.55% |
access |
4.84% | 95.16% |
この結果から、OSMは道路ネットワークの取得には利用できる一方、幅員や自転車関連属性は地域によって欠損が多く、欠損を無視したルート評価は危険だと説明できます。
取得・分析対象は次のとおりです。
- 方向・通行規制:
oneway、oneway:bicycle、bicycle、access - 自転車設備:
cycleway、cycleway:left、cycleway:right、cycleway:both - 道路特性:
highway、maxspeed、lanes、width、surface - 注意地点:
highway=traffic_signals、highway=stop、crossing
各タグを次の3状態に分類します。
| 状態 | 意味 | 例 |
|---|---|---|
present |
属性値が記録されている | cycleway=lane |
explicit_absent |
「ない」と明記されている | cycleway=no |
unknown |
タグがなく、実際にないか未調査か判断できない | タグ欠損 |
「タグがない」ことを「設備がない」と断定しない点が、今後のルート評価で重要です。
初期報告では、次の順序で説明できます。
- 背景
自転車への交通反則通告制度適用を背景に、最短距離だけでなくルール遵守を支援する必要がある。 - 研究目的
OSM道路属性を使い、ルール上の注意点・安全性・情報不足を説明できるルート比較システムを開発する。 - 開発方針
FastAPI、HTML/CSS/JavaScript、Leafletによる小さなWeb構成とし、経路評価部分を段階的に追加する。 - OSM取得手順
指定座標の周辺をnetwork_type="bike"で取得し、道路グラフと属性をGraphML・GeoJSONへ保存する。 - 初期成果
280ノード・474エッジを取得し、Web地図へ474道路区間を描画できた。 - 初期分析
cycleway、width、maxspeed等の記録率を算出し、OSM属性欠損を定量的に確認した。 - 課題
法令とOSMタグの対応検証、対象地域の決定、経路評価式、欠損時の扱い、現地確認が未実施である。
初期報告のデモでは、OSM取得コマンド、生成ファイル、タグ集計CSV、API接続状態、道路地図を見せられます。
- 距離最短だけでなく、研究目的に対応する5プロファイルを定義した。
- 明示的な
bicycle=no・access=no/privateは制度対応側で通行不可として扱う。 - 道路種別、自転車設備の有無、5属性の不明率を独立したコスト要素へ分けた。
- NetworkXの重み付き最短路として各プロファイルを実際に計算するAPIを作成した。
- Web画面で5ルートを色分けし、距離と道路属性指標を同条件で比較できるようにした。
- 東京駅周辺の実データで、距離増加と幹線道路率・自転車レーン率の変化というトレードオフを確認した。
- 現時点の重みは暫定値であり、次工程で感度分析、現地確認、複数ODペア評価を行う必要がある。
- OSMは共同編集データであり、現地の標識・規制・道路状況と一致する保証はありません。
network_type="bike"はOSMnxの既定アクセス規則も使って道路を抽出します。bicycleタグがないことは、直ちに自転車通行不可を意味しません。- OSMnxは一部属性を道路グラフ用に正規化します。今回の
oneway記録率100%は、元のOSMで全道路にタグが明記されていることを意味しません。 oneway:bicycleは特に一方通行道路で意味を持つため、全道路に対する単純な記録率だけで品質を判断しません。- 信号、一時停止、横断情報はノード化・簡略化の方法にも影響されます。
- 将来の評価では、警察庁等の一次資料、OSMタグ仕様、現地標識を照合します。
- OSMデータを公開・配布する際はOpenStreetMap contributorsの表示とODbLの条件を確認します。
- PowerShellで仮想環境をactivateできない
.\.venv\Scripts\python.exeを直接使えば実行ポリシー変更は不要です。 - Overpass APIの取得に失敗する
通信状態を確認し、少し時間を置いて再実行します。取得半径を小さくする方法もあります。 - 道路データが画面に出ない
OSM取得スクリプトを実行し、data/exports/sample_edges.geojsonの存在を確認します。 - 地図の背景だけ表示されない
Leaflet本体とOSMタイルはインターネットから読み込むため、ネット接続を確認します。 - 対象地域を変えたのに古いデータが見える
.envを確認して取得スクリプトを再実行し、ブラウザを再読み込みします。
- 研究対象地域を大学周辺へ変更し、地域選定理由を整理する
- 交通ルールとOSMタグ対応表の暫定判断を代表地点で検証する
- 感度分析の結果を現地確認と照らして暫定重みを見直す
- プロファイル間で同一経路になった場合を画面上で分かりやすく示す
- 注意地点を地図上に表示し、選定理由を説明する
onewayの生OSMタグとOSMnx正規化後属性を区別して分析する- 一方通行道路に限定した
oneway:bicycle充足率を追加する - OSM属性の一部を現地調査または公的情報で検証する
- 実際の自転車交通量と道路整備費用を集め、設備配置モデルへ反映する
- 整備後の経路変更と自転車ネットワークの連続性を評価する
- 制度変更前後ではなく「距離中心モデル」と「制度対応モデル」の比較として実験を設計する
docs/environment-report.md: PC環境とEドライブ配置方針docs/rule-tag-mapping.md: 交通ルール、OSMタグ、暫定コストの対応docs/work-log.md: 実行コマンド、確認結果、発生した問題docs/superpowers/specs/2026-07-27-initial-research-platform-design.md: 初期設計docs/superpowers/plans/2026-07-27-initial-research-platform.md: 実装計画