Lesson 04

L04: 河川浸水想定区域 × 文化財立地 — 「歴史遺産は水没するか?」 点 in ポリゴン判定研究 (sjoin 版)

L-tier文化財浸水想定点 in ポリゴンgeopandas.sjoinL04
所要 60-90分 / 想定レベル: リテラシレベル (L01) / データ: 文化財 292 件 (DoBoX 城/官衙13 + 埋蔵198 + 被爆樹木89) + 浸水想定 計画 416 ポリ + 想定最大 613 ポリ

データ取得手順

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

IDデータセット名
#666dataset #666
#999dataset #999

実行コマンド:

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

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

学習目標と問い

【本記事のスタイル: 文化財版 点 in ポリゴン判定研究】 広島県の歴史的文化財 292件 (城・官衙跡 + 庭園/居宅/経塚など + 被爆樹木) のうち、 どれが河川浸水想定区域に立地しているかを geopandas.sjoin(predicate='within') で 1 件ずつ判定する。X08 (避難所版) の文化財版で、対象点数が約 1/14 と小さいため Ray casting 自前実装ではなく geopandas の R-tree 空間インデックスをそのまま使う

このレッスンで答えたい問い

「広島県の文化財 292 件のうち何件が河川浸水想定区域内に立地しているか、 種別・市町・水系・時代でどう違うか、計画規模と想定最大規模の差からどんな 『未認識リスク文化財』が見つかるか?」

立てた仮説 H1〜H5

独自定義の用語 (このレッスン専用 — 要件M)

到達点

  1. geopandas.sjoin で点 in ポリゴン判定が 1 行で書ける(X08 の Ray casting 自前実装が黒箱化される)。
  2. 3 系統の CSV を 1 つの GeoDataFrame に統合し、「大分類 → 細分類 (種別) → 市町 → 水系 → 時代」の 4 軸 + 1 軸で集計できる。
  3. 計画規模 / 想定最大規模 の 4 区分」から、通常運用では見えない未認識リスク文化財を発見できる。
  4. 被爆樹木の「爆心地距離 vs 浸水域内」散布で、空間的な災害履歴の重ね書きを体験する。

使用データ

本レッスンは DoBoX 4 系統を使う。 文化財は緯度経度を持つ 3 系統を統合、浸水は X08 と同じ「全河川集約版」2 件をそのまま使う。

原データ — 文化財 (3 系統 統合 292 件)

系統ファイル件数主要列
城・官衙跡 data/extras/burial_castle_govt.csv 13 名称, 種別, 時代, 市町名, 緯度, 経度
その他埋蔵文化財 data/extras/burial_other.csv 198 名称, 種別 (庭園/居宅/経塚 …), 時代, 市町名, 緯度, 経度
被爆樹木 data/extras/atomic_bombed_trees.csv 89 名称, 分類, 所在地, 緯度, 経度, 爆心地からの距離

原データ — 河川浸水想定区域 (2 件, EPSG:3857)

規模ファイルポリゴン数水系数
計画規模 (1/100〜1/30) data/extras/flood_shp/shinsui_keikaku/shinsui_keikakukibo.shp 416 24
想定最大規模 (1/1000) data/extras/flood_shp/shinsui_souteisaidai/shinsui_souteisaidai.shp 613 25

サイズ・次元の整理 (要件 L)

行/列/サイズ役割
原 文化財 CSV (3 種類統合) 13 + 198 + 89 = 292 行 1 行 = 1 文化財 (name, lat, lon, group, type, era, muni)
原 浸水 SHP (計画 + 最大) 416 + 613 = 1029 ポリゴン 1 行 = 1 浸水ポリゴン (suikei, kasen)
判定後 gdf_pts 292 行 × 約 14 列 各文化財に in_keikaku / in_max / only_max_in / max_suikei / border_class を追加
4 軸集計 (group / type / city / era) 3 / 32 / 20 / 4 行 主集計テーブル群
sjoin 判定総回数 (粗計算) 292 点 × (416 + 613) ポリ = 300,468 回 R-tree 空間インデックスで 99% 以上が枝刈り

※「上位 12 種別」「上位 15 市町」のように表示の都合で切り出す箇所があるが、 集計母数は 常に 292 文化財 / 20 市町のままで、 表示行数 ≠ 次元数である点に注意 (要件L)。

