Lesson 20

L20 新築動向 20 件 統合分析 — 広島県全域 4.7 万棟の時空間分布構造

都市計画新築建物立地適正化計画GISgeopandassjoinhexbinHeaps則用途分類可視化
所要 読了 30 分 / コード実行 1 分以内 / 想定レベル: 応用 / データ: DoBoX 新築動向 20 件 (全市町、2016-2020)

データ取得手順

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

IDデータセット名
#222dataset #222
#444dataset #444
#888都市計画区域情報_区域データ_安芸高田市_行政区域
#1332都市計画区域情報_新築動向_安芸高田市_2016-2020
#1333都市計画区域情報_新築動向_海田町_2016-2020
#1334都市計画区域情報_新築動向_熊野町_2016-2020
#1335都市計画区域情報_新築動向_呉市_2016-2020
#1336都市計画区域情報_新築動向_広島市_2016-2020
#1337都市計画区域情報_新築動向_江田島市_2016-2020
#1338都市計画区域情報_新築動向_坂町_2016-2020
#1339都市計画区域情報_新築動向_三次市_2016-2020
#1340都市計画区域情報_新築動向_庄原市_2016-2020
#1341都市計画区域情報_新築動向_世羅町_2016-2020
#1342都市計画区域情報_新築動向_大竹市_2016-2020
#1343都市計画区域情報_新築動向_竹原市_2016-2020
#1344都市計画区域情報_新築動向_東広島市_2016-2020
#1345都市計画区域情報_新築動向_廿日市市_2016-2020
#1346都市計画区域情報_新築動向_尾道市_2016-2020
#1347都市計画区域情報_新築動向_府中市_2016-2020
#1348都市計画区域情報_新築動向_府中町_2016-2020
#1349都市計画区域情報_新築動向_福山市_2016-2020
#1350都市計画区域情報_新築動向_北広島町_2016-2020
#1516都市計画区域情報_新築動向_三原市_2016-2020

実行コマンド:

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

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

1. 学習目標と問い

