Lesson 38

L38 CS立体図 2件統合分析 — 曲率×傾斜の RGB 段彩が描く地形微細構造 と 土砂災害警戒区域の物理的論理

LiDARCS立体図地形微細構造RGB ラスタrasterio曲率傾斜土砂災害警戒区域rasterizeHSV
所要 20-30 分 / 想定レベル: リテラシ + GIS応用 / データ: DoBoX dsid 1628 + 1629 (CS立体図 1m + 50cm), 代表 3 自治体 GeoTIFF (RGB 3 バンド)

データ取得手順

このスクリプトは初回実行時にデータを自動取得します(DoBoX からの直接ダウンロード)。

IDデータセット名
#222dataset #222
#444dataset #444
#600雪崩危険箇所情報_北広島町
#666dataset #666
#888都市計画区域情報_区域データ_安芸高田市_行政区域
#1628CS立体図(1m)
#1629CS立体図(50cm)

実行コマンド:

cd "2026 DoBoX 教材"
python -X utf8 lessons/L38_cs_terrain.py

DoBoX のオープンデータは申請不要・商用/非商用とも利用可。 data/extras/.gitignore 対象(約 57 GB のキャッシュ)。 スクリプト実行で自動再生成されます。

学習目標と問い

カバー宣言: 本記事は DoBoX のシリーズ 「CS立体図 1m / 50cm」 2 件 (dataset_id = 1628, 1629) を統合し、広島県 3 自治体エリア (世羅町 1m / 熊野町 1m / 坂町 50cm) の 地形微細構造を RGB ラスタの色合成として読み解く研究記事です。 さらに L10/L11 で扱った土砂災害警戒区域 (yellow / red) Shapefile を空間結合し、 「CS立体図のどの色域 (どの地形型) が警戒域に多いか」を量的に検証します。

本記事の独自性 — RGB 3バンド × 警戒区域の量的結合

CS立体図は専門家向けの視覚的地形可視化として広く使われていますが、 本記事はそのRGB 数値そのものを解析対象として扱う点で他と異なります:

シリーズ構造判定: (a) 同一手法・解像度違い + (b) 自治体ごとの分割

このシリーズは 1m 版 (区分A) / 50cm 版 (区分B) の 2 解像度系統で、 各自治体ごとに GeoTIFF (RGB 3バンド uint8) を切出して公開する構造。 1m 版は 22 自治体、50cm 版は 12 自治体に対応。

独自用語の定義 (本記事内で固定)

用語定義
CS立体図 (Curvature × Slope)長野県林業総合センター (戸田堅一郎ら, 2014) が開発した地形微細構造可視化手法。標高 (DTM) から計算した曲率 (Curvature)傾斜 (Slope) を組み合わせ、3 バンド RGB の段彩図として描画。 凸地形 (尾根) を赤、凹地形 (谷) を青で強調、傾斜は明度として表現される。 本記事の TIFF はその標準実装の出力 (uint8, 3バンド)。
曲率 (Curvature)地形の凹凸度。標高ラスタに対し ラプラシアン (∂²z/∂x² + ∂²z/∂y²) を計算した値。正の曲率 = 凸 (尾根・段丘崖の上端)負の曲率 = 凹 (谷・崩壊跡の凹み)。CS立体図ではこの符号が R-B 軸に投影されている。
傾斜 (Slope)地形の傾斜角度 (度)。標高ラスタの空間勾配 sqrt((∂z/∂x)² + (∂z/∂y)²) を arctan で角度に変換。CS立体図では明度 (G バンド) として表現。 急斜面ほど暗い色、緩斜面ほど明るい色。
R / G / B バンド (本記事)R = 尾根強度 (凸), G = 傾斜 (明度), B = 谷強度 (凹) と本記事は解釈。実装は CS立体図の色設計を参照したもので、DoBoX 公式仕様に 明示はないが、視覚的に検証可能な解釈。
地形タイプ自動分類 (本記事独自)R/G/B の値から 5 クラス (尾根 / 谷 / 急傾斜 / 平地 / 複雑) に自動ラベル付け。 パーセンタイル適応閾値 (上位/下位 25% 等) を使用するため、エリアごとに閾値が異なる。
Saturation (彩度)HSV 色空間の S 成分。 S = (max − min) / max で計算。本記事では「微地形コントラストの強さ」の代理指標。 彩度が高い = 凹凸/傾斜のいずれかが強く出ている = 微地形構造あり。
土砂災害警戒区域 (yellow zone)土砂災害防止法に基づき指定。 本記事では DoBoX dsid 48「土砂災害警戒区域・特別警戒区域情報」の 3 種別 (土石流・急傾斜地・地すべり) を統合して使用。
特別警戒区域 (red zone)同法のレッドゾーン。建物倒壊リスクあり。 土石流・急傾斜地のみで指定 (地すべりはレッドなし)。
パーセンタイル適応閾値絶対値ではなく「そのエリアの分布のうち上位 X%」で 閾値を決める方法。CS立体図はパステル色 (中間値) が大多数のため、絶対値閾値ではほぼ全セルが 同じクラスになってしまう。各エリアの分布に応じて適応的に決めることで、 エリア横断的な意味のある比較が可能になる。
古砂防地形 / 古崩壊地形過去に発生した土石流・地すべり跡が地形に残ったもの。 CS立体図では微地形コントラストが強く、彩度高めで描かれる傾向。本記事の発展課題で扱う対象。

