6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixir Livebook で国土交通省の都市計画データを視覚化する(工業地域や商業地域、道路などを地図上に表す)

Last updated at Posted at 2024-08-19

はじめに

『国交省GISデータ「全公開」の衝撃、企業はどう活用すればいいのか?』という記事を見ました

とりあえず、 Livebook で視覚化してみましょう

以前、行政区域データを扱ったときと基本的には同じ手順になります

実装したノートブックはこちら

出典

「国土数値情報(都市計画データ)」(国土交通省)(https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-A55-2022.html)を加工して作成

都市計画とは

好き勝手に無秩序に都市を作ってしまうと、道路が上手く繋がっていないせいで渋滞が起きたり、商業施設があちこちに分散して不便になったり、住宅地のすぐ近くに工場ができたり、様々な問題が起こってしまいます

そこで、合理的に土地を使って都市を作るために都市計画を立てます

都市計画法という法律に都市計画のルールが決められています

第一章 第二条 (都市計画の基本理念)

都市計画は、農林漁業との健全な調和を図りつつ、健康で文化的な都市生活及び機能的な都市活動を確保すべきこと並びにこのためには適正な制限のもとに土地の合理的な利用が図られるべきことを基本理念として定めるものとする。

法律を読むより、実際に作られた都市計画を読んだ方が分かりやすいです

都市計画では、「どの土地をどういう目的で使うか?」といったことが計画されます

国土交通省で全国自治体の都市計画データが統一フォーマットで公開されたため、様々なことに活用しやすくなりました

都市計画データのダウンロード

以下の国土交通省の Web サイトから都市計画データがダウンロードできます

年度とデータ形式を選択します

本記事では GEOJSON 形式を使用します

スクリーンショット 2024-08-18 20.19.54.png

続いて県と市を指定すると、ダウンロードボタンが表示されます

本記事では大分県大分市を使用します

スクリーンショット 2024-08-18 20.22.10.png

データは "A55-22_44201_GEOJSON.zip" といったような ZIP ファイルでダウンロードされます

展開すると、以下のようなファイルが含まれています

  • 44201_bouka.geojson
  • 44201_chikukei.geojson
  • 44201_douro.geojson
  • 44201_koudori.geojson
  • 44201_kouen.geojson
  • 44201_ritteki.geojson
  • 44201_senbiki.geojson
  • 44201_tkbt.geojson
  • 44201_tochiku.geojson
  • 44201_tokei.geojson
  • 44201_youto.geojson
  • A55_R4_AttributeCodelist.xlsx
  • KS-META-A55-23_44.xml

本記事ではこれらのファイルを "/tmp/geo/" 配下に配置したものとして進めます

Livebook のはじめ方

Livebook のはじめ方は以下の記事を参照してください

都市計画視覚化の実装

セットアップ

Livebook を起動し、右上 "+ New notebook" ボタンで新しいノートブックを作成します

スクリーンショット 2024-08-18 20.28.55.png

セットアップセル("Notebook dependencies and setup" と書いてある枠内)をクリックします

スクリーンショット 2024-08-18 20.29.53.png

すると、黒い枠に変わり、 Elixir のコードが入力できるようになります

スクリーンショット 2024-08-18 20.32.20.png

以下のコードを入力し、左上の "Reconnect and setup" をクリックします

Mix.install([
  {:geo, "~> 3.6"},
  {:jason, "~> 1.4"},
  {:kino, "~> 0.13"},
  {:kino_maplibre, "~> 0.1"}
])

これにより、必要なモジュールがインストールされます

ファイル一覧の取得

ディレクトリーは以下にある ".geojson" ファイルの一覧を取得します

geo_dir = "/tmp/geo"

geojson_file =
  geo_dir
  # ファイル一覧取得
  |> File.ls!()
  # `.geojson` で終わるものを取得
  |> Enum.filter(&String.ends_with?(&1, ".geojson"))
  # 並べ替え
  |> Enum.sort()

