Lesson 21

L21 宅地開発状況 20 件 統合分析 — 広島県の宅地開発事業 1,038 件 の時空間構造

都市計画宅地開発事業期間GISgeopandassjoin用途地域datetime正規化スキーマ分岐可視化
所要 読了 30 分 / コード実行 1 分以内 / 想定レベル: 応用 / データ: DoBoX 宅地開発状況 20 件 (全市町、2016-2020)

データ取得手順

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

IDデータセット名
#222dataset #222
#444dataset #444
#888都市計画区域情報_区域データ_安芸高田市_行政区域
#1351都市計画区域情報_宅地開発状況_安芸高田市_2016-2020
#1352都市計画区域情報_宅地開発状況_海田町_2016-2020
#1353都市計画区域情報_宅地開発状況_熊野町_2016-2020
#1354都市計画区域情報_宅地開発状況_呉市_2016-2020
#1355都市計画区域情報_宅地開発状況_広島市_2016-2020
#1356都市計画区域情報_宅地開発状況_江田島市_2016-2020
#1357都市計画区域情報_宅地開発状況_坂町_2016-2020
#1358都市計画区域情報_宅地開発状況_三原市_2016-2020
#1359都市計画区域情報_宅地開発状況_三次市_2016-2020
#1360都市計画区域情報_宅地開発状況_庄原市_2016-2020
#1361都市計画区域情報_宅地開発状況_世羅町_2016-2020
#1362都市計画区域情報_宅地開発状況_大竹市_2016-2020
#1363都市計画区域情報_宅地開発状況_竹原市_2016-2020
#1364都市計画区域情報_宅地開発状況_東広島市_2016-2020
#1365都市計画区域情報_宅地開発状況_廿日市市_2016-2020
#1366都市計画区域情報_宅地開発状況_尾道市_2016-2020
#1367都市計画区域情報_宅地開発状況_府中市_2016-2020
#1368都市計画区域情報_宅地開発状況_府中町_2016-2020
#1369都市計画区域情報_宅地開発状況_福山市_2016-2020
#1370都市計画区域情報_宅地開発状況_北広島町_2016-2020

実行コマンド:

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

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

1. 学習目標と問い

