始点と終点を決めるだけで、東京の徒歩ルートを3D都市モデルの上で歩けるHTMLを1枚生成するSkill。
外部の経路探索APIも、地図タイルサーバーも、CDNも、MCPサーバーも使いません。国土交通省 Project PLATEAU / 東京都「都市の3Dデジタルマップデータ」のCityGMLだけを材料に、道路面ポリゴンそのものの上で経路を解いて、単体で開ける自己完結のビューアを書き出します。
Generate a self-contained 3D walkthrough of any walking route in Tokyo from PLATEAU CityGML. The route is solved on the published road-surface polygons — no routing API, no tile server, no CDN, no MCP server. Output is a single HTML file that opens offline.
秋葉原のヨドバシカメラから上野恩賜公園まで 2,004 m。建物7,936棟、地形の高低差24 m。朱色の帯が経路で、明るい側が歩き終えた区間。
「歩行者を追う」を有効にすると、街路レベルまで降りて進行方向を向いたまま追従します。
すぐ触りたい場合は examples/akihabara-ueno/index.html をブラウザで開いてください。 ビルド済みのサンプルを同梱しています(約3.5 MBの1ファイル、ダウンロード不要・オフライン可)。
- 徒歩ルートの探索 — 道路面(
tranLOD1)を2mグリッドにラスタ化し、建物と鉄道敷を障害物としてA*で解く - ルートの再生 — 再生/スクラブ/通過地点ジャンプ、歩行者追従カメラ、距離・所要時間・上り累計の表示
- 建物の3D表示 — LOD1押し出し、DEM由来の地形、道路面、鉄道、駅・施設名ラベル、等高線
- 属性による色分け — 高さ/用途(詳細用途)/建物構造(防火性能)/想定浸水深。凡例クリックで絞り込み
- 建物のクリック — 階数・建築面積・接地標高・建物構造・防火地域・変化フラグ・想定浸水深・建物IDを表示
出力はindex.html1枚(例のルートで約3.7 MB)。オフラインでもファイルを直接開けば動きます。
| Python | 3.8以上。標準ライブラリのみ。pip installは不要 |
| curl | TLS検証のため、HTTP取得はすべてcurlに委譲しています |
| ブラウザ | WebGL2対応(Chrome / Safari / Firefox の現行版) |
| ディスク | 作業用に2〜3 GB程度(DEMの展開後サイズが大きいため) |
このSkillはMCPサーバーに依存しません。 データはPLATEAUの配布ZIPとCKANの公開APIから直接取得するため、追加のサーバー設定は要りません。scripts/以下にMCPへの参照は1つもありません。
ただし、どのデータセットが存在するかを対話的に調べたい場合には、同じ作者の tokyo-data-mcp を併用すると便利です(任意)。東京都オープンデータカタログを検索・集計する読み取り専用のMCPサーバーです。
tokyo-data-mcp を入れる場合(任意)
git clone https://github.com/kofujimura/tokyo-data-mcp.git
cd tokyo-data-mcp
npm ci && npm run build # dist/index.js が生成されるMCPクライアントの設定に追加します(argsはdist/index.jsの絶対パス)。
{
"mcpServers": {
"tokyo-data": {
"command": "node",
"args": ["/absolute/path/to/tokyo-data-mcp/dist/index.js"],
"env": { "LOG_LEVEL": "info" }
}
}
}Claude Codeなら次のコマンドでも登録できます。
claude mcp add tokyo-data -- node /absolute/path/to/tokyo-data-mcp/dist/index.js登録後 search_catalog describe_dataset inspect_resource query_rows aggregate_rows の5ツールが見えれば成功です。
個人用(どのプロジェクトからでも使える):
git clone https://github.com/kofujimura/walk-route-3d.git ~/.claude/skills/walk-route-3dプロジェクト限定(チームで共有する):
git clone https://github.com/kofujimura/walk-route-3d.git .claude/skills/walk-route-3d開発しながら使うなら、クローン先はどこでもよくシンボリックリンクを張ります。
git clone https://github.com/kofujimura/walk-route-3d.git ~/src/walk-route-3d
ln -s ~/src/walk-route-3d ~/.claude/skills/walk-route-3dClaude Codeを再起動すると /walk-route-3d で呼び出せます。「秋葉原から上野公園までの徒歩ルートを3Dで作って」のように自然文で頼んでも、Skillの説明文からエージェントが自分で選びます。
SKILL.md はエージェント非依存のMarkdownです。agents/openai.yaml に表示名と既定プロンプトを置いてあるので、必要に応じて各ランタイムの形式に読み替えてください。
scripts/ は素のPythonスクリプトです。AIエージェントなしでも同じ結果が出ます。次の「使い方」がそのまま手順になります。
同梱サンプルを、手元で最初から作り直してみる例です。
git clone https://github.com/kofujimura/walk-route-3d.git
cd walk-route-3d/examples/akihabara-ueno
S=../../scripts
python3 $S/fetch.py --config route.json --work work/ --dry-run # ① メッシュの充足を確認
python3 $S/fetch.py --config route.json --work work/ # ② 取得(約150 MB転送)
python3 $S/build_scene.py --config route.json --work work/ # ③ scene.json を作る(約16秒)
python3 $S/build_page.py --scene work/scene.json --out index.html # ④ 1枚のHTMLにする
open index.html① の--dry-runは、必要な1kmメッシュを列挙し、どのPLATEAUパッケージがどれを提供するかを表示します。MISSINGが出たら、そのメッシュを含む自治体パッケージをpackagesに足してください。
自分のルートを作るときは、このディレクトリを複製してroute.jsonの緯度経度とパッケージ名を書き換えるだけです。テンプレートを触る必要はありません。
cp -r examples/akihabara-ueno my-route && rm my-route/index.html
$EDITOR my-route/route.json「ヨドバシAkiba」のような施設名を座標にするとき、当てずっぽうを避けるためのモードがあります。
python3 ../../scripts/build_scene.py --config route.json --work work/ --probe 35.6986,139.7746地図から目分量で拾った座標を渡すと、近くの大きな建物が距離・建築面積・LOD1高さ・階数・詳細用途つきで並びます。
28 m area 4644 m2 h 52.8 floors 9 use 1221 35.698854, 139.774605 13101-bldg-2423
109 m area 2631 m2 h 20.4 floors 2 use 1431 35.698305, 139.773447 13101-bldg-716
122 m area 2631 m2 h 19.8 floors 2 use 1431 35.698160, 139.773368 13101-bldg-1329
1件目は建築面積4,644 m²・9階・商業施設(1221)で、ヨドバシAkibaに間違いありません。2件目以降の1431(運輸施設等)は秋葉原駅の構造物です。この重心 35.698854, 139.774605 を始点に使います。
{
"title": "秋葉原 → 上野",
"eyebrow": "AKIHABARA – UENO WALK",
"start": { "lat": 35.698854, "lon": 139.774605,
"name": "ヨドバシカメラ マルチメディアAkiba", "short": "ヨドバシAkiba" },
"goal": { "lat": 35.713783, "lon": 139.774243,
"name": "上野恩賜公園", "short": "上野公園" },
"packages": ["plateau-13106-taito-ku-2025", "plateau-13101-chiyoda-ku-2025"]
}| キー | 既定値 | 意味 |
|---|---|---|
start / goal |
必須 | lat lon と、name(通過地点リストの端)・short(地図のピン) |
packages |
必須 | geospatial.jp のPLATEAUパッケージ名。--dry-runで過不足を判定 |
title / eyebrow / blurb |
自動生成 | ページ見出し。→を含めると矢印が強調される |
bbox |
端点から算出 | [南緯, 西経, 北緯, 東経]。文脈を広く見せたいときに明示 |
pad |
400 |
端点の外側に足す余白(m) |
minSpan |
1100 |
短辺の最小長(m) |
terrainCell |
10.0 |
地形グリッドの解像度(m) |
routeCell |
2.0 |
経路探索グリッドの解像度(m) |
offroadCost |
6.0 |
道路面外を歩くコスト倍率 |
railBlockRadius |
9.0 |
鉄道中心線から通行不可とする幅(m) |
walkMetresPerMinute |
80 |
所要時間の換算(不動産表示規約の目安) |
実物は examples/akihabara-ueno/route.json にあります。
パッケージ名はCKANで引けます。
curl -s "https://www.geospatial.jp/ckan/api/3/action/package_search?q=PLATEAU+台東区&rows=5" \
| python3 -c "import json,sys;[print(p['name'],p['title']) for p in json.load(sys.stdin)['result']['results']]"PLATEAUの配布ZIPは自治体あたり1 GB級ですが、必要なのは対象メッシュの.gml数本だけです。配信元がHTTP Rangeに対応しているので、scripts/rzip.pyが中央ディレクトリだけを読み、目的のエントリにRangeを張って取り出します。中央ディレクトリは~/.cache/rzipにキャッシュされ、fetch.pyはサイズが一致するファイルを飛ばすので、再実行はほぼ無料です。
なおメッシュファイルは区をまたいで完全です。53394632は台東区版と千代田区版でバイト単位で同一で、13101/13102/13106の建物3,665棟すべてを含みます。したがって1メッシュにつき1パッケージで足り、複数指定するのは「どのパッケージにも無いメッシュ」を埋めるときだけです。
PLATEAUが配るのは道路面であって道路網ではありません。中心線もトポロジーも無いので、グラフ探索の対象がそもそも存在しません。そこで面をラスタ化して解きます。
| セル | 出所 | コスト |
|---|---|---|
| 道路 | tran:Road LOD1 ポリゴンを走査線で塗る |
1.0 + 2.2·exp(−縁からの距離/3) |
| 障害物 | 建物フットプリント+鉄道中心線から9 m | 通行不可 |
| 空地 | それ以外 | offroadCost(既定6.0倍) |
道路は障害物に優先するので、高架下やアンダーパスは開いたまま、線路そのものは塞がれます。
「空地も通れるが割高」という設計が要点です。道路面データは駅前広場や公園の園路を含まないため、道路セルだけに限定すると上野公園にはそもそも到達できません(入口が階段のため園路が街路網から分断されている)。最初の試行は3,454 mも迂回しました。6倍の通行料を課すと、26 mの隙間は156 m相当になり、それを上回る短縮があるときだけ横断します。結果は2,004 m、うち道路面外はわずか96 m(5%未満)で、実際に人が歩道を離れる場所とほぼ一致しました。
詳しくは references/routing.md。出力のポリラインを手で編集してはいけません。 気に入らないときはコストモデルを変えて、何を変えたかを記録します。
scripts/template.html に自前のWebGL2レンダラとUIが入っており、build_page.pyがシーンを<script type="application/json">として流し込みます。差し替えるのは__TITLE__と__SCENE__の2箇所だけで、見出し・出典表記・ルート名はすべてscene.metaから描画されるため、新しいルートでテンプレートを触る必要はありません。
法線はdFdx/dFdyから取るフラットシェーディング、ピッキングはIDバッファへの第2パス。色分け・高さフィルタ・凡例の絞り込み・歩行済み区間の塗り分けは、すべてuniformの変更だけでバッファを作り直しません。詳しくは references/viewer.md。
結果を人に見せるときは、次を必ず添えてください。いずれも実在する制約です。
- 属性の基準時点は令和3年(2021)土地利用現況調査(
uro:surveyYear)。カタログの「令和7年度整備」は3Dモデルの整備年度であり、2021年以降の新築・建替え・除却は反映されていません。 - 建築年(
yearOfConstruction)と構造種別(buildingStructureType)は収録率0%。耐震性を軸にした応用は成立しません。防火性能・規制値・変化フラグは全棟に入っています。 - 経路は経路案内ではありません。 信号、一方通行、階段とスロープの別、駅の営業時間、エレベーター、私有地の通り抜け可否を一切知りません。
- 所要時間は距離÷80 m/分。信号待ちを含みません。
- 高さはLOD1。押し出しの上端は点群由来で、
measuredHeightとは異なります。ビューアは両方表示します。どちらかを「その建物の高さ」として断定しないでください。 - 地形はDEMのTIN頂点を10 mグリッドに平均化した派生物です。測量成果ではありません。
データの中身と収録率の実測値は references/plateau-data.md にまとめてあります。
PLATEAUが3D都市モデルを整備している東京都の自治体(区部・多摩部)。--dry-runが必要なメッシュの過不足をそのまま教えてくれるので、対応可否はそれで判断できます。
他都市のPLATEAUパッケージも同じスキーマなので原理的には動きますが、検証は東京都のみです。関連データセット(駅・ランドマーク・公園)の有無は自治体によって異なります。
| 対象範囲 | メッシュ数 | 転送量 | 展開後 | build_scene |
出力HTML |
|---|---|---|---|---|---|
| 約1 km² | 2〜4 | 約40 MB | 約0.5 GB | 約10秒 | 約2 MB |
| 約3 km² | 6〜9 | 約150 MB | 約1.6 GB | 約16秒 | 約3.7 MB |
展開後サイズが大きいのはDEMが約500 MBのテキストだからです。地形が不要ならfetch.py --no-demで省けます。
出力ページには出典パネルが常時表示されます。元データがCC BY 4.0であるため、これは表示義務です。剥がさないでください。
- 都市の3Dデジタルマップデータ(区部・多摩部) — 東京都都市整備局、CC BY 4.0
- 実体ファイル: Project PLATEAU の各自治体CityGML v5 — 利用条件はPLATEAUサイトポリシー「3.著作権について」に拠ります
このリポジトリのコードとドキュメントは MIT License(LICENSE)。生成される3Dモデルの中身は上記の出典データに由来し、それぞれの条件に従います。
- tokyo-data-mcp — 東京都オープンデータカタログの読み取り専用MCPサーバーと、
urban-discoverySkill - Project PLATEAU — 国土交通省

