0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【PLATEAU×Python】東京23区の建物DB構築(前編)— CityGMLのデータ構造を完全理解

0
Last updated at Posted at 2026-04-12

シリーズ記事

はじめに

国土交通省が推進する PLATEAU(プラトー) は、日本全国の3D都市モデルをオープンデータとして公開するプロジェクトです。建物の形状・高さ・用途から災害リスクまで、驚くほど詳細なデータが 無料で 手に入ります。

しかし、いざデータをダウンロードしてみると CityGML という馴染みのない形式で、ZIP を開いても大量のフォルダとファイルに圧倒されます。

この記事では 東京23区の建物データ を題材に、PLATEAU CityGML の構造を1つずつ解き明かしていきます。後編では、この理解をもとに Python で建物DBを実際に構築します。

PLATEAU データの入手

PLATEAU のデータは G空間情報センター からダウンロードできます。

各区ごとに ZIP ファイルが用意されており、東京23区分で 23個の ZIP があります。

13101_chiyoda-ku_pref_2023_citygml_2_op.zip    ← 千代田区
13102_chuo-ku_pref_2023_citygml_2_op.zip       ← 中央区
13103_minato-ku_pref_2023_citygml_2_op.zip     ← 港区
  ...
13123_edogawa-ku_pref_2023_citygml_2_op.zip    ← 江戸川区

ファイル名の構成は {都市コード}_{区名}_{提供元}_{年度}_citygml_{LOD}_{種別}.zip です。

ZIP の中身を見る

千代田区のZIPを展開してみると、以下の構造になっています。

13101_chiyoda-ku_pref_2023_citygml_2_op.zip
├── codelists/        ← コード値の辞書(55個のXML)
├── metadata/         ← メタデータ
├── schemas/          ← GML/XSD スキーマ定義
├── specification/    ← 仕様書(PDF/Excel)
├── udx/              ← ★ 実データ本体
│   ├── bldg/         ← 建築物モデル(今回の主対象)
│   ├── brid/         ← 橋梁モデル
│   ├── dem/          ← 地形モデル
│   ├── fld/          ← 洪水浸水想定区域
│   ├── frn/          ← 都市設備モデル
│   ├── htd/          ← 高潮浸水想定区域
│   ├── lsld/         ← 土砂災害警戒区域
│   ├── luse/         ← 土地利用モデル
│   ├── tran/         ← 道路モデル
│   ├── ubld/         ← 地下街モデル
│   ├── urf/          ← 都市計画決定情報
│   └── veg/          ← 植生モデル
├── README.md
└── indexmap.pdf

codelists/ 以外にも schemas/specification/ がありますが、DB化で主に使うのは codelists/udx/ です。

各フォルダの役割

フォルダ 内容 DB化での重要度
codelists/ コード値→意味の変換辞書。用途や分類が数値で入っているのを「住宅」「商業施設」等に変換 ★★★ 必須
metadata/ データセットのメタデータ。リソース一覧CSV等 ★ 参考
schemas/ CityGML + PLATEAU拡張のスキーマ定義 ★ 参考
specification/ 仕様書(PDF/Excel) ★ 参考
udx/ 実データ本体。テーマ別にGMLファイルが格納 ★★★ 必須

udx/bldg/ — 建物データの構造

udx/bldg/ の中には、メッシュコード単位で GML ファイルが分割されています。

udx/bldg/
├── 53394509_bldg_6697_appearance/  ← テクスチャ画像
├── 53394509_bldg_6697_op.gml      ← ★ 建物データ本体
├── 53394518_bldg_6697_appearance/
├── 53394518_bldg_6697_op.gml
└── ...(千代田区で21組)

appearance フォルダ にはテクスチャ画像、GML ファイル に建物の属性とジオメトリが入っています。千代田区だけで 21 GML、23区合計では 985 GML になります。

GML ファイルの中身

GML ファイルの先頭部分を見てみましょう。

<?xml version="1.0" encoding="UTF-8"?>
<core:CityModel
  xmlns:bldg="http://www.opengis.net/citygml/building/2.0"
  xmlns:gml="http://www.opengis.net/gml"
  ...>
  <gml:boundedBy>
    <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/6697"
                  srsDimension="3">
      <gml:lowerCorner>35.666... 139.737... 0</gml:lowerCorner>
      <gml:upperCorner>35.675... 139.750... 271.776...</gml:upperCorner>
    </gml:Envelope>
  </gml:boundedBy>
  <!-- この下に bldg:Building が並ぶ -->
</core:CityModel>

1つの GML ファイルに数百〜数千棟の bldg:Building 要素が含まれています。
千代田区の最初の GML には 897棟 の建物データがありました。

各要素の出現数を確認

import re
import zipfile

with zipfile.ZipFile(zip_path, "r") as zf:
    raw = zf.read("udx/bldg/53394509_bldg_6697_op.gml").decode("utf-8")

checks = {
    "bldg:Building": r"<bldg:Building ",
    "lod0RoofEdge": r"<bldg:lod0RoofEdge>",
    "lod1Solid": r"<bldg:lod1Solid>",
    "lod2Solid": r"<bldg:lod2Solid>",
    "boundedBy": r"<bldg:boundedBy>",
}
for name, pattern in checks.items():
    print(f"{name}: {len(re.findall(pattern, raw))}")