研究の問い (RQ)

広島県の CS立体図 2 解像度 (1m / 50cm) は、それぞれ 世羅町 (中山間/林業地), 熊野町 (都市近郊/山岳混在), 坂町 (平成30豪雨被災地) という異なる地形リスク特性のエリアを公開している。 3 エリアの CS立体図を RGB 3 軸で比較し、地形微細構造の構成比を量化する。 さらに土砂災害警戒区域との空間結合で、CS図のどの色域が警戒域に多いかを定量化する。

  1. 3 dataset の解像度・面積・有効データ率・ピクセル数の構造比較は?
  2. R, G, B 各バンドの値分布はエリアごとにどう違うか?
  3. 適応閾値による地形タイプ自動分類の構成比は?
  4. HSV 散布から見える 3 エリアの色相・彩度パターン差は?
  5. 土砂災害警戒区域内 vs 区域外で R, G, B, Saturation はどう違うか?
  6. 解像度差 (1m vs 50cm) で微地形コントラストはどう変わるか?

仮説 H1〜H6

到達点

3 エリアの CS立体図を「3 自治体の代表エリア」として読み解き、 合計 633 M セル × 3 バンド ≈ 1,900 M 数値の RGB 段彩データを overview ピラミッドで効率的に概観する。 さらに土砂災害警戒区域 Shapefile (~ 2,000 ポリゴン) との空間結合で 「CS図と警戒区域の関係」を量的に検証する。 これは CS立体図単独・警戒区域単独では不可能な、両者の同時空間整合分析である。

本記事のスコープ外:
  • 個別ピクセルの地形微細構造判読 (古砂防地形 / 段丘崖 / 地すべり地塊 等の手動デリネーション)
  • L36 樹高 / L37 点群密度 との 3 軸結合 (各ラスタの座標系統合は実装上重い → 別記事 X 系で扱う)
  • 標高図 (DTM, dsid 1635/1636) との直接比較 (発展課題)
  • 長野県オリジナル CS立体図との配色合致確認 (DoBoX 実装の配色は標準実装と微妙に異なる可能性あり)
  • 過去の土石流・地すべり履歴データ (DoBoX 外) との時系列照合
本記事は CS立体図の2 dataset (1m + 50cm) のみを統合し、土砂警戒区域との空間結合に特化する。

使用データ

本記事が使用する 2 dataset の一覧。両者は同一手法 (CS立体図 = 曲率×傾斜の RGB 段彩) の 解像度違いで、各自治体ごとに GeoTIFF を切り出して公開する構造。本記事は 2 dataset から 合計 3 自治体を代表として用います。

dsid名称解像度公開単位本記事の代表TIFF サイズセル数 (×3バンド)DoBoX
1628CS立体図(1m)1.0 m/cell 22 自治体別 GeoTIFF世羅町 (34462) + 熊野町 (34307) 1,275 + 186 MB 510.9 M #1628
1629CS立体図(50cm)0.5 m/cell 12 自治体別 GeoTIFF坂町 (34384) 350 MB 122.6 M #1629

データ仕様 (両 dataset 共通)

L36 樹高 / L37 点群密度 との関係 (本記事は単独, 参考併置のみ)

L36 樹高L37 点群密度L38 CS立体図 (本記事)
計測対象樹冠の高さ (m)地面到達パルス数地形の微細構造 (RGB)
派生過程DSM − DTMグラウンド分類点数DTM → 曲率 + 傾斜 → RGB
同じ点群?YES — 同一の航空レーザ計測点群から 派生した 3 つの集計
表現連続値 float32整数 uint8/int16RGB 3 バンド uint8
本記事のスコープ L38 単独で完結 (L36/L37 とは合体しない)

3 自治体の特性比較

世羅町 (1m)熊野町 (1m)坂町 (50cm)
立地備後内陸 (中山間)広島市東 (都市近郊)呉市西 (沿岸山間)
面積 (行政界) 278.0 km² 33.6 km² 24.5 km²
主産業農林業 (世羅梨・大根)筆 (熊野筆) 製造住宅地 + 港湾
地形特性緩傾斜丘陵花崗岩マサ土山地急傾斜面 + 崩壊跡 (H30豪雨被災地)
有効セル比率 65.9% 57.2% 63.1%
R 平均 202.4 196.3 175.5
G 平均 192.5 185.2 162.2
B 平均 187.9 180.8 159.4
Sat 平均 0.074 0.083 0.096
土砂警戒 (yellow) 1575 polys / 19.6 km² 293 polys / 10.8 km² 170 polys / 5.3 km²
特別警戒 (red) 1350 polys / 2.56 km² 228 polys / 0.56 km² 128 polys / 0.40 km²

データ品質メモ

ダウンロード

生データ (DoBoX 直リンク)

容量警告: 3 ZIP の合計は約 1136 MB、 展開後の TIFF は約 1812 MB。 他自治体や 50cm 広島市版はさらに大きい (世羅町 50cm 版だけで 3.6 GB) ため、本記事のスコープ外。

土砂災害警戒区域データ (本記事の空間結合に必要)

本記事はL10 土砂災害警戒区域 × 用途地域と 同じ Shapefile (DoBoX dsid 48) を使用します。 data/extras/sediment_shp/ に展開済みであれば自動利用。