実行結果

["44201_bouka.geojson", "44201_chikukei.geojson", "44201_douro.geojson", "44201_koudori.geojson",
 "44201_kouen.geojson", "44201_ritteki.geojson", "44201_senbiki.geojson", "44201_tkbt.geojson",
 "44201_tochiku.geojson", "44201_tokei.geojson", "44201_youto.geojson"]

GEOJSON の読込

各ファイルを読み込みます

geo_data =
  geojson_file
  |> Enum.into(%{}, fn filename ->
    key =
      filename
      |> String.split(".")
      |> hd()
      |> String.split("_")
      |> Enum.reverse()
      |> hd()
      |> String.to_atom()

    data =
      [geo_dir, filename]
      |> Path.join()
      |> File.read!()
      |> Jason.decode!()
      |> Geo.JSON.decode!()

    {key, data}
  end)

例えば geo_data.tokei の中には都市計画区域のデータが入っています

関数の定義

後で使う関数を定義しておきます

# 地理情報を抽出する
filter_geometries = fn geometries, key, value ->
  geometries
  |> Enum.filter(fn geometry ->
    Map.get(geometry.properties, key) == value
  end)
  |> then(fn filtered ->
    %{
      __struct__: Geo.GeometryCollection,
      srid: nil,
      geometries: filtered,
      properties: %{}
    }
  end)
end
# 地図上にレイヤーを追加する
add_layer = fn map, data, key, color, opacity ->
  map
  |> MapLibre.add_geo_source(key, data)
  |> MapLibre.add_layer(
    id: key,
    source: key,
    type: :fill,
    paint: [fill_color: color, fill_opacity: opacity]
  )
end

都市計画区域

以下のコードを実行すると、大分市の都市計画区域が地図上に青く表示されます

MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 9.5)
|> add_layer.(geo_data.tokei, "都市計画区域", "#0000FF", 0.5)

スクリーンショット 2024-08-18 20.52.02.png

青くなっていないところは都市計画区域外です

このように、 MapLibre を使うことで地図情報を簡単に視覚化できます

区域区分

区域区分は以下の二つに分類されます

  • 市街化区域: すでに市街化されているか、今後10年以内に優先的かつ計画的に市街化する地域
  • 市街化調整区域: 市街化を抑制する地域

市街化区域を紫、市街化調整区域を緑で色分けしてみましょう

senbiki_color_map =
  %{
    "市街化区域" => "#FF00FF",
    "市街化調整区域" => "#00FF00"
  }
senbiki_map = MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 9.5)

senbiki_color_map
|> Enum.reduce(senbiki_map, fn {senbiki, color}, map ->
  target_data = filter_geometries.(geo_data.senbiki.geometries, "区域区分", senbiki)
  add_layer.(map, target_data, senbiki, color, 0.7)
end)

スクリーンショット 2024-08-18 21.23.53.png

概ね、平野が紫に、山地が緑になっています

用途地域

用途地域とは、商業地域や工業地域など、目的に応じた用途を定めている地域です

用途地域データを一つ見てみましょう

hd(geo_data.youto.geometries)

実行結果

%Geo.Polygon{
  coordinates: [
    [
      {131.65889593, 33.137780418},
      {131.658823506, 33.137769104},
      {131.658637339, 33.138286862},
      {131.658549054, 33.13849049},
      {131.65847681, 33.138666893},
      {131.658259591, 33.139260104},
      {131.658187178, 33.139464643},
      {131.658143537, 33.139574701},
      ...
    ]
  ],
  srid: nil,
  properties: %{
    "Citycode" => "44201",
    "Cityname" => "大分市",
    "Pref" => "大分県",
    "YoutoID" => 12,
    "告示番号" => nil,
    "容積率" => 200.0,
    "建ぺい率" => 60.0,
    "決定区分" => nil,
    "決定日" => nil,
    "決定者" => nil,
    "用途地域" => "工業地域"
  }
}