本記事は、広島県インフラマネジメント基盤 DoBoX 公開の 「都市計画区域情報_新築動向」シリーズ 20 件 (#1336, #1335, #1349, #1344, #1345, #1346, #1516, #1343, #1347, #1342, #1339, #1340, #1332, #1337, #1348, #1333, #1334, #1338, #1350, #1341) を縦結合し、2016-2020 年に広島県内 20 市町で建設された全 46,613 棟の新築建物 の Point データから、時空間分布構造、用途構成、建物高さ分布、立地誘導政策の機能性を 研究する記事である。

研究の問い (RQ): 広島県内の新築建物 4.7 万棟は、市町別・年別・用途別・建物高さの 観点でどのような時空間分布を持つか? そこから人口減少社会における都市の成長/衰退、 コンパクトシティ政策の機能性をどう読み取るか?

仮説 H1〜H6

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

到達点

  1. 20 個の GeoJSON ZIP を 1 個の GeoDataFrame (46,613 行 × 13 列) に縦結合できる。
  2. 1,275 種類の YOTO_SUB を 9 大分類に集約し、市町別構成を把握する。
  3. 市町別 新築密度 (棟/km², 棟/千人) を計算し、2 桁の二極化を見出す。
  4. 4km ビン地理集計で県全域の新築ホットスポットを log scale で可視化する。
  5. 建物高さの二峰性 (6-9m + 20m 超) を確認し、高層建築 495 棟の地理集中を見る。
  6. LIP 8 市について geopandas.sjoin(predicate='within') で 新築点が居住誘導区域内に何 % あるかを定量し、政策機能性を判定する。
  7. 用途多様性 vs 新築総数の log-log 関係から Heaps 的構造を検証する。

本記事のスコープ宣言

本記事は新築動向シリーズ 20 件のみを主データとする研究記事である。 L15 行政区域 21 件は市町別空間集計の境界として参照、 L17 用途地域 21 件・L19 居住誘導 9 件はH6 検証および政策的考察の併置として参照するが、 L17/L19 を主役にした合体記事ではない。 他のサブシリーズ (宅地開発 L21・人口 L22 等) との合体も将来的な発展課題に留め、 本記事では行わない (要件 I 違反の水増し回避)。

2. 使用データ

新築動向 20 件 はそれぞれ 1 市町分の Point GeoJSON を ZIP で配布している。 列構造は全 20 件で完全同一 (11 列: ID, TOKEI_CD, CITY_CD, KUIKI_CD, ZU_NO, NEW_YCD, YOTO_SUB, KAIHATU_S, TATE_H, RITTEKI_CD, geometry) で、 和集合化 (pd.concat) で 1 個の GeoDataFrame にできる。

20 dataset_id 一覧 (新築総数 多→少)

dataset_id市町市町タイプDoBoX新築棟数 (5 年計)
#1336広島市政令市DoBoX18,174
#1335呉市中核市DoBoX2,659
#1349福山市中核市DoBoX10,162
#1344東広島市施行時特例市DoBoX4,735
#1345廿日市市DoBoX2,472
#1346尾道市DoBoX1,913
#1516三原市DoBoX1,085
#1343竹原市DoBoX339
#1347府中市DoBoX586
#1342大竹市DoBoX610
#1339三次市DoBoX760
#1340庄原市DoBoX283
#1332安芸高田市DoBoX106
#1337江田島市DoBoX128
#1348府中町DoBoX793
#1333海田町DoBoX745
#1334熊野町DoBoX511
#1338坂町DoBoX244
#1350北広島町DoBoX189
#1341世羅町DoBoX119

列の意味 (全 20 件で同一)

列名意味と本記事での扱い
IDint32 各市町内連番。市町をまたがると重複しうる。本記事は src_city + ID で識別
TOKEI_CDint32 統計区分コード。ほぼ 1 一定 (46,592/46,613)。参考列扱い
CITY_CDint32 市町区分コード (例: 105=広島市佐伯区, 207=福山市)。広島市は 8 区を 101-108 で分割。 本記事は src_city (ZIP ファイル名から) を主に使う
KUIKI_CDint32 都市計画区域コード (1=市街化区域, 3=市街化調整区域, 5=都計外, 等の対応と推定)。 参考列扱い
ZU_NOint32 図郭番号。地理タイル ID。参考列扱い
NEW_YCDint32 新築年コード (1-5)。1 が最大バケット (91.9%)。 DoBoX 仕様書未公開のため独自定義扱いとし、市町別偏り分析に用いる
YOTO_SUBobject 建物用途の日本語文字列。ユニーク値 1,275 種類。9 大分類に集約して使う
KAIHATU_Sint32 開発種別コード (0/1/2)。市町ごとに記録慣習差があり比較不可のため参考列扱い
TATE_Hfloat64 建物高さ (m)。中央値 7.78m, 最大 178.07m (広島市の高層マンション類)。 本記事の主指標の 1 つ
RITTEKI_CDint32 立地コード (0/1/2)。仕様未公開のため参考列扱い
geometryPoint 新築建物の代表点 (棟の代表座標)。EPSG:6671 (JGD2011 平面直角第III系, m 単位)。 本記事の主役データ

調査期間と対象範囲

仕様書未公開のコード列について: NEW_YCD, KAIHATU_S, RITTEKI_CD, KUIKI_CD は DoBoX に意味の公式辞書がない。本研究は「観察される分布から推定する」 方針を採り、推定が困難なものは参考列扱いに留める。学習者が実務で扱う場合は データ提供元 (広島県土木建築局) に照会するのが望ましい。

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

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

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

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

cd "2026 DoBoX 教材"
py -X utf8 data\extras\L20_new_construction\fetch_new_construction.py

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

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

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

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

4. 分析1: 20 GeoJSON を 1 枚の GeoDataFrame に統合する

狙い

20 個の ZIP を、プログラム上は 1 個の GeoDataFrame として扱える形にする。20 件すべてが同列構造 (11 列) であることが事前監査で確認済みなので、和集合化なしで縦結合できる。本記事は単純に pd.concat し、src_city / src_dsid / ctype の 3 列で出所市町を識別できるようにする。

手法

直感: ZIP×20→geopandas→属性付与→concat→to_crs の 5 ステップ。Point データは Polygon と違って dissolve も sjoin も軽量なので、4.7 万点でも 1 秒未満で読み込める。

大筋 (5 ステップ)

  1. 20 市町について、それぞれの新築動向 ZIP を load_geojson_zip() で読む
  2. 各 GeoDataFrame に src_city/src_dsid/ctype 列を付与
  3. 20 個を pd.concat で縦結合 → 46,613 行 1 個
  4. to_crs(EPSG:6671) で広島県平面直角座標系に投影変換 (m 単位確保)
  5. 21 行政区域 (L15 共有) を dissolve(by='city') で 21 行政市町の境界にする

入出力: 入力 = 20 ZIP、出力 = 46,613 行 × 14 列の GeoDataFrame 1 個 + 21 市町行政境界 (背景描画用)。

前提と限界: 20 件の列構造が同一であることが大前提 (事前監査で OK 確認済)。NEW_YCD, KAIHATU_S, RITTEKI_CD は仕様書未公開のため、本記事はこれらを「観察可能な値の分布」として扱い、推測を抑える。

パラメータの意味: TARGET_CRS=EPSG:6671 は広島県専用の平面直角座標系。面積計算が m² 単位で正確になり、Point 間の距離も m で扱える。

実装

L20_new_construction.py 行 1108–1286

 1
 2
 3
 4
 5
 6
 7
 8
 9
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
DATA_DIR = ROOT / "data" / "extras" / "L20_new_construction"
ADMIN_DIR = ROOT / "data" / "extras" / "L15_admin_zones"
TARGET_CRS = "EPSG:6671"  # JGD2011 平面直角第III系 (広島県, m 単位)

# (dataset_id, 市町名, 行政_dsid, 都市タイプ) — 20 件
CITY_DEFS = [
    (1336, "広島市",     786, "政令市"),
    (1335, "呉市",       797, "中核市"),
    (1349, "福山市",     832, "中核市"),
    (1344, "東広島市",   868, "施行時特例市"),
    # ... 計 20 行
]


def load_geojson_zip(zip_path):
    """ZIP 内の単一 .geojson を BytesIO 経由で読み込む (一時ファイル不要)"""
    import io, zipfile
    with zipfile.ZipFile(zip_path) as zf:
        gjs = [n for n in zf.namelist() if n.endswith(".geojson")]
        with zf.open(gjs[0]) as f:
            return gpd.read_file(io.BytesIO(f.read()))


# 20 新築動向 GeoJSON を 1 GDF に縦結合
frames = []
for dsid, name, _adm, ctype in CITY_DEFS:
    g = load_geojson_zip(DATA_DIR / f"shinchiku_{dsid}_{name}.zip")
    g["src_city"] = name
    g["src_dsid"] = dsid
    g["ctype"] = ctype
    frames.append(g)

new_pts = gpd.GeoDataFrame(pd.concat(frames, ignore_index=True),
                            geometry="geometry", crs=frames[0].crs)
new_pts = new_pts.to_crs(TARGET_CRS)             # m 単位 化
N_POINTS = len(new_pts)  # 46,613 棟

# 21 行政区域 (L15 共有) を背景・面積基盤として読込
admin_frames = []
for _dsid, name, adm_ds, _ct in CITY_DEFS:
    g = load_geojson_zip(ADMIN_DIR / f"admin_{adm_ds}_{name}.zip")
    g["city"] = name
    admin_frames.append(g)
admin_all = gpd.GeoDataFrame(pd.concat(admin_frames, ignore_index=True),
                              geometry="geometry", crs=admin_frames[0].crs)
admin_all = admin_all.to_crs(TARGET_CRS)
admin_diss = admin_all.dissolve(by="city").reset_index()
admin_diss["admin_area_km2"] = admin_diss.geometry.area / 1e6

入出力 Before/After (具体例: ds=1336 広島市 新築動向)

段階サイズこのデータで起きていること
① 元 ZIPZIP (中身は 1 個の .geojson + 1 個の .xml メタ)648 KB 広島市の 2016-2020 新築 18,174 棟の Point + 11 属性
load_geojson_zip()GeoDataFrame18,174 行 × 11 列 ID, TOKEI_CD, CITY_CD (101-108 8 区), KUIKI_CD, ZU_NO, NEW_YCD, YOTO_SUB, KAIHATU_S, TATE_H, RITTEKI_CD, geometry (Point)
③ 属性付与GeoDataFrame18,174 行 × 14 列 src_city, src_dsid, ctype 付与
pd.concat (20 GDF)GeoDataFrame46,613 行 × 14 列 20 市町分が 1 個に縦結合される (広島市 18,174 + 福山市 10,162 + ... + 安芸高田市 106)
to_crs(EPSG:6671)GeoDataFrame46,613 行 JGD2011 平面直角第III系 (m 単位) に投影変換 (元から 6671 だが念のため統一)
⑥ 21 行政区域 dissolveGeoDataFrame20 行政市町 L15 で取得済の 21 行政区域 ZIP から MultiPolygon を 1 市町 1 行に整える

結果 (次セクションで使う)

このステップで new_pts (46,613 行 × 14 列, Point) と admin_diss (20 行政市町, MultiPolygon) が用意できた。以降の分析は全部これで完結する。全件 concat に要した時間は 1 秒未満 で、要件 S (1 分以内完走) を余裕でクリアする。

5. 分析2: YOTO_SUB 1,275 種を 9 大分類に集約

狙い

YOTO_SUB の生ユニーク値は 1,275 種類と非常に多い。このまま市町別構成比を計算すると、ほぼ全市町で 1 列 (一戸建ての住宅) だけが圧倒的になり、他の用途を比較できない。9 大分類に集約してから市町間比較する

手法

直感: YOTO_SUB は日本語自由記述に近いが、実は建築基準法施行令で定型語が決まっている (一戸建ての住宅、共同住宅、長屋、事務所、店舗、工場、倉庫、診療所、保育所...)。これらの定型語をキーワードとして文字列マッチで分類すれば、1,275 種類は 9 個に縮約できる。

9 大分類の境界

  1. 一戸建住宅: 「一戸建ての住宅」「一戸建の住宅」の表記揺れを統合
  2. 共同住宅: アパート/マンション類
  3. 長屋: テラスハウス類
  4. 住宅併用: 「住宅で〜を兼ねる」住居併用建築
  5. 店舗・商業: 物販・飲食・ホテル・銀行など商業全般
  6. 事務所: オフィスビル類 (純事務所、住宅併用は ④ に行く)
  7. 工場・倉庫: 製造・貯蔵・車庫
  8. 医療・福祉・教育: 病院・保育所・学校・福祉施設
  9. 公共・その他: 残り (公衆便所・あずまや・図書館等)

適用順 (重要): 上から順に評価し、最初にマッチしたバケットを採用する。「住宅で事務所、店舗を兼ねる」のような複合用途は ④ 住宅併用 を先に判定するため、事務所単独カテゴリには入らない。

限界: 「住宅併用」と「店舗・商業」の境界は曖昧 (例: 「住宅で店舗」は ④, 「店舗併用住宅」も ④, でも単独「物品販売店舗」は ⑤)。「自動車修理工場」は ⑦ 工場・倉庫だが、「自動車車庫」も ⑦。意思決定は本記事独自のもので、他の研究と直接比較するには分類規則を再公開する必要がある。

実装

L20_new_construction.py 行 1222–1285

 1
 2
 3
 4
 5
 6
 7
 8
 9
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
# YOTO_SUB 文字列を 9 大分類にバケット化するルール
# 順序が重要: 上から順に適用、最初にマッチしたルールを採用
YOTO_RULES = [
    ("一戸建住宅",   ["一戸建ての住宅", "一戸建の住宅"]),
    ("共同住宅",     ["共同住宅"]),
    ("長屋",         ["長屋"]),
    ("住宅併用",     ["住宅で", "併用住宅", "兼ねる"]),
    ("店舗・商業",   ["店舗", "コンビニ", "物品販売", "百貨店", "飲食店", "ホテル", "旅館",
                     "銀行", "美容", "理髪", "サロン", "クリーニング"]),
    ("事務所",       ["事務所"]),
    ("工場・倉庫",   ["工場", "倉庫", "車庫", "ガソリン"]),
    ("医療・福祉・教育", ["診療所", "病院", "保育", "幼稚", "学校", "図書", "美術", "博物",
                       "老人", "介護", "福祉", "助産", "養護", "デイ"]),
    ("公共・その他", []),  # 残り
]


def yoto_bucket(s):
    """YOTO_SUB 文字列を 9 大分類に分類"""
    if not isinstance(s, str):
        return "公共・その他"
    for label, kws in YOTO_RULES:
        if not kws:
            continue
        for kw in kws:
            if kw in s:
                return label
    return "公共・その他"


new_pts["yoto_bucket"] = new_pts["YOTO_SUB"].map(yoto_bucket)
yoto_dist = new_pts["yoto_bucket"].value_counts()

適用例 (Before/After 9 サンプル)

YOTO_SUB 生文字列 (Before)9 大分類 (After)
一戸建ての住宅一戸建住宅
共同住宅共同住宅
住宅で事務所、店舗その他これらに類する用途を兼ねるもの住宅併用
倉庫業を営まない倉庫工場・倉庫
診療所(患者の収容施設のないものに限る。)医療・福祉・教育
幼保連携型認定こども園公共・その他
コンビニエンスストア店舗・商業
工場(自動車修理工場を除く。)工場・倉庫
あずまや公共・その他

9 サンプルすべてが意図通りに分類された。「住宅で事務所、店舗その他...」のような複合用途が「住宅併用」に正しく振り分けられている点が重要 (順序ルールが効いている)。

図 5 — 市町別 用途構成 stack

なぜこの図か: 市町ごとに用途構成のバランスが違うかを 1 枚で見たいので、縦軸 0-100% 帯の積み上げ棒で全市町を並べる。もしすべての市町でほぼ同じ用途構成 (例: 一戸建が 80%) なら、棒は同じ色配分で並ぶ。もし市町ごとに大きく違うなら、色分布が市町間で目に見えて変わる。

市町別 新築用途構成 (9 大分類 stack)
市町別 新築用途構成 (9 大分類 stack)

この図から読み取れること (仮説 H2 と関係)

表 5a — 9 大分類 全県集計

順位9 大分類棟数シェア
1一戸建住宅38,40582.39%
2長屋2,0284.35%
3共同住宅1,9164.11%
4工場・倉庫1,0842.33%
5公共・その他8791.89%
6店舗・商業8411.8%
7事務所6961.49%
8医療・福祉・教育5001.07%
9住宅併用2640.57%

この表から読み取れること: 一戸建住宅が 38,405 棟 (82.39%) で圧倒的多数。住宅系 4 種で 90% を超える。店舗・商業と工場・倉庫がほぼ同水準 (各 1-2%)、医療・福祉・教育が 1% 弱。公共・その他は 1% 未満で、市町間比較では参考程度。

表 5b — YOTO_SUB 生文字列 上位 10

順位YOTO_SUB棟数シェア
1一戸建ての住宅37,99581.51%
2長屋2,0124.32%
3共同住宅1,8443.96%
4事務所5711.22%
5倉庫業を営まない倉庫4170.89%
6一戸建の住宅2990.64%
7自動車車庫1740.37%
8物品販売業を営む店舗980.21%
9飲食店820.18%
10日用品の販売を主たる目的とする店舗790.17%

この表から読み取れること: 1 位「一戸建ての住宅」が圧倒的で、81.5% を占める。2-3 位の長屋・共同住宅と合わせ、上位 3 種で 90% 弱。「一戸建ての住宅」と「一戸建の住宅」の表記揺れが本当に存在する (中黒「の」の有無) 。9 大分類化はこういう表記揺れも吸収できるメリットがある。

6. 分析3: 市町別 3 指標 (棟数 / 密度 / 人口千人あたり)

狙い

新築棟数を絶対値だけで比較すると、広島市が 18,174 棟で他をすべて圧倒し「人口集中市が新築 1 位」というほぼ自明の結論しか出ない。面積で割って密度 (棟/km²)、人口で割って人口千人あたり (棟/千人)という 2 つの正規化指標を加えると、新築の地理的密度住民あたりの建設活発度を同時に見られる。

手法

3 種の指標

密度と人口千人あたりは別物: 山間部の小村落は人口も面積も小さいので、両指標で別の側面が見える。広島市は密度トップだが人口千人あたりでは中位、府中町は面積 10km² と狭いため密度が高めに出る。

限界: 新築棟数は建築確認の正本ベースであり、増改築や仮設は含まないと推定。人口は R2 国勢調査値で 2020 年時点の値のため、2016-2020 期間平均としてはやや偏る (新築期間の前半は別の人口で割るべき)。本記事は「人口千人あたり」を 5 年累積の建設活発度として読む。

実装

L20_new_construction.py 行 1374–1401

 1
 2
 3
 4
 5
 6
 7
 8
 9
1383
1384
1385
1386
1387
# 市町別 集計
city_n = new_pts.groupby("src_city").size().rename("n_new")
city_summary = pd.DataFrame({
    "city": [d[1] for d in CITY_DEFS],
    "ctype": [d[3] for d in CITY_DEFS],
    "dsid": [d[0] for d in CITY_DEFS],
})
city_summary["area_km2"] = city_summary["city"].map(lambda c: CITY_REF[c]["area_km2"])
city_summary["pop_k"] = city_summary["city"].map(lambda c: CITY_REF[c]["pop_k"])
city_summary["n_new"] = city_summary["city"].map(city_n).fillna(0).astype(int)
# 3 種の正規化指標
city_summary["density_per_km2"] = city_summary["n_new"] / city_summary["area_km2"]
city_summary["per_1000pop"] = city_summary["n_new"] / city_summary["pop_k"]
city_summary["lip_strategic"] = city_summary["city"].isin(LIP_CITY_DSIDS).astype(int)

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

なぜこの図か: 3 つの指標 (棟数 / 密度 / 人口千人あたり) を同時に並列で見たいので、横並び 3 panel の棒グラフにする。棒の色は市町タイプ (政令市/中核市/特例市/市/町) で塗り分けると、都市階層と各指標の関係が一目で分かる。

市町別 新築指標 3 種 (棟数 / 密度 / 人口千人あたり)
市町別 新築指標 3 種 (棟数 / 密度 / 人口千人あたり)

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

表 6 — 市町別 全指標一覧 (棟数降順)

市町タイプ棟数面積 (km²)人口 (千人)密度 (棟/km²)千人あたり
広島市政令市18,1749071,18920.0415.29
福山市中核市10,16251845919.6122.14
東広島市施行時特例市4,7356351987.4523.91
呉市中核市2,6593532107.5412.66
廿日市市2,4724901175.0521.13
尾道市1,9132851306.7114.72
三原市1,085472902.3012.06
府中町793105376.2514.96
三次市760778500.9815.20
海田町745143053.9924.83
大竹市61079267.7523.46
府中市586196372.9915.84
熊野町511342315.1622.22
竹原市339118242.8714.12
庄原市2831246330.238.58
坂町244161215.5420.33
北広島町189646170.2911.12
江田島市128101221.275.82
世羅町119278150.437.93
安芸高田市106538270.203.93

この表から読み取れること: 棟数では広島市が圧倒だが、密度では府中町が1 位、千人あたりでは東広島市が突出。1 つの指標だけ見ると都市の特徴を見誤る。3 指標の総合で見ると、新築の都市的活発度は 東広島市 → 府中町 → 広島市 → 海田町 → 福山市 の順に高い、と評価できる。

7. 分析4: 全県点マップ + 20 市町 small multiples

狙い

46,613 点を 1 枚の地図にプロットして、県全域でどこに新築が立っているかを直感的に把握する。さらに 20 市町別のsmall multiples で、市町内の新築の集まり方 (中心集中型 / 分散型) を比較する。

手法

全県マップは scatter(x, y, c=用途, s=1, alpha=0.5)用途別色分け。Small multiples は 4×5 subplot で 20 市町を 1 panel 1 市町で並べる。地理スケールが市町ごとに違うのは敢えてそのまま (各市町を等比に)、「市町内の集まり方」を比較する目的に向いた表示。

実装

L20_new_construction.py 行 1469–1524

 1
 2
 3
 4
 5
 6
 7
 8
 9
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
yoto_palette = {
    "一戸建住宅":   "#1f77b4",  "共同住宅":     "#aec7e8",
    "長屋":         "#9edae5",  "住宅併用":     "#ff9896",
    "店舗・商業":   "#ff7f0e",  "事務所":       "#d62728",
    "工場・倉庫":   "#8c564b",  "医療・福祉・教育": "#2ca02c",
    "公共・その他": "#7f7f7f",
}

# 全県点マップ (Fig 1)
fig, ax = plt.subplots(figsize=(13, 9))
admin_diss.boundary.plot(ax=ax, color="#aaa", linewidth=0.4)
for yb in yoto_order:
    sub = new_pts[new_pts["yoto_bucket"] == yb]
    ax.scatter(sub.geometry.x, sub.geometry.y,
               c=yoto_palette[yb], s=1.0, alpha=0.5, label=f"{yb} ({len(sub):,})")
ax.set_aspect("equal")

# Small multiples (Fig 4)
fig, axes = plt.subplots(4, 5, figsize=(18, 14))
for ax_, city in zip(axes.flat, CITY_ORDER):
    pts = new_pts[new_pts["src_city"] == city]
    bg = admin_diss[admin_diss["city"] == city]
    bg.boundary.plot(ax=ax_, color="#888", linewidth=0.5)
    for yb in yoto_order:
        sub = pts[pts["yoto_bucket"] == yb]
        ax_.scatter(sub.geometry.x, sub.geometry.y,
                    c=yoto_palette[yb], s=2, alpha=0.6)
    ax_.set_aspect("equal")

図 1 — 全県 4.7 万点 用途別マップ

なぜこの図か: 4.7 万点を 1 枚で見ることで、新築が県内のどこに濃く分布しているかを直感的に把握できる。ホットスポットがあれば視覚的に塊として見える。用途別色分けで「住宅と工業の地理的住み分け」も同時に観察できる。

広島県 新築建物 2016-2020 用途別点マップ
広島県 新築建物 2016-2020 用途別点マップ

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

図 4 — 20 市町 small multiples

なぜこの図か: 全県マップは大都市が支配して小自治体の構造が見えない。各市町を等しい紙面サイズで並べる small multiples なら、「広島市の中心集中」「庄原市の谷沿い線形」「江田島市の島内分散」など市町内の構造が比較できる。20 panel 同時表示の効果は他では得られない。

市町別 small multiples — 新築点 用途別 (20 panel)
市町別 small multiples — 新築点 用途別 (20 panel)

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

8. 分析5: 4km 矩形ビンによる新築ホットスポット同定

狙い

点マップは 4.7 万点を一覧できるが、「ここに何棟あるか」を定量できない。県全域を 4km×4km の矩形セルに区切り、各セル内の新築棟数を集計してカラースケール (log scale) で塗ると、ホットスポットが定量的に見える。

手法

直感: 全県を 4km 格子に切る → 各点がどのセルに入るかをnumpy.searchsorted で求める → セル毎に件数集計 → 矩形を log スケールで塗る。

大筋 (4 ステップ)

  1. 新築点の bbox を取得 (xmin, ymin, xmax, ymax)
  2. 4km 間隔で gx, gy 軸を作る (numpy.arange)
  3. np.searchsorted(gx, xs) で各点が属するセル ix, iy を計算
  4. groupby(['ix','iy']).size() でセル毎件数を集計

パラメータ: セルサイズ 4km は試行錯誤の結果。1km だとセル数 6 万超になり描画が重い。10km だと粗すぎて広島市内の構造が見えない。4km は広島市内に約 10 セル × 10 セル のグリッドが乗り、解像度と表示量のバランスが良い。

log スケール: ビン内棟数は 1 〜 1000+ の 3 桁スパンを持つので、リニアスケールでは広島市中心部 (1000+) だけ目立って他のホットスポットが潰れる。log スケール (LogNorm) で、低密度から高密度まで均等に見える。

ハッシュ的軽量実装の理由: H3 (Uber 製ヘキサゴングリッド) を使うと綺麗な六角形になるが追加ライブラリ依存になる。np.searchsorted での矩形ビンはgeopandas + numpy だけで完結し、4.7 万点に対して 0.05 秒で終わる (要件 S 完璧クリア)。

実装

L20_new_construction.py 行 1580–1625

 1
 2
 3
 4
 5
 6
 7
 8
 9
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
xmin, ymin, xmax, ymax = new_pts.total_bounds
HEX_SIZE_M = 4000  # 4 km grid
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)