中間データ (本記事生成 CSV)

図 (本記事生成 PNG)

再現用 Python スクリプト

L38_cs_terrain.py を取得して プロジェクトルートで py -X utf8 lessons/L38_cs_terrain.py を実行。 TIFF が無ければ ZIP 自動 DL → 自動展開 → overview 読込で分析が走ります (初回 DL を除けば約 13 秒で完走)。

分析 1: 3 dataset とエリアの構造を可視化

狙い

2 dataset (1m / 50cm) と 3 自治体 (世羅 / 熊野 / 坂) の規模・形状・データ量を 1 枚の絵で示す。Saturation ヒストグラムを重ねて地形微細構造の強さを最初に視覚化する。

手法 (リテラシレベル解説)

L36 / L37 と全く同じ rasterio スタイルだが、CS立体図には重要な違いがある:

実装

L38_cs_terrain.py 行 1659–1721

 1
 2
 3
 4
 5
 6
 7
 8
 9
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
import rasterio
from rasterio.enums import Resampling
import numpy as np

TARGET_CELL_M = 32   # overview 目標セルサイズ
for area in AREAS:
    with rasterio.open(area["tif"]) as ds:
        ovr_choices = ds.overviews(1)
        target_factor = TARGET_CELL_M / area["resolution_m"]
        best = next((f for f in ovr_choices if f >= target_factor),
                    ovr_choices[-1] if ovr_choices else int(target_factor))
        ov_w = ds.width // best
        ov_h = ds.height // best

        # 3 バンドを 1 度に読込 → shape (3, H, W)
        rgb = ds.read(out_shape=(3, ov_h, ov_w),
                      resampling=Resampling.average).astype(np.float32)
        area["rgb"] = rgb

        # nodata マスク (全バンド 0 = 無効)
        valid_mask = rgb.sum(axis=0) > 0
        area["valid_mask"] = valid_mask

        # HSV の Saturation 計算
        maxv = np.maximum.reduce(rgb)
        minv = np.minimum.reduce(rgb)
        sat = np.where(maxv > 0, (maxv - minv) / np.maximum(maxv, 1), 0)
        area["sat"] = sat

図と読み取り (図 1: dataset カード + Saturation ヒスト)

なぜこの図か: 3 dataset の規模と特性をカードで言語的に、 かつ Saturation ヒストグラムで「微地形コントラスト分布」として量的に、 同時に 1 枚で伝えるため。

図 1: 3 dataset カード (左) + Saturation 分布 (右)
図 1: 3 dataset カード (左) + Saturation 分布 (右)

読み取り:

表 (基本統計)

label n_cells_total n_cells_valid valid_ratio R_mean R_median R_std G_mean G_median G_std B_mean B_median B_std Sat_mean Sat_std Sat_p90 diff_RB_mean diff_RB_std
sera_1m 世羅町 434861 286691 0.66 202.37 204.0 15.69 192.50 194.0 19.84 187.93 190.0 20.98 0.07 0.04 0.13 14.44 7.77
kumano_1m 熊野町 63484 36305 0.57 196.34 194.0 19.67 185.19 181.0 24.47 180.81 177.0 25.91 0.08 0.06 0.17 15.53 11.09
saka_50cm 坂町 29670 18717 0.63 175.48 177.0 42.00 162.19 159.0 42.97 159.44 155.0 43.12 0.10 0.06 0.17 16.05 9.46

読み取り: R/G/B 平均は 3 エリアで似た値域 (160-202) だが、標準偏差は明確に違う ⇒ 世羅 R-std=15.7, 熊野 19.7, 坂 42.0。坂町は標準偏差が約 3 倍も大きい = 「明るい部分と暗い部分が広く分布」 ⇒ 急傾斜面と平地の混在による陰影コントラストの強さを示す。 Sat 平均と Sat 標準偏差はどちらも坂町が最大で、仮説 H3 (坂町は崩壊跡を含む急傾斜) を支持する強い量的証拠。

分析 2: CS立体図 RGB 主題図化

狙い

CS立体図のRGB 元画像を 3 エリア並列で表示し、 「地形微細構造はどう見えるか」を視覚的に理解する。これは CS立体図本来の使い方 (目で見て地形を読む) を踏襲したセクション。

手法 (リテラシレベル解説)

matplotlib.pyplot.imshow(H, W, 3) 形状の uint8 配列を渡すと RGB 画像として表示される。rasterio の read() 結果は (3, H, W) なので np.stack([R, G, B], axis=-1) で軸を入れ替える必要がある。

実装

L38_cs_terrain.py 行 1738–1753

1738
1739
1740
1741
1742
# 3 バンドを RGB 画像形式に整形
rgb_disp = np.stack([rgb[0], rgb[1], rgb[2]], axis=-1).astype(np.uint8)
# nodata セルを白に置換
rgb_disp_show = np.where(valid_mask[..., None], rgb_disp, 255)
ax.imshow(rgb_disp_show, extent=area_bounds, origin="upper", interpolation="nearest")

図と読み取り (図 2: CS立体図 RGB 主題図)

なぜこの図か: 3 エリアの地形微細構造を視覚的に並べ、 専門家のように「赤=尾根、青=谷、暗=急斜面」を読み取る練習をするため。

