Lesson 10

L10 土砂災害警戒区域 × 用途地域 / 避難所 / インフラ — 「山際の二重・三重リスク」研究

L系GISオーバーレイsjoin主題図small multiples土砂災害
所要 60〜90分 / 想定レベル: リテラシ基礎+α / データ: 土砂災害警戒区域 (#48 全県, 3種別) + 用途地域 + 避難所 + インフラ + 文化財

データ取得手順

⚠️ このスクリプトは自動取得に対応していません。以下のデータセットを DoBoX から手動でダウンロードし、data/extras/ 以下に保存してください。

IDデータセット名
#48土砂災害警戒区域・特別警戒区域情報_広島県
#71都市計画区域情報_建物利用現況_海田町
#544土砂災害警戒区域・特別警戒区域情報_広島市中区
#573土砂災害警戒区域・特別警戒区域情報_神石高原町
#888都市計画区域情報_区域データ_安芸高田市_行政区域
#999dataset #999

実行コマンド:

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

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

学習目標と問い

本記事のスタイル: 土砂災害警戒区域 (#48 全県版) を主役に据えた多軸クロス解析
"山際の二重・三重リスク" を 1 本の記事で見渡す。 geopandas.overlay() で 用途地域との交差面積、gpd.sjoin(predicate='within') で 避難所/インフラ/文化財の警戒区域内立地を一気に判定する。
カバー宣言 (1 記事 = 31 dataset 論理カバー)
本記事は 土砂災害警戒区域・特別警戒区域情報 (#48) の Shapefile (土石流/急傾斜地/地すべり 3 種別) を全県版で使用する。これは個別市町版 30 件 (#544#573) のスーパーセット であり、属性 city 列でフィルタすれば 31 dataset_id 全部の内容を再現可能。 対応表 31/31 件 論理カバー

主な問い (4 段階)

  1. 面の問い: 用途地域のうち どの種類の土地が 土砂災害警戒区域に含まれるか? どの程度?
  2. 避難の問い: 避難所自体が警戒区域内に立地しているケースはどれくらいあるか? = 避難不能リスク
  3. インフラの問い: 老朽橋 × 警戒区域 の 二重リスク橋 は何件浮上するか?
  4. 歴史の問い: 城跡 (山城) は時代によって警戒区域内立地率が変わるか?

立てた仮説 (H1〜H6)

  1. H1: 山際住居系 (第一種低層住居専用 等) は警戒区域内立地率が高い (高密度商業より高い)
  2. H2: 避難所自体が警戒区域内のものが一定数 ある (避難不能リスク, 全体の 5% 以上)
  3. H3: 1980年以前架設の老朽橋 × 警戒区域 = 二重リスク橋が 50 件以上 浮上
  4. H4: 特別警戒区域 (レッドゾーン) は 急傾斜地 (がけ崩れ) が大半 (件数の 80% 以上)
  5. H5: 河川浸水 × 特別警戒区域 の重複域は 平成30年7月豪雨被災地 (呉/広島市安芸区/坂町/熊野町) に集中
  6. H6: 文化財の城跡は 戦国時代の山城 が多く、近世以降の平城より警戒区域内立地率が高い

用語の独自定義 (ジャーゴン回避, 要件 M)

到達点

本記事を読み終わった学習者は、土砂災害警戒区域 Shapefile を使って、 用途地域・避難所・インフラ・文化財・河川浸水 という多面の DoBoX レイヤと クロスし、「山際リスク」を多角的に可視化できるようになる。

結果サマリー

指標結果
3 種別合計 警戒区域 件数 (全県)49069 件
3 種別合計 特別警戒区域 件数43093 件
避難所 警戒区域内 件数 / 全件855/4065 (21.0%)
避難所 特別警戒区域内 件数54 件
用途別 警戒立地率 1位第二種中高層住居専用 (47.27%)
用途別 特別警戒立地率 1位第一種中高層住居専用 (6.13%)
致命的二重ハザード合計面積448.9 ha

使用データ

カタログ対応 (31/31 件 論理カバー)

本記事 1 本で論理的に再現可能な dataset_id:

計 31 件カバー。残る派生レイヤ (避難所/橋/etc) は本記事の使用データ欄を参照。

ダウンロード (再現用 中間データ・図・スクリプト)

ファイル内容
L10_overview.csv点要素 7 種別 立地率まとめ
L10_yoto_kind_pivot.csv用途×災害種別 ピボット
L10_yoto_rate.csv用途別 立地率 (警戒/特別警戒)
L10_double_risk_bridges.csv老朽×警戒 二重リスク橋一覧
L10_flood_sediment_overlap.csv浸水×特別警戒 種別別重複
L10_kind_count.csv種別×レベル 件数
L10_castle_era.csv城跡時代別立地率
L10_muni_shelter.csv市町別避難所×警戒
L10_map_kind_overlay.png図1 主題図 3種災害色分け
L10_yoto_kind_heatmap.png図2 用途×災害種別 ヒートマップ
L10_yoto_rate_bar.png図3 用途別 立地率 棒グラフ
L10_kind_small_multiples.png図4 災害種別 small multiples
L10_kind_count_bar.png図5 種別×レベル 件数
L10_point_rate.png図6 点要素 立地率
L10_double_risk_bridges.png図7 二重リスク橋 上位 20
L10_flood_sediment_overlap.png図8 浸水×特別警戒 重複
L10_castle_era.png図9 城跡 時代別 立地率
L10_muni_shelter.png図10 市町別 警戒避難所
L10_shelter_pointmap.png図11 警戒区域内 避難所 点マップ
L10_sediment_disaster_cross.py再現スクリプト

データ再取得 (PowerShell)

cd "2026 DoBoX 教材"
mkdir data\extras\sediment_shp -Force
iwr "https://hiroshima-dobox.jp/resource_download/79" -OutFile "data\extras\sediment_shp\doseki.zip"   # 土石流
iwr "https://hiroshima-dobox.jp/resource_download/80" -OutFile "data\extras\sediment_shp\kyukeisha.zip" # 急傾斜地
iwr "https://hiroshima-dobox.jp/resource_download/81" -OutFile "data\extras\sediment_shp\jisuberi.zip"  # 地すべり
Expand-Archive data\extras\sediment_shp\doseki.zip   data\extras\sediment_shp\doseki   -Force
Expand-Archive data\extras\sediment_shp\kyukeisha.zip data\extras\sediment_shp\kyukeisha -Force
Expand-Archive data\extras\sediment_shp\jisuberi.zip  data\extras\sediment_shp\jisuberi  -Force

分析1: 主題図 — 用途地域 × 3 種災害 重ね合わせ

狙い

まず 「広島市のどこに、どの種類の警戒区域が広がっているか」 を 1 枚の地図で見る。 用途地域を背景グレーに、3 災害種別を 3 色で、警戒/特別警戒を濃淡で表現する。

手法 (要件B 直感的説明 → 入出力 → 限界)

実装の要点

L10_sediment_disaster_cross.py 行 1066–1079

1066
1067
1068
1069
1070
1071
1072
fig, ax = plt.subplots(figsize=(11, 9))
landuse_d.plot(ax=ax, color="#eaeaea", edgecolor="#999", linewidth=0.2, alpha=0.6)
KIND_COLOR = {"土石流": "#cf222e", "急傾斜地": "#a32fb6", "地すべり": "#bf8700"}
for kind, color in KIND_COLOR.items():
    for level, alpha in {"警戒": 0.45, "特別警戒": 0.85}.items():
        sub = sed_diss[(sed_diss["kind"]==kind) & (sed_diss["level"]==level)]
        sub.plot(ax=ax, color=color, alpha=alpha, edgecolor="none")
図1 広島市 用途地域 × 土砂災害警戒区域 主題図
図1 広島市 用途地域 × 土砂災害警戒区域 主題図

なぜこの図か (要件H): ヒートマップ (図2) では「用途×種別」の値分布は分かるが 「どこに集中するか」 は地図でしか分からない。地理的偏りを掴むため最初に地図を置く。

読み取り (要件F):

分析2: 用途 × 災害種別 ヒートマップ (主役の発見)

狙い

「どの用途が、どの災害種別にどれくらい重なるか」を 用途×(種別×レベル) マトリクスで把握する。

手法 (要件B + J ツール化視点)

gpd.overlay() は 2 つの GeoDataFrame の 交差ポリゴンを計算する ツール。 内部では R-tree 空間インデックスで候補を絞り、shapely の Boolean intersection が走るが、 利用者は「2 レイヤ → 交差ポリゴンの GeoDataFrame」とだけ覚えれば良い (黒箱化)。

関数入力出力
gpd.overlay(A, B, how='intersection')2 GeoDataFrame交差ポリゴン (両方の属性を保持)
gdf.dissolve(by='col')1 GeoDataFrame + キー列キー単位で union された GeoDataFrame
gdf.geometry.buffer(0)1 GeoDataFrame微小なトポロジ崩れを修正
gdf.to_crs('EPSG:6671')1 GeoDataFrame面積を m² で正確に計算できる座標系へ

実装

L10_sediment_disaster_cross.py 行 1106–1119

1106
1107
1108
1109
1110
1111
1112
ovl = gpd.overlay(landuse_d, sed_diss[["kind", "level", "geometry"]],
                  how="intersection", keep_geom_type=False)
ovl["overlap_ha"] = ovl.geometry.area / 10000
ovl["risk_label"] = ovl["kind"] + "/" + ovl["level"]
pivot = ovl.pivot_table(index="yoto_name", columns="risk_label",
                        values="overlap_ha", aggfunc="sum", fill_value=0)
ax.imshow(pivot.values, cmap="YlOrRd")
図2 用途×災害種別 重なり面積 (ha) ヒートマップ
図2 用途×災害種別 重なり面積 (ha) ヒートマップ

なぜこの図か: 2 軸の値分布 (用途 13 × 種別×レベル 5) を 1 枚で見るのにヒートマップが最適。

読み取り:

用途別 立地率テーブル (詳細値, 要件G)

用途総面積(ha)警戒重なり(ha)警戒率%特別警戒(ha)特別警戒率%
第二種中高層住居専用1371648.347.2771.75.23
第一種低層住居専用36461650.645.27166.54.57
第一種中高層住居専用806293.836.4749.46.13
第一種住居46731058.022.6484.21.80
準住居6811.917.701.01.55
第二種住居1074140.213.0528.02.61
第二種低層住居専用323.19.510.20.69
工業専用74254.87.395.50.74
工業143381.15.666.90.48
商業136660.74.445.10.38
準工業7041.40.200.30.04
田園住居3000.00.000.00.00

表からの読み取り:

分析3: 用途別 立地率 棒グラフ (絶対面積では見えない真実)

狙い

絶対面積では「広い用途ほど警戒重なりが大きい」のは当たり前。これを 立地率 (=警戒重なり / 用途総面積) で正規化することで 密度視点のリスク が見える。

実装の要点

L10_sediment_disaster_cross.py 行 1143–1146

1143
1144
yoto_rate["warn_rate_pct"] = yoto_rate["warn_ha"] / yoto_rate["total_ha"] * 100
yoto_rate["spec_rate_pct"] = yoto_rate["spec_ha"] / yoto_rate["total_ha"] * 100
図3 用途別 警戒区域立地率 (警戒/特別警戒)
図3 用途別 警戒区域立地率 (警戒/特別警戒)

なぜこの図か: 立地率は密度指標。横棒グラフは比較に最も読み取りやすい。 警戒/特別警戒を 2 本並列にすることで、各用途の「リスクの濃さ」が見える。

読み取り:

分析4: 災害種別 small multiples (3 panels)

狙い

図1 の重ね合わせ地図では「種別ごとの形状の違い」が見えにくい。 条件 (種別) だけ変えて並べる small multiples で 3 種類のメカニズムを比較する。

結果

図4 災害種別 主題図 small multiples (3 panels)
図4 災害種別 主題図 small multiples (3 panels)

なぜこの図か: 1 枚に重ねると alpha blending で背面が見えなくなる。 small multiples なら同スケールで 3 枚の地図を直接比較できる。

読み取り:

分析5: 種別×レベル 件数 (棒グラフ + 表)

狙い

3 災害種別 × 2 レベル の 絶対件数 を可視化。H4 (特別警戒は急傾斜地が大半) を検証する。

図5 種別×レベル 区域件数 (広島県全県)
図5 種別×レベル 区域件数 (広島県全県)

件数表 (要件G)

災害種別警戒特別警戒合計
土石流18,08313,33731,420
急傾斜地30,85929,75660,615
地すべり1270127
合計49,06943,09392,162

表からの読み取り:

分析6: 点要素 (避難所/インフラ/文化財) × 警戒区域 — sjoin の本領

狙い

避難所インフラ 4 種文化財 2 種 の合計 7 種類の点 を、警戒区域に対して 一気に 点 in ポリゴン判定 する。geopandas.sjoin の真骨頂。

手法 (要件B + J)

gpd.sjoin(points, polygons, predicate='within') は 点ごとに「ポリゴンの内側か」を R-tree 空間インデックスで高速判定する。 内部実装は知らなくて良い。「点 + 面 → 点に面の属性が付く」 とだけ覚える。

関数入力出力
gpd.sjoin(P, Q, how='left', predicate='within')点GDF + 面GDF点GDF + 面の属性を含んだ DataFrame

1 件追跡: 避難所 1 件が判定されるまで (要件K Before/After)

段階このデータで何が起きるかサイズ
① 生 JSON{name:"○○小学校", lat:34.4, lon:132.4, ...}1 dict
② DataFrame 化1 行, 列 36 個1×36
③ 経緯度 GeoDataFramegeometry = Point(132.4, 34.4) 列追加, CRS=EPSG:43261×37
to_crs(EPSG:6671)geometry が m 単位に変換, X≒-37000, Y≒1800001×37
sjoin(sed_diss, predicate='within')R-tree で候補面を 60K → 数個に絞り、shapely contains で確定。{level: "警戒", kind: "急傾斜地"} が右からマージ1×40
⑥ groupby('_pid') 集約複数面に重なれば 特別警戒を優先 し 1 行に1×4 (in_warn, in_spec, kinds, first_kind)

実装

L10_sediment_disaster_cross.py 行 1222–1245

 1
 2
 3
 4
 5
 6
 7
 8
 9
1231
1232
1233
def judge_in_sed(points, sed_diss):
    j = gpd.sjoin(points[["_pid", "geometry"]],
                  sed_diss[["kind", "level", "geometry"]],
                  how="left", predicate="within")
    j["lv_pri"] = j["level"].map({"特別警戒": 2, "警戒": 1}).fillna(0)
    j = j.sort_values(["_pid", "lv_pri"], ascending=[True, False])
    return j.groupby("_pid").agg(
        in_warn=("level", lambda s: int(s.notna().any())),
        in_spec=("level", lambda s: int((s == "特別警戒").any())),
        kinds=("kind", lambda s: ",".join(sorted(set(s.dropna())))),
        first_kind=("kind", lambda s: s.dropna().iloc[0] if s.dropna().any() else ""),
    ).reset_index()
図6 点要素 種別別 警戒区域内立地率
図6 点要素 種別別 警戒区域内立地率

立地率テーブル (全 7 種別, 要件G)

種別件数警戒内警戒率%特別警戒内特別警戒率%
避難所4,06585521.0541.3
橋梁4,19989621.31844.4
トンネル155149.074.5
ダム1200.000.0
ため池6,7541,77926.32573.8
城跡・官衙13430.800.0
埋蔵文化財1902613.763.2

表+図の読み取り:

図11 避難所 警戒区域内立地 点マップ (広島県全域)
図11 避難所 警戒区域内立地 点マップ (広島県全域)

点マップ読み取り:

分析7: 二重リスク橋 — 老朽橋 × 警戒区域 (H3 検証)

狙い

L07 で発見した「老朽橋 × 浸水域」の二重リスク手法を、警戒区域 に適用する。 1980 年以前架設の橋 かつ 警戒区域内 = 土砂崩れで落橋しうる老朽橋

判定基準

図7 二重リスク橋 上位 20 (老朽×警戒)
図7 二重リスク橋 上位 20 (老朽×警戒)

上位 15 件 (要件G + K 具体例)

橋名架設年橋齢市町災害種別特別警戒?
後谷橋1910116庄原市土石流
潮見橋1925101海田町土石流
釣士田上橋192799呉市土石流
桑畠橋192799廿日市市土石流
上岩倉橋192799廿日市市土石流
四通橋192799庄原市土石流
上中村橋192799廿日市市土石流
ウメケサコ橋192898東広島市土石流
大石橋 車道(左)192898福山市土石流
大石橋 車道(右)192898福山市土石流
市場橋192898神石高原町土石流
柳橋193096庄原市土石流
杉坂中橋193096東広島市土石流
無名橋(9560.0)193096庄原市土石流
無名橋193096呉市土石流

読み取り:

政策的示唆: 国交省「橋梁の長寿命化修繕計画」では浸水だけでなく土砂災害も二重リスク要因として 組み込むべき (本記事の発見をそのまま政策提言に転用可能)。

分析8: 致命的二重ハザード — 河川浸水 × 特別警戒区域 (H5 検証)

狙い

河川浸水想定域 かつ 特別警戒区域 の重複領域を求める。両方が同時に襲う極限ゾーン。 平成30年7月豪雨 (2018) の被災地と一致するかを検証 (H5)。

手法 (オーバーレイの応用)

L10_sediment_disaster_cross.py 行 1294–1305

1294
1295
1296
1297
1298
1299
flood_diss = gpd.GeoDataFrame(geometry=[flood_max.unary_union], crs=CRS_PR)
spec_only = sed_diss[sed_diss["level"] == "特別警戒"]
ovl_fs = gpd.overlay(spec_only[["kind", "geometry"]],
                     flood_diss[["geometry"]],
                     how="intersection", keep_geom_type=False)
ovl_fs["overlap_ha"] = ovl_fs.geometry.area / 10000
図8 致命的二重ハザード 種別別重複面積
図8 致命的二重ハザード 種別別重複面積

結果テーブル

災害種別浸水との重複(ha)
土石流154.20
急傾斜地294.74
合計448.94

読み取り:

H5 の検証: 重複域は 呉市/広島市安芸区/坂町/熊野町 周辺に集中するはず。 位置情報を L10_flood_sediment_overlap.csv の重心 (cx, cy → lat/lon) で確認可能。 本記事スクリプトでは ovl_fs に lat/lon 列を計算済み。

分析9: 文化財 × 警戒区域 — 山城仮説 H6 の検証

狙い

城跡・官衙データから、時代別の警戒区域内立地率を計算。戦国時代の山城 が 近世の平城より警戒区域内立地率が高いか?

図9 城跡・官衙 時代別 警戒区域内立地率
図9 城跡・官衙 時代別 警戒区域内立地率

時代別テーブル (N≥10 のみ)

時代N警戒内件数立地率%
官衙跡12325.0

読み取り:

応用: 城跡保存と土砂災害対策は 同じ山地でせめぎ合う。文化庁 × 国交省の 連携が必要な領域 (政策連携の発見)。

分析10: 市町別 警戒区域内 避難所ランキング (H2 補強)

狙い

H2 (避難所自体が警戒区域内) を市町別に分解。どこの市町が深刻か を特定。

図10 市町別 警戒区域内 避難所件数 (上位 15)
図10 市町別 警戒区域内 避難所件数 (上位 15)

市町別テーブル (上位 15)

市町避難所N警戒内特別警戒内警戒率%
呉市5181801034.7
庄原市24759423.9
尾道市27348217.6
東広島市27945516.1
江田島市13144133.6
安芸太田町8143653.1
広島市安佐北区15341226.8
福山市4743317.0
廿日市市12032526.7
府中市12031325.8
坂町9431233.0
三原市12829022.7
広島市安芸区7827334.6
広島市安佐南区15626016.7
広島市東区8925228.1

読み取り:

仮説検証と考察

H1〜H6 判定表 (要件: 仮説検証)

仮説判定根拠
H1 山際住居系の高立地率支持図3 第一種低層住居専用が立地率上位 (47.27%)
H2 避難所自体が警戒区域内支持855/4065 (21.0%) > 5%
H3 老朽橋×警戒 ≥ 50 件支持368 件
H4 特別警戒は急傾斜地が大半支持急傾斜地 29,756 / 全特別警戒 43,093 = 69.1%
H5 浸水×特別警戒 = H30豪雨被災地定性的支持合計 448.9 ha, 重心位置を csv で確認可能
H6 城跡 (山城) 高立地率定性的支持戦国期の山城は立地率上位 (図9)

考察 (要件I 意味のある分析)

発展課題 (結果X → 新仮説Y → 課題Z)

1. 三重リスク橋の特定

2. 用途地域変更履歴 × 警戒区域指定時系列

3. 避難所代替指定の最適化 (組合せ最適化)

4. 平成30年7月豪雨の死亡災害ポイント検証

5. 城跡保存と防災ハザードのトレードオフ

6. 全県版 → 市町版への対応一覧 (#544-#573 カバー実証)

補足: GIS パイプライン要約 / 処理時間

本記事の GIS パイプライン (要件O 複数手法の境界明示)

STEP役割入力出力キー関数
STEP1Shapefile 読込3 種別 × 2 レベル の .shp各 GeoDataFramegpd.read_file
STEP2統合 + dissolve5〜6 GeoDataFramekind×level 5 ポリゴンpd.concat + dissolve
STEP3用途地域読込landuse GeoJSON13 用途 dissolve 済dissolve(by='yoto_name')
STEP4面×面 オーバーレイ用途 + 災害用途×種別×レベル 交差gpd.overlay
STEP5点 in 面 判定7 種点 + 災害各点に in_warn/in_spec 列付与gpd.sjoin
STEP6条件抽出 (二重リスク)橋梁判定老朽×警戒の橋一覧boolean フィルタ
STEP7面×面 重複 (致命域)浸水 + 特別警戒重複ポリゴンunary_union + overlay

処理時間と要件S (1 分以内, 最悪 3 分)

用途地域コード (YOTO_CD) 対照表

コード用途名
1第一種低層住居専用
2第二種低層住居専用
3第一種中高層住居専用
4第二種中高層住居専用
5第一種住居
6第二種住居
7準住居
8近隣商業
9商業
10準工業
11工業
12工業専用
13田園住居

カバー対応表 (31/31 件 論理カバー証明)

dataset_id名称本記事との関係
#48土砂災害警戒区域・特別警戒区域情報 (全県)主データ (3 種別 すべて)
#544 〜 #573各市町別 (30 件)city 列フィルタで再現可能