LoginSignup
3
3

日本の行政区域データから都道府県と市区町村のポリゴンを作ってYellowfinでマップグラフにする

Last updated at Posted at 2023-07-04

先日の記事では世界の国単位での地図をYellowfinで作成しましたが、そうなると次は国内の地図が欲しくなるところです。さっそくやってみましょう。

なお、手順はどうでもいいからデータがほしいというお急ぎの方は、こちらへ飛んでください。

日本の行政区域データの入手

国土交通省の国土数値情報ダウンロードサイトで公開されている行政区域データを利用します。
kokudo.png

日本全体の地図が作りたいので、都道府県に別れたファイルではなく、全国の最新のもの(記事公開時点では平成31年)を選択してダウンロードします。

QGISでシェープファイルをCSVにエクスポートしてみる

先日の記事の手順に沿って、ダウンロードしたシェープファイルをQGISでCSVエクスポートすれば、簡単にYellowfinで使えるデータが手に入ります。
qgis_csv.png

ただ、このデータは行政区域単位のポリゴンなので 一般的な業務用途には細かすぎる というデメリットがあります。
実際にYellowfinでこのデータを使ってみると、以下のように市区町村レベルや都道府県レベルで表示したい場面でも細かく分かれてしまい、期待した仕上がりにならないことがあります。
yf_s.png

これでは使い勝手が悪いので、行政区域で分かれたポリゴンを結合して、都道府県や市区町村の単位のポリゴンデータを作りたいと思います。

PostGISの環境構築

ポリゴンを結合する方法はいろいろありますが、今回はPostGISというPostgreSQLの拡張を使います。
既存の環境を汚したくないので、Dockerを使って新規に環境構築します。

Dockerのインストール

Dockerを使うのがはじめての場合は、とりあえずDocker Desktopをインストールしておけばいいでしょう。

Dockerイメージの取得

Docker Hubで公開されているpostgis/postgisのイメージを使います。
この記事の公開時点では 15-3.3 が最新だったのですが、後述の docker compose での起動がうまくいかなかったので、今回は 14-3.3 を使うことにしました。
以下のコマンドをシェル(Windowsならコマンドプロンプト、Macならターミナル)で実行してイメージを取得します。

Dockerイメージ取得
$ docker pull postgis/postgis:14-3.3

docker-compose.ymlの作成

どこか任意のディレクトリに、以下のような内容の docker-compose.yml ファイルを作成します。

docker-compose.yml
version: '3'
services:
  pg:
    container_name: postgis_container
    image: postgis/postgis:14-3.3
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
    ports:
      - 15432:5432
    volumes:
        - pg_data:/var/lib/postgresql/data
volumes:
  pg_data:
    driver: local

PostGISコンテナの起動

docker-compose.yml を保存したディレクトリに移動して、以下のコマンドを実行します。

コンテナ起動
$ docker compose up -d

正常にコンテナが起動したら、Dockerのログに以下のようなメッセージが出ます。なお、ログはdocker logs --tail postgis_container等のコマンドで確認できます。

2023-07-03 02:52:00.237 UTC [1] LOG:  database system is ready to accept connections

PostGISが起動したら、docker-compose.yml で指定したユーザー名/パスワード/ポート番号に対して接続すれば普通のPostgreSQLと同じように使えます。
試しにpgAdmin4で接続してみると以下のような感じです。
pgadmin4.png
上記の docker-compose.yml ではローカルホスト側のポート番号を 15432 に、Dockerコンテナ内のポート番号を 5432 にしていますので、YellowfinやpgAdminなどのツールからは 15432 に対して接続しにいくことになります。

ちなみにコンテナを停止するときは以下のコマンドです。

コンテナ停止
$ docker stop postgis_container  (←docker-compose.ymlで設定したコンテナ名)

データの結合

構築したPostGISを使って、行政区域データから都道府県単位と市区町村単位に結合したデータをそれぞれ作ります。

シェープファイルをPostGISへインポート

まずはシェープファイルをPostGISへインポートします。
インポートする方法としてshp2psqlというPostGIS付属のコマンドを使う例がよく紹介されていますが、QGISで画面から簡単に行うこともできますので、今回はその方法を採用します。

シェープファイルの読み込み

ダウンロードした国土数値情報の.shpファイルをQGISにドラッグ&ドロップすると、シェープファイルが読み込まれます。
shp.png

PostGISへの接続

左ペインのブラウザからPostgreSQLを右クリックし、接続の新規作成を選択します。
set.png

接続先のPostGISの情報を入力します。
setp.png

レイヤのインポート

メニューのデータベースからDBマネージャーを起動し、PostGISのデータベースを選択してレイヤ/ファイルのインポートをクリックします。
layer.png

そして以下の画像の設定でインポートを実行します。
imp.png

OKをクリックするとしばらくフリーズしたような状態になりますが、私の環境では2分間くらい待つとインポートが完了しました。
suc.png