本記事は、広島県インフラマネジメント基盤 DoBoX が公開する 「都市計画区域情報_宅地開発状況」シリーズ 20 件 (#1355, #1354, #1369, #1364, #1365, #1366, #1358, #1363, #1367, #1362, #1359, #1360, #1351, #1356, #1368, #1352, #1353, #1357, #1370, #1361) を縦結合し、2016-2020 年に広島県内 20 市町で実施された宅地開発事業 計 1038 件 の Point データから、事業の血流 ── 開発面積・事業期間・用途/種別・地理分布・年次推移 ── を分析する研究記事である。宅地開発状況は「これから新しい街区が立つ場所」を示すデータであり、 L20 が見た新築動向 (= 結果) の前史として機能する。

研究の問い (RQ): 広島県内の宅地開発事業 1038 件 (2016-2020) は、 面積規模・事業期間・用途/種別・地理分布の観点でどのような時空間構造を持ち、 何年の事業期間を経てどんな地区が形成されているか?

仮説 H1〜H6

独自用語の定義 (本レッスン内のみ)

到達点

  1. 20 個の GeoJSON ZIP のうち 17 件 (Point) を主スキーマ として 1 個の GeoDataFrame (1027 行) に縦結合できる。
  2. 残り 3 件 (Polygon) の異種スキーマを識別し、 なぜ列構造が違うかをデータ構造から読み解ける
  3. datetime 型の市町間混在 (object/datetime64) を pd.to_datetime(errors="coerce") で正規化する実装パターンを身に付ける。
  4. 開発面積 KAIHATU_A が 4 桁オーダーのスパンで分布することを log スケールで観察する。
  5. 事業期間 (JIGYO_KE − JIGYO_KS) を計算し、「宅地開発は何ヶ月で終わるか」を定量する。
  6. 用途地域 (L17) との geopandas.sjoin「開発はどの用途地域に立地したか」を結合分析する。
  7. 大規模開発 (≥10ha) と都市計画区域 (KUIKI_CD) の関係を見て、 「大開発は市街化調整に集中するか」を検証する。
  8. 年別事業開始数の推移を観察し、2016-2020 のトレンドから人口減少社会のサインを読む。

本記事のスコープ宣言

本記事は宅地開発状況シリーズ 20 件のみを主データとする研究記事である。 L15 行政区域 21 件は市町別空間集計の境界として参照、 L17 用途地域 21 件は「開発がどの用途地域に立地したか」の sjoin 検証として参照するが、 L17 を主役にした合体記事ではない。 他のサブシリーズ (新築動向 L20・人口 L22 等) との合体は発展課題に留め、 本記事では行わない (要件 I 違反の水増し回避)。 ただしL20 (新築動向) との比較は H1 検証のため数行レベルで言及する。

2. 使用データ

宅地開発状況 20 件 はそれぞれ 1 市町分の GeoJSON を ZIP で配布している。 事前監査では「列構造は全 20 件で完全同一 (13 列)」と報告されていたが、 本研究の実データ取得で3 市町に重大な構造差異を発見した。 本記事はこの発見を正面から扱う (要件 K, データの落とし穴を学習者と共有)。

重要な構造発見 (監査時点では見えていなかった事実):
  • 17 市町 (PRIMARY) は Point + KAIHATU_A/JIGYO_KS/JIGYO_KE/JIGYO_YO/JIGYO_SIN宅地開発標準スキーマを持つ。これが本記事の主分析対象 (n=1027)。
  • 3 市町 (江田島市・三原市・竹原市) は Polygon/MultiPolygon + JIGYO_CD/JIGYO_D/JIGYO_N/KARI_D という異種スキーマ (ALT)を持つ。レコードは「公有水面埋立事業」「庁舎建設」 等で、宅地造成とは性質が違う事業 (n=11)。 DoBoX のシリーズ括りが運用上のものであり、データ性質と一致しないことを示す事例。
  • これは「同シリーズなら同列構造」という素朴な前提が破綻する実例。 実務ではサンプル抽出によるスキーマ確認だけでは不十分で、 全件取得後の dtype 一致確認が必須であることを学べる。

20 dataset_id 一覧

dataset_id市町市町タイプDoBoX 件数スキーマgeometry 型
#1355広島市政令市DoBoX140PRIMARYPoint
#1354呉市中核市DoBoX21PRIMARYPoint
#1369福山市中核市DoBoX496PRIMARYPoint
#1364東広島市施行時特例市DoBoX213PRIMARYPoint
#1365廿日市市DoBoX42PRIMARYPoint
#1366尾道市DoBoX67PRIMARYPoint
#1358三原市DoBoX6ALTMultiPolygon,Polygon
#1363竹原市DoBoX2ALTPolygon
#1367府中市DoBoX6PRIMARYPoint
#1362大竹市DoBoX1PRIMARYPoint
#1359三次市DoBoX3PRIMARYPoint
#1360庄原市DoBoX1PRIMARYPoint
#1351安芸高田市DoBoX2PRIMARYPoint
#1356江田島市DoBoX3ALTMultiPolygon
#1368府中町DoBoX3PRIMARYPoint
#1352海田町DoBoX8PRIMARYPoint
#1353熊野町DoBoX18PRIMARYPoint
#1357坂町DoBoX2PRIMARYPoint
#1370北広島町DoBoX3PRIMARYPoint
#1361世羅町DoBoX1PRIMARYPoint

主スキーマ PRIMARY の列の意味 (17 市町で同一)

列名意味と本記事での扱い
IDint32 各市町内連番。市町をまたがると重複しうる
TOKEI_CDint32 統計区分コード。参考列扱い
CITY_CDint32 市区町村コード。広島市は 8 区を 101-108 で分割
KUIKI_CDint32 都市計画区域コード (1=市街化, 3=市街化調整, 5=都計外 等と推定)。 本記事は H5 検証で用いる
ZU_NOint32 図郭番号。地理タイル ID。参考列扱い
KAIHATU_Aint32 開発面積 (m²)。本記事の主規模指標。 150 ~ 511,001 (51ha) のレンジ
JIGYO_KSdatetime64[ms] / object 事業開始日 (許可日と推定)広島市・廿日市市は dtype=object (文字列「2016/04/06」)、他は datetime。pd.to_datetime で正規化必須
JIGYO_KEdatetime64[ms] / object 事業終了日 (工事完了日と推定)。海田町・世羅町は dtype=object
JIGYO_YOint32 事業用途コード (1-6)。仕様書未公開、1 が支配的 (84.7%) のため「住宅用と推定」と本記事ラベル付け
JIGYO_SINint32 事業種別コード (1 or 2)。仕様書未公開、参考列扱い
BIKOUobject 備考自由文字列。本データでは全件 null (運用上未入力列の典型)
RITTEKI_CDint32 立地コード。仕様書未公開、参考扱い
geometryPoint 開発事業の代表点。EPSG:6671 (JGD2011 平面直角第III系)。 本記事の主役データ

異種スキーマ ALT (3 市町、参考)

江田島市・三原市・竹原市の 3 件は列名・型・geometry が異なる。 レコードは「江田島町小用公有水面埋立事業」「三原市庁舎本館建替」等の埋立・公共事業で、 他 17 市町の「住宅団地造成事業」と性質が違う。 本記事では分析対象外とし、セクション 12「異種スキーマの観察」で別途報告する。

調査期間と件数

L20 新築動向との対比: 新築動向 (L20) は 4.7 万棟、宅地開発 (本記事) は 1,038 件。 1 開発事業 ≅ 数〜数百棟の新築を生む。 新築動向は「結果」、宅地開発は「原因 (事業計画)」を映すデータ。 両者を組み合わせれば「計画 → 実建物」のフロー分析が成立する (発展課題)。

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

本記事の再現性を担保するため、HTML 1 枚から 生データ・中間 CSV・図 PNG・再現 Python を直リンクで取得できる。

(1) 生データ ZIP (DoBoX 直)

20 件の ZIP は前項の表からそれぞれ DoBoX へリンク。 あるいは一括取得スクリプト:

cd "2026 DoBoX 教材"
py -X utf8 data\extras\L21_housing_development\fetch_housing_development.py

(2) 中間 CSV (本スクリプトの出力)

(3) 図 PNG (本記事掲載 9 枚)

(4) 再現用 Python スクリプト

実行は cd "2026 DoBoX 教材"; py -X utf8 lessons\L21_housing_development.py。 20 ZIP がローカルにあれば 1 分以内で全図 + CSV 再生成 (要件 S 準拠)。

4. 分析1: 20 GeoJSON 統合 — スキーマ分岐 + datetime 正規化

狙い

20 個の ZIP を 1 個の GeoDataFrame に統合したいが、事前監査では見えていなかった構造差異が実データには存在する。本セクションは「読込前に列構造を確認し、PRIMARY/ALT を分岐する」という防御的プログラミングの実例を示す。また、PRIMARY 17 件の中でも JIGYO_KS が市町間で dtype 不一致 という落とし穴があり、これも pd.to_datetime(errors='coerce') で吸収する。

手法

直感: ZIP を読む → 列名を見てPRIMARY か ALT かを判定 → PRIMARY だけを統合 GeoDataFrame に積む → datetime 正規化 → CRS 変換。ALT は別 GeoDataFrame に保管して観察用に温存。

大筋 (5 ステップ)

  1. 20 市町について load_geojson_zip() で GeoDataFrame を読む
  2. 各 GDF の列に KAIHATU_AJIGYO_KS があるかで PRIMARY 判定
  3. PRIMARY なら safe_to_datetime()JIGYO_KS / JIGYO_KE を正規化、src_city / src_dsid / ctype を付与
  4. PRIMARY フレーム達を pd.concat で縦結合 → 1027 行 1 個の GeoDataFrame
  5. to_crs(EPSG:6671) で広島県平面直角座標系に投影変換 (m 単位確保)

前提と限界: PRIMARY 判定の基準を 'KAIHATU_A & JIGYO_KS 両方持つ' とした。もし将来 DoBoX 側でデータ仕様が変更されれば、この判定も追従修正が必要。errors='coerce'解釈不能な文字列を黙って NaT にするので、「何件 NaT になったか」を必ずログ出力するべき (本スクリプトは行う)。

実装

 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
DATA_DIR = ROOT / "data" / "extras" / "L21_housing_development"
TARGET_CRS = "EPSG:6671"  # JGD2011 平面直角第III系 (広島県, m)

# (dataset_id, 市町名, 行政_dsid, 用途地域_dsid, 都市タイプ) — 20 件
CITY_DEFS = [
    (1355, "広島市",     786, 794, "政令市"),
    (1354, "呉市",       797, 804, "中核市"),
    (1369, "福山市",     832, 837, "中核市"),
    (1364, "東広島市",   868, 875, "施行時特例市"),
    # ... 計 20 行
]

# 主スキーマ判定: KAIHATU_A と JIGYO_KS を持つ ZIP を PRIMARY とする
PRIMARY_COLS = {"KAIHATU_A", "JIGYO_KS"}

def safe_to_datetime(s):
    """object/datetime 混在を許容して datetime に正規化。
    解釈不能な文字列は NaT になる。"""
    if pd.api.types.is_datetime64_any_dtype(s):
        return s
    return pd.to_datetime(s, errors="coerce")

primary_frames = []  # 17 市町 (Point + KAIHATU_A 系)
alt_frames = []      # 3 市町 (Polygon + JIGYO_N 系)
for dsid, name, _adm, _yz, ctype in CITY_DEFS:
    z = DATA_DIR / f"takuchi_{dsid}_{name}.zip"
    g = load_geojson_zip(z)
    cols = set(g.columns)
    is_primary = "KAIHATU_A" in cols and "JIGYO_KS" in cols
    if is_primary:
        # 重要: 広島市・廿日市市・海田町・世羅町は object 混在のため正規化必須
        g["JIGYO_KS"] = safe_to_datetime(g["JIGYO_KS"])
        g["JIGYO_KE"] = safe_to_datetime(g["JIGYO_KE"])
        g["src_city"] = name
        primary_frames.append(g)
    else:
        g["src_city"] = name
        alt_frames.append(g)

# PRIMARY 17 件を統合 (Point + 13 列)
hd_pts = gpd.GeoDataFrame(pd.concat(primary_frames, ignore_index=True),
                            geometry="geometry", crs=primary_frames[0].crs)
hd_pts = hd_pts.to_crs(TARGET_CRS)
N_PRIMARY = len(hd_pts)  # 1,029 件

# ALT 3 件は別 GDF (Polygon、列構造異なる、観察用)
alt_concat = gpd.GeoDataFrame(pd.concat(alt_frames, ignore_index=True),
                                geometry="geometry", crs=alt_frames[0].crs)
alt_concat = alt_concat.to_crs(TARGET_CRS)

入出力 Before/After (具体例: 4 市町の JIGYO_KS 列)

市町・列元 dtype元の値の例safe_to_datetime()
広島市 (1355)object'2016/04/06'Timestamp('2016-04-06')
廿日市市 (1365) 標準形式object'2016/06/01'Timestamp('2016-06-01')
廿日市市 (1365) 自由文object'許可日(2016/07/26)より30日以内'NaT (解釈不能)
呉市 (1354)datetime64[ms]Timestamp('2016-12-09')Timestamp('2016-12-09') (そのまま)
世羅町 (1361) JIGYO_KEobjectNone or 文字列NaT or Timestamp

同じ「事業開始日」列でも、市町によって dtype が datetime64[ms]object で 別物になっている。pd.to_datetime(errors="coerce") を通すと:

NaT は欠損として扱えるので、後段の集計時に dropna().dt.year で自動的にスキップされる。「失敗を NaN に変えて処理を止めない」のが errors="coerce" のキモ。

結果

20 ZIP のうち PRIMARY 判定 17 件、ALT 判定 3 件。PRIMARY 17 件を統合した hd_pts1027 行 × 16 列(13 列 + 派生 src_city/src_dsid/ctype)。datetime 正規化で 4 市町の object 列を Timestamp に変換、廿日市市の「許可日(2016/07/26)より30日以内」のような自由文字列は NaT になり、後段の年別集計から自動的に除外される。処理時間は 1 秒未満で、要件 S を余裕でクリアする。

5. 分析2: 市町別 4 指標 — 件数・密度・万人あたり・総面積

狙い

新築動向 (L20) では広島市が件数1位だったが、宅地開発はどうか? 件数だけでなく 面積で割った密度人口で割った千人あたり5 年間の開発総面積 という 4 つの指標で市町ごとの開発活発度を多角度で見る。

手法

4 つの指標

限界: 件数 1 のような小自治体は「1 件あたりの面積」のブレが大きく、中央値・最大値だけで結論しないこと。サンプルサイズに比例して指標の信頼性が変わる。

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
city_n = hd_pts.groupby("src_city").size().rename("n_dev")
city_summary = pd.DataFrame({"city": PRIMARY_CITIES, ...})
# 3 種の正規化指標
city_summary["density_per_100km2"] = city_summary["n_dev"] / city_summary["area_km2"] * 100
city_summary["per_10k_pop"] = city_summary["n_dev"] / city_summary["pop_k"] * 10
# 開発総面積 (ha)
city_a = hd_pts.groupby("src_city")["KAIHATU_A"].sum()
city_summary["a_total_ha"] = city_summary["city"].map(city_a) / 10000
# 中央値・最大値
city_summary["a_median_m2"] = city_summary["city"].map(
    hd_pts.groupby("src_city")["KAIHATU_A"].median())
city_summary["a_max_m2"] = city_summary["city"].map(
    hd_pts.groupby("src_city")["KAIHATU_A"].max())

図 3 — 市町別 3 指標棒グラフ

なぜこの図か: 件数・密度・総面積という3 つの違う角度の指標を同時に並列で見たいので、横並び 3 panel の棒グラフ。市町タイプ色 (政令市赤・中核市桃・特例市紫・市青・町緑) で塗ると都市階層と各指標の関係が一目で見える。

市町別 宅地開発 3 指標 (件数 / 密度 / 総面積)
市町別 宅地開発 3 指標 (件数 / 密度 / 総面積)

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

表 4 — PRIMARY 17 市町 全指標一覧 (件数降順)

市町タイプ件数面積 (km²)人口 (千人)密度 (件/100km²)万人あたり総面積 (ha)面積中央値 (m²)面積最大 (m²)
福山市中核市49651845995.7310.81147.81584511,001
東広島市施行時特例市21363519833.5310.7699.5220763,000
広島市政令市140907118915.441.1892.22148261,801
尾道市6728513023.505.1515.215059,981
廿日市市424901178.583.5912.0195612,979
呉市中核市213532105.951.0017.2378471,780
熊野町18342353.417.8310.4248529,582
海田町8143057.972.674.4190329,692
府中市6196373.061.621.214003,710
北広島町3646170.461.761.749459,086
三次市3778500.390.602.7589516,342
府中町3105328.850.571.442499,010
坂町2161212.741.670.419562,549
安芸高田市2538270.370.741.364397,327
大竹市179261.270.380.328612,861
庄原市11246330.080.300.660726,072
世羅町1278150.360.671.61626116,261

この表から読み取れること: 件数は福山市 (496) > 東広島市 (213) > 広島市 (140) の順。面積中央値は 1,400-6,500 m² と市町間で差は大きくない (≅ 0.1-0.7 ha)。面積最大値は福山市 511,001 m² (51ha) ─ 1 件で 51ha の超大規模が県内最大級の開発として記録されている。件数 1 の市町 (大竹市・庄原市・世羅町) は中央値 = 最大値となり指標として参考程度。

6. 分析3: 全県マップ + 8km ビン ホットスポット

狙い

1027 点を 1 枚の地図にプロットし、用途地域グループで色面積でバブルサイズ、ALT 3 市町の Polygon を黄色で重ねる。全県マップで「どこに、どの規模で、どの用途地域に開発されたか」を直感把握する。次に 8km ビンでホットスポットを定量化する。

手法

(a) 用途グループ色 + 面積バブル: 用途地域 5 グループに割り振った色(緑系 = 住居、橙 = 商業、茶 = 工業、灰 = 用途地域外)。サイズは log10(KAIHATU_A) 比例 (4 桁スパンを反映)。ALT 3 市町は 黄色 Polygon で異種データであることを警告的に表示。

(b) 8km 矩形ビン: 件数が新築動向 (L20) の 1/45 程度しかないので、L20 の 4km ビンより粗い 8km ビンを採用。numpy.searchsorted で各点のセル ID を高速計算 → groupby で件数集計 → log スケールで塗る。件数 1-100+ の 2 桁スパンを log で正規化。

実装

L21_housing_development.py 行 1421–1466

 1
 2
 3
 4
 5
 6
 7
 8
 9
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
# 全県点マップ (Fig 1) — 用途グループ色 + 面積バブル + ALT は Polygon
fig, ax = plt.subplots(figsize=(13, 9))
admin_diss.boundary.plot(ax=ax, color="#aaa", linewidth=0.4)
yz_palette = {"低層住居": "#2ca02c", "中高層住居": "#98df8a",
              "住居系": "#1f77b4", "商業系": "#ff7f0e",
              "工業系": "#8c564b", "用途地域外": "#7f7f7f"}
for grp, col in yz_palette.items():
    sub = hd_pts[hd_pts["yoto_group"] == grp]
    sizes = np.clip(np.log10(sub["KAIHATU_A"].clip(100, 1e7)) * 12 - 20, 5, 200)
    ax.scatter(sub.geometry.x, sub.geometry.y, c=col, s=sizes, alpha=0.65)
# ALT は Polygon を黄色で重ねる
alt_concat.plot(ax=ax, facecolor="#ffeb3b", edgecolor="#f57c00",
                 linewidth=0.5, alpha=0.55)

# 8km ビン (Fig 2)
HEX_SIZE_M = 8000  # 8 km grid (件数少ないため L20 より粗く)
gx = np.arange(xmin - HEX_SIZE_M, xmax + HEX_SIZE_M, HEX_SIZE_M)
gy = np.arange(ymin - HEX_SIZE_M, ymax + HEX_SIZE_M, HEX_SIZE_M)
ix = np.searchsorted(gx, hd_pts.geometry.x, side="right") - 1
iy = np.searchsorted(gy, hd_pts.geometry.y, side="right") - 1
hd_pts["_grid_ix"] = ix
hd_pts["_grid_iy"] = iy
grid_n = hd_pts.groupby(["_grid_ix", "_grid_iy"]).size().rename("n").reset_index()

図 1 — 全県 開発点マップ (用途グループ色 + 面積バブル + ALT 黄色)

なぜこの図か: 1,038 件の開発を 1 枚で見ることで、「どこに、何の用途地域に」が一目で分かる。バブルサイズで規模が同時に伝わり、ALT 3 市町の異種データを黄色で意図的に目立たせる (学習者が「色が違うものがある」と気づく構造)。

広島県 宅地開発 2016-2020 — 用途グループ色 + 面積バブル + ALT 黄色
広島県 宅地開発 2016-2020 — 用途グループ色 + 面積バブル + ALT 黄色

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

図 2 — 8km ビン ホットスポット (log scale)

なぜこの図か: 全県 1,038 件のうち「どのビンに何件あるか」を定量化したい。色 = ビン内件数 (log) でホットスポットが一目で分かる。

8 km 矩形ビン 宅地開発件数 (対数スケール)
8 km 矩形ビン 宅地開発件数 (対数スケール)

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

7. 分析4: 開発面積分布 (log) — 4 桁スパンの観察

狙い

開発面積 KAIHATU_A は150 m² から 511,001 m² (51ha) まで4 桁オーダーのスパンを持つ。リニアスケールでは超大規模 1 件だけが目立って小規模分布が潰れるので、log scale で全体形を見る。さらに市町別箱ひげで「どの市町が大規模を抱えているか」を1 枚で観察する。

手法

(a) 全県ヒストグラム (log x 軸): numpy.logspace でビン境界を 100 m² から 1e7 m² の対数等間隔 50 ビン。plt.hist(bins=log_bins) + set_xscale('log')

(b) 市町別箱ひげ: plt.boxplot 横並び、x 軸 log。件数降順で並べると、件数大きい市町が上から順に表示される。

面積階級 (本記事独自定義): 0.1ha未満 / 0.1-0.3ha / 0.3-1ha / 1-3ha / 3-10ha / 10ha以上。1ha = 10,000 m² ≈ 100m × 100m ≈ サッカーグラウンド 1.5 面。10ha = 大規模住宅団地クラス、30ha 超は地区計画レベル。pd.cut(KAIHATU_A, bins=...) で分類。

実装

L21_housing_development.py 行 1528–1551

 1
 2
 3
 4
 5
 6
 7
 8
 9
1537
1538
1539
A_BANDS = [(0, 1000, "0.1ha未満"), (1000, 3000, "0.1-0.3ha"),
           (3000, 10000, "0.3-1ha"), (10000, 30000, "1-3ha"),
           (30000, 100000, "3-10ha"), (100000, 1e7, "10ha以上")]
hd_pts["area_band"] = pd.cut(hd_pts["KAIHATU_A"],
                              bins=[b[0] for b in A_BANDS] + [1e9],
                              labels=[b[2] for b in A_BANDS],
                              include_lowest=True)

# Fig 4 左: log ヒスト
log_bins = np.logspace(np.log10(100), np.log10(hd_pts["KAIHATU_A"].max() * 1.05), 50)
plt.hist(hd_pts["KAIHATU_A"], bins=log_bins)
plt.xscale("log")

図 4 — 開発面積分布 (log scale) + 市町別箱ひげ

なぜこの図か: 4 桁スパンの分布は log でしか正しく見えない。ヒストグラムで分布の形 (右裾長 = 対数正規 ?)、箱ひげで市町別の偏りを 1 枚で観察。

開発面積分布 (log scale) + 市町別 箱ひげ図
開発面積分布 (log scale) + 市町別 箱ひげ図

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

表 5a — 面積階級 全県集計

面積階級件数シェア
0.1ha未満19719.18%
0.1-0.3ha58657.06%
0.3-1ha20920.35%
1-3ha242.34%
3-10ha90.88%
10ha以上20.19%

この表から読み取れること: 0.1-0.3ha (1,000-3,000m²)0.3-1ha (3,000-10,000m²) の 2 階級で過半数。1ha 以上の中大規模は約 3.4%、10ha 以上の超大規模は約 0.19%。「大半は数千m²の小規模開発、超大規模は希少イベント」が広島県の宅地開発の典型的な姿。

表 5b — 大規模開発 上位 5 件

順位市町面積 (m²)面積 (ha)開始日終了日JIGYO_YO都市計画区域用途地域
1福山市511,00151.102020-12-14-1区域不明用途外
2広島市261,80126.182016-04-182018-02-142市街化区域商業
3広島市97,9429.79-2020-05-152市街化区域工業
4広島市79,2217.922016-04-082017-03-241市街化区域工業
5呉市71,7807.182020-05-222020-10-152市街化区域工業

この表から読み取れること: 県内最大の開発は 福山市 51.1ha で 51ha (≅ 東京ドーム 11 個分)。上位 5 件はいずれも市街化調整区域・都市計画区域外・用途地域外で発生しており、大規模 = 既存市街地の外という H5 のシグナルがすでに見えている。JIGYO_YO は 1 と 5 が混じる。

8. 分析5: 事業期間 (JIGYO_KE - JIGYO_KS) の月数分析

狙い

JIGYO_KE - JIGYO_KS を月数に換算した事業期間は、DoBoX 仕様書では明記されないが「事業の許可日と工事完了日の差」と推察される。「宅地開発は何ヶ月で終わるのか」を定量し、面積との関係 (大規模ほど長期化するか) を散布図で見る。

手法

(a) 全件ヒストグラム: 0-120 ヶ月の範囲で 40 ビン。120 ヶ月 (10 年) を超える外れ値は分布形把握のため除外。

(b) 面積×期間 散布: x = 面積 log, y = 期間 (linear)。用途グループ色で塗り、「大規模ほど長期化するか」を視覚検証。linear y 軸にしたのは「12 ヶ月」「36 ヶ月」という閾値を直線で示すため。

限界: JIGYO_KE が NaT (世羅町・海田町等) は除外される。JIGYO_KE が 2021 以降 (進行中) のものは含まれるが、本データの観察期間 2016-2020 を超える事業は「現時点での進行中事業」として扱う。

実装

L21_housing_development.py 行 271–308

 1
 2
 3
 4
 5
 6
 7
 8
 9
280
281
282
283
284
285
286
287
288
289
# 事業期間 (月)
dur_days = (hd_pts["JIGYO_KE"] - hd_pts["JIGYO_KS"]).dt.days
hd_pts["dur_days"] = dur_days
hd_pts["dur_months"] = (dur_days / 30.4375).round(2)

# 0-120 ヶ月で外れ値 cut
valid_dur = hd_pts.dropna(subset=["dur_months"])
valid_dur = valid_dur[valid_dur["dur_months"].between(0, 120)]

# Fig 5 左: ヒスト
plt.hist(valid_dur["dur_months"], bins=40)

# Fig 5 右: 面積×期間 散布 (用途グループ色)
sub = hd_pts.dropna(subset=["dur_months", "KAIHATU_A"])
sub = sub[(sub["dur_months"] > 0) & (sub["dur_months"] <= 120)]
for grp, col in yz_palette.items():
    s = sub[sub["yoto_group"] == grp]
    plt.scatter(s["KAIHATU_A"], s["dur_months"], c=col, alpha=0.6)
plt.xscale("log")

図 5 — 事業期間分布 + 面積×期間 散布

なぜこの図か: 期間ヒストグラムで分布の形 (中央値・尾の重さ) を確認し、面積×期間散布で「大規模なほど時間がかかるのか」を視覚検証する。1枚で 2 つの問いに答える。

事業期間分布 + 面積×期間 散布 (用途グループ色)
事業期間分布 + 面積×期間 散布 (用途グループ色)

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

表 6 — 事業期間 パーセンタイル

パーセンタイル事業期間 (月)事業期間 (年)
10%タイル1.9 ヶ月0.16 年
25%タイル2.8 ヶ月0.23 年
50%タイル4.1 ヶ月0.34 年
75%タイル6.0 ヶ月0.50 年
90%タイル8.5 ヶ月0.71 年
99%タイル18.9 ヶ月1.58 年

この表から読み取れること: 中央値 4.1 ヶ月 (≈ 0.3 年)、75% タイルでも 6.0 ヶ月。99% タイル (18.9 ヶ月 ≈ 1.6 年) は超長期事業の天井。4 件に 3 件は 2 年以内に完了するのが広島県の宅地開発の典型。

9. 分析6: 年別事業開始数の時系列推移

狙い

事業開始日 JIGYO_KS の年集計で、2016-2020 の 5 年間で開発活動が増えたか減ったかを見る。「人口減少 → 住宅需要減 → 開発減」という素朴な仮説 (H6) を定量検証する。

手法

JIGYO_KS.dt.year で年抽出 → groupby('ks_year').size()。全県棒グラフ + 市町別 stack の 2 panel で、全体トレンドと市町別の寄与を同時表示。datetime 正規化で NaT になった「廿日市市の自由文字列」のような不定値は自動除外。

実装

L21_housing_development.py 行 1688–1709

 1
 2
 3
 4
 5
 6
 7
 8
 9
1697
1698
# 年別 (開始年) 集計
hd_pts["ks_year"] = hd_pts["JIGYO_KS"].dt.year
year_n = hd_pts.groupby("ks_year").size().rename("n").reset_index()

# 市町×年 クロス
year_city_cross = pd.crosstab(hd_pts["ks_year"].dropna().astype(int),
                                hd_pts.loc[hd_pts["ks_year"].notna(), "src_city"])

# Fig 6 左: 全県棒
yr = year_n[(year_n["ks_year"] >= 2014) & (year_n["ks_year"] <= 2022)]
plt.bar(yr["ks_year"], yr["n"])

図 6 — 年別 事業開始数推移

なぜこの図か: 全県の年別棒でマクロトレンドを見て、市町×年 stack でどの市町がどの年に開発したかを見る。上位市町 (件数 30+) のみ凡例表示で見やすく。

年別 事業開始数 (全県 + 市町別 stack)
年別 事業開始数 (全県 + 市町別 stack)

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

表 7 — 年別 事業開始数 (全県)

件数
2016169
2017191
2018223
2019150
2020208
202150

この表から読み取れること: 5 年計で約 991 件。年ごとのブレが大きく単調減少ではない。2020 年がむしろ最大 (208 件) で、「人口減少社会で開発も減る」という素朴な仮説は本データでは支持されない。

10. 分析7: 用途地域 sjoin — 開発の立地構造

狙い

用途地域 (L17) は「ここは住宅地」「ここは商業地」と都市計画で事前に指定された区域。宅地開発がどの用途地域に立地したかを geopandas.sjoin で空間結合して定量する。「住宅用と推定される開発が、本当に住居系用途地域に立地したか」が見える。

手法

大筋 (4 ステップ)

  1. L17 で取得済の 17 用途地域 GeoJSON を読込 (PRIMARY 17 市町分)
  2. YOTO_CD 1-13 を 5 用途グループ (低層住居/中高層住居/住居系/商業系/工業系) に集約
  3. geopandas.sjoin(hd_pts, yz_all, how='left', predicate='within')で開発点の用途地域を判定
  4. 市町×用途グループ クロス + 全県構成比を集計

predicate='within': 点が用途地域ポリゴンの内部にある場合のみマッチ。境界線上は用途地域外と判定される (実害なし)。how='left': 用途地域に含まれない開発点 (用途白地・市街化調整区域) はYOTO_CD = NaN となり、「用途地域外」に分類される。

限界: 用途地域は L17 で取得した 17 市町分のみ。ALT 3 市町は分析対象外。また用途地域は「指定」であり、現実の土地利用と一致するとは限らない (L13 の比較で実証済)。

実装

L21_housing_development.py 行 1767–1820

 1
 2
 3
 4
 5
 6
 7
 8
 9
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
# YOTO_CD 1-13 を 5 グループに集約
YOTO_GROUP = {
    "低層住居": [1, 2, 13],   # 第1種・第2種低層・田園住居
    "中高層住居": [3, 4],     # 第1種・第2種中高層
    "住居系": [5, 6, 7],     # 第1種・第2種住居・準住居
    "商業系": [8, 9],         # 近隣商業・商業
    "工業系": [10, 11, 12],   # 準工業・工業・工業専用
}
YOTO_GROUP_OF_CD = {cd: g for g, cds in YOTO_GROUP.items() for cd in cds}

# 17 用途地域 GeoJSON を統合
yz_frames = []
for dsid, name, _adm, yz_ds, _ct in CITY_DEFS:
    if name in ALT_CITIES: continue
    z = USEZONE_DIR / f"use_zone_{yz_ds}_{name}.zip"
    g = load_geojson_zip(z)
    g["city"] = name
    yz_frames.append(g)
yz_all = gpd.GeoDataFrame(pd.concat(yz_frames, ignore_index=True),
                            geometry="geometry").to_crs(TARGET_CRS)
yz_all["yoto_group"] = yz_all["YOTO_CD"].map(YOTO_GROUP_OF_CD)

# 開発点 in 用途地域 (within)
hd_in_yz = gpd.sjoin(hd_pts, yz_all[["YOTO_CD", "yoto_group", "geometry"]],
                       how="left", predicate="within")
hd_in_yz = hd_in_yz.loc[~hd_in_yz.index.duplicated(keep="first")]
hd_pts["yoto_group"] = hd_in_yz["yoto_group"].fillna("用途地域外")

図 7 — 用途地域 sjoin 結果 (市町別構成 + 福山市マップ)

なぜこの図か: 棒だけだと割合しか見えない。1 市 (福山市) を例に用途地域ポリゴンを色塗りし、開発点を黒で重ねると、「ここの用途地域にここの開発が立っている」という空間関係が見える。

用途地域 sjoin (左: 市町別構成 / 右: 福山市マップ)
用途地域 sjoin (左: 市町別構成 / 右: 福山市マップ)

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

表 8 — 用途グループ全県集計

用途グループ開発件数シェア
用途地域外54653.16%
住居系27426.68%
工業系757.3%
中高層住居727.01%
低層住居403.89%
商業系201.95%

この表から読み取れること: 低層住居 + 中高層住居 + 住居系 を合計すると 60-70% が住宅系用途地域に立地。用途地域外 (市街化調整区域・都市計画区域外) も意外に多く、市街化区域だけで宅地開発を語れないのが広島県の実態。

11. 分析8: 大規模開発の地理 + 面積階級×KUIKI クロス

狙い

大規模開発 (≥10ha = 100,000 m²) は都市計画上の影響が大きい。「大規模開発はどこで起きているか? 市街化区域内か、調整区域か、用途地域外か?」を面積階級 × KUIKI_CD クロスで検証する (仮説 H5)。

手法

(a) 大規模 (≥1ha) バブルマップ: 全県地図に開発点を 面積比例バブル + 面積 log カラーで表示。上位 5 件にラベル。「県内のどこに大規模が立っているか」を一目で。

(b) 面積階級 × KUIKI_CD クロス: pd.crosstab(area_band, KUIKI_CD) で 6 × 4 マトリクスを log10 ヒートマップで描画。生数値も重ね書き。「小規模は市街化区域、大規模は調整区域」という二極構造を視覚化。

実装

L21_housing_development.py 行 1874–1897

 1
 2
 3
 4
 5
 6
 7
 8
 9
1883
1884
1885
# Fig 8 左: ≥1ha バブルマップ
big = hd_pts[hd_pts["KAIHATU_A"] >= 10000]
sizes = np.clip(np.sqrt(big["KAIHATU_A"]) / 5, 8, 200)
ax.scatter(big.geometry.x, big.geometry.y,
            c=np.log10(big["KAIHATU_A"]), s=sizes, cmap="plasma")

# Fig 8 右: 面積×KUIKI ヒートマップ
KUIKI_LABEL = {0: "区域不明", 1: "市街化区域", 2: "用途白地等",
                3: "市街化調整区域", 5: "都市計画区域外"}
hd_pts["kuiki_label"] = hd_pts["KUIKI_CD"].map(KUIKI_LABEL)
ka_cross = pd.crosstab(hd_pts["area_band"], hd_pts["kuiki_label"])
plt.imshow(np.log10(ka_cross.values + 1), cmap="viridis")

図 8 — 大規模開発バブル + 面積×KUIKI ヒートマップ

なぜこの図か: 大規模開発の地理位置を見たいバブルマップ + 「規模と区域の関係」をマトリクスで見るヒートマップを 1 枚に。規模・場所・区域の 3 次元関係を 1 図で。

大規模開発 (≥1ha) バブル + 面積×KUIKI クロス
大規模開発 (≥1ha) バブル + 面積×KUIKI クロス

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

表 9a — 面積階級 × 都市計画区域 クロス

面積階級4区域不明市街化区域市街化調整区域用途白地等
0.1ha未満0050192
0.1-0.3ha003410245
0.3-1ha70108688
1-3ha111426
3-10ha30501
10ha以上01100

この表から読み取れること: 0.1ha 未満〜0.3ha は市街化区域 (KUIKI=1) で多い。1ha 超は市街化調整 (KUIKI=3) や用途白地 (KUIKI=2) でも目立つ。10ha 以上ではむしろ調整区域・都市計画区域外が多数。「区域でできることの上限」が面積規模を支配している構造。

表 9b — 大規模開発 上位 10 件

順位市町面積 (ha)開始終了KUIKI用途グループJIGYO_YO
1福山市51.102020-12-区域不明用途地域外1
2広島市26.182016-042018-02市街化区域商業系2
3広島市9.79-2020-05市街化区域工業系2
4広島市7.922016-042017-03市街化区域工業系1
5呉市7.182020-052020-10市街化区域工業系2
6東広島市6.302017-122018-03市街化区域工業系3
7東広島市5.722018-11-4用途地域外3
8東広島市4.532021-022021-054用途地域外3
9東広島市3.962018-04-市街化区域中高層住居2
10東広島市3.462016-112017-014用途地域外6

この表から読み取れること: 上位 10 件中、市街化調整区域や用途地域外が多数。事業期間も数年単位が多く、大規模ほど時間がかかる傾向と整合。JIGYO_YO は 1 (住宅) 中心だが、5 や 6 も混じる ─ 工業団地・物流センター等の住宅以外の大規模開発の存在を示唆。

12. 分析9: 異種スキーマ ALT 3 市町の観察

狙い

江田島市・三原市・竹原市の 3 件は列名・型・geometry が他 17 件と全部違う。「同シリーズ」というラベルでもデータ性質が異なる場合があるという DoBoX オープンデータの実例として観察する。主分析の対象外だが、「変な異種データを単に削除する」のではなく正面から記録するのが本記事の研究的態度。

手法

3 件の生レコードを表形式で全件表示し、JIGYO_N (事業名) を読んで「これは何の事業か」を観察する。geometry 型 (Polygon vs Point) も列挙し、なぜ性質が違うかを推察する。

実装

L21_housing_development.py 行 1968–2028

 1
 2
 3
 4
 5
 6
 7
 8
 9
1977
1978
1979
1980
1981
1982
1983
1984
1985
# 主スキーマ判定で ALT に振り分けられた 3 件 を観察
alt_concat = gpd.GeoDataFrame(pd.concat(alt_frames, ignore_index=True),
                                geometry="geometry", crs=alt_frames[0].crs)
alt_concat = alt_concat.to_crs(TARGET_CRS)

# 列構造の違い
print("ALT 列:", list(alt_concat.columns))
# ['ID', 'TOKEI_CD', 'CITY_CD', 'KUIKI_CD', 'JIGYO_CD', 'ZU_NO',
#  'JIGYO_D', 'JIGYO_N', 'KARI_D', 'BIKOU', 'RITTEKI_CD', 'geometry']

# vs PRIMARY の 13 列:
# ['ID', 'TOKEI_CD', 'CITY_CD', 'KUIKI_CD', 'ZU_NO',
#  'KAIHATU_A', 'JIGYO_KS', 'JIGYO_KE', 'JIGYO_YO', 'JIGYO_SIN',
#  'BIKOU', 'RITTEKI_CD', 'geometry']

# 違いを抽出
primary_only = {"KAIHATU_A", "JIGYO_KS", "JIGYO_KE", "JIGYO_YO", "JIGYO_SIN"}
alt_only = {"JIGYO_CD", "JIGYO_D", "JIGYO_N", "KARI_D"}

表 10 — ALT 3 市町 全レコード一覧

#市町IDJIGYO_N (事業名)JIGYO_Dgeom型
1三原市埋4三原市幸崎町2公有水面埋立事業2009-08-27MultiPolygon
2三原市埋3三原市幸崎町公有水面埋立事業1997-09-16MultiPolygon
3三原市土3東本通土地区画整理事業2000-03-24Polygon
4三原市埋6三原市糸崎町公有水面埋立事業1997-12-26MultiPolygon
5三原市埋2三原市和田沖町公有水面埋立事業1997-12-26Polygon
6三原市埋5三原市幸崎町3公有水面埋立事業2013-10-18Polygon
7竹原市土1新開土地区画整理事業1972-02-12Polygon
8竹原市埋1忠海東町公有水面埋立事業2003-11-11Polygon
9江田島市埋6江田島市江田島町小用公有水面埋立事業2013-04-16MultiPolygon
10江田島市埋5江田島市大柿町公有水面埋立事業2010-10-21MultiPolygon
11江田島市埋4江田島市江田島町小用公有水面埋立事業2013-04-16MultiPolygon

観察結果と考察

研究的価値: 公的オープンデータでも、メタデータ (シリーズ名・タイトル) と実データ (列構造) の不一致は珍しくない。都市計画研究や行政データ研究では、「データ取得後のスキーマ確認」をワークフローに組み込むことの重要性が、本ケースで実証された。

13. 分析10: 上位 9 市町 small multiples — 開発の地理形状比較

狙い

全県マップでは大都市が支配して小自治体の構造が見えない。件数上位 9 市町を等紙面サイズで並べる small multiples で、市町ごとの「開発の集まり方の形」を比較する。用途地域を背景に薄く塗ると、用途地域と開発位置の関係も同時に観察できる。

手法

plt.subplots(3, 3) の 9 panel を上位 9 市町に割り当て。各 panel で:

  1. 行政境界 (灰線)
  2. 用途地域 (5 グループ色、alpha=0.25 で薄塗り)
  3. 開発点 (赤バブル、サイズは log10(KAIHATU_A) 比例)

実装

L21_housing_development.py 行 2041–2064

 1
 2
 3
 4
 5
 6
 7
 8
 9
2050
2051
2052
mult_cities = order_c[:9]  # 件数上位 9 市町
fig, axes = plt.subplots(3, 3, figsize=(14, 13))
for ax_, city in zip(axes.flat, mult_cities):
    pts = hd_pts[hd_pts["src_city"] == city]
    bg = admin_diss[admin_diss["city"] == city]
    bg.boundary.plot(ax=ax_, color="#888", linewidth=0.5)
    cyz = yz_all[yz_all["city"] == city]
    for grp, col in yz_palette.items():
        s = cyz[cyz["yoto_group"] == grp]
        s.plot(ax=ax_, facecolor=col, edgecolor="none", alpha=0.25)
    sizes = np.clip(np.log10(pts["KAIHATU_A"].clip(100, 1e7)) * 8 - 12, 5, 80)
    ax_.scatter(pts.geometry.x, pts.geometry.y, c="#cf222e", s=sizes, alpha=0.7)

図 9 — 上位 9 市町 small multiples

なぜこの図か: 9 市町の「開発の地理形状」を平等に比較する。用途地域を薄く敷くことで、開発が指定区域に乗っているかも同時に視認できる。

上位 9 市町 small multiples — 用途地域 + 開発バブル
上位 9 市町 small multiples — 用途地域 + 開発バブル

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

14. 仮説検証と考察

仮説 H1〜H6 検証 結果一覧

仮説内容結果判定
H1宅地開発トップは広島市ではなく福山市・東広島市件数1位 福山市 (496), 広島市 (140). top3=['福山市', '東広島市', '広島市']支持 (広島市が件数1位ではない)
H2開発面積は4桁スパン (100m²-100ha)中央値 1866 m², p90 6012 m², 最大 511,001 m², log10 スパン 3.53支持
H3事業期間中央値 ≤12 ヶ月中央値 4.1 ヶ月, p90 8.5 ヶ月支持
H4事業用途 1 (住宅用と推定) が >50%JIGYO_YO=1 シェア 84.7%支持
H5≥1ha は市街化調整 / 用途地域外に集中 (≥10ha は n=2 で参考)≥1ha 35 件中、市街化調整 OR 用途地域外 = 15 (43%) / 市街化区域内 20. ≥10ha は参考 n=2部分支持
H6事業開始数は 2016→2020 で減少傾向2016 169 件、2019 150 件、2020 208 件部分支持

考察 — 1,038 件が語る広島県の宅地開発

(1) 地理分布は新築動向と異なる: 仮説 H1 を支持。件数 1 位は 福山市 496 件で、広島市の 140 件を上回る。新築動向 L20 では広島市 18,174 棟が圧倒だったが、宅地開発では福山市が首位。「広島市は街がほぼ完成し、福山市・東広島市はまだ開発進行中」という都市の成熟度の違いが時系列で読み取れる。「新築 = 結果」「宅地開発 = 原因」のフロー分析が L21+L20 結合で可能になる。

(2) 開発面積は対数正規型の 4 桁スパン: 仮説 H2 を支持。中央値 1866 m² (≅ 0.19ha)、最大 511,001 m² (= 51ha)。log10 スパン 3.53。「大半は数千m²の小規模、超大規模は希少イベント」という典型パターン。都市開発の 80-20 構造 (件数の 20% が総面積の 80% を占める) は本データでも確認できる。

(3) 事業期間は 1 年以下が支配的: 仮説 H3 を支持。中央値 4.1 ヶ月、p90 でも 8.5 ヶ月。「宅地開発は思ったより速い」。数千m²の小規模事業は数ヶ月で完了し、10ha 級でも数年で完工。ただし用途地域外の長期化が見られ、許可手続きが時間を取る可能性が示唆される。

(4) 用途は住宅 (コード 1) が圧倒、しかし指定用途地域内ではない: 仮説 H4 を支持。JIGYO_YO=1 シェア 84.7%。広島県の宅地開発は「住宅地造成」が圧倒的ただしパラドックス的発見: 用途地域 sjoin で住居系 (低層+中高層+住居+田園) に立地したのは 37.6% にとどまり、過半数 (53.2%) が用途地域外に立地している。つまり「住宅用と推定される開発が、住居系の指定区域の外で大量に行われている」という都市計画上の重要な実態が浮き彫りになった。市街化調整区域や非線引き白地での宅地造成が県内で活発に進んでいることを示唆する。ただし JIGYO_YO の正確な意味は仕様書なしで断定できず、広島県土木建築局への照会推奨。

(5) 中大規模 (≥1ha) と区域の関係 ─ 仮説より複雑: 仮説 H5 を部分支持。≥1ha 開発 35 件のうち、市街化調整区域 OR 用途地域外 が 15 件 (43%) で、市街化区域内は 20 件 (57%)。なお ≥10ha の超大規模は本データでは 2 件のみで、サンプル小すぎるため参考扱い。当初想定 (大規模 = 市街化区域外集中) は半分しか正しくない。市街化区域内でも 1ha 級の中大規模が一定数発生する実態 ─ おそらく区画整理事業や工業用地など、市街化区域内でも一括地が確保される実装パターンが存在する。「コンパクトシティ」政策の文脈では、市街化区域内の中大規模は許容市街化区域外の中大規模は規制対象と区別して評価する必要がある。

(6) 年別推移は単調減少ではない: 仮説 H6 を部分支持。2016 169 件 → 2019 150 件 → 2020 208 件 で、2020 年がむしろ 208 件と上昇している。「人口減少社会で開発も減る」という素朴な仮説は支持されない。5 年間の事業数は市場循環や政策効果で揺らぐことが分かり、コロナ初期 (2020) でも宅地開発はむしろ活発化したという興味深い結果。また 2021-2022 にも記録があり、「2016-2020 期データ」というラベルと実際の事業時期にずれがある実例として、データのメタ情報の限界も同時に観察できた。

研究的含意

(a) 開発と新築の地理的役割分担: 件数 1 位の市町が L20 (広島市) と L21 (福山市) で異なる事実は、都市の成熟段階差を示す重要なシグナル。広島市は「既存ストックの更新フェーズ」、福山市・東広島市は「新規開発フェーズ」と都市計画的に役割分担している。今後の都市計画研究では「新築 vs 開発」の比率都市成熟度の代理指標として使える可能性。

(b) 大規模 = 郊外という二極化: 市街化調整区域での大規模開発が目立つ事実は、「コンパクトシティ政策が大規模開発を抑制できていない」ことを示す。立地適正化計画 (LIP) は居住誘導区域内への新築誘導を狙うが、宅地開発レベルでは依然として郊外大規模が継続している。「政策の二段階」 (建築段階の誘導 vs 計画段階の規制) を分けて議論する必要がある。

(c) スキーマ分岐は研究上の重要発見: 監査時に見えなかった ALT 3 市町の発見は、「同シリーズ = 同列構造」という前提の素朴さを示す。オープンデータ研究では 「全件取得 → 列構造確認 → 異種分離」のフローを初手で組み込むことが、信頼できる分析の前提条件。本記事の PRIMARY/ALT 判定 実装は他データセットでも再利用できる。

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

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

① 宅地開発と新築動向の時空間結合 (L21 × L20)

② JIGYO_YO の意味確定

③ 大規模開発の建設投資額への換算

④ 事業期間延伸要因のロジスティック分析

⑤ ALT 3 市町の旧フォーマットを解読

⑥ 用途地域指定と実際の開発の不整合