図 2: 3 エリア CS立体図 RGB 元画像
図 2: 3 エリア CS立体図 RGB 元画像

読み取り:

表 (TIFF メタ + 行政界面積)

項目世羅町熊野町坂町
解像度 (m/cell)1.01.00.5
セル数 (M, ×3バンド)445.765.2122.6
TIFF bbox 面積 (km²)445.765.230.7
行政界面積 (km²)278.033.624.5
有効セル比率65.9%57.2%63.1%
nodata 値0 (全バンド)0 (全バンド)None (= (0,0,0) を境界マスクとして扱う)
overview 倍率/1/32/1/32 (内部 ovr 無)/1/64
実効セル (m/cell)323232

読み取り: 世羅町は 27 × 16 km と広大で 446 M セル × 3 = 約 1.3 GB の生 TIFF。 熊野町は内部 overview を持たない (= ピラミッド未構築) ため out_shape で擬似粗化。 坂町は 50cm 解像度のため 30 km² で 122 M セル相当。解像度差 = ピクセル数 4 倍がはっきり分かる。

分析 3: 地形タイプ自動分類 (パーセンタイル適応閾値, 5 クラス)

狙い

専門家の目で「赤い場所は尾根、青い場所は谷」と判読する代わりに、 RGB 値からアルゴリズム的に地形タイプを自動分類する。 これにより 3 エリアの地形タイプ構成比を量的に比較可能になる。

手法 (リテラシレベル解説)

本記事独自のパーセンタイル適応閾値分類を使う。CS立体図の RGB は パステル色 (中間値) が大多数なので、絶対値閾値ではほぼ全セルが同じクラスに振られる。 そこで各エリアの分布から相対的に閾値を決める。

クラス条件意味
1. 尾根R - B >= P75 (上位 25%)R が B より明らかに大きい = 凸地形
2. 谷R - B <= P25 (下位 25%)B が R より明らかに大きい = 凹地形
3. 急傾斜brightness <= P15 (下位 15%, 上記 1, 2 ではない)暗い色 = 影 = 急斜面
4. 平地3 バンド std <= P25, 上記いずれでもないほぼグレー = 緩傾斜の平地
5. 複雑地形上記いずれでもない (= 中間色だが彩度あり)細かい起伏が混在する地形

限界と代替:

実装

L38_cs_terrain.py 行 1816–1873

 1
 2
 3
 4
 5
 6
 7
 8
 9
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
def classify_terrain(rgb, valid_mask):
    """RGB を 5 種地形タイプにラベル付け (パーセンタイル適応閾値)"""
    R, G, B = rgb[0], rgb[1], rgb[2]
    diff_RB = R - B
    bright = (R + G + B) / 3.0
    band_std = np.stack([R, G, B], axis=0).std(axis=0)

    # 各エリアの分布から閾値を決める
    p75 = np.percentile(diff_RB[valid_mask], 75)
    p25 = np.percentile(diff_RB[valid_mask], 25)
    bp15 = np.percentile(bright[valid_mask], 15)
    sp25 = np.percentile(band_std[valid_mask], 25)

    label = np.zeros(R.shape, dtype=np.int8)
    is_ridge  = (diff_RB >= p75) & valid_mask
    is_valley = (diff_RB <= p25) & valid_mask
    is_steep  = (bright <= bp15) & ~is_ridge & ~is_valley & valid_mask
    is_flat   = (band_std <= sp25) & ~is_ridge & ~is_valley & ~is_steep & valid_mask
    is_complex = valid_mask & ~is_ridge & ~is_valley & ~is_steep & ~is_flat

    label[is_ridge]   = 1
    label[is_valley]  = 2
    label[is_steep]   = 3
    label[is_flat]    = 4
    label[is_complex] = 5
    return label

図と読み取り (図 3: 地形タイプ分類マップ)

なぜこの図か: RGB 元画像 (図 2) の隣に分類結果を並べて、 「色がどの分類クラスに対応するか」を視覚的に確認する。

図 3: 地形タイプ自動分類マップ (5 クラス)
図 3: 地形タイプ自動分類マップ (5 クラス)

読み取り:

図と読み取り (図 5: 地形タイプ構成比 stack-bar)

図 5: 5 種地形タイプの構成比 (3 エリア)
図 5: 5 種地形タイプの構成比 (3 エリア)

読み取り: 3 エリアの構成比は非常に似ている (尾根 25-28%, 谷 25-30%, 急 4-6%, 平地 0-1%, 複雑 38-42%)。 これは「パーセンタイル適応閾値」の必然的帰結 — 各エリア内で上位/下位 25% を取るので、 クラス間バランスはエリア横断でほぼ均一になる。 意味のある違いは「どの場所がそのクラスに分類されているか」 (= 空間分布) にあり、 それは図 3 と次節 (small multiples) で見る。

図と読み取り (図 11: 地形タイプ別 small multiples)

図 11: 地形タイプ別の空間分布 small multiples (3 エリア × 4 タイプ)
図 11: 地形タイプ別の空間分布 small multiples (3 エリア × 4 タイプ)

読み取り:

表 (地形タイプ構成比 wide)