地域は多角形(ポリゴン)として表され、その頂点を coordinates 内に緯度経度で保持しています

properties には各地域の属性情報が入っており、 YoutoID用途地域 を見れば、どの用途に使う地域なのかがわかるようになっています

YoutoID などのコードマスターはこちら

用途地域毎に色分けしてみましょう

youto_color_map =
  %{
    "第1種低層住居専用地域" => "#549F52",
    "第2種低層住居専用地域" => "#B0D397",
    "第1種中高層住居専用地域" => "#64B36D",
    "第2種中高層住居専用地域" => "#9FC662",
    "第1種住居地域" => "#F4EB4E",
    "第2種住居地域" => "#F5C345",
    "準住居地域" => "#ED9D3E",
    "田園住居地域" => "#BE6C38",
    "近隣商業地域" => "#EACFE2",
    "商業地域" => "#BC7CAE",
    "準工業地域" => "#9595C5",
    "工業地域" => "#D9EBF1",
    "工業専用地域" => "#77C4F2"
  }

各関数を利用し、用途地域毎のレイヤーを地図上に表示します

youto_map = MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 10.5)

youto_color_map
|> Enum.reduce(youto_map, fn {youto, color}, map ->
  target_data = filter_geometries.(geo_data.youto.geometries, "用途地域", youto)
  add_layer.(map, target_data, youto, color, 0.7)
end)

実行結果

スクリーンショット 2024-08-18 21.09.51.png

また、以下のコードを実行すると、用途地域毎に別タブで表示することができます

youto_color_map
|> Enum.map(fn {youto, color} ->
  target_data = filter_geometries.(geo_data.youto.geometries, "用途地域", youto)

  map =
    MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 10.5)
    |> add_layer.(target_data, youto, color, 0.7)

  {youto, map}
end)
|> Kino.Layout.tabs()

実行結果

map_tab.gif

大分駅周辺が商業地域、新日鐵の辺りが工業専用地域になっていることなどが分かります

高度利用地区

高度利用地区とは、有効活用するために空けておく地区です

MapLibre.new(style: :terrain, center: {131.606, 33.234}, zoom: 16)
|> add_layer.(geo_data.koudori, "高度利用地区", "#0000FF", 0.7)

実行結果

スクリーンショット 2024-08-18 21.34.05.png

大分駅北西側が対象になっています

近年、大規模な整理が行われたことは記憶に新しいですね

防火地域・準防火地域

防火地域・準防火地域は、市街地における火災の被害抑制のため、設備などに制限を設ける地域です

防火地域を明るい赤、準防火地域を暗い赤で視覚化してみます

bouka_color_map =
  %{
    "防火地域" => "#FF0000",
    "準防火地域" => "#880000"
  }

bouka_map = MapLibre.new(style: :terrain, center: {131.64, 33.24}, zoom: 12)

bouka_color_map
|> Enum.reduce(bouka_map, fn {bouka, color}, map ->
  target_data = filter_geometries.(geo_data.bouka.geometries, "防火準防火", bouka)
  add_layer.(map, target_data, bouka, color, 0.8)
end)

実行結果

スクリーンショット 2024-08-18 21.43.05.png

準防火地域は大分市街地と鶴崎が対象になっています

防火地域は大分駅から竹町、中央町の商店街辺りが対象です

地区計画

開発や再開発を促進しようとしている地区です

MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 10.5)
|> add_layer.(geo_data.chikukei, "地区計画", "#0000FF", 0.8)

実行結果

スクリーンショット 2024-08-18 21.48.05.png

大分駅周辺や荷揚町などが対象になっています

荷揚リンクスクエアが最近オープンしましたね

特別用途地区

住環境を保全するなどの目的のため、大型集客施設などの建築を抑制する地区です

MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 10.5)
|> add_layer.(geo_data.tkbt, "特別用途地区", "#0000FF", 0.8)

実行結果

スクリーンショット 2024-08-18 21.57.59.png

土地区画整理事業

土地区画整理事業の対象となっている地域です

土地区画整理事業は、道路、公園、河川等の公共施設を整備・改善し、土地の区画を整え宅地の利用の増進を図る事業

MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 10.5)
|> add_layer.(geo_data.tochiku, "土地区画整理事業", "#FF00FF", 0.8)

実行結果

スクリーンショット 2024-08-18 22.03.43.png

大分市街地から鶴崎、大在、坂ノ市など、人口の多い地域をカバーしています

立地適正化計画

住居や福祉施設、商業施設がまとまっているようにするための計画です

我が国の都市における今後のまちづくりは、人口の急激な減少と高齢化を背景として、高齢者や子育て世代にとって、安心できる健康で快適な生活環境を実現すること、財政面及び経済面において持続可能な都市経営を可能とすることが大きな課題です。こうした中、医療・福祉施設、商業施設や住居等がまとまって立地し、高齢者をはじめとする住民が公共交通によりこれらの生活利便施設等にアクセスできるなど、福祉や交通なども含めて都市全体の構造を見直し、『コンパクト・プラス・ネットワーク』の考えで進めていくことが重要です。

居住誘導区域外に住居を建てる場合、特別な届出が必要になります

また、都市機能誘導区域外に大規模商業施設や福祉施設を建てる場合、逆に都市機能誘導区域内の大規模商業施設や福祉施設を休廃止する場合にも特別な届出が必要です

居住誘導区域 を赤、 都市機能誘導区域 を青にしました

ritteki_color_map =
  %{
    "居住誘導区域" => "#FF0000",
    "都市機能誘導区域" => "#0000FF"
  }

ritteki_map = MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 10.5)

ritteki_color_map
|> Enum.reduce(ritteki_map, fn {ritteki, color}, map ->
  target_data = filter_geometries.(geo_data.ritteki.geometries, "区域区分", ritteki)
  add_layer.(map, target_data, ritteki, color, 0.5)
end)

実行計画

スクリーンショット 2024-08-18 22.13.15.png

いわゆる市街地に集中するように計画されています

都市施設

公園や緑地、墓場、道路など、都市機能に必要な施設を視覚化します

  • 公園: 黄
  • 緑地: 緑
  • 墓場: 青
  • 道路、広場: 黒線
kouen_color_map =
  %{
    "公園" => "#FFFF00",
    "緑地" => "#00FF00",
    "墓園" => "#0000FF"
  }

road_data = filter_geometries.(geo_data.douro.geometries, "区分", "道路")
plaza_data = filter_geometries.(geo_data.douro.geometries, "区分", "広場")

kouen_map = MapLibre.new(style: :terrain, center: {131.68, 33.21}, zoom: 10.5)

kouen_color_map
|> Enum.reduce(kouen_map, fn {kouen, color}, map ->
  target_data = filter_geometries.(geo_data.kouen.geometries, "種類", kouen)
  add_layer.(map, target_data, kouen, color, 0.8)
end)
|> MapLibre.add_geo_source("道路", road_data)
|> MapLibre.add_layer(id: "道路", source: "道路", type: :line)
|> MapLibre.add_geo_source("広場", plaza_data)
|> MapLibre.add_layer(id: "広場", source: "道路", type: :line)

実行結果

スクリーンショット 2024-08-18 22.30.10.png

川沿いに緑地が作られていることがわかります

一番大きい黄色は大分スポーツ公園ですね

まとめ

都市計画データを視覚化することで、今後10年、どこの土地がどのように使われようとしているのかが分かります

本記事のように 2024 年現在から 2022 年の都市計画を見ると、「だからあの辺りにあの施設ができたのか」というように納得できるデータです

皆さんも、地元の都市計画を見てみましょう

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?