みなさんこんにちは!!!
「渋谷駅周辺の建物データを検索して」と頼んで、地図で範囲を確認し、そのまま3D表示や建物の抽出まで進められたら便利ですよね。
そんな入口を作ろうと、City Data Toolkit と City Data Agent を実装しています。PLATEAUの検索・取得・変換・解析を、手元のAIエージェントとWebブラウザから使うための試作です。
この記事では、GISの処理をエージェントにつなぐ設計と、Webアプリにするときに必要になった工夫を紹介します!GISやWeb開発に触れたことがある方に向けて、ローカルとWebをどう使い分けるかも含め、データを探してから結果を確認するまでの仕組みを説明していきます。
まず、何ができるの?
Web側のCity Data Agentでは、会話と地図を行き来しながらPLATEAUの都市モデルを扱えます。
1. 「渋谷駅周辺の建物データを検索して」と依頼する
2. 場所の候補と地図を見て、検索する範囲を決める
3. CityGMLの候補から、使うデータと変換先の形式を選ぶ
4. 変換したMVTや3D Tilesを地図に表示し、必要ならGeoPackageもダウンロードする
5. 同じデータに対して「高さ30m以上の建物を抽出して」と続けて解析の依頼する
会話の横に結果が地図で出てくると、何を処理したのかがわかりやすいですねー!
当然ですが、地図上でレイヤの表示切り替えをしたり、地図を傾けたりといった基本的なことはできます。
(Cesiumなので!)
この体験を作るには、場所の特定、ファイルの取得、変換、保存、描画をつなぐ必要があります。各ツールの実行結果を受け渡しながら、処理を進めます。
方針と手順はLLM、実行はGISやツールに任せる
LLMには、依頼の解釈と手順の組み立てを任せます。地名から位置を求めたり、データを取得・変換・解析したりする処理は、GISや外部ツールが実行します。 LLMはその結果を受け取り、次に何をするかを判断します。
例えば「渋谷駅周辺の建物データを検索して」という依頼から、場所・対象・目的は読み取れます。ただし、正確な座標や「周辺」の範囲は、地名検索や地図で確認する必要があります。座標変換や距離・面積の計算も、実際のデータと条件を指定してGISで行います。
GIS CopilotやAutonomous GISなどの研究でも、自然言語の依頼から処理手順やコードを生成し、GISツールやライブラリで実行する構成が採られていました。
今回も、LLMが手順を考え、GISやツールが実行し、結果を確かめるという分担にしました。使ったデータや処理条件を残しておけば、結果を追跡し、再実行して確認できます。
MicrosoftとAWSにも、データとツールをつなぐ実装がある
実装例として参考にしたのが、MicrosoftのPlanetary Explorerです。自然言語の質問からデータを選択し、地図に描画して結果を扱うWebアプリを備え、外部のAIエージェントから使うためのMCPも提供しています。データカタログへの接続やGDAL・Rasterioによる処理を、エージェントから利用する構成です。
もう一つは、awsのGeospatial Power Packです。Kiroを中心に、データ探索、GIS処理、基盤モデルの利用に関するMCPサーバーと、スキル・ワークフローをまとめています。座標変換や幾何演算にはPyProj・Shapely・GeoPandasなどを使い、重い処理をAWSの計算基盤へつなぐ仕組みも含みます。