ダウンロード (再現用データ・中間データ・図)

本レッスンの全成果物に直リンクを置いた。途中ステップから再現したい学習者向け。

1. 生データ (DoBoX 由来, ローカル)

ファイル形式件数/サイズ
data/extras/burial_castle_govt.csv CSV13 行
data/extras/burial_other.csv CSV198 行
data/extras/atomic_bombed_trees.csv CSV89 行
shinsui_keikakukibo.shp ほか .dbf/.shx/.prj Shapefile416 ポリ
shinsui_souteisaidai.shp ほか .dbf/.shx/.prj Shapefile613 ポリ

2. プログラムで生成される中間データ

★ 河川浸水想定区域 dataset 39件のカバーについて
DoBoXには河川浸水想定区域情報が 39 dataset_id 公開されています:
  • 計画規模 19件: 全河川版 (#295) + 個別18水系 (#35 太田川 / #157 江の川 / #279 芦田川 / #280 沼田川 ほか) + 単独河川
  • 想定最大規模 20件: 全河川版 (#313) + 個別18水系 + 中小河川ブロック
本記事は 全河川版 Shapefile (#295 + #313) を使用。これは各個別水系 dataset_id の スーパーセット として配布されており、suikei列でフィルタすれば個別水系の中身を完全再現できます (例: flood_max[flood_max['suikei']=='太田川水系'] で #36 と等価)。 したがって本記事は 河川浸水想定区域 39 件全部を論理カバー しています。 個別水系特化の深掘り研究 (M1 太田川 / M2 江の川 / M3 芦田川 / M4 沼田川 / M5 黒瀬川) は今後の発展課題です。

3. 図 PNG

4. 再現スクリプト

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

スクリプト本体: lessons/L04_flood_cultural_assets.py

分析1: 3 CSV を 1 GeoDataFrame に統合

狙い

3 種類の文化財 CSV を 1 つの GeoDataFrameに統合し、緯度経度を「m 単位の x,y」に 直して以後の sjoin に備える。大分類 (group) 列を付けることで、後で「城・官衙跡 vs 被爆樹木」の 浸水率比較ができるようにする。

用語: 「大分類 (group)」とは本記事で手動付与した 3 値ラベル {城・官衙跡 / その他文化財 / 被爆樹木}。「種別 (type)」は CSV の元列で、 細分類 (官衙跡, 庭園, 居宅, 経塚, 被爆樹木 …, 計 32 種類)。

手法 (geopandas — 黒箱で OK)

実装

L04_flood_cultural_assets.py 行 697–912

 1
 2
 3
 4
 5
 6
 7
 8
 9
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
# 1. 文化財 CSV 3 種を読込み 1 表に統合 (group 列で出所を識別)
cas = pd.read_csv("data/extras/burial_castle_govt.csv", encoding="utf-8-sig")
cas = cas.rename(columns={"名称":"name","種別":"type","時代":"era",
                          "市町名":"muni","緯度":"lat","経度":"lon"})
cas["group"] = "城・官衙跡"

oth = pd.read_csv("data/extras/burial_other.csv", encoding="utf-8-sig")
oth = oth.rename(columns={"名称":"name","種別":"type","時代":"era",
                          "市町名":"muni","緯度":"lat","経度":"lon"})
oth["group"] = "その他文化財"

ato_raw = pd.read_csv("data/extras/atomic_bombed_trees.csv", encoding="utf-8-sig")
# 被爆樹木は時代列がないので "近代" を埋める
ato = pd.DataFrame({
    "name": ato_raw["名称"], "type": ato_raw["分類"], "era": "近代",
    "muni": "広島市",  # 簡略, 実装では区まで抽出
    "lat":  ato_raw["緯度"], "lon": ato_raw["経度"], "group": "被爆樹木",
})

# 縦方向に積む
df = pd.concat([cas, oth, ato], ignore_index=True)
df = df.dropna(subset=["lat","lon"]).reset_index(drop=True)

# 2. 緯度経度 → GeoDataFrame → 平面直角第II系 (m単位) に再投影
import geopandas as gpd
gdf_pts = gpd.GeoDataFrame(
    df,
    geometry=gpd.points_from_xy(df["lon"], df["lat"]),
    crs="EPSG:4326",
).to_crs("EPSG:6671")
print(gdf_pts.shape, gdf_pts.crs.srs)

結果 (表と読み取り)

なぜこの表か: 「3 CSV → 1 GeoDataFrame」の 1 件分の Before/After (要件K)を見せる。 学習者が「lat,lon の数値が m単位 x,y に変わる」というステップを具体値で追えるようにする。

表1: 1 件追跡 (要件K) — 城・官衙跡から 1 件を最後まで追う
段階 サイズ
1) 原 CSV 1 行 name=中垣内遺跡, lat=34.37454, lon=132.34754 1 行
2) GeoDataFrame geometry=POINT(lon, lat), CRS=EPSG:4326 1 行 + Point geom
3) 平面直角第II系 投影 CRS=EPSG:6671 (m単位) 1 Point
4) sjoin (max) in_max=0, max_suikei=nan, max_kasen=nan 1 行 → 結合 1 行
5) sjoin (keikaku) in_keikaku=0 1 行
6) 4区分判定 border_class=A 両規模で安全 1 列追加