area nodata_n nodata_pct 尾根_n 尾根_pct 谷_n 谷_pct 急傾斜_n 急傾斜_pct 平地_n 平地_pct 複雑_n 複雑_pct
世羅町 148170 34.07 73470 16.90 79589 18.30 12560 2.89 0 0.00 121072 27.84
熊野町 27179 42.81 9267 14.60 10797 17.01 2285 3.60 0 0.00 13956 21.98
坂町 10953 36.92 5261 17.73 4755 16.03 977 3.29 139 0.47 7585 25.56

分析 4: RGB バンド分布と HSV 散布

狙い

3 エリアのR, G, B 各バンドの値分布を直接比較し、 HSV 散布図で「色相 × 彩度」の 2 次元パターンを観察する。 バンドごとの違いは「どの地形指標がエリアごとに強いか」を語る。

手法 (リテラシレベル解説)

2 つの可視化を併用:

HSV とは: RGB の代替表現で、 H = 色相 (0=赤, 0.33=緑, 0.66=青), S = 彩度, V = 明度。 S = (max - min) / max の式で「色がどれだけ偏っているか」を 0-1 で表現する。 グレー (R=G=B) は S=0、純赤 (R=255, G=B=0) は S=1。

実装

1
2
3
4
5
6
7
8
9
import matplotlib

# RGB を HSV に変換 (各値 0-1 にスケール)
rgb_norm = (rgb_arr / 255.0).reshape(-1, 3)
hsv = matplotlib.colors.rgb_to_hsv(rgb_norm.reshape(1, -1, 3)).reshape(-1, 3)
hue, sat, val = hsv[:, 0], hsv[:, 1], hsv[:, 2]

# 散布図: 各点の色は実際の RGB そのまま
ax.scatter(hue, sat, c=rgb_norm, s=2, alpha=0.5)

図と読み取り (図 4: RGB バンドヒスト)

なぜこの図か: 3 バンドを別々に並べて、各エリアの値域シフトを見るため。 散布図ではなくヒストにすることで、各バンドの中央値・裾の重さが分かりやすい。

図 4: R/G/B 各バンドの 3 エリア比較ヒストグラム
図 4: R/G/B 各バンドの 3 エリア比較ヒストグラム

読み取り:

図と読み取り (図 10: HSV 散布)

なぜこの図か: RGB の 3 軸では分布パターンが見えづらい。 HSV に変換して 2 次元の Hue × Sat 平面で見ると、 「赤系の凸地形」「青系の凹地形」「灰系の平地」のクラスタリング構造がよく見える。

図 10: HSV 散布図 — Hue × Sat 平面 (各点を実 RGB 色で描画)
図 10: HSV 散布図 — Hue × Sat 平面 (各点を実 RGB 色で描画)

読み取り:

分析 5: 警戒区域 × CS立体図 — ポリゴン×ラスタの空間結合 (本記事の核心)

狙い (本記事の核心)

土砂災害警戒区域 (yellow) と特別警戒区域 (red) のポリゴンを CS立体図のラスタ座標系に rasterize して、 「警戒区域内 vs 区域外で CS立体図の RGB 平均値はどう違うか」を量的に比較する。 これは CS立体図単独・警戒区域単独では出せない本記事の独自貢献

手法 (リテラシレベル解説)

「ポリゴン → ラスタ化 (rasterize)」とは: 不規則な形のポリゴン (警戒区域) を「画素ごとに 0/1 のマスク」に変換する操作。具体的には:

  1. 警戒区域ポリゴンを rasterio の features.rasterize に渡し、 対象ラスタと同じ shape・transform で描画。
  2. 得られたバイナリマスク (1=区域内, 0=外) と CS立体図ラスタをセル単位でペア化
  3. 各 zone (特別警戒 / 警戒 / 区域外) に分けて R, G, B, Sat の平均を計算。
  4. 3 ゾーン × 3 エリア × 4 指標 (R, G, B, Sat) のクロス表を作る。

パッケージ: rasterio.features.rasterizegeopandas.overlayshapely.contains よりもラスタ向けに最適化されており、 60K セル × 数千ポリゴンでも数秒で完了。

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from rasterio.features import rasterize
from rasterio.transform import from_bounds

def rasterize_polys(polys_gdf, area):
    """警戒区域 polygons をエリア overview の (H, W) shape にラスタ化"""
    bb = area["bounds"]
    transform = from_bounds(bb.left, bb.bottom, bb.right, bb.top,
                            area["arr_w"], area["arr_h"])
    shapes = ((geom, 1) for geom in polys_gdf.geometry)
    mask = rasterize(shapes, out_shape=(area["arr_h"], area["arr_w"]),
                     transform=transform, fill=0, dtype="uint8")
    return mask.astype(bool)

# 警戒区域 / 特別警戒 / 区域外 で各バンド平均
yellow_mask = rasterize_polys(area["sed_yellow"], area)
red_mask = rasterize_polys(area["sed_red"], area)
in_yellow = yellow_mask & area["valid_mask"]
in_red    = red_mask    & area["valid_mask"]
out_warn  = ~yellow_mask & ~red_mask & area["valid_mask"]

for zone, m in [("特別警戒", in_red), ("警戒", in_yellow), ("区域外", out_warn)]:
    R_mean = rgb[0][m].mean()
    G_mean = rgb[1][m].mean()
    B_mean = rgb[2][m].mean()
    Sat_mean = sat[m].mean()

図と読み取り (図 6: 警戒区域 × CS overlay)

