はじめに
Mapbox のカスタム Indoor Mapは、身近な建物やイベント会場を含めて、まだまだ活発に利用されている状況にはなっていないように見えます。
カスタム Indoor Map(自分のデータで屋内地図)を作る方法自体は、Dev.to の記事「Build an indoor map with your own data in Mapbox GL JS」で詳しく説明されています。非常に良い記事なので、ぜひ読んでみてください。この情報があれば、geojson.io のようなツールに使い慣れている人なら、屋内地図を作ること自体は問題ないでしょう。しかし、実際の座標を意識しながら、部屋のポリゴンを一つひとつ描いていくのは、少し敷居が高いかもしれません。この記事では、まさにこの最初のハードルをできるだけ低くするために、Mapbox の屋内地図データ(Indoor data model)を、自然言語で作って直せるツール(indoor-generator)を紹介します。個人が気軽に作れる便利なツールがあれば、活用の範囲はもっと広がり、屋内地図の利用が進むのではないでしょうか。
屋内地図で扱う図面は、衛星画像から建物や道路の形を読み取る地図づくりとは、事情が少し違います。屋内地図の元データは、ベクターデータがはじめから手に入ることも珍しくはありません。ラスター画像しかない場合でも、衛星画像と違って、鮮明で詳細な図面が手に入ることが多いです。こうした画像からなら、画像認識でベクターデータを作ることが、比較的現実的な場合も少なくありません。つまり、画像から屋内地図を作ることは、Claude Code のようなツールと相性の良いユースケースだと考えています。(もちろん、実際には細部の確認と修正が要ります。)
以下では indoor-generator で、PMO新橋IIビルの5階の屋内地図を、フロア図の画像1枚から作る流れを紹介します。
※ 個人のプロジェクトで、Mapbox 社の公式製品ではありません。
こんな人・こんな用途を想定しています
つまずきやすいポイント
屋内地図を作ろうとすると、最初にこのあたりで止まりがちです。
- どう始めたら良いかわからない
- 何が必要?
- ツールは?
- 手持ちの屋内地図データや画像をどうしたら良い?
- そもそもデータがない
- プライベートなタイルセットにしたい
- Mapbox の indoor タイルセット(v3)の詳細を知らない
厳密さより「それなりに動く」を早く手軽に
一方で、用途によっては次のような性質があります。
- おおまかな位置関係が合っていれば、厳密な位置は問わない
- 頻繁に更新する(売り場案内など)
- 展示会、学園祭、運動会、フードフェスなど、一度きりで使い捨て
- 会社のオフィスのフロアプランなど、社内や関係者だけで使うプライベートな屋内地図
- ポジショニング(現在地)やルーティングは、必ずしも要らない
足りないのは、「それなりに動くものを簡単に作れて、すぐデプロイできる」ツールだと考えました。
ツールの特徴
| 特徴 | 内容 |
|---|---|
| ソース | 必要なら Web から自動で検索(公式サイトの階数・面積・フロアガイドなど) |
| 手持ちデータ | 自分で図面や画像を持っているなら、それを使う |
| 修正・更新 | 自然言語、またはプレビュー上の手作業で修正し、必要なときにデプロイ |
仕組みは次のとおりです。Claude Code(.claude/skills/ のスキル)が調査・設定ファイルの作成・対話を担当し、設定ファイルから GeoJSON を作る部分は決まった手順の Python パイプラインです。
「PMO新橋II 5Fの屋内地図を以下の画像から作成して」
→ 建物の位置特定(OSM)+ 外形(OSM、または図面から描く)+ Web 調査
→ configs/<slug>.json ← これが正(source of truth)
→ Python パイプライン
→ output/<slug>/indoor.geojson + ライブプレビュー
→ 「会議室を広く」「元に戻して」で対話しながら修正
準備
Quick start
このツールは、リポジトリをクローンしたフォルダの中で Claude Code と対話して使います。建物を調べて、パイプラインを動かす方法を知っているスキル(.claude/skills/ と CLAUDE.md)はこのリポジトリの中にあり、Claude Code が読み込むのは、起動したフォルダ(とその上位のフォルダ)にあるものだけです。別のフォルダで起動すると、このツールのことは何も知らない状態になります。
必要なもの
- Claude Code(ターミナルの CLI、デスクトップアプリ、VS Code 拡張のどれでも可)と、そのサインイン。Claude のサブスクリプションか API アカウントが要り、利用量を消費します
- Python 3.10 以上(開発に使っているバージョン。それより古いものは未確認)と git
-
Mapbox のアカウントと、地図をロードするためのパブリックトークン(
pk.*) - タイルセットをアップロード、ホスティングする場合のみ、**シークレットトークン(
sk.*)**も必要になります
以下のコマンドは macOS / Linux 前提です(Windows では .venv\Scripts\... に読み替えます)。
手順
-
クローンして、セットアップします。
git clone https://github.com/akiramur/indoor-generator.git cd indoor-generator python3 -m venv .venv && .venv/bin/pip install -r requirements.txt cp .env.example .env # MAPBOX_ACCESS_TOKEN にパブリックトークン(pk.*)を入れる -
そのフォルダで Claude Code を起動します(デスクトップアプリや VS Code では、クローンしたフォルダをプロジェクトとして開きます)。
claude -
Claude Code のプロンプトに、依頼をチャットとして入力します(シェルのコマンドではありません)。
丸の内ビルディングの屋内マップを作ってClaude Code が建物を調べ、
configs/<slug>.jsonを書き、output/<slug>/indoor.geojsonを生成して、ライブプレビュー(http://127.0.0.1:8765)を起動します。修正は同じセッションで続けて頼みます(「2階の北側を会議室にして」など)。コマンドの実行や Web の取得の前に、Claude Code が許可を求めることがあります。内容を読んで、許可できるものだけ承認してください。一番簡単なのは、このあとの例のように英語や日本語で建物の名前を書くだけです。
補足
-
.envは git の管理外です。pk.*トークンはoutput/<slug>/index.htmlに書き込まれるので、そのファイルを共有するときは、Mapbox のコンソールでトークンに URL 制限をかけてください。 -
Claude Code を使わずにパイプラインだけ試すなら、同梱のサンプルが動きます。
.venv/bin/python main.py build samples/building_config.json .venv/bin/python main.py serve marubiru-sample # http://127.0.0.1:8765 -
1 つの建物の調査とビルドには、Web の検索と取得を含めて数分かかります。Claude の利用料は
main.py costで目安(公開単価での換算)を見られます。
作ってみる: PMO新橋IIビル 5F
1. 画像を渡して、依頼する
用意したのは、**5階の貸室のフロア図(画像1枚)**だけです。このリポジトリで Claude Code を開き、こう頼みました。
PMO新橋II 5Fの屋内地図を以下の画像から作成して
2. Claude Code がやること
indoor-map スキルと indoor-floor-image スキルが、次の順で進めます。人がクリックして位置合わせをする必要はありません。
-
建物を特定して調べる: 住所から OSM で建物を探し、Web で階数・延べ面積・基準階の面積などを調べます。PMO新橋IIビルは地上14階、基準階は約281㎡でした。調べた出典は
configs/<slug>.jsonのprovenance.sourcesに残ります。 - 外形を決める: 外形は OSM の建物の形を使います。PMO新橋IIビルの OSM は、再開発前の旧ビル(矩形)のままだったので、このように古い・粗いときは、フロア図の外壁から実寸で描きます。Mapbox の地図タイル(Mapbox Streets の建物)から形を取り出すことは、Mapbox の製品規約で認められていない可能性があるので避けています。
-
画像を建物に重ねる: 画像は曲げず、拡大縮小・回転・移動だけで、図面の外形が建物の外形に最もよく重なる位置を探します(
main.py basemap)。画像の上がどちらの方角かは、周辺の道路や衛星写真なども見て Claude が判断して指定します(今回の判断は後述)。 -
部屋の輪郭をトレースする: 画像の部屋(執務エリア、会議室、エレベーター、トイレ、階段…)の輪郭を Claude が読み取り、建物に合わせた座標に変換します(
main.py trace)。EV・階段・トイレなどのピクトグラムは点(POI)としても入ります。 -
ビルドしてプレビュー:
indoor.geojsonを生成し、ブラウザでライブプレビューします。
手で打つなら、核になるのは次のコマンドです(普段は Claude が実行します)。
.venv/bin/python main.py build configs/pmo-shimbashi2.json
.venv/bin/python main.py serve pmo-shimbashi2 # http://127.0.0.1:8765
3. できあがったもの
プレビュー(Mapbox GL JS の Standard スタイル + indoor ブロック + IndoorControl)の右下で、階を切り替えられます。左の「Floor map from the source」のチェックで、元のフロア図の重ね表示を切り替えられます(冒頭の画像は重ねた状態です)。
ここまでで見せたのは、ツールに付いている確認用のプレビュー(編集機能つき)の画面です。これとは別に、できあがった屋内地図を、素の Mapbox GL JS だけで表示するデモも用意しました。ツールのプレビュー用サーバーは使わず、生成した GeoJSON(施設ごとのファイル)を読み込んで表示するだけの、1枚のページです。自分の屋内地図を Web ページに載せるときの、最小の例として見てください(フロア図の画像は含まず、生成した部屋や設備のアイコンなどだけを表示しています)。
デモでは、地図を回したり傾けたり、右下の IndoorControl の一番上のボタンで階を隠して、元の 3D の建物に戻したりできます。
デモのソースは、ブラウザのページのソース表示で読めます。ページ(index.html)と、data/ フォルダの JSON ファイル(施設の一覧、アイコンの定義、施設ごとの GeoJSON)だけでできています。
なお、デモが階の切り替えに合わせて 3D の建物を出し入れするのに使っている map.style.indoorManager は、公開された仕様のない、実験的な API です。真似るときは、将来の変更に注意してください。
5Fの結果は次のとおりです。
| 項目 | 結果 |
|---|---|
| 部屋数 | 16(画像からトレースした 15 部屋 + 残りの共用部・通路 1 件) |
| 画像からトレースした部屋 | 面積の約 49% |
| 残りの共用部・通路 | 約 51%(外形から、トレースした部屋を引いて自動で導出) |
| ピクトグラム | エレベーター・階段・トイレの点(POI)を 6 点 |
入った部屋は、男性・女性トイレ、前室、エレベーター、非常用エレベーター、エレベーターホール、PS・DS・EPS、階段 2 か所、会議室(円形)、会議室、ブース 2 室、執務エリア、ラウンジです。名前と用途(category)は画像の文字から付けています。
作業の流れで見ると、依頼を1回入力してから約5分でプレビューまで進みました。Claude の利用料の目安は約 $0.9 です(請求額ではなく、公開単価での換算)。
4. 初回の結果と、直し方
最初から完璧にはなりません。Claude 自身が、できあがりと一緒に次の点を報告しています。
- トイレの個室や円弧の壁など、細部は簡略化しています。
- トレースした部屋が、外形(OSM や、図面から描いた形)から一部はみ出すことがあります。そのときも、部屋は削らずに残す方針です(外に出た割合は、
traceの出力で報告されます)。 - 位置合わせは、ランドマークではなく、建物の外形に合わせた自動配置です。
- 画像の向き(上=東)は、目視での判断です。
直すときは、チャットで「男性トイレをもっと広く」のように名前で頼むか、プレビューで部屋をクリックして「この部屋を〜」と頼みます。手で直すなら、プレビューの Edit floor から、頂点の移動、部屋の追加・削除、結合ができます。画像のずれは「Floor map」モードでドラッグ・拡大縮小して「Save this floor only」で保存できます。直前の状態に戻したいときは「元に戻して」(undo)です。ただし、undo が戻すのは設定ファイルだけです。プレビューで手直しした部屋の形は戻らないので(バックアップは configs/.history/plans/ にあります)、保存前なら編集モードの Undo(取り消し)を使ってください。
5. 根拠の強さを数字で見る
main.py report で、どの部屋がどれくらい根拠のあるデータかを確認できます。
.venv/bin/python main.py report configs/pmo-shimbashi2.json
今回の5Fは、「画像から起こした(traced)」が面積の 49.2%、「導出(derived)」が 50.8% でした(「名前だけ(listed)」と「推定(estimated)」は 0%)。
「画像から起こした(traced)」「名前だけ(listed)」「推定(estimated)」「導出(derived)」を区別して数字で出すので、どこを信じてよくて、どこが推定かが分かります。複数階の建物では、図面のない階が「推定」として一覧に出るので、次に調べる場所の見当がつきます。
もう一例: 画像がなくても、Webから探して作る(三井アウトレットパーク 多摩南大沢)
PMO新橋IIビルは自分で図面を渡しましたが、図面を持っていない場合は、Claude が Web から探します。例として、三井アウトレットパーク 多摩南大沢で、最初に入れたプロンプトはこれです。
三井アウトレットパーク 多摩南大沢 のインドアマップを作って
画像も、URLも、階数も渡していません。ただし、この後で見せるスクリーンショットは、この一言だけの結果ではありません。最初のビルドのあと、何度も修正を繰り返して仕上げたものです。経緯は後半に書きます。
Claude が Web で見つけたもの
調査メモ(output/<slug>/research.md)と設定ファイルの出典から、実際に起きたことを引用すると次のとおりです。
| 見つけたもの | 使い方 |
|---|---|
| 公式フロアガイド 1F / 2F(画像のみ。図形やホットスポットなどの機械可読データはなし) | 店舗の輪郭と店名を読み取る(画像は URL のまま登録) |
| OSM の relation / way(A街区・Villa棟と中央の島) | 建物の位置の特定。外形は OSM の形と店舗の和集合に |
公式サイトの図が画像だけだったので、先ほどの5Fと同じ「画像を重ねる → トレースする」の流れになりました。違うのは、画像を探してくるところまでが自動という点です。位置合わせは、名前付きのランドマークが OSM になかったので、駐車場ブロックの角などを対応点にして、誤差は 1〜2 m 程度でした。(この例の1Fは、作成当時の方法である対応点でのアフィン変換で、画像を少し変形して合わせています。現在のツールは、画像を曲げない相似変換だけです。)
できあがり(修正を重ねたあとの状態)
| 項目 | 結果 |
|---|---|
| 階数 | 2階建て(1F・2F) |
| 店舗などの輪郭 | 1F 66 部屋、2F 59 部屋を画像からトレース(階段や駐車場を含む) |
| トレースが占める面積 | 約 51%(残りは屋外の通路・中庭など、外形から導出した共用部) |
店名・位置・形・用途の区分(物販 / 飲食 / サービスなど)が入った状態で、プレビューの右側に店舗の一覧も出ます。
最初の一言から、ここまでの道のり
最初のプロンプトの結果は、店舗の形が元の図とずれている部分が多い、粗いものでした。そこから、実際には次のように直していきました(セッションの記録から)。
- 最初のビルド: 上のプロンプトを入力。公式フロアガイドから店舗をトレースして、1F・2F の最初の地図ができる。
- 形が合わない: 「店舗の形が、背景(元の図)の形と合っていないので合わせて」と指示。
-
店舗ごとの修正を、約10回: 次のような指摘を、店舗ごとに繰り返しました。
- ある店が隣の店に食い込んで、飛び地(島)になっている
- 店の右側や角が欠けている
- 別々の2店が1つにまとまってしまっている
- 店の側面に、おかしな突起ができている
- 階段を追加: 階段が入っていなかったので、図から階段の形を読み取って追加しました(調査メモにも「階段 追加」として記録されています)。
つまり、最初の一言で出てくるのは、あくまで出発点です。そこから「この店はおかしい」「ここが欠けている」と、気になるところを一つずつ会話で直して、ようやく上のスクリーンショットの状態になりました。
直しきれていないこと
調査メモには、いまもわかっていないことが記録されています。
- 中央の島は店舗の境界が細かく、位置も形も概略です。
- 用途は店名からの推定です(公式のカテゴリ表は取り込んでいません)。
- 階段かエスカレーターかは図から断定できず、矢印1本のはしご形を階段と判断しています。
- 閉店予定と書かれた店舗は、掲載時点のままです。
「それなりに動く」ところまでは自動で行き、細部の確認と直しは、人が行うものです。直し方は、Claude との対話でも、プレビュー上の手動(Edit floor)でも選べます。また、元は公式サイトの図なので、冒頭の著作権の注意がそのまま当てはまります(画像はコミットせず URL のみを保持、公開前に権利を確認)。
FAQ
Mapbox Tiling Service(MTS)にアップロードしなくても使える?
使えます。 この記事のプレビューは、生成した indoor.geojson をそのまま Mapbox GL JS の GeoJSON ソースとして読み込んでいます。アップロードもデプロイも要りません。必要なのはパブリックトークンだけです。
たとえば、数棟のイベント会場を作って手元で確認する、といった用途ならここで完結します。複数人に配る、ホスティングしたい、という段階で初めて MTS を使います。
アップロードする場合は、main.py publish で全ビルド済みの建物を1つのタイルセットにまとめます。--upload を付けない限りドライランで、既定の送り先は開発用(indoor-dev)です。シークレットトークン(sk.*)は .env から読み、HTML には埋め込みません。
Processing と hosting の料金は?
料金は変わることがあるので、最新の単価と無料枠は公式のページで確認してください。
- Mapbox Pricing(Tilesets の項目に、Processing と Hosting の単価と無料枠があります。地図の表示(Mapbox GL JS)の料金もここです)
- Mapbox Tiling Service の料金の考え方(何に対して課金されるかの説明)
無料枠に収まる目安
2026-10-21 時点の公式ページの無料枠(Processing は月 10,000 MB と 20 CU、Hosting は月 750 日分、GL JS の地図表示は月 50,000 ロード)と比べた、おおまかな見立てです。目安なので、実際の請求は公式の単価と、ご自身の使い方で確認してください。
- データの大きさ(MB): デモに載せている 6 施設の GeoJSON は、合計で約 1.3 MB です。手元でこのツールで作った 14 棟(大きなホールや商業施設を含む)を全部足しても、約 5 MB です。月 10,000 MB の無料枠の 0.1% 未満なので、数棟〜数十棟の屋内地図では、まず気にならない大きさです。
- 処理の量(CU): 公式ページでは、ベクタータイルセットの処理は 1 ジョブあたり 0.3〜5 CU 程度が多いと案内されています。月 20 CU の無料枠だと、多く見積もっても(5 CU)月 4 回、少なく見積もれば(0.3 CU)月 60 回ほどのアップロードに相当します。頻繁に作り直してアップロードするほど、ここから先に消費します。 手元で直している間はアップロードせず、プレビューで確認するのが無難です。
- ホスティング(日数): このツールは、すべての建物を1 つのタイルセットにまとめて公開します。1 つなら月 30 日分で、無料枠の 750 日分(平均 25 タイルセット)に十分収まります。
- 地図の表示(GL JS): 月 50,000 ロードまでが無料枠です。展示会や学園祭のように、短い期間だけ、限られた人が見る地図なら、これも収まりやすい規模です。
逆に、アップロードを何度も繰り返す、公開して多くの人が見る、といった使い方になると、無料枠を超えることがあります。
Claude の利用料は?
このツールは、ビルドごとの Claude の利用料の目安を、Claude Code のセッションログから計算します(main.py cost、請求額ではなく、公開単価での換算)。今回の PMO新橋IIビル では次のようになりました。
| 作り方 | 目安 | ターン数 | 作業時間 |
|---|---|---|---|
| PMO新橋IIビル 5F だけ(上のとおり、1回の依頼で) | 約 $0.9 | 1 | 約 5 分 |
| 同じ建物を、他の階の図面まで作り込んだもの(調整の往復を含む、8日間) | 約 $9.8 | 37 | 約 35 分 |
上の行は、1回の依頼で地図ができあがるまでの目安です(その後の修正やプレビューの表示の操作は含みません)。下の行は、1F・2F・3F・7F・8F などの作成と、対話での修正の往復を含むので、桁が違います。直せば直すほど、利用量は増えます。
著作権は?
ここは気をつけてください。 公式サイトのフロアマップや募集資料の図面は、一般に著作物です。このツールでは次のようにしています。
- 第三者の画像はリポジトリにコミットしません(
configs/plans/*/maps/は git の管理外)。設定ファイルには出典の URL だけを残し、画像は手元のキャッシュに置きます。 - 地図データの外形や座標は © OpenStreetMap contributors(ODbL)を使うので、公開するときは帰属表示を残します。外形が OSM にないとき(古い建物など)は、図面から描きます。Mapbox の地図タイルから形を取り出すことは、製品規約で認められていない可能性があるので避けています。
- 公式サイトのフロアガイドを読み込むインポーターは、利用規約と robots.txt を確認したうえで、個人での、たまの利用を前提にしています。
記事に載せる画像や、作った地図を公開・配布するときに、元の図面の権利が許すかは、作る人が確認する必要があります。ツールが解決してくれるものではありません。今回のように、自分(または自分の施設)の図面から作るのが一番安全です。
うまくいったこと
- 店名を1つずつ入力しなくて済みます。 公式フロアガイドの画像から、店名と店舗の形が読み取られます。多摩南大沢では、1F・2F 合わせて約125の区画が、手で入力せずに入りました。私の感覚では、手作業に比べて、労力はかなり減ります。
- 調べものも、任せられます。 建物の階数や面積などを、Web から調べて、出典と一緒に設定ファイルに残します。
- 直すのも、会話でできます。 「この店が隣に食い込んでいる」と伝えるだけで、形が直ります。
ただし、読み取りは完璧ではありません。店名の誤読や、形のずれは起こるので、確認と修正は、必ず必要です。
うまくいかなかったこと
正直に書くと、次のあたりは苦戦しました。
- 複雑な形状の施設: PMO新橋IIビルの5Fは円形の会議スペースや斜めの壁があり、四角く単純な建物より、輪郭の読み取りも位置合わせもずれやすいです。空港ターミナルのような大きく複雑な建物は、さらに手がかかります。
- 対応点を指定しての変形: 画像上の点と地図上の点を対応させて画像を変形する方法は、うまくいかずにやめました。いまは画像を曲げず、拡大縮小・回転・移動だけで合わせています。
-
方角の自動認識: 画像の上がどちらを向いているかは、自動では当たらないことがありました。細長い建物は上下を逆にしてもほぼ同じに見えるためです。コンパスや北向きの矢印を Claude が読んで
--map-up/--north-degで渡し、曖昧なときは警告を出して確認します。今回の5Fも、「上=東」と「上=西」の2通りが同じくらいの精度で当てはまり、周辺の道路と衛星写真(ガラス面が南の道路側、コア部分が北の隣のビル側)から「上=東」と判断しました。この判断は目視なので、逆に見えるときは指摘して直します。
注意点
- 一発で地図を作る魔法のツールではありません。 初回の結果は「それなりに」で、そこから直して仕上げます。
- 複数回のやり取りが必要です。 今回の5Fも、トイレの個室や円弧の壁など細部は簡略化されたままで、直すには「ここを広く」「この辺の線を壁に合わせて」といった指示を重ねることになります。
- 著作権には注意が必要です(上記)。
- 精度は、位置合わせの誤差が数 m の「おおまかな位置関係」です。測量図ではないので、現在地測位やルーティングの用途には向きません。
まとめ
これまで、Indoor Map は、どこから、どのように始めればよいのかが分かりにくく、最初の一歩のハードルが高いものでした。このツールを使えば、図面の画像1枚と、チャットでの依頼から、最初の地図ができます。そこから会話で直していけば、屋内地図づくりのハードルは、かなり下がるのではないかと思います。
- フロア図の画像1枚と1行の依頼から、Mapbox の屋内地図(
facility > structure > floor > room)を作れる - プレビューはアップロードなしで動く。配りたくなったら MTS へ
- 修正は自然言語でも、プレビュー上の手作業でもできる
- 「どれくらい根拠のあるデータか」を数字で確認できる
- 一発では終わらない。そして元の図面の権利は、作る人が確認する
頻繁に変わるスーパーの売り場案内や、展示会、学園祭、フードフェスのような一度きり・使い捨ての場の案内図や、会社のフロアプランのような社内向けのプライベートな屋内地図など、身近な場所の屋内地図を、お気軽に作ってみてはいかがでしょうか?
おまけ: 他の施設のデモ
先ほどのデモには、PMO新橋IIビルのほかにも、このツールで作った施設を載せています。左上のプルダウンで施設を切り替えられます(選んだ施設は、URL の ?b= に入ります)。スクリーンショットで紹介します。
なお、これらは非公式・参考用で、形状には、公式の図面などをもとにした推定を含みます(デモの画面にも、同じ注意書きを出しています)。
東京駅丸の内駅舎
東京国際フォーラム ホールC(座席の試作)
さらに拡大すると、座席1つひとつと、席番号・列番号まで見えます。
ららぽーと立川立飛
IKEA立川(2F)
福岡空港 国内線旅客ターミナルビル