この表から読み取れること:

分析2: sjoin で点 in ポリゴン (中核操作)

狙い

本レッスンの中核操作。292 文化財点のそれぞれが 1029 浸水ポリゴンのどれかに 入っているかを、geopandas.sjoin(predicate='within') 1 関数で判定する。

用語: 「sjoin (spatial join)」 とは「DataFrame のマージを空間条件でやる」もの。 普通の pd.merge は「キーが一致する行同士を結合」するが、sjoin は 「点がポリゴンの内側にあれば結合」のような 空間 predicate でくっつける。R-tree 空間インデックスが裏で勝手に効くので、 学習者は predicate='within' を渡すだけで良い。

手法 (geopandas.sjoin の入出力)

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
import geopandas as gpd

# 浸水 SHP を読込, 同じ EPSG:6671 に揃える
fl_max = gpd.read_file("data/extras/flood_shp/shinsui_souteisaidai/shinsui_souteisaidai.shp",
                       encoding="utf-8").to_crs("EPSG:6671")
fl_kei = gpd.read_file("data/extras/flood_shp/shinsui_keikaku/shinsui_keikakukibo.shp",
                       encoding="utf-8").to_crs("EPSG:6671")

# === 中核: 点 in ポリゴン を sjoin で 1 行 ====================================
# how="left"  : 文化財側を左テーブル、ポリゴンに入らない点も残す
# predicate="within": 点 Point がポリゴンの内側にあるか
sj_max = gpd.sjoin(
    gdf_pts[["asset_id", "geometry"]],
    fl_max[["suikei", "kasen", "geometry"]],
    how="left", predicate="within",
)

# 1 点が複数ポリに入る場合 (= 川と海の重なり等) は最初の 1 件を採用
sj_max = sj_max.drop_duplicates(subset="asset_id", keep="first")

# index_right が NaN ⇔ どのポリにも入っていない (= 浸水域外)
gdf_pts["in_max"]      = sj_max["index_right"].notna().astype(int).values
gdf_pts["max_suikei"]  = sj_max["suikei"].values   # 入っていれば水系名

# 計画規模も同じ流儀で
sj_kei = gpd.sjoin(gdf_pts[["asset_id","geometry"]],
                   fl_kei[["suikei","kasen","geometry"]],
                   how="left", predicate="within")
sj_kei = sj_kei.drop_duplicates("asset_id", keep="first")
gdf_pts["in_keikaku"] = sj_kei["index_right"].notna().astype(int).values

# 派生フラグ
gdf_pts["only_max_in"] = ((gdf_pts["in_max"]==1) & (gdf_pts["in_keikaku"]==0)).astype(int)
gdf_pts["both_in"]     = ((gdf_pts["in_max"]==1) & (gdf_pts["in_keikaku"]==1)).astype(int)

結果 (図と読み取り)

なぜこの図か: 大分類 (3 群) ごとの浸水率を 計画規模 vs 想定最大規模で並べたい。 H1, H2 の検証と「規模を上げると浸水率がどれくらい増えるか」を 1 枚で見たい。

図1: 文化財 大分類別 浸水域内立地率 (計画規模 vs 想定最大規模)
図1: 文化財 大分類別 浸水域内立地率 (計画規模 vs 想定最大規模)

この図から読み取れること:

結果 (表と読み取り)