なぜこの図か: 警戒区域がCS立体図のどの色域に集塊しているかを視覚的に確認。 ポリゴンの透明度を調整して下地の RGB 段彩を見せつつ、警戒域 (yellow/red) を半透明で重ねる。

図 6: CS立体図 + 土砂災害警戒区域 (yellow/red) の重ね合わせ
図 6: CS立体図 + 土砂災害警戒区域 (yellow/red) の重ね合わせ

読み取り:

図と読み取り (図 7: RGB 平均比較 grouped bar)

なぜこの図か: 視覚的な印象 (図 6) を量的に裏付ける。 3 エリア × 3 ゾーン × 3 指標 (R, R-B, Sat) のクロス比較。

図 7: 警戒区域 内/外 の RGB / R-B / Sat 平均比較
図 7: 警戒区域 内/外 の RGB / R-B / Sat 平均比較

読み取り (重要発見):

表 (警戒区域 内/外 の RGB 平均)

area zone n R_mean G_mean B_mean diff_RB_mean Sat_mean
世羅町 特別警戒 2503 195.63 186.09 182.54 13.09 0.07
世羅町 警戒 14179 206.29 199.13 196.34 9.95 0.05
世羅町 区域外 272512 202.17 192.16 187.50 14.67 0.07
熊野町 特別警戒 517 195.23 187.86 185.90 9.33 0.05
熊野町 警戒 6445 210.73 204.48 202.05 8.68 0.04
熊野町 区域外 29860 193.24 181.03 176.22 17.01 0.09
坂町 特別警戒 390 177.73 163.87 162.23 15.49 0.09
坂町 警戒 2197 190.02 179.43 179.08 10.94 0.06
坂町 区域外 16520 173.55 159.90 156.82 16.72 0.10

読み取り: 警戒区域内のセル数は世羅町で 14,179, 熊野町で 6,445, 坂町で 2,197。 特別警戒区域は各エリアで 390-2,503 セルと小規模だが、量的比較は十分可能。 diff_RB_mean (R-B 平均)を見ると: 区域内は +9〜+15、区域外は +14〜+17 と一貫して 区域外の方が高い (= 区域外は尾根成分が強い、区域内は谷成分が強い)。

分析 6: 中央サンプルと CS立体図のしくみ概念

狙い

各エリアの中央 1024×1024 セルを本来解像度で読込み、CS立体図の細かい構造を体感する。 さらに概念図で「CS立体図がどうやって作られているか」を学習者に理解させる。

手法 (リテラシレベル解説)

rasterio.windows.Window で各 TIFF の中央 1024×1024 セルだけを読込み、 本来解像度で表示。1m なら 1024m × 1024m の正方領域、50cm なら 512m × 512m の領域。 3 バンド同時読込で RGB 画像として可視化。

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from rasterio.windows import Window

RAW_SAMPLE = 1024
for area in AREAS:
    with rasterio.open(area["tif"]) as ds:
        cx, cy = ds.width//2, ds.height//2
        win = Window(cx-RAW_SAMPLE//2, cy-RAW_SAMPLE//2,
                     RAW_SAMPLE, RAW_SAMPLE)
        raw = ds.read(window=win).astype(np.uint8)  # (3, H, W)
        # imshow に渡せる (H, W, 3) に転置
        rgb_disp = np.stack([raw[0], raw[1], raw[2]], axis=-1)
        ax.imshow(rgb_disp)

図と読み取り (図 8: 中央サンプル)

なぜこの図か: overview 表示では微地形の細部が見えない。 本来解像度で見ると CS立体図の真価 (尾根線・谷線・崩壊跡地が筋状に明瞭) が分かる。

図 8: 中央 1024×1024 セルの本来解像度サンプル
図 8: 中央 1024×1024 セルの本来解像度サンプル

読み取り:

図と読み取り (図 9: CS立体図のしくみ概念図)

図 9: CS立体図の概念図 — 標高 → 曲率 + 傾斜 → RGB 合成
図 9: CS立体図の概念図 — 標高 → 曲率 + 傾斜 → RGB 合成

読み取り:

表 (中央サンプル統計)

エリアサイズ (px)実距離 (m)R 平均G 平均B 平均
世羅町1024×10241024×1024 m209.5201.9197.8
熊野町1024×10241024×1024 m218.2212.8209.9
坂町1024×1024512×512 m178.0162.5160.2

読み取り: 中央サンプルの RGB 平均は 3 エリアで類似 (160-200) だが、 サイズ差 (= 実距離差)が解像度差を反映する。坂町は 50cm 解像度のため 同じ 1024×1024 でも 512m 四方しかカバーしない。 これは「ピクセル数 = 情報密度ではない」という重要な GIS リテラシ。 解像度で正規化して比較すべき。

仮説検証と考察

本記事で立てた 6 つの仮説 (H1〜H6) と、3 エリアの CS立体図 RGB 解析 + 警戒区域空間結合の照合結果:

H主張結果判定
H1世羅町は緩傾斜丘陵が主で、CS図の Saturation 平均 <= 0.10 (淡い中間色多)世羅 Sat_mean=0.074 (Sat_std=0.043)支持
H2熊野町は急峻地形で Sat 平均が世羅より大きい熊野 Sat_mean=0.083, 世羅 Sat_mean=0.074, 差 +0.009支持
H3坂町は3エリアで Sat 平均が最大 (= 急傾斜が広く分布)世羅 0.074, 熊野 0.083, 坂 0.096支持
H4土砂災害特別警戒区域内の CS図 Saturation は区域外より大きい (急斜面の微地形)世羅町: Sat 内0.068 vs 外0.075 (差-0.007), diff_RB 内+13.1 vs 外+14.7 | 熊野町: Sat 内0.050 vs 外0.091 (差-0.041), diff_RB 内+9.3 vs 外+17.0 | 坂町: Sat 内0.090 vs 外0.100 (差-0.010), diff_RB 内+15.5 vs 外+16.7反証
H5色相 (Hue) ヒストの広がり (h_std) は両エリアとも > 0.05 (赤系-青系の双方が存在)世羅町: mode_bin=0/11, h_std=0.057 | 熊野町: mode_bin=0/11, h_std=0.136 | 坂町: mode_bin=0/11, h_std=0.252支持
H650cm 版 (坂町) は 1m 版より Sat 標準偏差が大きい (微地形コントラスト高)世羅 Sat_std=0.043, 熊野 0.060, 坂 0.060支持

判定サマリ: 支持 5 / 部分支持 0 / 反証 1 (全 6 仮説中)

主な発見 (3-5 点)

  1. H4 (警戒区域内の Sat は外より大きい) は反証されたが、その反対方向が 3 エリア共通で量的に確認された: 警戒区域は CS立体図で「より低い R-B 差・より低い Saturation」を持つ。 = 警戒区域は谷底や急斜面の影に多く重なり、尾根の凸地形は警戒区域として 指定されにくいという物理的論理が CS立体図の RGB に明瞭に刻まれている。 これは本記事の最も重要な発見であり、 「土砂災害指定の地形物理学」がオープンデータの 2 dataset 結合で再現できることを示す。
  2. H3 (坂町は崩壊跡を含む急傾斜) が強支持された: 坂町の Saturation 平均 0.096 は 3 エリアで最大。 さらに R/G/B の標準偏差も最大 (R-std=42.0 vs 世羅 15.7)。 平成30年7月豪雨の被災地形が CS立体図に量的に保存されていることを示す。
  3. H2 (熊野町は急峻地形) は支持されたが差は微小 (Sat 0.083 vs 世羅 0.074)。 熊野は花崗岩マサ土地形で急傾斜面が多いと予想したが、実データ上は世羅との 差は限定的。これは「都市近郊の山地」の急峻度が中山間の丘陵地形と大差ない という意外な発見 (発展課題 Z3 で再検証)。
  4. H5 (色相は 2 峰性) が支持された: 全エリアで Hue が 赤帯 (0.0) と青帯 (0.66) の双方に分布。Hue 標準偏差は世羅 0.057 < 熊野 0.136 < 坂 0.252と 段階的に増加 = エリアの地形多様度を量的に区別する指標として機能。
  5. H6 (50cm 版は微細構造強) が支持された: 坂町 (50cm) の Sat 標準偏差 0.060 は 1m 版 (世羅 0.043, 熊野 0.060) より大きい。 高解像度ほど微地形のばらつきを拾うことを実証。 ただし熊野 (1m) も同等の Sat std を持つため、解像度差より地形類型差の方が Sat std に効く可能性も残る。

3 エリアの地形特性比較 (本記事の量的サマリ)

世羅町 (1m)熊野町 (1m)坂町 (50cm)
地形類型緩傾斜丘陵 (中山間)急峻山地 + 都市平地急斜面 + 崩壊跡
R 平均202.4196.3175.5
R-B 平均14.415.516.0
Sat 平均0.0740.0830.096
Sat 標準偏差0.0430.0600.060
Hue 標準偏差0.0570.1360.252
警戒区域率7.0% 32.1% 21.6%
特別警戒区域率0.9% 1.7% 1.6%

考察

本記事の主たる発見は、「警戒区域の指定論理が CS立体図の RGB に量的に刻まれている」 ことが 3 エリア共通で確認されたことである。仮説 H4 は反証されたが、 反対方向の関係 (警戒区域は谷底寄り = R-B 平均が低い) が一貫して観察された。 これは「土砂災害警戒区域 = 谷頭 / 急斜面の影」という地形物理的論理の量的証拠であり、 オープンデータの 2 dataset 結合だけで再現可能なことを示している。

同時に、解像度差 (1m vs 50cm)は overview レベルでは認識困難だが、 本来解像度のサンプル (図 8) では 50cm の優位性が見える。微細な凹凸 (古砂防地形・ 古崩壊跡など) は 50cm 版でしか拾えない可能性が高く、地形リテラシ研究には 50cm 版が必須

3 エリアの絶対値の RGB スケールには大差はないが、標準偏差・彩度には明確な 階層 (世羅 < 熊野 ≦ 坂) が見える。これは「地形微細構造の強さ」を CS立体図 RGB から 量的に評価する手法として有効。仮説を立てる前にデータの値域を観察する重要性を示す事例。

パーセンタイル適応閾値での地形タイプ分類 (尾根/谷/急/平地/複雑) は各エリア内の相対分類として 意味があるが、絶対値での横断比較には不向き。絶対閾値 vs 相対閾値の使い分けは リテラシ上の重要論点 (発展課題 Z2)。

発展課題