xs = new_pts.geometry.x.values
ys = new_pts.geometry.y.values
ix = np.searchsorted(gx, xs, side="right") - 1
iy = np.searchsorted(gy, ys, side="right") - 1
new_pts["_grid_ix"] = ix
new_pts["_grid_iy"] = iy
grid_n = new_pts.groupby(["_grid_ix", "_grid_iy"]).size().rename("n").reset_index()

# 描画 (log scale)
norm = LogNorm(vmin=1, vmax=grid_n["n"].max())
cmap = plt.get_cmap("magma_r")
for _, row in grid_n.iterrows():
    cx = gx_centers[int(row["_grid_ix"])]
    cy = gy_centers[int(row["_grid_iy"])]
    ax.add_patch(plt.Rectangle((cx - HEX_SIZE_M/2, cy - HEX_SIZE_M/2),
                                HEX_SIZE_M, HEX_SIZE_M,
                                facecolor=cmap(norm(row["n"])),
                                edgecolor="none", alpha=0.85))

図 2 — 4 km ビン 新築密度 (log scale)

なぜこの図か: 全県の新築ホットスポットを定量で見たい。非ゼロセル 233 個を log カラーマップで塗ると、max 1918 棟/16km² (広島市中心部) と 1 棟/16km² (山間部) の 3 桁スパンが同時に見える。