(Geospatial Power Pack公式リポジトリ)
こうした実装を見ると、データへの接続と専門処理を道具として整え、それを会話から利用する構成が具体的に見えてきます。Webの画面から使う入口も、手元のAIエージェントから使う入口もある。今回もこの考え方を参考に、PLATEAUに対象を絞って実装しました。
今回の役割分担
City Data ToolkitとCity Data Agentでは、次のように分担しています。
| 担当 | 役割 |
|---|---|
| LLM | 依頼の解釈、ツールの選択、結果に応じた次の行動、利用者への説明 |
| 地名解決・カタログ検索 | 対象の場所や、実在するデータの候補を返す |
| GIS処理・Converter | 範囲の作成、形式変換、属性条件による抽出、空間演算 |
| アプリケーション | 入出力の検証、会話と作業状態の保持、成果物の管理 |
ツールを一度呼んだ後にも判断が続きます。候補が複数あれば選択を促し、処理が失敗したら結果を確認して次の手順を考える。この繰り返しを支えるのが、エージェントの実行を管理する仕組みである「ハーネス」です。
共通のGIS処理に、ローカルとWebの入口を作る
まず作ったCity Data Toolkitは、AIエージェントから使うためのツール群です。処理は4つに分けています。
| MCP | 扱う処理 |
|---|---|
| Location | 地名検索、地点からの範囲作成、範囲の移動・拡大縮小、座標参照系の変換 |
| PLATEAU | PLATEAUデータの検索と取得 |
| Conversion | MVT、3D Tiles、GeoPackageへの変換 |
| Analysis | 建築物の集計・抽出、交差・近接の解析 |
さらに、範囲作成やPLATEAUデータの準備、空間解析の進め方をスキルとして用意しています。MCPで処理を呼べるようにし、スキルでそれらの使い方を伝える構成です。
ローカルでは、CodexなどのAIエージェントがCity Data Toolkitに含まれる4つのMCPサーバーを通して処理を呼び出します。Location・PLATEAU・Conversion・AnalysisはいずれもToolkitの機能で、Conversionは変換エンジンとしてPLATEAU GIS Converterを利用します。生成したファイルはローカル作業領域へ保存し、工程間ではその参照を受け渡します。
最近の高性能なモデルとエージェントであれば、専用のMCPを用意しなくても、Web検索から必要なデータや変換ツールを見つけたり、その場で解析コードを書いて処理したりできちゃいます。それでもMCPとスキルを明示的に用意する理由は、大きく2つあります。
一つ目は、スキルで作業手順のばらつきを抑えるためです。毎回エージェントが一から方法を考えると、使うツールや処理の順番、座標系の確認、結果の検証まで実行ごとに変わり得ます。MCPで呼び出せる処理を用意し、スキルに手順や確認事項をまとめておけば、同じ作業を一定の進め方で実行しやすくなります。
二つ目は、Web側のCity Data Agentでも同じ専門処理を利用するためです。手元の高性能なエージェントが、その都度調べたりコードを書いたりして補ってくれる部分を、あらかじめツールとして整えておきます。Web側では高価なLLMが利用できない場合も多いので、その共通処理と必要な検証をハーネスに組み込みます。モデルやハーネスの性能が手元の環境より限られていても、同じGIS処理を安定して進められるようにすることが狙いです。
Web側で共有するのはMCPの背後にある処理です。ローカルではMCPとスキルを通して利用し、Webではアプリケーションから共通の処理を呼び出す。この構成で、エージェントが毎回自力で解決しなければならない部分を減らしています。
Webでは、状態・処理環境・配信まで面倒を見る
同じ処理をブラウザからも使えるようにしたのが、City Data Agentです。ここで必要になる仕事がかなり増えます。
まず、会話をまたいで作業対象を保持する必要があります。「この範囲」「さっきの建物」という依頼を扱うために、対象範囲、検索候補、選択したデータ、成果物、地図レイヤーを保存します。City Data Agentでは、これらを会話とともにChatAgentのDurable Objectで管理します。
次に、GIS処理を実行する場所が必要です。データの取得や変換には時間がかかり、Converterなどの実行環境も必要になるので、ToolkitのPythonパッケージとConverterをContainerに配置しました。
完成したファイルは、本番用の保存先をR2、ローカル開発時の保存先をRustFSとして扱います。そこからブラウザへ配信し、表示やダウンロードにつなげます。会話の実行にはCloudflare Agents SDKとWorkers AIを使っています。
で、ローカルとWebをどう使い分けるの?
両方を作って使ってみた感想ですが、普段のGIS処理をゴリゴリ任せるなら、まずはローカルのCity Data Toolkitを使いたい、というのが自分の感触です。
ここでいう「ローカル」は、手元で動かすエージェントが、自分のマシンのファイルやGISツールを操作する構成です。LLMの推論自体はクラウドのモデルを使っても構いません。
変換や空間解析を試行錯誤するなら、手元がやりやすい
今回のような専用Webアプリと比べると、手元のコーディングエージェントでは、高性能なモデルと、コード実行やエラー修正を繰り返せるハーネスを利用しやすいと感じています。決められた操作で足りなければコードを書き、中間ファイルを調べ、条件を変えて処理し直せます。
データ変換や空間解析も、手元のマシンに収まる規模なら、その場で実行してファイルを保存できます。手元のGISで結果を開いて、またエージェントに続きを頼む、といった作業もしやすいです。
同じことをWebで提供すると、処理用Containerの起動に加えて、時間のかかる処理を非同期で待つ仕組み、進捗や失敗の通知、成果物の保存とダウンロードまで必要になります。処理そのものに加えて、アプリケーションとして管理するものが増えるわけです。
なので、手元で処理できるデータを相手に、条件を変えながら変換や解析を繰り返したい場合は、Toolkitの形が合っていると思います。これはローカルの計算速度が常に上という話ではなく、エージェントの自由度と、処理環境を扱う手間を含めた使いやすさの話です。
検索や候補の確認には、Webの入口が効く
一方、「この地域にはどんなデータがある?」「欲しいデータはこれで合っている?」という軽量な操作を利用する場面では、Webが使いやすいと思います。
利用者がGISの実行環境やMCPを準備せずに、ブラウザで検索して候補を見られる。地名や範囲の曖昧さも、その場で地図を使って確認できます。取得や変換を始める前の、データを探して選ぶ入口として有効です。
City Data Agentでは、その先の変換・表示・解析まで実装しています。ただ、すべてのGIS作業をWebで完結させる必要はありません。Webでデータを探し、ダウンロードした後の詳しい解析は手元で進める、という使い分けも自然です。
手元に収まらない処理なら、遠隔の計算基盤を使う
さらに重い処理になると、今度は手元のマシンでは足りなくなります。例えば、地理空間向けの基盤モデルを使って大量の衛星画像を解析するなど、必要なGPUメモリやデータ量が手元の容量を超えるようなケースです。
そうした処理では、GPUサーバーやクラウドの計算基盤へジョブを送り、結果を待って確認する構成が候補になります。Web UIで対象データと条件を指定し、進捗や結果を確認できるようにする意味も大きくなります。
整理すると、使い分けはこんな感じです。
| やりたいこと | 使いたい構成 | 理由 |
|---|---|---|
| データ検索、候補や対象範囲の確認 | WebのCity Data Agent | ブラウザから入り、会話と地図で確認できる |
| 手元に収まるデータの変換・空間解析を繰り返す | ローカルのエージェントとCity Data Toolkit | ファイルやGISツールを直接扱い、処理を試行錯誤しやすい |
| 手元の計算資源を超えるモデル実行や大量データ解析 | 遠隔の計算基盤と、ジョブを操作する入口 | 必要なGPU・メモリ・ストレージを処理側に用意できる |
最後のケースでは、操作する入口と、計算を実行する場所を分けて考えます。入口にはWeb UIを使えますし、ローカルのエージェントから遠隔のジョブを呼ぶ方法もあります。衛星画像の基盤モデル解析は今回のPLATEAU向け実装の範囲外ですが、処理規模が変わったときの構成を考える例です。
軽い検索はWeb、普段の本格的なGIS作業は手元、手元に収まらない処理は遠隔の計算基盤へ。こうして作業に合わせて選べるようにする意味でも、専門処理と利用者の入口を分けておく価値があると思っています。
「渋谷駅周辺」を、確認できる範囲にする
ここからは、実際の依頼をどう扱うかを見ていきます。
最初の難所は「周辺」です。駅の周辺と行政区全域では、対象の広さがまったく違います。同じ地名でも複数の候補が返ることがあります。
そこで、PLATEAUカタログや地名検索で場所を解決し、一意に決まれば初期範囲を作成します。複数の候補がある場合は、利用者に選んでもらいます。
同じ「渋谷駅」でも、ホームや出入口などの候補が返ってきます。住所や地点の種類を見ながら、対象を選べます。
作成した範囲はAOI、つまり検索や解析の対象範囲として地図に出します。駅などの地点には代表点を中心とした矩形を用意し、利用者が移動やサイズ変更をできるようにしました。
この画面では約500m四方に設定しています。ここで大事なのは、初期値を利用者が確認して直せることです。「周辺」の解釈を地図で共有できます。
そして、「検索して」という依頼なら、範囲を確定して候補を検索したところで結果を返します。候補カードから変換先を選び、変換を実行すると次に進みます。依頼の段階で対象と変換先が明示されている場合は、その条件に沿って処理を進めます。
CityGMLを用途に合った形式へ変換する
検索後は、保存済みの候補と処理対象を照合し、CityGML Pack APIでデータを取得します。取得したデータは、PLATEAU GIS Converterで変換します。
この記事で扱う出力は、次の3形式です。
| 形式 | City Data Agentでの使い道 |
|---|---|
| MVT | 2Dの地物をタイルとして配信し、地図に重ねる |
| 3D Tiles | 3Dの都市モデルをタイルとして配信し、地図に表示する |
| GeoPackage | ダウンロードして、手元のGISで利用する |
候補カードでデータの内容を確認し、変換先を選んで実行します。この例では、渋谷区の建築物モデルを3D Tilesへ変換しています。
変換後には形式に応じてファイルの配置や範囲などを検査し、ストレージへ保存します。さらに、配信URLから取得できることを確認して、地図やダウンロード用の参照を返します。
変換した都市モデルを地図で見る
変換した建物が地図上に現れると、対象の街の様子を見ながらデータを確かめられます。
建物の高さや形が見えると、街の雰囲気がぐっと伝わりますね!
地図表示にはCesiumを使い、MVTと3D Tilesを同じシーンへ載せています。MVTは変換時にタイルを生成し、XYZ形式のURLからMVTDataProviderで読みます。3D Tilesはtileset.jsonを入口に、Cesium3DTilesetで読み込みます。
レイヤーの表示・非表示や透明度を切り替えたり、視点を傾けて建物の形を見たりできます。対象範囲へ移動して街の様子を確認し、不要になったレイヤーは削除できます。
GeoPackageはアセット一覧からダウンロードして、手元のGISで利用できます。ブラウザでデータを見てから、詳しい作業をローカルへ持ち帰ることもできます。
「さっきの建物」を引き継いで解析する
地図上で建物を確認できたら、今度はそのデータについて知りたくなります。続けて、こんな依頼をします。
この範囲の建物から、高さ30m以上のものを抽出して件数を教えて。
このとき、会話の中の「この範囲」を、保存してあるAOIと結びつけます。対象データも選択済みの候補を引き継ぎ、GIS側で属性条件による抽出を実行します。
この実行例では、渋谷区・2025年・メッシュ53393596の建築物モデルを使い、設定したAOIの建物324件から、高さ30m以上の123件を抽出しています。件数は、このデータと範囲、条件に対する結果です。
会話を続けて処理できると、かなり使いやすくなりますね!
解析では、件数・面積・高さ・階数・用途の集計や、地物同士の交差・近接も扱います。現在の解析は、建物属性と2次元の幾何形状に基づきます。3Dで表示している建物でも、この解析が扱う形状は2次元です。
継続して使うために、まだ確かめたいこと
ということで、Web版のCity Data Agentでは一連の処理を試作できました!
が、プロダクション品質の実装と運用には、まだまだたくさんの検証が必要です。
変換後のファイルを開けても、元の地物や属性がすべて保たれたとまでは言えません。入力と出力の件数だけでなく、属性や形状の対応、データごとの高さの整合を確認する必要があります。
Webでは、静的タイル群の公開・更新・削除や、ダウンロードURLの扱い、長時間処理の再開も課題になります。描画用の3D Tilesを追加生成する場合は、保存量と処理コストも増えます。
本番R2や高密度の都市データでの検証、外部APIやLLMが失敗した場合の通し確認も、継続して進めたい部分です。
一方、ローカルで使うCity Data Toolkitは、手元で動かしている範囲では比較的安定しています。Web特有のContainerの起動管理や非同期処理、成果物の公開・配信といった部分を抱えず、手元のマシンで処理してファイルを保存する構成なので、公開に向けて整えることも少なく済みます。
データごとの変換・解析結果の確認は引き続き必要ですが、Toolkitの方は先にサクッと公開できそうです! まずは手元のAIエージェントから使ってもらえる形にしたいと思っています。
おわりに
今回作ってみて、GISエージェントでは、専門処理をツールとして揃えたうえで、処理対象と結果を追えるようにする設計が効くと感じました。
使う場所についても、検索の入口にはWeb、手元での変換や解析にはToolkitという使い分けができます。さらに大きな計算資源が必要なら、処理を遠隔へ任せる構成を考える。必要な処理と作業の進め方に合わせて、入口と実行場所を選んでいきたいです。
曖昧な場所は地図で確認する。共通のGIS処理をローカルとWebで使う。ツールの実行結果を、エージェントの次の判断につなげる。こうした仕組みを合わせることで、「検索して」と頼んだところから、実際にデータを使うところまで進められます。
都市データをこんなふうに扱えたら、試してみたいことが増えそうですよね。実データでの検証を重ねながら、使える入口に育てていきたいです!