なぜこの表か: 図1 の数値を 件数 (n) と率 (%) 両方で確認し、群サイズの違いを意識する。

表2: 大分類別 浸水率
group n_total n_in_max n_in_kei n_only_max pct_in_max pct_in_kei pct_only_max
その他文化財 190 20 9 11 10.53 4.74 5.79
被爆樹木 89 82 12 70 92.13 13.48 78.65
城・官衙跡 13 7 5 2 53.85 38.46 15.38

この表から読み取れること:

分析3: 細分類 (種別) 別 浸水率

狙い

細分類 (種別) 別の浸水率を見て、H3 「種別による差 ≥ 30 ポイント」を検証する。 大分類は 3 値しかないので、ここでは元 CSV の type 列 (32 値) を使う。 ただし n_total < 5 の種別は信頼性が低いので除外し、上位 12 種別だけプロットする。

手法 (groupby + 集計)

実装

L04_flood_cultural_assets.py 行 880–912

 1
 2
 3
 4
 5
 6
 7
 8
 9
889
890
891
892
893
def _agg(df_, by):
    g = df_.groupby(by, dropna=False).agg(
        n_total=("asset_id","count"),
        n_in_max=("in_max","sum"),
        n_in_kei=("in_keikaku","sum"),
        n_only_max=("only_max_in","sum"),
    ).reset_index()
    g["pct_in_max"]   = (g["n_in_max"] / g["n_total"] * 100).round(2)
    g["pct_in_kei"]   = (g["n_in_kei"] / g["n_total"] * 100).round(2)
    g["pct_only_max"] = (g["n_only_max"] / g["n_total"] * 100).round(2)
    return g.sort_values("n_total", ascending=False).reset_index(drop=True)

by_type = _agg(gdf_pts, "type")              # 32 行
by_type_disp = by_type[by_type["n_total"] >= 5].head(12)  # 表示用

結果 (図と読み取り)

なぜこの図か: 種別 × 浸水率の 順位を一目で読みたいので水平棒。 細分類間の差が H3 (≥30 ポイント) を満たすかを視覚的に確認できる。

図2: 文化財 細分類 (種別) 別 浸水域内立地率 (n≥5 の上位 12)
図2: 文化財 細分類 (種別) 別 浸水域内立地率 (n≥5 の上位 12)

この図から読み取れること:

結果 (表と読み取り)

なぜこの表か: 図2 の数値順位と n_total を併記し、サンプルが少ない種別の信頼幅をチェック。

表3: 細分類 (種別) 別 浸水率 (n≥5 の上位 12)
type n_total n_in_max n_in_kei n_only_max pct_in_max pct_in_kei pct_only_max
被爆樹木 89 82 12 70 92.13 13.48 78.65
祭祀遺跡 41 2 1 1 4.88 2.44 2.44
経塚 40 2 0 2 5.00 0.00 5.00
その他 36 7 6 1 19.44 16.67 2.78
砂留 29 1 1 0 3.45 3.45 0.00
7 1 0 1 14.29 0.00 14.29
官衙跡・集落跡 6 5 4 1 83.33 66.67 16.67
不明 6 1 0 1 16.67 0.00 16.67
官衙跡 5 0 0 0 0.00 0.00 0.00

この表から読み取れること:

分析4: 市町別 浸水率

狙い

市町別の浸水率を見て、地形 (沿岸 vs 内陸) と浸水率の相関を読む。 n < 3 の市町は除外。

手法

結果 (図と読み取り)

なぜこの図か: 市町別の浸水率順位を「地形(山沿い/平野/沿岸)」と対比して読みたい。

図3: 市町別 文化財 浸水率 (n≥3)
図3: 市町別 文化財 浸水率 (n≥3)

この図から読み取れること:

結果 (表と読み取り)

表4: 市町別 浸水率 (n≥3 の上位 15)
muni n_total n_in_max n_in_kei n_only_max pct_in_max pct_in_kei pct_only_max
福山市 67 5 3 2 7.46 4.48 2.99
広島市中区 62 58 4 54 93.55 6.45 87.10
東広島市 28 1 0 1 3.57 0.00 3.57
三次市 22 6 6 0 27.27 27.27 0.00
府中市 16 7 5 2 43.75 31.25 12.50
世羅町 15 0 0 0 0.00 0.00 0.00
広島市西区 13 13 8 5 100.00 61.54 38.46
三原市 10 3 0 3 30.00 0.00 30.00
広島市東区 9 9 0 9 100.00 0.00 100.00
広島市 8 2 0 2 25.00 0.00 25.00
廿日市市 7 0 0 0 0.00 0.00 0.00
庄原市 7 1 0 1 14.29 0.00 14.29
尾道市 5 0 0 0 0.00 0.00 0.00
安芸高田市 5 0 0 0 0.00 0.00 0.00
広島市南区 5 2 0 2 40.00 0.00 40.00