4 km 矩形ビン 新築棟数 (対数スケール)
4 km 矩形ビン 新築棟数 (対数スケール)

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

9. 分析6: 建物高さ分布 (全県 + 市町別) + 高層集中

狙い

新築建物の高さ分布は、その都市の住宅形態 (戸建 vs マンション)都心の高密度開発の有無 を強く反映する。全県のヒストグラムで二峰性を確認し、市町別箱ひげで「どの市町が高層化しているか」を見る。

重要なデータ注記: 本分析中、尾道市, 三原市 の 2 市の TATE_H は全件 0.0m という観察を得た (計 2,998 棟分)。これは記録段階での欠損 (測量データ未入力) と判断され、高さ分析からは当該 2 市を除外する。残り 18 市町 (n=43,615) が分析対象となる。DoBoX オープンデータの「同列構造でも市町ごとに記録粒度が異なる」という実例として、本記事は意図的にこの欠損問題を可視化する。

手法

(a) 全県ヒストグラム: np.histogram で 80 ビン、縦軸 log スケール (低頻度の高層が見えるように)。

(b) 市町別箱ひげ: plt.boxplot で 20 市町を縦並び、横軸 log スケール (中央値 7m と外れ値 100m を同時に見るため)。棟数降順に並べる。

9 段階の高さバンド (本記事独自定義): 0-3m / 3-6m / 6-9m / 9-12m / 12-15m / 15-20m / 20-30m / 30-60m / 60m超。「6-9m」が一戸建て (2 階建て) の標準、「9-12m」が 3 階建て一戸建てや小規模共同住宅、「12-15m」が中層共同住宅 (4-5 階)、「15-20m」が中規模マンション、「20-30m」が 7-10 階マンション、「30-60m」が 10-20 階タワー、「60m超」が超高層。

