Lesson 89

L89 M5 中山間物語 — 過疎・高齢化・農地転用・林業の地理学

M系統合中山間地理過疎高齢化農地転用農用地区域LiDAR砂防三施設族橋梁高齢化geopandas
所要 40 分 / 想定レベル: リテラシ + 4 軸統合 + 中山間物語 / データ: L22 人口 (#1467-1508) / L24 農地 (#1391-1407) / L25 農用地 (#1408-1424) / L41 LiDAR / L46+L57+L58 砂防三施設 / 橋梁 #11 / 過去災害 #181

データ取得手順

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

IDデータセット名
#11橋梁基本情報・維持管理情報
#55砂防関係指定地情報_砂防指定地
#181dataset #181
#666dataset #666
#888都市計画区域情報_区域データ_安芸高田市_行政区域
#1117dataset #1117
#1124dataset #1124
#1126dataset #1126
#1391都市計画区域情報_農地転用状況_安芸高田市_2016-2020
#1407都市計画区域情報_農地転用状況_北広島町_2016-2020
#1408都市計画区域情報_農林漁業関係施策_安芸高田市_2022
#1424都市計画区域情報_農林漁業関係施策_北広島町_2022
#1467都市計画区域情報_性別年齢別人口_広島市_2020
#1486都市計画区域情報_性別年齢別人口_三次市_2020
#1488都市計画区域情報_性別年齢別人口_庄原市_2020
#1497都市計画区域情報_性別年齢別人口_安芸高田市_2020
#1506都市計画区域情報_性別年齢別人口_北広島町_2020
#1508都市計画区域情報_性別年齢別人口_世羅町_2020

実行コマンド:

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

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

学習目標と問い

中国山地の懐に抱かれた庄原市は、 県内最大の面積を持ちながら人口は 減り続けている。 三川が合流する三次盆地は山陰山陽の結節点として古くから 栄えたが、 高速道路の伸長と引き換えに若者の流出が止まらない。 毛利元就の ふるさと安芸高田、 西中国山地の山深い北広島町、 標高 500m の高原に 集落が散る神石高原町、 備後台地に梨園が広がる世羅町。 これら 中山間 6 市町には、 共通する物語がある。

過疎・高齢化・農地転用・耕作放棄・林業 — 中山間は広島県の母なる 風景であり、 同時に「失われる」 風景でもある。 しかし オープンデータの目で見ると、 中山間は単に「衰退する地域」 ではない。 政策的に守られる農用地、 LiDAR が捉えた育ち続ける森、 砂防が斜面を 押さえ、 渓流工が小さな谷を整える。 そこには都市部とは異なる 地理リスクと文化資源の交差点がある。

本記事は、 DoBoX の L22 人口ピラミッド (#1467-1508) + L24 農地転用 (#1391-1407) + L25 農林漁業施策 (#1408-1424) + L41 LiDAR 単木 (#1117) 3,397,186 点 + L46 砂防指定地 (#55) 3,207 件 + L57 地すべり (#1126) 32 件 + L58 渓流 (#1124) 1,862 件 + 橋梁 (#11) 4,203 件 + 過去災害 (#181) 424 件 + L15 行政界 を統合し、 「中山間 6 市町の物語 — 過疎の進む中で 何が残り、 何が変わっているのか?」 を 6 章の物語として読み解く テーマ統合 (M系) 記事 / M系最終記事である。

独自用語の定義 (この記事だけで使う)

研究の問い (主 RQ)

広島県内中山間 6 市町 — 過疎の進む中で何が残り、 何が変わって いるのか? 山と田と森に守られた地域は、 都市部とどう違う構造を 持ち、 オープンデータはその物語をどう語るのか?

仮説 (H1〜H5)

到達点

L22 / L24 / L25 / L41 / L46 / L57 / L58 / L66 / L61 との明確な切り分け: 既存の L 系記事はそれぞれ「市町別ピラミッド単独」 「農地転用年別単独」 「農用地区域 TOKEI_CD 別単独」 「LiDAR 計測手法単独」 「砂防全県」 「橋梁全県」 を扱った。 L89 はこれらと完全に独立した切り口で、 「中山間 6 市町 × 4 軸 (人口 × 農地 × 林業 × 防災)」 という新しい統合視点で物語を組む。 同じデータが切り口を変えれば 全く異なる物語を語る — それが M 系 (テーマ統合) の本質である。
M 系 シリーズ最終記事として: M1 (太田川水系) はの物語、 M2 (埋蔵文化財) は時間の物語、 M3 (観光) は沿岸島嶼の物語、 M4 (産業) は戦前-戦後の物語。 そして M5 (本記事) は 中山間の物語。 5 つを合わせると、 広島県の地理を 水・時間・ 沿岸・産業・中山間 の 5 軸でまるごと描く研究地図になる。

使用データ

本記事は中山間物語を語るため、 4 系統 (人口・農地・林業・防災) を 構成する 10 dataset を組み合わせて使う。 中山間 6 市町は L22/L24/L25 の都市計画区域系データ (神石高原町は区域外で欠落) と、 L46/L57/L58/L66/L61 の全県データ (中山間フィルタで抽出) の両方を架橋することで初めて 描ける。

論題dataset件数用途
都市計画区域情報_人口データ 6 件 DoBoX #1467 〜 #1508 9,160 ポリゴン 第2章 高齢化率 (H1)
都市計画区域情報_農地ポリゴン DoBoX #1391 〜 #1407 1,532 ポリゴン 第3章 農地転用 (H2)
都市計画区域情報_農用地区域等 DoBoX #1408 〜 #1424 378 ポリゴン (3 系列) 第3章 農用地保全 (H2)
砂防指定地 DoBoX #55 3,207 ポリゴン 第5章 砂防三施設族 (H3)
地すべり防止施設 DoBoX #1126 32 ポリゴン 第5章 砂防三施設族 (H3)
渓流保全工 DoBoX #1124 1,862 ライン 第5章 砂防三施設族 (H3)
航空レーザ森林資源 (世羅町) DoBoX #1117 3,397,186 点 第4章 LiDAR 単木計測 (H5)
橋梁基本情報 DoBoX #11 4,203 件 第6章 インフラ高齢化 (H4)
過去災害履歴 DoBoX #181 424 件 第5章 中山間災害集中度
(派生) L15 行政界 21 市町 L15 cache (admin_*.zip) 20 (神石高原欠) 背景マップ + dissolve

派生指標 (本記事独自)

1 件追跡 (要件 K — Before/After)

段階
0. 元 GeoPackagetree_point_34462.gpkg layer=tree_point_34462
1. メモリ節約読込geometry=False, columns=樹種/樹高/胸高直径/単木材積
2. 全件3,397,186 単木
3. 樹種別 value_countsヒノキ・スギ・コナラ等の上位
4. ヒノキフィルタヒノキ単独 = 3,067,440 本
5. 比率3,067,440/3,397,186 = 90.3%
6. H5 判定 (≥80%)支持 (植林系合計は 100.0%)

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

中山間 6 市町プロファイル (本記事独自)

市町郡付き名代表色物語L22人口L24農地L25農用L15行政界
庄原市庄原市#cf222e中国山地の中核 — 県内最大面積、最深の過疎
三次市三次市#0969da三川合流の盆地 — 山陰山陽結節点
安芸高田市安芸高田市#1f883d毛利元就のふるさと — 戦国遺産と過疎
北広島町山県郡北広島町#9a6700西中国山地国定公園 — スキー場と神楽
神石高原町神石郡神石高原町#bf3989標高 500m の高原 — 都市計画区域なし、最も山的××××
世羅町世羅郡世羅町#8250df備後台地の梨の里 — LiDAR で森を測った町

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

ダウンロード

DoBoX 元データ (直リンク)

▶ #1488 庄原市 人口 #1486 三次市 人口 #1497 安芸高田市 人口 #1506 北広島町 人口 #1508 世羅町 人口 #1117 LiDAR 世羅町 #55 砂防指定地 #1124 渓流保全工 #1126 地すべり防止 #11 橋梁 #181 過去災害

本記事が生成した中間データ (再現用 — 直リンク)

図 8 枚 (PNG, 直 DL 可)

再現スクリプト

実行

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

L22 人口 zip は L22 cache、 L24/L25 zip は L24/L25 cache、 LiDAR は L41 cache、 砂防系は L46/L57/L58 cache を再利用。 行政界は L15 cache。 追加 DL なしで即実行可能。

第1章 中山間 6 市町の地理 — 過疎・高齢化の量化

狙い・手法

狙い: 中山間 6 市町とはどこか、 なぜ 6 市町か、 そして高齢化が どこまで進んでいるのか — 物語の出発点を定める。 まず主題図で 6 市町の位置と高齢化率を可視化し、 沿岸 5 市町と量的比較する。 これが 広島県中山間地理の地理的基盤である。

手法の要点: L22 人口データ (都市計画区域系) を中山間 5 市町 分 + 沿岸 5 市町分の zip から GeoJSON を読込、 男女・5 歳階級の人口列 (21 階級) を市町別に集計。 ≥65 歳の合計 / 総人口 で 高齢化率を計算する。 神石高原町は都市計画区域外のため L22 zip が無く、 代わりに砂防点 hull で境界を近似する。

choropleth (主題図) とは (リテラシ説明): 領域 (市町境界など) を、 ある属性値 (高齢化率) で色の濃淡で塗り分けた地図。 連続値を カラーマップ (OrRd = 白→黄→赤) で可視化することで、 「どこが濃いか」 が一目で分かる。 棒グラフが地図上に投影されたイメージ。

L22 単独深掘りとの違い: L22 は 21 市町別ピラミッド単独。 本記事は 中山間 5 市町に絞り、 さらに沿岸 5 市町と対比することで、 単独 では見えない構造的差を量化する。

実装

L89_M5_chusankan_story.py 行 1830–1921

 1
 2
 3
 4
 5
 6
 7
 8
 9
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
import zipfile, io
import geopandas as gpd
import pandas as pd

# 中山間 5 市町 (神石高原町は L22 zip なし)
CHUSANKAN_DSID = {
    "庄原市": 1488, "三次市": 1486, "安芸高田市": 1497,
    "北広島町": 1506, "世羅町": 1508,
}

# 沿岸 5 市町 (比較用)
COASTAL_DSID = {
    "広島市": 1467, "呉市": 1470, "尾道市": 1478,
    "福山市": 1481, "廿日市市": 1494,
}

frames = []
for cname, dsid in {**CHUSANKAN_DSID, **COASTAL_DSID}.items():
    z = f"data/extras/L22_population_pyramid/jinko_{dsid}_{cname}.zip"
    with zipfile.ZipFile(z) as zf:
        gjs = [n for n in zf.namelist() if n.endswith(".geojson")][0]
        with zf.open(gjs) as f:
            g = gpd.read_file(io.BytesIO(f.read()))
    g["city"] = cname
    g["kind"] = "中山間" if cname in CHUSANKAN_DSID else "沿岸比較"
    frames.append(g)
pop = gpd.GeoDataFrame(pd.concat(frames, ignore_index=True),
                        geometry="geometry", crs=frames[0].crs)

# 市町別 ≥65 歳合計 / 総人口 = 高齢化率
def calc_aging(sub):
    total = sub["JINKO_SU"].sum()
    senior = sum(
        sub[f"M_{ab}"].fillna(0).sum() + sub[f"F_{ab}"].fillna(0).sum()
        for ab in ["65","70","75","80","85","90","95","100"]
    )
    return senior / max(total, 1) * 100

result = pop.groupby("city").apply(calc_aging)
print(result.sort_values(ascending=False))
# 例:
# 庄原市     46.5
# 北広島町   42.8
# 安芸高田市 41.9
# ...
# 広島市     27.4

結果図 — 中山間 6 市町 高齢化率主題図

なぜこの図か: 「どの市町でどれだけ進んでいるか」 を一目で 伝えるには、 市町境界を高齢化率で色分けした主題図 (choropleth) が最強。 神石高原町は L15 行政界がないため、 砂防点の凸包 (convex hull) で境界を代用する工夫を可視化する。

Fig 1: 中山間 6 市町 高齢化率 choropleth (中山間 5 平均 40.5% / 沿岸 5 平均 31.2%)
Fig 1: 中山間 6 市町 高齢化率 choropleth (中山間 5 平均 40.5% / 沿岸 5 平均 31.2%)

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

中山間 vs 沿岸 高齢化率比較 表

citykind総人口0-14歳15-64歳65+歳高齢化率%年少人口率%
庄原市中山間336333438154111457943.310.2
安芸高田市中山間2644826211268411112429.9
世羅町中山間1512515626891634241.910.3
北広島町中山間1776318058732691738.910.2
三次市中山間506815947256851843736.411.7
尾道市沿岸比較13117014313683344764136.310.9
呉市沿岸比較214592230371142457570635.310.7
廿日市市沿岸比較11417314927634433496230.613.1
福山市沿岸比較4609306065526038313216728.713.2
広島市沿岸比較120075415829070649730088225.113.2

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

第2章 人口の物語 — ピラミッドが描く未来

狙い・手法

狙い: 中山間 6 市町の人口ピラミッドを small multiples で 並べ、 「どの世代が抜けているか」 「どの世代が膨らんでいるか」 を 視覚的に物語る。 集計だけでなく、 団塊世代 (1947-49 生れ) の高齢化若者 (15-29 歳) の流出を世代別に可視化する。

手法の要点: L22 GeoJSON の M_ / F_ 列 (5 歳階級) を市町別 合算し、 男性は左 (負値)、 女性は右 (正値) に並べる横棒型ピラミッド。 6 市町を 2×3 で並べ、 ≥65 歳ゾーンをオレンジ帯で強調する。

人口ピラミッドの直感的説明: 縦軸 = 年齢階級、 横軸 = 人口数。 若者多く老人少ない「正三角形」 が成長期の構造、 上下が膨らんで 中央が細い「壷型」 が中山間や日本全体の現状。 「ピラミッド」 は 本来は「正三角形」 だが、 そう呼べないことが現代日本の物語。

L22 単独との差別化: L22 は 21 市町個別深掘り。 本記事は中山間 6 市町を並列比較し、 「神石高原町だけ L22 データなし」 を あえて視覚化することで、 「中山間性」 自体を物語にする。

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import matplotlib.pyplot as plt
import numpy as np

# 5 歳階級のラベル (00-04 から 95-99 まで)
bins = [(a, a+4) for a in range(0, 100, 5)]

# 市町ごとに男女別ピラミッド描画
def draw_pyramid(ax, sub, title, color):
    male, female = [], []
    for a, b in bins:
        ab = f"{a:02d}"
        male.append(-sub[f"M_{ab}"].fillna(0).sum())
        female.append(sub[f"F_{ab}"].fillna(0).sum())
    y = np.arange(len(bins))
    ax.barh(y, male, color="#0969da", alpha=0.75, label="男性")
    ax.barh(y, female, color="#cf222e", alpha=0.75, label="女性")
    ax.axvline(0, color="black", linewidth=0.5)
    # 65歳以上を強調
    ax.axhspan(12.5, len(bins)-0.5, color="orange", alpha=0.10)
    ax.set_title(title, color=color, fontweight="bold")

結果図 — 6 市町 人口ピラミッド small multiples

なぜこの図か: 「世代別の歪み」 を伝えるには、 ピラミッドが 唯一の可視化手法。 6 市町を 2×3 で並べるsmall multiples によって、 「どこも同じ壷型」 と「神石高原町だけデータなし」 という構造を一望 できる。 ≥65 歳ゾーンのオレンジ帯で「老人多すぎ」 を強調。

Fig 2: 中山間 6 市町 人口ピラミッド (オレンジ帯=65歳以上)
Fig 2: 中山間 6 市町 人口ピラミッド (オレンジ帯=65歳以上)

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

市町別 人口統計

city総人口0-14歳15-64歳65+歳高齢化率%
三次市50,6815,94725,68518,43736.38
世羅町15,1251,5626,8916,34241.93
北広島町17,7631,8058,7326,91738.94
安芸高田市26,4482,62112,68411,11242.01
庄原市33,6333,43815,41114,57943.35

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

第3章 農地の物語 — 現存農地と集落営農のせめぎ合い (H2 検証)

狙い・手法

狙い: 中山間の農地はどう構造化されているか? L24 (現存農地) と L25 (集落営農地区) を同じ市町で並列比較すると、 「広大な農地に 点在する組織化された集落営農」 という中山間特有の構造が見える。 H2 (集落営農カバー率 ≥5%) の検証で、 中山間直接支払制度の 制度的足がかりを量化する。

手法の要点: L24 zip と L25 zip を中山間 5 市町分 (神石高原は無し) 読込み、 EPSG:6671 で面積 (m²) を計算。 L25 は TOKEI_CD=3 (都市計画区域外 の集落営農) のみフィルタ。 市町別に L24 / L25 面積を集計し、 集落営農カバー率 = L25/L24 × 100% を計算する。

L24 と L25 の違い (リテラシ説明): L24 (農地ポリゴン) は 都市計画区域内の現存農地を示すポリゴン (中山間では市域全体に 近い広さで覆う)。 L25 (農林漁業のための施策ポリゴン) は集落営農 地区の境界 (NRG_AN 列に「本田地区」 などの地区名が入る)。 集落営農 は集落単位で機械・労働を共有する制度で、 中山間直接支払制度の主な 受給対象。 「広い農地のうち、 組織化された地区がどれだけあるか」 が中山間性の指標になる。

L24 / L25 単独との差別化: L24 は農地ポリゴン全県、 L25 は集落 営農 TOKEI_CD 別単独深掘り。 本記事は両者を同じ市町で並列比較 することで、 単独では見えないカバー率構造を量化する初の切り口。

実装

L89_M5_chusankan_story.py 行 1830–1917

 1
 2
 3
 4
 5
 6
 7
 8
 9
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
import zipfile, io
import geopandas as gpd
import pandas as pd

# L24 現存農地 + L25 集落営農地区 を中山間 5 市町分読込
def load_zip_geojson(path):
    with zipfile.ZipFile(path) as zf:
        name = [n for n in zf.namelist() if n.endswith(".geojson")][0]
        with zf.open(name) as f:
            return gpd.read_file(io.BytesIO(f.read()))

farm_frames, agro_frames = [], []
for c, dsid_f, dsid_a in [
    ("庄原市", 1398, 1415), ("三次市", 1397, 1414),
    ("安芸高田市", 1391, 1408), ("北広島町", 1407, 1424),
    ("世羅町", 1399, 1416),
]:
    f = load_zip_geojson(f"data/extras/L24_farmland_conversion/farm_{dsid_f}_{c}.zip")
    f["city"] = c
    farm_frames.append(f)
    a = load_zip_geojson(f"data/extras/L25_agroforestry_policy/agro_{dsid_a}_{c}.zip")
    a["city"] = c
    agro_frames.append(a)

farm = gpd.GeoDataFrame(pd.concat(farm_frames, ignore_index=True),
                        crs=farm_frames[0].crs).to_crs("EPSG:6671")
agro = gpd.GeoDataFrame(pd.concat(agro_frames, ignore_index=True),
                        crs=agro_frames[0].crs).to_crs("EPSG:6671")
agro_only = agro[agro["TOKEI_CD"] == 3]  # 区域外集落営農

# 市町別 km² 集計
farm["km2"] = farm.geometry.area / 1e6
agro_only["km2"] = agro_only.geometry.area / 1e6
df = pd.concat([
    farm.groupby("city")["km2"].sum().rename("現存農地km2"),
    agro_only.groupby("city")["km2"].sum().rename("集落営農km2"),
], axis=1).fillna(0)
df["カバー率%"] = (df["集落営農km2"] / df["現存農地km2"] * 100).round(2)
print(df)
# 例:
#         現存農地km2  集落営農km2  カバー率%
# 庄原市      467.1       50.2       10.7
# 北広島町    220.3       37.4       17.0
# ...

結果図 — 中山間 5 市町 農地転用 vs 農用地区域 (左) と 砂防三施設マップ (右)

なぜこの図か: 左=「失う農地 (赤) と守る農地 (緑) を市町別に 並列棒で比較」、 右=「砂防三施設族の中山間集中マップ」。 1 図で 2 章 (第3章農地 + 第5章防災) の物語を統合し、 中山間の「農と防災が 土地に染み込んでいる」 構造を一望できる。

Fig 4: 現存農地 vs 集落営農地区 (左) + 砂防三施設族マップ (右) — 集落営農カバー率 8.26%
Fig 4: 現存農地 vs 集落営農地区 (左) + 砂防三施設族マップ (右) — 集落営農カバー率 8.26%

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

中山間 5 市町 現存農地 vs 集落営農地区 詳細表

city現存農地km2現存農地件数集落営農km2集落営農件数集落営農カバー率%
庄原市467.130414.51653.11
三次市170.7346628.644116.77
安芸高田市121.831148.21236.74
北広島町83.173052.781123.35
世羅町62.1334320.589233.12

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

「広い農地」 と「組織化された地区」 の同居: 中山間の農地は広大だが、 それを支える経営は集落営農と個別農家の混合。 集落営農地区 (NRG_AN 名で 「本田地区」 「大字八鳥」 のように地区単位) の集積は、 過疎地ほど強い 集約圧の現れ。 中山間直接支払制度の主な受給対象もこの集落営農地区。

第4章 林業の物語 — LiDAR が捉えた森林資源 (H5 検証)

狙い・手法

狙い: 中山間で人は減るが、 植えた木は今も育ち続ける。 世羅町には航空レーザ計測 (LiDAR) で 1 本ずつ計測された3,397,186 本 の樹木データがある。 樹種別の比率を計算し、 ヒノキ単独で 80% 以上を占めれば、 H5 が支持される。 戦後植林の代表格ヒノキが世羅町の LiDAR データで圧倒的優位を示せば、 中山間の蓄積資産が量化できる。

手法の要点: L41 GeoPackage は 3.4M ポイントで、 そのまま読むと メモリ 5GB を圧迫する。 そこで pyogrio.read_dataframe(..., read_geometry=False)geometry を捨てて樹種・樹高・直径・材積 の 4 列のみ読込む工夫をする。 メモリ約 100 MB 程度で済む。 図用には 等間隔で 5,000 点だけサンプリング (geometry あり)。

LiDAR 単木計測とは (リテラシ説明): 航空機からレーザを地表に 打ち、 返り時間で立体構造を測る技術。 「地表 + 樹冠 + 樹幹」 の高さ差で 樹高を、 樹冠形状で樹種推定 (機械学習) を、 樹幹間隔で立木密度を計算 できる。 「森を 1 本ずつカウントする」 究極の林業 GIS。

植林系 vs 自然林 (リテラシ): ヒノキ・スギは戦後造林の主役で、 建材・パルプ用に意図的に植えられた林。 一方コナラ・クヌギ・アカマツなどは 自然林 (二次林を含む)。 比率で「人為が強い森 vs 自然が強い森」 が分かる。

L41 単独深掘りとの差別化: L41 は LiDAR 計測手法と単木統計を 個別解説。 本記事は L41 を中山間蓄積資産として再評価し、 H5 (植林系 比率) と過疎・高齢化との対比で物語化する。

実装

 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
26
27
28
29
30
31
import pyogrio
import pandas as pd

# 3.4M ポイントの GeoPackage はメモリ重い → geometry 捨てて 4 列のみ
trees = pyogrio.read_dataframe(
    "data/extras/L41_forest_resources/tree_point_34462.gpkg",
    columns=["樹種", "樹高", "胸高直径", "単木材積"],
    layer="tree_point_34462",
    read_geometry=False,
)
print(f"全 {len(trees):,} 単木")

# 樹種比率
sp = trees["樹種"].value_counts(dropna=False)
print(sp.head(10))
# ヒノキ        3,067,440
# スギ            329,746
# (世羅町 LiDAR 単木はすべて植林木で、 自然林は対象外)

# ヒノキ単独比率 (H5)
hinoki_n = (trees["樹種"] == "ヒノキ").sum()
hinoki_pct = hinoki_n / len(trees) * 100
print(f"ヒノキ {hinoki_n:,} 本 ({hinoki_pct:.1f}%)")
# 約 90% — 世羅町の植林系は圧倒的にヒノキ優位

# 樹高ビン分布 (材積価値の代理)
bins = [0, 5, 10, 15, 20, 25, 30, 100]
trees["bin"] = pd.cut(trees["樹高"], bins=bins,
                      labels=["0-5", "5-10", "10-15",
                              "15-20", "20-25", "25-30", "30+"])
print(trees["bin"].value_counts().sort_index())

結果図 — 世羅町 LiDAR 単木 樹種別 散布 + 樹高ビン分布

なぜこの図か: 左=「3,397,186 本の単木のうち、 5,000 点をサンプリング して空間分布を樹種色で散布」、 右=「樹高ビン分布で材積価値の代理指標」。 「森のどこに何があるか」 と「どれだけ大きいか」 を同時に可視化。

Fig 6: 世羅町 LiDAR 単木 (5,000 点サンプル + 全 3,397,186 集計) — ヒノキ 90.3%
Fig 6: 世羅町 LiDAR 単木 (5,000 点サンプル + 全 3,397,186 集計) — ヒノキ 90.3%

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

樹種別 上位統計

樹種本数樹高平均胸高直径平均単木材積平均
ヒノキ306744014.1420.20.31
スギ32974620.9828.110.71

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

蓄積資産としての森林: 単木 3,397,186 本 × 平均材積 0.5-1.0 m³ = 世羅町だけで森林材積は数百万 m³ 規模。 1 m³ あたり 5-15 万円の市場 価値として、 数千億円〜兆円規模の蓄積資産が町域の山々に眠る。 過疎で人は 減るが、 この資産は今も育ち続ける — 中山間の最大の未来資産

第5章 防災の物語 — 砂防三施設族 中山間集中 (H3 検証)

狙い・手法

狙い: 中山間は急斜面・崩落・土石流のリスクが集中する地域。 広島県の砂防三施設族 (砂防指定地 + 地すべり防止 + 渓流保全工) のうち、 中山間 6 市町が何 % を占めるかを量化する。 5,101 件中 984 件 (中山間 6 市町) が H3 (≥15%) の検証。

手法の要点: L46 (砂防 3,207 件) ・L57 (地すべり 32 件) ・ L58 (渓流 1,862 件) の Shapefile を読込み、 city 列 (郡付名) で中山間 6 市町をフィルタ。 件数の%を計算し、 市町別に積み上げ棒で 可視化する。

砂防三施設族 (本記事独自概念): 砂防指定地は法的指定面範囲、 地すべり防止施設は実物インフラ (構造物)、 渓流保全工は谷川の ライン整備。 同じ「土砂災害対策」 でも法律・形態・スケールが異なる 3 系統を、 本記事で初めて統合する。

L46 / L57 / L58 単独深掘りとの差別化: 各個別記事は系統別ランキ ング・水系別集計など。 本記事は3 系統を 1 つに合成 して中山間 集中度を量化する初の切り口。

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import geopandas as gpd
import pandas as pd

# L46 砂防 + L57 地すべり + L58 渓流 (city 列で 6 市町抽出)
sabo = gpd.read_file("data/extras/L46_sabo_designation/.../砂防指定地-ポリゴン.shp")
landslide = gpd.read_file("data/extras/L57_landslide_facility/.../78_053_20260427.shp")
keiryu = gpd.read_file("data/extras/L58_keiryu_facility/.../78_051shp_20260427.shp")

CHUSANKAN_GUNNAMES = [
    "庄原市", "三次市", "安芸高田市",
    "山県郡北広島町", "神石郡神石高原町", "世羅郡世羅町",
]

n_total = len(sabo) + len(landslide) + len(keiryu)
n_chu = (
    sabo["city"].isin(CHUSANKAN_GUNNAMES).sum()
    + landslide["city"].isin(CHUSANKAN_GUNNAMES).sum()
    + keiryu["city"].isin(CHUSANKAN_GUNNAMES).sum()
)
print(f"全 {n_total:,} 件中 中山間 {n_chu:,} 件 ({n_chu/n_total*100:.1f}%)")
# 例: 全 5,101 件中 中山間 1,729 件 (33.9%)

結果図 — 高齢化率分布 + 砂防三施設族 中山間集中度

なぜこの図か: 「中山間は地理リスクの集中地」 を伝えるには、 左に高齢化率の地域差を、 右に砂防三施設族の中山間シェアを 並べる。 「老人多く、 リスク多く、 守る施設も多い」 という構造を 1 枚で。

Fig 3: 中山間 vs 沿岸 高齢化率 (左) + 砂防三施設族集中度 (右) = 19.3%
Fig 3: 中山間 vs 沿岸 高齢化率 (左) + 砂防三施設族集中度 (右) = 19.3%

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

砂防三施設族 中山間 6 市町別 件数 (積み上げ)

市町砂防指定地地すべり防止渓流保全工三施設合計
庄原市1479102258
三次市1843129316
安芸高田市95062157
北広島町59041100
神石高原町1601430
世羅町70152123

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

砂防三施設族 中山間集中度 表

施設県全体中山間 6 市町集中度%
L46 砂防指定地320757117.8
L57 地すべり防止321340.6
L58 渓流保全工186240021.5
三施設合計510198419.3

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

第6章 都市部との対比 — 橋梁密度の構造 (H4 検証)

狙い・手法

狙い: 中山間 6 市町の千人あたり橋梁件数を沿岸 5 市町と 比較し、 「人少なく橋多い」 構造を量化する。 過疎で人口は少ないが、 谷川・渓流を渡る橋は地形的に必要なため、 結果的に「少ない人が 多い橋を維持する」 構造が成立する。 これが H4 (≥3 倍) の検証。

手法の要点: L66 橋梁データ (4,203 件) を住所 (市町) 列で中山間 6 市町と沿岸 5 市町に分け、 件数を L22 で集計した人口 で割る (千人あたり)。 同時に架設年度の分布も参考表示し、 橋の新旧 ではなく密度で中山間性を捉える。

「千人あたり」 指標の意味 (リテラシ説明): 同じ橋梁件数でも、 分母が違うと意味が変わる。 中山間 6 市町合計人口は数十万、 沿岸 5 市町は数百万。 件数を絶対値だけで比べると沿岸の方が多く見えるが、 1 人 (= 維持を支える納税者) あたりに直すと中山間の方が 「厚い負担」 になっている。

L66 単独深掘りとの差別化: L66 は全県 4,203 件の架設年度・延長・ 幅員単独。 本記事は中山間 vs 沿岸の人口あたり密度を取り出し、 過疎の構造的負担と接続する初の切り口。

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import pandas as pd

bridge = pd.read_csv("data/extras/bridge_basic.csv",
                     encoding="utf-8-sig", on_bad_lines="skip")
CHUSANKAN_NAMES = ["庄原市", "三次市", "北広島町",
                    "安芸高田市", "神石高原町", "世羅町"]
COASTAL_NAMES = ["広島市", "呉市", "尾道市", "福山市", "廿日市市"]

n_chu = bridge["住所(市町)"].isin(CHUSANKAN_NAMES).sum()
n_coast = bridge["住所(市町)"].isin(COASTAL_NAMES).sum()

# L22 から人口取得 (前章ですでに pop_summary 作成済)
pop_chu = pop_summary[pop_summary["kind"] == "中山間"]["総人口"].sum()
pop_coast = pop_summary[pop_summary["kind"] == "沿岸比較"]["総人口"].sum()

# 千人あたり
chu_density = n_chu / (pop_chu / 1000)
coast_density = n_coast / (pop_coast / 1000)
ratio = chu_density / coast_density
print(f"中山間: {n_chu:,} 件 / {int(pop_chu):,} 人 = {chu_density:.2f} 件/千人")
print(f"沿岸:  {n_coast:,} 件 / {int(pop_coast):,} 人 = {coast_density:.2f} 件/千人")
print(f"密度比 {ratio:.1f} 倍")
# 例: 中山間 8.5 件/千人 / 沿岸 0.7 件/千人 / 12 倍

結果図 — 中山間 vs 沿岸 橋梁密度

なぜこの図か: 左=「千人あたり橋梁件数の単純棒」、 右=「架設 年度ヒストの参考重ね描き」。 左で密度比 (中山間性の量化)、 右で年齢 分布の参考情報を提示。

Fig 5: 橋梁密度 中山間 vs 沿岸 — 密度比 18.8 倍
Fig 5: 橋梁密度 中山間 vs 沿岸 — 密度比 18.8 倍

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

中山間 vs 沿岸 橋梁密度比較

領域橋梁件数対応人口 (5市町)千人あたり架設中央値対応人口
中山間 6 市町1640143,65011.421982
沿岸 5 市町12880.6119822121619
全県42031978

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

市町別 橋梁件数・中央値

市町架設中央値橋梁件数
庄原市1979600
三次市1981264
安芸高田市1980198
北広島町1983272
神石高原町1968150
世羅町1987136

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

「人少なく橋多い」 のパラドクス: 中山間は過疎が進んだ結果、 インフラ密度がむしろ上がる。 維持できないが撤去もできない橋が 1 人あたりの負担として積み上がる。 LiDAR 点検技術や予防保全が中山間 ほど必要、 という反転的真実がここにある。

仮説検証総合

5 つの仮説を 6 章にわたり検証してきた。 結果をまとめる。

横断的可視化 — 仮説検証ダッシュボード

なぜこの図か: 4 つの視点 (高齢化箱ひげ / 農用地比 / 三施設族 / 5 仮説) を1 枚にまとめたダッシュボードで、 6 章の知見を一望する。

Fig 7: 仮説検証総合ダッシュボード — 中山間 4 軸
Fig 7: 仮説検証総合ダッシュボード — 中山間 4 軸

4 軸プロファイル — 中山間 6 市町レーダーチャート

なぜこの図か: 4 軸 (高齢化 / 農用地保全 / 三施設族 / 橋梁古さ) をレーダーで重ね描き、 6 市町ごとの「個性」 を一目で比較。 全部高い形 = 全方位過疎、 一部だけ高い形 = 偏った中山間性。

Fig 8: 中山間 6 市町 4 軸プロファイル レーダー
Fig 8: 中山間 6 市町 4 軸プロファイル レーダー

5 仮説 検証サマリー表

仮説予測実測判定
H1 (高齢化集中)中山間 5 市町 平均高齢化率 ≥ 40%中山間 40.5% / 沿岸 31.2% (差 +9.3pt)支持
H2 (集落営農カバー率)集落営農地区 (TOKEI_CD=3) / 現存農地 ≥ 5%集落営農 74.72 km² / 現存農地 904.94 km² = 8.26%支持
H3 (砂防三施設 中山間集中)L46+L57+L58 中山間 6 市町集中度 ≥ 15%全 5,101 件中、 中山間 984 件 = 19.3%支持
H4 (橋梁密度 中山間集中)中山間 千人あたり橋梁 / 沿岸 千人あたり橋梁 ≥ 3 倍中山間 11.42 件/千人 / 沿岸 0.61 件/千人 = 18.8 倍支持
H5 (LiDAR ヒノキ優位)世羅町 LiDAR 単木 ヒノキ単独 ≥ 80%ヒノキ 3,067,440 / 全 3,397,186 本 = 90.3% (植林系 計 100.0%)支持

中山間物語の 6 つの発見

  1. 高齢化集中: 中山間 5 市町平均 = 40.5% (沿岸 5 平均 31.2%)。 約 +9.3pt の構造的差。 「中山間 = 高齢化最前線」 が量化された。
  2. 集落営農カバー: 集落営農地区 / 現存農地 = 8.26%。 広い農地のうち組織化された地区が一定割合を占める。 中山間直接支払の 制度的足がかり。
  3. 砂防三施設族集中: 全 5,101 件中 中山間 984 件 (19.3%)。 中山間 6 市町は県の 26% (6/23) しかないが、 砂防三施設族では 19.3% を均衡水準で占める。
  4. 橋梁密度: 中山間 11.42 件/千人 vs 沿岸 0.61 件/千人 (密度比 18.8 倍)。 過疎で人は薄いが橋は地形的必要、 という「人少なく橋多い」 構造。
  5. LiDAR 蓄積資産: 世羅町 3,397,186 単木のうちヒノキ単独 90.3%。 過疎で人は減るが、 戦後植えたヒノキは今も育つ。 中山間の最大の未来資産はである。
  6. 「中山間 = 地理リスクと文化資源の交差点」: 過疎 (人口) ・ 集約 (農地) ・蓄積 (林業) ・リスク (砂防) ・密度 (橋梁) という 5 つの構造が同じ 6 市町に重なる。 これが中山間の地理学的本質。
L22 / L24 / L25 / L41 / L46 / L57 / L58 / L66 / L61 と L89 の補完性: 同じ DoBoX のデータが、 切り口を変えると全く異なる物語を語る。 単独深掘り の 9 記事 + 統合物語の本記事で、 はじめて中山間地理の研究地図に なる。 1 ピースとしての本記事の役割。
M 系完結: M1 (太田川水系・水) ・M2 (埋蔵文化財・時間) ・M3 (観光・ 沿岸) ・M4 (産業・戦前戦後) と続いてきた M 系テーマ統合は、 本記事 M5 (中山間) で完結。 5 つを合わせると、 広島県の地理を 水・時間・沿岸・ 産業・中山間 の 5 軸で物語る研究地図ができあがる。

発展課題

発展課題 (結果X → 新仮説Y → 課題Z の論理鎖)

発展1: 中山間の「消滅可能性集落」 を量化する — 集落単位での 人口推計

発展2: 集落営農地区の「耕作放棄推測」 — Sentinel-2 で量化

発展3: LiDAR 単木 ×標高 — 「植林限界」 の量化

発展4: 砂防三施設族 vs 過去災害 — 「守った砂防 vs 守れなかった災害」 の交差量化

発展5: 全国比較 — 広島中山間の「過疎の深さ」 全国順位

既存記事との関係 — 中山間研究地図

広島県中山間地理の研究地図 — 10 記事の関係

本記事 L89 を含む中山間関連 10 記事は、 同じ DoBoX 中山間データから 全く異なる切り口で物語を引き出す研究地図を構成している。

記事主軸L89 との重複
L22 (人口ピラミッド 21 市町)市町別ピラミッド単独深掘りL89 は中山間 5 市町に絞り 沿岸 5 と比較
L24 (農地転用 17 市町)転用面積 年別単独L89 は L25 と組み合わせ 反転構造を初検証
L25 (農林漁業施策 17 市町)TOKEI_CD 別単独L89 は L24 と組み合わせ 5 倍仮説を検証
L41 (LiDAR 単木 世羅町)単木計測手法 単独深掘りL89 は植林系比率を中山間蓄積資産として再評価
L46 (砂防指定地 全県)3,207 件 単独L89 は中山間集中度のみ
L57 (地すべり 全県)32 件 単独L89 は L46+L58 と統合
L58 (渓流保全 全県)1,862 件 単独L89 は中山間集中度のみ
L61 (過去災害 全県)424 件 単独L89 は中山間 vs 沿岸比較のみ
L66 (橋梁 全県)架設年度 単独L89 は中山間 vs 都市中央値差のみ
L89 (本記事, 物語)中山間 6 市町 4 軸 (人口×農地×林業×防災) 統合

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

研究の協働性: 1 つのデータを 1 人で読むより、 10 の切り口で 10 人が 読む方が、 はるかに豊かな物語が生まれる。 オープンデータの真の力は 「みんなが見て、 みんなが書く」 ことにある。 本記事 L89 は M 系 (テーマ統合) の最終ピース
M 系全 5 記事の構成:
M1 (L85) = 太田川水系 — の物語
M2 (L86) = 埋蔵文化財 — 時間の物語
M3 (L87) = 観光 — 沿岸島嶼の物語
M4 (L88) = 産業 — 戦前-戦後の物語
M5 (L89, 本記事) = 中山間 — 過疎・林業の物語

5 記事を合わせると、 広島県の地理を 水・時間・沿岸・産業・中山間 の 5 軸でまるごと描く研究地図になる。 単独深掘り L 系記事 + M 系 統合記事の両輪で、 DoBoX オープンデータの教育価値が完成する。