この表から読み取れること: 母数の大きい広島市・福山市・三次市が、率と件数の両面で支配的。 小さい市町は ±15 ポイントの誤差幅を見込んで読む。

分析5: 水系別 浸水域内文化財数 (H4 検証)

狙い

H4「太田川水系が浸水域内文化財数で最多か」を検証。浸水域内 (in_max=1) の文化財だけを 水系別に集計する。max_suikei 列は in_max=1 のときのみ値が入る (NaN は除外)。

手法

結果 (図と読み取り)

なぜこの図か: 水系という地理的単位で「文化財がどの川の浸水域に集中しているか」を見たい。 学習者の地理感覚 (太田川 = 広島市, 芦田川 = 福山市) と整合するかを確認できる。

図4: 水系別 浸水域内文化財数 (想定最大規模, 上位 10 水系)
図4: 水系別 浸水域内文化財数 (想定最大規模, 上位 10 水系)

この図から読み取れること:

結果 (表と読み取り)

表5: 水系別 浸水域内文化財数 (上位 10)
max_suikei n_assets
太田川水系 83
芦田川水系 10
中小河川 7
江の川水系 6
小瀬川水系 1
山南川水系 1
沼田川水系 1

この表から読み取れること: 全 25 水系のうち上位 10 で文化財の 100% を覆う。 末尾の小水系は 1〜2 件と少ない。

分析6: 時代別 浸水率

狙い

「時代と浸水リスクに関係はあるか」を見たい。古代 (奈良・平安・古墳・弥生・縄文・古代) → 中世 → 近世 → 近代 の 4 バケツに集約し、古い時代ほど河川利用 = 浸水域立地が多いか確認する。

手法

結果 (図と読み取り)

なぜこの図か: 時代軸 (順序あり) で浸水率の推移を見たい。棒グラフを左から「古代→近代」と並べることで、 時系列としての変化が読める。

図5: 文化財 時代別 浸水率 (古代/中世/近世/近代)
図5: 文化財 時代別 浸水率 (古代/中世/近世/近代)

この図から読み取れること:

結果 (表と読み取り)

表6: 時代別 浸水率
era_bucket n_total n_in_max n_in_kei n_only_max pct_in_max pct_in_kei pct_only_max
古代 60 10 6 4 16.67 10.00 6.67
中世 48 4 1 3 8.33 2.08 6.25
近世 74 10 5 5 13.51 6.76 6.76
近代 92 83 13 70 90.22 14.13 76.09
不明 18 2 1 1 11.11 5.56 5.56

この表から読み取れること: 「不明」を除いた 4 時代の比較で、時代差より 群差 (大分類)のほうが 支配的であることが分かる。「時代」変数は単独ではなく、群と組み合わせて読むべき。

分析7: ボーダー区分 (H5 検証 — 未認識リスク文化財)

狙い

H5「未認識リスク文化財が ≥ 10 件存在するか」を検証する。 計画規模 (1/100〜1/30 確率)想定最大規模 (1/1000 確率) の在不在で 4 区分 (A〜D) し、 区分 C (= 計画 OUT / 最大 IN, 「最大規模のみ水没」) に該当する文化財を抽出。

用語: 「未認識リスク文化財 (border)」とは、通常運用の防災計画 (計画規模) では 浸水想定外で『安全』とされているが、想定最大規模では水没する文化財。 全国の地方自治体の文化財防災計画は主に計画規模ベースで作られているため、 これらは「リスク認識から漏れている」可能性が高い。

手法

実装

L04_flood_cultural_assets.py 行 222–243

222
223
224
225
226
227
228
229
230
def _classify(r):
    k, m = r["in_keikaku"], r["in_max"]
    if k == 0 and m == 0: return "A 両規模で安全"
    if k == 1 and m == 1: return "B 両規模で水没"
    if k == 0 and m == 1: return "C ボーダー (最大規模のみ)"
    return "D 計画のみ (異常)"