実装

L20_new_construction.py 行 283–304

 1
 2
 3
 4
 5
 6
 7
 8
 9
292
293
H_BANDS = [(-0.01, 3, "0-3m"), (3, 6, "3-6m"), (6, 9, "6-9m"),
           (9, 12, "9-12m"), (12, 15, "12-15m"), (15, 20, "15-20m"),
           (20, 30, "20-30m"), (30, 60, "30-60m"), (60, 200, "60m超")]
new_pts["h_band"] = pd.cut(new_pts["TATE_H"],
                            bins=[b[0] for b in H_BANDS] + [200],
                            labels=H_LABELS,
                            include_lowest=True)
h_cross = pd.crosstab(new_pts["src_city"], new_pts["h_band"])
h_cross = h_cross.reindex(CITY_ORDER, fill_value=0)[H_LABELS]
high20 = new_pts[new_pts["TATE_H"] >= 20]
print(f"高層 (≥20m) 棟数: {len(high20)}")

図 6 — ヒストグラム + 市町別箱ひげ (有効 18 市町)

なぜこの図か: ヒストグラムだけだと「どの市町に高層が集中するか」が分からない。ヒストグラムと市町別箱ひげを並べると「全体の形」と「市町別の偏り」を 1 枚で観察できる。尾道市・三原市は TATE_H 全件 0 のため除外、有効 18 市町のみで描画する。