都道府県・市区町村単位のデータ結合

pgAdminで確認すると、以下のようにきちんとテーブルが作成されています。
pad.png

今回はPostGISで結合の処理を行うので、pgAdmin等を使って以下のSQLを実行します。

SQLで都道府県のポリゴンを結合

都道府県テーブルの作成
CREATE TABLE public."N03_pref" (
    n03_001 character varying(10) PRIMARY KEY,
    geom geometry(MULTIPOLYGON, 3857) NOT NULL
);
都道府県で結合したデータの投入
INSERT INTO public."N03_pref"
SELECT n03_001, ST_Multi(ST_Union(ST_SetSRID(geom, 3857)))
FROM public."N03-19_190101"
WHERE n03_001 IS NOT NULL
GROUP BY n03_001;

SQLで市区町村のポリゴンを結合

市区町村テーブルの作成
CREATE TABLE public."N03_city" (
    n03_007 character varying(5) PRIMARY KEY,
    geom geometry(MULTIPOLYGON, 3857) NOT NULL
);
市区町村で結合したデータの投入
INSERT INTO public."N03_city"
SELECT n03_007, ST_Multi(ST_Union(ST_SetSRID(geom, 3857)))
FROM public."N03-19_190101"
WHERE n03_007 IS NOT NULL
GROUP BY n03_007;

結合時の注意点

上記では都道府県はn03_001(都道府県名)を、市区町村はn03_007(行政区域コード)を集約のキーにしています。
市区町村のキーをn03_004(市区町村名)にしなかったのは、重複の可能性があるからです。
また、利便性を考えると、都道府県を表す2桁のコードをここで生成しておくのがいいかもしれません。

データの簡素化

QGISのメニューからレイヤデータソースマネージャを選択し、PostgreSQLの中にある先ほど作成した都道府県のテーブルを選択して追加をクリックします。
dbm.png

すると、問題なく都道府県単位のポリゴンが表示されました。
npref.png

結合したデータの問題点

Yellowfinからこのテーブルを直接参照することもできますし、先日の記事の内容に沿ってCSVにエクスポートすることも可能です。
しかしこのデータには詳細すぎて重いという欠点があります。

たとえば東京湾を拡大してみると、以下のように細部まで形状がわかります。
nbay.png

ですが、正直なところ都道府県レベルでここまで詳細な形状は必要ありません。
むしろ描画の処理が重くなり、場合によってはOutOfMemoryなどのシステムエラーの原因になってしまいます。

そこで、簡素化というポリゴンの頂点を間引いてデータを軽くする処理を施していきます。

QGISでジオメトリを簡素化

QGISのメニューからベクタジオメトリツールジオメトリを簡素化と進みます。
gek.png

簡素化のパラメーターを設定します。
許容範囲の値が小さくなると精度が高まり、ポリゴンの頂点が多くなって、データとしては重くなります。今回、都道府県の場合は0.01にしました。
param.png

簡素化されたレイヤを確認すると、きちんと都道府県の形を保って表示されています。
layerout.png

このレイヤをまたPostgreSQLへインポートするか、CSVにエクスポートすればYellowfinで使える都道府県ポリゴンのデータになります。
市区町村についても同様の操作で簡素化すればOKですが、許容範囲は0.001くらいに細かくするのがいいでしょう。

ここまでの手順で、Yellowfinの地図で都道府県や市区町村のポリゴンが使えるようになりました。
yfs.png

簡素化したデータの問題点

上記の手順で簡素化した都道府県のレイヤを拡大してみると、領域間に隙間や重なりが生じています。
kanso.png

ですが、Yellowfinで地図を描画する程度なら支障ないレベルだと思われるので、今回はこの問題を無視します。
この問題を解消するにはPostGISでトポロジトポジオメトリというものを駆使する必要があるらしいのですが、この記事ではキーワードを紹介するだけにとどめ、また別の機会に検証したいと思います。

Yellowfinで今すぐ活用できるデータ

ここまでの手順をそっくりそのまま真似していただければ、Yellowfinで使えるポリゴンデータが手に入るわけですが、そもそも作業するのが面倒だという方もいらっしゃるでしょうから、作成したデータをダウンロードできるようにしておきます。
なお、データ内容は記事執筆時点(2023年7月)のものです。

都道府県・市区町村ポリゴンのCSVファイル

上記の手順で作成したCSVファイルを以下に置いています。

さらに細かな町丁目レベルのデータが必要な場合は、お手数ですがこの手順に沿ってご自身で作成してください。(ファイルサイズが大きくなりすぎてGitHubには置けませんでした…)

行政区域コードのExcelファイル

ポリゴンと紐付けるために必要な都道府県や市区町村の名称及びコードの情報は、国土数値情報のサイトからダウンロード可能です。

行政区域データ.png

参考情報

PostGIS環境構築

行政区域データのインポート

都道府県・市区町村のポリゴンデータ作成

PostGIS全般

3
3
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
3
3