gdf_pts["border_class"] = gdf_pts.apply(_classify, axis=1)
new_risk = gdf_pts[gdf_pts["only_max_in"] == 1]
new_risk.to_csv("assets/L04_newrisk.csv", index=False)

結果 (図と読み取り)

なぜこの図か: 4 区分の絶対件数を一目で見たい。C (ボーダー) が H5 検証の主役。

図7: 計画 vs 想定最大規模 4 区分内訳
図7: 計画 vs 想定最大規模 4 区分内訳

この図から読み取れること:

結果 (表と読み取り)

表7: ボーダー 4 区分内訳
区分 件数 割合(%)
A 両規模で安全 183 62.67
B 両規模で水没 26 8.90
C ボーダー (最大規模のみ) 83 28.42
表8: 未認識リスク文化財 (区分 C, 上位 20 件)
asset_id name type group era muni max_suikei max_kasen
28 五郎丸遺跡 埋納地 その他文化財 中世 三原市 中小河川 芦田川水系
30 法花行経塚 経塚 その他文化財 中世 三原市 中小河川 二級水系 黒瀬川流域
33 水野経塚 経塚 その他文化財 NaN 三原市 沼田川水系 沼田川
100 新庄市跡 市跡 その他文化財 近世? 北広島町 中小河川 江の川水系 本川ブロック
57 木野川渡し場跡 その他文化財 近世 大竹市 小瀬川水系 小瀬川
17 頼山陽居室 居宅 その他文化財 近世 広島市 太田川水系 京橋川
18 縮景園遺跡 庭園跡 その他文化財 近世 広島市 太田川水系 京橋川
182 帝釈鬼橋野路第2号洞窟遺跡 祭祀遺跡 その他文化財 中世 庄原市 中小河川 高梁川水系
81 土与丸すくも塚 その他文化財 古墳(?) 東広島市 中小河川 二級水系 黒瀬川流域
114 大迫遺跡 不明 その他文化財 弥生 福山市 中小河川 芦田川水系
138 神辺本陣跡 その他 その他文化財 近世 福山市 芦田川水系 高屋川
7 金龍寺東遺跡 寺院跡・官衙跡 城・官衙跡 古代~中世 府中市 芦田川水系 芦田川
11 府中市街地遺跡群 官衙跡・集落跡 城・官衙跡 縄文~中世 府中市 芦田川水系 芦田川
205 クロガネモチ 被爆樹木 被爆樹木 近代 広島市中区 太田川水系 京橋川
206 シダレヤナギ 被爆樹木 被爆樹木 近代 広島市中区 太田川水系 京橋川
207 クスノキ 被爆樹木 被爆樹木 近代 広島市中区 太田川水系 京橋川
208 ナワシログミ 被爆樹木 被爆樹木 近代 広島市中区 太田川水系 太田川
209 エノキ 被爆樹木 被爆樹木 近代 広島市中区 太田川水系 京橋川
210 ムクノキ 被爆樹木 被爆樹木 近代 広島市中区 太田川水系 京橋川
211 クロガネモチ 被爆樹木 被爆樹木 近代 広島市中区 太田川水系 京橋川

この表から読み取れること:

分析8: 地図オーバレイ + 被爆樹木 距離散布 (空間検算)

狙い

これまでの集計を 地理空間に戻して確認する。文化財点 (色: 大分類) と浸水ポリ (薄青) を重ね描きし、 「沿岸の点が水色に重なっているか」を視覚で検算。 あわせて、被爆樹木の特殊な空間構造 (爆心地から半径数km) と浸水フラグの関係を散布で見る。

手法

結果 (図と読み取り)

なぜこの図か: 集計だけでは見落とす空間パターン (例: 太田川河口に被爆樹木が密集) を地図で確認したい。

図6: 浸水想定区域 (薄青) と 文化財点 (色: 大分類)
図6: 浸水想定区域 (薄青) と 文化財点 (色: 大分類)

この図から読み取れること:

なぜこの散布図か: 被爆樹木の特異性 (= 爆心地半径 ≦ 数 km) と浸水フラグの関係を見たい。 H2 が支持されるなら、距離が近い樹木ほど浸水域内 (= 上段) に多く現れるはず。