建物高さ分布 + 市町別 箱ひげ図 (有効 18 市町)
建物高さ分布 + 市町別 箱ひげ図 (有効 18 市町)

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

図 7 — 高層 (≥20m) バブルマップ

なぜこの図か: 全 4.7 万点のうち高層は約 495 棟 (1.06%) と少数だが、都市計画上の影響は大きい。位置を地図にプロットして高さでバブル + カラーすると、「県内のどこに高層が立っているか」が一目で分かる。

高層新築 (≥20m) の地理分布
高層新築 (≥20m) の地理分布

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

表 9a — 高さバンド集計 (有効 18市町計, n=43,615)

高さバンド棟数シェア
0-3m5661.30%
3-6m2,8336.50%
6-9m34,34178.74%
9-12m5,04311.56%
12-15m2070.47%
15-20m1300.30%
20-30m1680.39%
30-60m3180.73%
60m超90.02%

この表から読み取れること: 6-9m バンドが 78.74% で圧倒的。9-12m (3 階建て) が次点 (11.6%)。20m 以上は合計でも 1% 未満。「広島県の新築は基本的に低層」が定量で示される。

表 9b — 高層 (≥20m) 上位 5 棟

順位市町用途 (YOTO_SUB)高さ (m)
1広島市共同住宅178.07
2広島市診療所(患者の収容施設のあるもの)産婦人科106.00
3広島市事務所     08490 自動車車庫94.89
4広島市ホテル93.92
5広島市事務所、ホテル、テナント(物品販売業を営む店舗等)90.75

この表から読み取れること: 県内最大は 広島市 の 178m (おそらく中区/南区のタワーマンション)。上位 5 棟すべてが共同住宅または事務所で、『高層 = タワーマンション + 事務所ビル』という都市の超高密化を象徴。

10. 分析7: 用途多様性 vs 新築総数 (Heaps 的構造)

狙い

大都市は商業・住宅・工業・公共などあらゆる用途が建つが、小自治体は「ほぼ一戸建てだけ」になる傾向。これを用途多様性として定量し、新築総数との関係を log-log で見れば、テキスト解析の Heaps の法則(文書サイズが N 倍ならユニーク語彙は √N 倍) と類似の構造があるかを検証できる。

手法

(a) ユニーク値数: YOTO_SUB.nunique() を市町別に計算。1,275 種類の生文字列のうち、各市町で何種類が現れたかをカウント。

(b) シンプソン多様度: 9 大分類のシェア p_i を使って 1 - sum(p_i^2)。0=完全に 1 用途、1=完全に均等。解釈しやすい標準指標。

(c) log-log 散布: x = 新築総数, y = YOTO_SUB ユニーク値数 を log-log 軸で。Heaps の法則なら直線 (傾き 0.4-0.7) になる。

限界: 1 棟しかない市町は YOTO_SUB ユニーク値も 1 しか取れず、サンプルサイズ依存性がある。本記事は 100 棟以上の市町だけ強い結論にし、100 棟未満は参考扱い。

実装

L20_new_construction.py 行 268–301

 1
 2
 3
 4
 5
 6
 7
 8
 9
277
278
279
280
281
282
283
284
def simpson_diversity(row):
    p = row / row.sum() if row.sum() > 0 else row
    return 1.0 - (p ** 2).sum()

city_summary["yoto_diversity"] = city_summary["city"].map(
    lambda c: simpson_diversity(yoto_cross.loc[c]) if c in yoto_cross.index else 0.0
)
yoto_unique = new_pts.groupby("src_city")["YOTO_SUB"].nunique()
city_summary["yoto_unique_raw"] = city_summary["city"].map(yoto_unique)

# log-log 回帰
log_x = np.log10(city_summary["n_new"])
log_y = np.log10(np.where(city_summary["yoto_unique_raw"] > 0,
                           city_summary["yoto_unique_raw"], 1))
mask = (city_summary["n_new"] > 0) & (city_summary["yoto_unique_raw"] > 0)
a, b = np.polyfit(log_x[mask], log_y[mask], 1)
print(f"傾き a={a:.3f}, 切片 b={b:.3f}")

図 8 — 用途多様性 log-log 散布

なぜこの図か: 直線関係 (べき乗則) を確認したい時はlog-log 散布が最適 (両軸 log で直線になる)。傾き a が Heaps 指数 (β とも書く) で、テキスト解析では 0.4-0.6 程度が知られる。用途多様性に同様の構造があるかを検証する。

用途多様性 — Heaps 的構造 (log-log)
用途多様性 — Heaps 的構造 (log-log)

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

表 10 — 市町別 用途多様性ランキング

順位市町新築棟数YOTO_SUB ユニーク値シンプソン多様度
1広島市18,1745280.329
2福山市10,1623440.315
3東広島市4,7351990.271
4呉市2,6591510.282
5尾道市1,9131440.337
6廿日市市2,4721100.221
7三原市1,085690.270
8三次市760550.410
9府中市586540.365
10府中町793440.361
11熊野町511390.198
12庄原市283360.494
13大竹市610350.304
14竹原市339330.446
15海田町745330.313
16北広島町189270.593
17安芸高田市106220.534
18江田島市128220.519
19坂町244170.256
20世羅町119150.289

この表から読み取れること: ユニーク値 1 位は広島市 (528 種類)、2 位 福山市 (344 種類)、3 位 東広島市。シンプソン多様度では順位が変わり、0.3-0.5 のレンジに大半が収まる ─ どの市町も 「一戸建が 80%」に支配されているため。シンプソン高めの市町は住宅併用や工場が混じる小都市 (尾道市・三原市) で、用途構成が均等寄り。

11. 分析8: LIP 8 市 — 新築の居住誘導内シェア (政策機能検証)

狙い

立地適正化計画 (LIP) は、人口減少社会で都市を集約するために 8 市が策定した法定計画。計画上の居住誘導区域 (KUIKI_CD=1) に、実際の新築がどれだけ立地したかを空間結合 (sjoin) で定量する。これは政策の機能性検証そのものであり、「政策があれば実建設は誘導されるか?」という都市計画学の中心問題に応える。

手法