bldg:Building  : 897件
lod0RoofEdge   : 897件
lod1Solid      : 897件
lod2Solid      : 897件
boundedBy      : 31,894件(壁面・屋根面の総数)

建物1棟のデータ構造(18属性)

1つの bldg:Building を取り出すと、18個のトップレベル属性 を持っています。

基本属性(8個): creationDate / stringAttribute / class / usage / measuredHeight / storeysAboveGround / storeysBelowGround / address

形状データ(3個): lod0RoofEdge / lod1Solid / lod2Solid

構成要素(2個): outerBuildingInstallation / boundedBy

PLATEAU拡張属性(5個): buildingIDAttribute / buildingDetailAttribute / bldgDisasterRiskAttribute / bldgDataQualityAttribute / bldgKeyValuePairAttribute

基本属性

属性 実データ例 説明
creationDate 2024-03-15 データ作成日
stringAttribute [{name: '大字・町コード', value: '1'}, ...] 拡張文字列属性
class 3001 建物形態区分(コード値)
usage 422 用途(コード値)
measuredHeight 5.9 (m) 計測高さ
storeysAboveGround 2 地上階数
storeysBelowGround 0 地下階数
address 東京都港区赤坂一丁目 住所

形状データ(LOD)

LOD(Level of Detail)は詳細度のレベルです。

  • lod0RoofEdge: 真上から見た建物外周の座標列。DB化の際の 主ジオメトリ として最適
  • lod1Solid: 外周を高さ方向に押し出した箱型の3Dモデル
  • lod2Solid: 屋根形状まで含む詳細な3Dモデル

PLATEAU 拡張属性

CityGML の標準仕様に加えて、PLATEAU 独自の拡張属性が充実しています。

属性 内容 実データ例
buildingIDAttribute 建物の一意ID + 自治体コード buildingID: 13103-bldg-904, city: 13103
buildingDetailAttribute 屋根面積、防火構造、都市計画区域、容積率等 buildingRoofEdgeArea: 53.79, specifiedFloorAreaRate: 400
bldgDisasterRiskAttribute 災害リスク(洪水浸水深、ランク等) rank: 1, depth: 0.05
bldgDataQualityAttribute データ品質情報(LODタイプ、測量精度等) lodType: 2.2
bldgKeyValuePairAttribute 追加コード属性 key=100:value=11, key=101:value=1, ...

codelists — コード値の辞書

class3001usage422 と言われても意味が分かりません。ここで codelists/ の出番です。

Building_class.xml(建物形態区分)

# codelist XML をパースして辞書化
def read_codelist_df(zf, xml_path):
    raw = zf.read(xml_path)
    root = ET.fromstring(raw)
    rows = []
    for defn in root.iter():
        if local_name(defn.tag) == "Definition":
            rows.append({
                "gml_id": defn.attrib.get("{http://www.opengis.net/gml}id", ""),
                "description": descendant_first_text(defn, "description"),
                "name": descendant_first_text(defn, "name"),
            })
    return pd.DataFrame(rows)
コード 意味
3001 普通建物
3002 堅ろう建物
3003 普通無壁舎
3004 堅ろう無壁舎
3000 分類しない建物
9999 不明

Building_usage.xml(用途)

コード 意味
401 業務施設
402 商業施設
403 宿泊施設
404 商業系複合施設
411 住宅
412 共同住宅
413 店舗等併用住宅
414 店舗等併用共同住宅
415 作業所併用住宅
421 官公庁施設
422 文教厚生施設
431 運輸倉庫施設
441 工場
451 農林漁業用施設
452 供給処理施設
461 不明

ZIP 内には 55個のコードリスト XML があり、建物以外(橋梁、道路等)のコードリストも含まれています。

DB化に必要な属性の選定

18属性すべてをDB化するのは現実的ではありません(特に3Dジオメトリは巨大です)。分析や可視化に必要な属性を選定すると、以下の 13カラム が実用的です。

カラム 取得元 役割
gml_id Building の gml:id CityGML内の一意識別子
building_id buildingIDAttribute 現実世界の建物ID(13103-bldg-904
city_code buildingIDAttribute 区コード(1310113123
area_code_full stringAttribute 区+大字+町丁目の結合コード
class class 形態区分コード
usage usage 用途コード
measuredHeight measuredHeight + 補完 高さ(m)
storeysAboveGround 直値 地上階数
storeysBelowGround 直値 地下階数
address address 住所テキスト
lod0RoofEdge_posList lod0RoofEdge 建物外周の座標列

lod0RoofEdge を主ジオメトリに選んだ理由は、2D の外周線として軽量かつ、地図上での建物ポリゴン表示に直接使えるためです。

まとめ

  • PLATEAU CityGML は udx/bldg/ に建物データの GML が格納されている
  • 1つの GML に数百〜数千棟の bldg:Building が含まれ、東京23区で 985 GML
  • 各建物は 18 属性を持ち、基本属性・LOD0〜2の形状・PLATEAU拡張属性に分類される
  • コード値(用途 422 = 文教厚生施設、等)は codelists/ で人間が読める形に変換できる
  • DB化には 13カラム を選定し、lod0RoofEdge を主ジオメトリとする

後編 では、この構造理解をもとに Python で23区全域の建物DBを実際に構築します。高さの補完ロジックや Parquet 分割保存など、実装の詳細を解説します。

GitHub

ソースコード一式は以下のリポジトリで公開しています。

シリーズ記事

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?