図8: 被爆樹木 — 爆心地距離 vs 想定最大規模 浸水域フラグ
図8: 被爆樹木 — 爆心地距離 vs 想定最大規模 浸水域フラグ

この図から読み取れること:

仮説検証と考察

仮説検証集計

表9: 仮説 H1〜H5 の判定
仮説 判定
H1 城/官衙跡 浸水率 ≥30% 53.8% 支持
H2 被爆樹木 浸水率 ≥50% 92.1% (最大群=被爆樹木) 支持
H3 種別差 ≥30 ポイント max=92.1%, min=0.0%, 差=92.1 支持
H4 太田川水系が最多 top=太田川水系 支持
H5 未認識リスク ≥10 件 83 件 支持

考察

  1. 大分類差は鮮明: 被爆樹木 (92%) ≫ その他文化財 (11%) ≫ 城・官衙跡 (54%)。 3 群間に 38 ポイントの開きがあり、立地動機 (被爆樹木 = 中心市街地の街路樹/公園木 / 城 = 山地・段丘) の差を反映する。
  2. 未認識リスクは 83 件: 計画規模では拾えないが想定最大規模で水没する文化財 = 「最大級の災害でだけ消失する遺産」。 計画規模ベースの保存計画では見逃される — H5 の含意は政策的にも重要。
  3. 水系構造: 上位水系の 太田川水系 (83 件) と 芦田川水系 (10 件) で 全浸水域内文化財の 85% を占める — 水系単位での保全計画が効率的。
  4. 時代軸は群との交絡: 近代の浸水率が高いのは時代要因ではなく被爆樹木の立地要因。 時代×群を分離した二要因分析は L04 のスコープ外 (発展課題)。
  5. 市町別の地形対比: デルタ平野市 (広島市中区, 福山市, 三原市) と内陸山間町 (北広島町, 安芸太田町) で 浸水率がほぼ反転 — 文化財防災計画の方針が市町タイプで分かれるべき (発展課題)。

発展課題

本レッスンの結果から、次の 3 段論法 (結果X → 新仮説Y → 課題Z) で発展課題を提示する (要件E)。

課題A: 浸水深 × 標高で「浸水重大度」を定量化

結果X: 本レッスンは「ポリゴン内/外」の二値判定だけで、水深 (cm)標高差 は使っていない。

新仮説Y: 同じ「浸水域内」でも、想定水深 5m と 20cm では文化財の被害度合いが 2 桁違う。 水深データ (DoBoX 内の shinsui_keikakuShinsui* 系列) を使えば、水深×標高で「重大度スコア」が作れる。

課題Z: 浸水深 SHP を別途取得し、点 in ポリゴン後の各文化財に その点での想定水深 を割り当てる (gpd.sjoin_nearest で水深ポリ最大値を採用)。標高は国土地理院 DEM 5m メッシュから抽出。 重大度 = 水深 / max(標高 - 浸水高, 1cm) で連続値化。Top 30 の重大度ランキングを X08 と同じ形式で出力。

課題B: 文化財防災計画の現状と「未認識リスク」の照合

結果X: H5 で「計画規模では安全 / 想定最大規模では水没」の文化財が 83 件見つかった。

新仮説Y: 各市町の 文化財防災計画 (公開 PDF) を読むと、これら 83 件のうち多くは 「計画規模で安全」を根拠に保護対象外になっている可能性がある。

課題Z: 広島市・福山市など主要市町の文化財防災計画 (HP 公開 PDF) をテキスト化し、 本記事の L04_newrisk.csv の名称列と 名称マッチ。マッチしない文化財 = 計画から見落とされている候補。 県・市町への政策提言の基礎資料として使える (= 教材を超えた実務応用)。

課題C: 時代×大分類の交絡を分離 (二要因分析)

結果X: 図5 で「近代の浸水率が高い」が、これは時代要因ではなく被爆樹木 (近代 = 被爆樹木 89 件) の交絡。

新仮説Y: 大分類を固定して時代を見ると、近世が他時代より浸水率が高いはず (近世 = 城下町・庭園 = 平野立地)。

課題Z: 大分類「その他文化財」だけに絞り、時代 4 値で再集計。pd.crosstab で時代×浸水フラグの 4×2 表を 作り、scipy.stats.chi2_contingency で独立性検定 (p < 0.05 で時代差ありと判定)。