大筋 (4 ステップ)

  1. L19 (居住誘導区域) で取得した 8 市分の Polygon GeoJSON を読込
  2. 各市について、KUIKI_CD=1 (居住誘導) と KUIKI_CD=3 (都市機能誘導) に分離(KUIKI=2,4 は境界線データなので除外)
  3. geopandas.sjoin(points, polygons, how='inner', predicate='within')で、新築点が KUIKI=1/3 内に入っているかを判定
  4. 市町ごとに in/out 件数を集計、居住誘導内シェアを算出

predicate='within': 点が完全にポリゴン内部にある場合のみマッチ。境界線上は除外される (within ⊃ contains の双対)。新築点はほぼ常に建物中心なので within で安全。

限界: 居住誘導区域は「居住を集めたい区域」であり、区域外の建設を法的に禁じてはいない。シェアが低くても LIP が「機能していない」とまでは断定できない (緩やかな誘導)。本記事は「50% を切るならまだ誘導が実態をリードできていない」と保守的に読む。

実装

L20_new_construction.py 行 108–161

 1
 2
 3
 4
 5
 6
 7
 8
 9
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
LIP_CITY_DSIDS = {
    "広島市":   795, "呉市":     805, "竹原市":   812, "三原市":   822,
    "福山市":   838, "府中市":   848, "東広島市": 876, "廿日市市": 886,
}

lip_records = []
for city, dsid in LIP_CITY_DSIDS.items():
    z = LIP_DIR / f"jukyo_{dsid}_{city}.zip"
    lip_g = load_geojson_zip(z).to_crs(TARGET_CRS)
    lip_jukyo = lip_g[lip_g["KUIKI_CD"] == 1].copy()    # 居住誘導 (面)
    lip_kinou = lip_g[lip_g["KUIKI_CD"] == 3].copy()    # 都市機能誘導 (面)
    pts_city = new_pts[new_pts["src_city"] == city]
    in_jukyo = gpd.sjoin(pts_city, lip_jukyo[["geometry"]],
                          how="inner", predicate="within")
    in_kinou = gpd.sjoin(pts_city, lip_kinou[["geometry"]],
                          how="inner", predicate="within")
    n_total = len(pts_city)
    n_in_jukyo = in_jukyo.index.nunique()  # 重複ポリゴンによる重複排除
    n_in_kinou = in_kinou.index.nunique()
    lip_records.append({
        "city": city, "n_new": n_total,
        "n_in_jukyo": n_in_jukyo,
        "share_jukyo_pct": 100 * n_in_jukyo / n_total,
        "n_in_kinou": n_in_kinou,
        "share_kinou_pct": 100 * n_in_kinou / n_total,
    })
lip_summary = pd.DataFrame(lip_records)

図 10 — LIP 8 市 居住誘導内シェア + 広島市重ねマップ

なぜこの図か: 棒グラフだけだと「割合」しか見えない。1 市 (広島市) を例に in/out をマップで重ねると、「誘導区域はどこに、新築はどこに」「区域外に立っている新築はどこか」という地理的な実態が見える。

LIP 8 市 — 新築の居住誘導区域内シェア + 広島市マップ
LIP 8 市 — 新築の居住誘導区域内シェア + 広島市マップ

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

表 11 — LIP 8 市 居住誘導内シェア

市町新築総数居住誘導内シェア(居住)都市機能内シェア(都市機能)
広島市18,17417,36095.5%00.0%
廿日市市2,4722,32994.2%220.9%
府中市58646579.3%00.0%
福山市10,1627,76276.4%00.0%
呉市2,6591,60460.3%1164.4%
三原市1,08562357.4%14613.5%
東広島市4,7352,60154.9%1332.8%
竹原市33900.0%21463.1%

この表から読み取れること: 居住誘導内シェアの分布から、「LIP は計画と実態が一致する市町」と「ずれている市町」が分かる。都市機能内シェアは全市町で低く (1-10%) 、これは都市機能区域が物理的に小さい設計のため自然。居住誘導は政策の機能性を測る主指標として、市町別の都市計画評価に使える。

12. 分析9: NEW_YCD クロス + 市町別 集中度

狙い

NEW_YCD は仕様未公開だが、市町別偏りから年代差や記録手続きの違いを推察できる。一方、市町別の集中度 (重心からの平均距離) は、新築が市町内のどこに集まっているかを 1 値で表す古典的指標。両者を組み合わせると、市町ごとの「いつ、どこに集まったか」が見える。

手法 (1) NEW_YCD ヒートマップ

pd.crosstab(src_city, NEW_YCD) で 20×5 のクロス表を作り、log10 スケールで imshow。もし NEW_YCD が単純に年 (1-5 が 2016-2020) なら、市町間でほぼ同じ分布になるはず。ばらつきがあれば記録慣習の違い建設時期の偏りを示す。

手法 (2) 集中度

標準距離: sqrt(((x-x_mean)² + (y-y_mean)²).mean())median 距離: 重心からの距離の中央値。P90 距離: 90 パーセンタイル距離。標準距離が小さければ「重心に集中」、大きければ「広く分散」。市町タイプとセットで散布図にすると、規模と集中度の関係が見える。

実装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# (1) NEW_YCD クロス
ycd_cross = pd.crosstab(new_pts["src_city"], new_pts["NEW_YCD"])

# (2) 集中度
centroid_records = []
for city in CITY_ORDER:
    pts = new_pts[new_pts["src_city"] == city]
    if len(pts) == 0: continue
    cx, cy = pts.geometry.x.mean(), pts.geometry.y.mean()
    dx = pts.geometry.x - cx
    dy = pts.geometry.y - cy
    sd = float(np.sqrt((dx**2 + dy**2).mean())) / 1000  # km
    d_each = np.sqrt(dx**2 + dy**2) / 1000
    p90 = float(d_each.quantile(0.90))
    p50 = float(d_each.quantile(0.50))
    centroid_records.append({"city": city,
                              "centroid_x": cx, "centroid_y": cy,
                              "std_dist_km": sd,
                              "median_dist_km": p50,
                              "p90_dist_km": p90})
centroid_df = pd.DataFrame(centroid_records)

図 9 — NEW_YCD 市町別ヒートマップ

なぜこの図か: 20 市町×5 コード のクロス表は表のままだと桁違いの数値で読みづらい。log10 ヒートマップに、生数値を重ね書きすると、「何件あったか」と「市町間の比較」が同時に見える。

市町 × NEW_YCD クロス (log10 ヒートマップ + 数値)
市町 × NEW_YCD クロス (log10 ヒートマップ + 数値)

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

図 11 — 市町別 集中度 散布図