結果 X1 → 仮説 Y1 → 課題 Z1: 警戒区域 ⇔ 谷地形の量的検証 (本記事の発見の深掘り)

結果 X1: 3 エリア共通で警戒区域の R-B 平均は区域外より低い (= 谷成分強)。 H4 を反対方向で支持する量的傾向。

新仮説 Y1: 警戒区域内の「谷タイプ (B>R)」セルの比率は区域外より明確に高い。 50%以上の警戒域が谷タイプに分類される。

課題 Z1: 警戒区域内の地形タイプ構成比 (尾根/谷/急/平地) を本記事のラスタ化マスクで集計し、 区域外と並列比較。クロス表で「警戒域は谷タイプが何 % か」を量化。 さらに土石流・急傾斜・地すべりの 3 種別ごとに比較すると、各災害タイプの 地形特性が CS立体図でどう違うか分かる。

結果 X2 → 仮説 Y2 → 課題 Z2: 標高ラスタからの直接的な曲率計算

結果 X2: 本記事の「地形タイプ自動分類」は CS立体図の RGB から逆推定したものだが、 適応閾値が必要なため絶対比較が困難。

新仮説 Y2: 標高ラスタ (DTM, dsid 1635/1636) から直接 曲率・傾斜を計算した方が 量的に精確で、絶対閾値での横断比較が可能。

課題 Z2: 標高 GeoTIFF を読み込んで scipy.ndimage.laplace で曲率を、 numpy.gradient で傾斜を直接計算。本記事の RGB 推定と相関係数で照合。 高い相関が出れば「CS立体図の配色は曲率・傾斜の忠実な可視化」と確認できる。

結果 X3 → 仮説 Y3 → 課題 Z3: 多自治体一括の地形指標化

結果 X3: 本記事は 3 自治体のみ。Sat 平均 (= 微地形コントラスト) で 世羅 < 熊野 < 坂 の階層が見えたが、サンプル数が少なすぎて地形類型と Sat の関係が 仮説止まり。

新仮説 Y3: 全 22 自治体 (1m 版) で Sat 平均を計算すると、 中山間 / 都市近郊 / 沿岸被災地 / 島嶼 などの地形類型クラスタが自然分類できる。

課題 Z3: 22 自治体すべての CS立体図を順次 DL → overview 読込 → Sat 平均計算で 22 値の分布を作る。k-means や階層クラスタリングで類型化。 さらに各自治体の警戒区域率と Sat 平均を散布図にプロット ⇒ 「Sat 高 = 警戒区域率高」の正相関が出れば 「CS立体図の Sat は土砂災害リスクの代理指標」という新提案ができる。

結果 X4 → 仮説 Y4 → 課題 Z4: 古崩壊地形の自動検出

結果 X4: 坂町 (H30豪雨被災地) は 3 エリアで最高の Sat 標準偏差を示した。 微細な凹凸 (= 過去の崩壊地形 / 古砂防地形) が CS立体図に保存されていると示唆。

新仮説 Y4: 「Sat の局所変動が大きい場所」は古崩壊地形の可能性が高い。 過去の航空写真や砂防履歴と照合可能。

課題 Z4: 各セルの周囲 5×5 セルでの Sat 局所標準偏差を計算し、 高い局所 std セルを抽出。これが既知の H30 崩壊跡 (地理院地図の被災地マップ) と 空間的に一致するかを精度評価。一致が高ければ「Sat 局所 std による古崩壊地形自動検出」を提案できる。 これは砂防研究・防災マップ更新に直接応用可能。

結果 X5 → 仮説 Y5 → 課題 Z5: L36/L37 との 3 軸結合 (LiDAR 派生物の三脚)

結果 X5: 本記事は CS立体図のみ単独扱い (合体禁止)。 L36 樹高 / L37 点群密度との関係は未検証。

新仮説 Y5: 同じ航空レーザ点群から派生した 3 ラスタ (樹高 / 点群密度 / CS立体図) は 3 軸の地形・植生指標として機能。 3 軸の組合せで「裸地崩壊」「森林急斜面」「都市平地」等の 9-12 クラス自動分類が可能。

課題 Z5: X 系の横断記事として、3 ラスタを同一座標系で空間結合し、 GMM (Gaussian Mixture Model) で 9-12 クラスタリング。各クラスタが 何の地形/植生に対応するかを衛星 NDVI や建物 footprint で検証。 これは LiDAR ファミリ全体を統合する集大成記事になる。

結果 X6 → 仮説 Y6 → 課題 Z6: 過去被災地のセル単位検出

結果 X6: 坂町の特別警戒区域 (0.40 km²) と CS立体図の急斜面 (G 低) は 重なるが、過去の被災実績との照合は未実施。

新仮説 Y6: 平成30年7月豪雨で実際に崩壊が発生したセルは CS立体図で 特定の RGB 特徴 (Sat 中, 谷タイプ, 急傾斜) を持つ。RGB 特徴量で機械学習による被災予測が可能。

課題 Z6: 国交省の H30 豪雨被災調査データ (発生位置 GIS) を入手し、 CS立体図の RGB 特徴でロジスティック回帰や Random Forest による被災予測モデルを訓練。 特徴量重要度から「どのバンドが被災予測に効くか」を判定。 高い AUC が出ればCS立体図ベースの土砂災害発生予測モデルとして実装可能。