なぜこの図か: 「広い市町は新築も広く散らばるか」を見たい。log scale 横軸 (新築総数) × 縦軸 (標準距離) で 20 市町を点として並べ、市町タイプ色で塗ると、4 象限の都市類型が見える。

市町タイプ別 集中度 — 「広いが疎」と「狭いが密」の二極
市町タイプ別 集中度 — 「広いが疎」と「狭いが密」の二極

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

表 12 — 市町別 集中度

市町タイプ新築棟数標準距離 (km)中央値 (km)P90 (km)
安芸高田市1060.890.581.59
海田町7450.960.801.57
府中町7931.030.961.41
世羅町1191.200.991.85
熊野町5111.511.142.03
北広島町1891.701.442.54
坂町2441.731.073.15
大竹市6101.851.473.01
府中市5863.241.262.52
竹原市3393.751.297.25
廿日市市2,4723.853.185.60
三次市7604.102.307.69
三原市1,0854.163.116.15
江田島市1284.263.986.84
東広島市施行時特例市4,7355.733.5511.22
呉市中核市2,6595.954.549.04
福山市中核市10,1626.215.309.94
尾道市1,9136.253.8812.24
広島市政令市18,1747.056.0110.79
庄原市2838.513.4820.39

この表から読み取れること: 集中度の小さい (重心に集まっている) 順。府中町・海田町・坂町などベッドタウン町部が上位 (狭いから当然)。中位は中規模都市 (尾道市・福山市・三原市)。下位 (広く分散) は山間部の三次市・庄原市・北広島町。標準距離は市町面積の影響が強いので、生値だけで都市類型を結論するのは禁物。図 11 の散布図と組み合わせて読むこと。

13. 仮説検証と考察

仮説 H1〜H6 検証 結果一覧

仮説内容結果判定
H1上位 3 市で 70% 超['広島市', '福山市', '東広島市'] で 70.95%支持
H2一戸建住宅 80% 超 / 住宅系で 90% 超一戸建 82.39%, 住宅系 91.42%支持
H3新築密度の最大/最小比が 2 桁以上府中町 76.2 / 安芸高田市 0.20 = 386.9 倍支持
H4高さ 6-9m が 70% 超 / 高層 (>=20m) は局所6-9m 78.74%, ≥20m 495 棟支持
H5用途多様性 ∝ 新築総数 (Heaps 的)傾き a=0.669, 切片 b=-0.178支持
H6LIP 策定市の新築居住誘導内シェア中央値 76.38%, 最小 東広島市, 最大 広島市部分支持 (50% 以上、政策効いている)

考察 — 4.7 万棟が語る広島県の都市構造

(1) 集中構造: 仮説 H1 が支持され、上位 3 市 (広島市・福山市・東広島市) で 県全体の 70.95% を占める。新築は人口集中市に集中するという単純則が確認された。残り 17 市町が分け合うのは 30% 弱で、町部 7 自治体だけ見れば全県の 5% 未満しかない。「人口減少社会で建設活動も減る」が県平均では成り立つが、市町別では 2 桁スケールの差が広がる。

(2) 用途の単一化: 仮説 H2 が支持され、住宅系 4 種で 91.42%、一戸建てだけで 82.39% を占める。「新築 ≅ 一戸建ての住宅」という現実が定量で出た。これは持ち家文化の継続と、新築需要の中心が依然として戸建てにある実態を示す。共同住宅の比率は約 4% で、賃貸供給の主力は中古ストックリノベーションに移っている可能性も読める。

(3) 地理的二極化: 仮説 H3 が支持され、新築密度の最大/最小比は 386.9 倍 (府中町 76.2 棟/km² / 安芸高田市 0.20 棟/km²)。同じ広島県でも 2 桁オーダーの密度差。図 2 の 4km ビンで見ると、新築は広島市デルタ + 福山市平野 + 沿岸ベルトに集中し、北部山間部はほぼ空白。「コンパクト化」と「過疎化」が同じ県内で並行進行している事実が見える。

(4) 高さ構造: 仮説 H4 が支持され、6-9m バンドが 78.74% で圧倒的。高層 (>=20m) は 495 棟 (1.06%) に過ぎず、広島市・福山市の中心部にほぼ局所集中。広島県の新築は基本的に低層 + 中心部だけ高層という二峰構造。東京 23 区のような全面的な高層化はまだ起きていない。

(5) Heaps 的構造: 仮説 H5 が 支持。傾き a=0.669, 切片 b=-0.178 の log-log 直線が20 市町を概ね通る。テキストの語彙成長と同様の飽和的成長が用途多様性にも見える。「新築が 10 倍になると用途種類は約 4.7 倍」という数式的関係が示唆される。これは都市の経済規模と機能多様性が結合する古典的な都市経済学命題と整合する。

(6) LIP 政策機能性: 仮説 H6 の判定は 居住誘導策定 7 市 (KUIKI=1 不在の竹原市を除く) で中央値 76.38% で 部分支持 (50% 以上、政策効いている)。最低 東広島市 (シェア最小) と最高 広島市 (シェア最大) で大きな差。中央値 が 76.38% ということは、LIP 策定市の新築の「過半数」が居住誘導内に立地していることを意味する。計画と実態のミスマッチを抱える市町があり、誘導の仕組み (税制優遇・インフラ整備優先) を見直す必要があるのか、計画区域そのものを実態に合わせて見直す必要があるのか、政策評価の出発点として極めて重要なシグナル。また、竹原市の「居住誘導区域 0 件」という発見は、LIP 策定済みでも法定区域の整備状況が市町によって異なることを示している。

研究的含意

(a) コンパクト+ネットワークの実装は不均衡: 全 8 市が LIP を策定したが、実建設の誘導内シェアは市町間で大差。計画策定 = 実装ではないことが実証された。今後の都市計画研究は「策定済み市の実装度」のモニタリングに移る必要がある。

(b) 一戸建て中心は政策的課題: 90% 超が住宅、80% 超が一戸建ての現実は、コンパクトシティ理論が想定する「集合住宅 + 都市機能集積」とは方向性が異なる。持ち家戸建て指向の慣習が、コンパクト化政策を内側から限界付けている可能性が読める。

(c) 山間部の新築 1 棟/km² 未満は人口維持の最後線: 5 年間で 100 棟程度 (= 年 20 棟) しか建っていない自治体があり、建設業者の存続も困難になる水準。建設活動の維持自体が地域維持の閾値に達している可能性が、本データから示唆される。

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

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

① 計画と実態のミスマッチを定量する

② NEW_YCD の意味を確定する

③ 一戸建ての地理空間特性を深掘り

④ 用途地域 (L17) との空間結合

⑤ 高層建築 501 棟の経済的意味

⑥ 宅地開発 L21 (S03 系) との時空間結合