e-Stat 統計地理情報システム ・小地域（町丁・字等）データ（国政調査2020）を全国マージしてベクトルタイル化する

# はじめに
## 背景
全国の町字を見てみたいと思いました。本当は地番の地番区域図を見たいのですが、全国をカバーしているデータがないので、類似のデータを探したところ国勢調査のデータにたどり着きました。こちらをベクトルタイルに変換して見てみます。なお、国勢調査の地図データは地番区域や住所街区と必ずしも一致するわけではないので注意が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/29fd4a36-6d8d-b476-2f6d-fceed76bf382.png)

サンプル地図はこちらから：
https://ubukawa.github.io/estat01/map/map.html

## 私の環境
* Windows PC (Windows 10 home)
* Github repository (今回のレポジトリはこちら：  )
* Raspberry Pi 400
私のWindows パソコンでWSL2が上手く使えないので、Raspberry Pi でベクトルタイル化を行いました。

## 利用したデータ
eStat　国勢調査2020、小地域（町丁・字等）のJDG11、緯度経度のファイルを都道府県単位でダウンロードしてきます。

https://www.e-stat.go.jp/gis/statmap-search?page=1&type=2&aggregateUnitForBoundary=A&toukeiCode=00200521&toukeiYear=2020&serveyId=A002005212020&coordsys=1&format=shape&datum=2011

### データ利用時の注意事項
いくつか注意事項があったので確認しておきました。
> 国勢調査の基本単位区及び町丁・字等の境界データは、地方公共団体が調査を実施する際に設定した調査区の境界を基に作成しているため、住居表示等で用いられている実際の町丁・字の境界と一致しない場合があります。また、町丁・字の名称についても、一致しない場合があります。（ https://www.e-stat.go.jp/pdf/gis/notes/00200521.pdf より）

### データベース定義
以下のURLにあります。
https://www.e-stat.go.jp/gis/statmap-search/data?datatype=2&serveyId=A002005212020&downloadType=1&datum=2011
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/65536d40-856d-e430-ea6c-a8253263da31.png)

S_NAMEとCITY_NAMEあたりをラベルにするといいかもしれません。

### データ利用について
ダウンロードしたデータの利用制限等については必ず確認しているのですが、本データについては以下のページにダウンロードデータに関する注意がありました。しかし、データのライセンスなどについては記載がありません。
https://www.e-stat.go.jp/help/data-definition-information/download

Q&Aでe-Statから取得した統計表の引用について説明がありました。
> e-Statで公開している情報は、利用ルールに従うことにより引用・転載等、自由にご利用いただくことができます。ご利用の際には、出典（府省名、統計調査名）の記載をお願いいたします。詳しくは「利用規約」をご参照ください。（ https://www.e-stat.go.jp/help/e-Stat-1-2 ）

利用規約を見るとサイトで公開している情報は利用規約に従って使えそうです。政府標準利用規約（第2.0版）に準拠していて、クリエイティブ・コモンズのCC BYと互換性のあるもののようです。
https://www.e-stat.go.jp/terms-of-use

# 手順
## Step. 0: 作業環境の準備
Raspberry Pi Imager でマイクロSDカードにラズベリーパイOSを準備します。以下に示す以前の記事のStep2-1と2-2の手順でやりました。

https://qiita.com/T-ubu/items/ee48cfa1ef7d5fce70cc

その後、ツールのインストールについてはベクトルタイル関係ツールを[unvt/eqinox](https://github.com/unvt/equinox)をつかってインストールしました。

```
curl -sL https://unvt.github.io/equinox/install.sh | bash -
```

GISの処理によく使うgdalやベクトルタイル変換ツールfelt/tippecanoeも入っています。

## Step. 1: データのダウンロード
データ定義書にも書いてありますが、今回の対象は都道府県ごとにダウンロードしてくる必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/34110728-3770-ec67-5ddd-05a5aa639f3a.png)
URLは・・・・
* 北海道: https://www.e-stat.go.jp/gis/statmap-search/data?dlserveyId=A002005212020&code=01&coordSys=1&format=shape&downloadType=5&datum=2011 
* 青森： https://www.e-stat.go.jp/gis/statmap-search/data?dlserveyId=A002005212020&code=02&coordSys=1&format=shape&downloadType=5&datum=2011

どうやら、上記URLのcodeのところを01～47で指定すれば北海道から沖縄のデータがダウンロード出来ます。
Curlでは上手くいかなかったのですが、ウェブブラウザにURLを入れるとダウンロードが出来ます。

ダウンロードされたデータはZIPに圧縮されていますが、解凍するとr2kaXX.shp というシェープファイルが得られます（XXは都道府県ごとの番号）。
今回使ったダウンロードデータを作業レポジトリに格納しました  https://github.com/ubukawa/estat01/tree/main/01_src

## Step. 2： ラズベリーパイでの処理
ラズベリーパイで作業ディレクトに移動した後、以下のコマンドを実行します。

↓ まず、レポジトリをクローンしてきた後にZIPファイルを解凍する場所を作る↓
```bash
git clone https://github.com/ubukawa/estat01
cd estat01
mkdir 02_unpack
```

↓ 次にファイルを解凍します。フォルダにあるものをbashで一括回答します。
解凍したファイルは合計するとそれなりのファイルになるのでGitHubレポジトリにアップしないように.gitignoreファイルを編集しておきます。
```bash
for f in 01_src/*.zip; do unzip ${f} -d 02_unpack; done
vi .gitignore # gitignoreファイルに02_unpackを追加
git add .gitignore
```

↓ 次に47個のシェープファイルを1つのGeoJSONファイルにマージします（中間ファイルなので作らないで直接ベクトルタイル変換ツールに流し入れる方が処理的には良いですが、わかりやすさのために中間ファイルを作ります）。ogr2ogrでもマージ出来るかもしれませんが、全てのファイルを一度にやりたかったので、 ogrmerge.py を使いました。unvt/equinoxにはpython系のgdalツールもそろえられていますね。文字コードの警告が出る場合は-lco ENCODING=utf8等のオプションで出力文字コードの指定ができます。

このマージしたファイルもそれなりのサイズになるので、gitignoreで設定しておきましょう。

```bash
mkdir 03_merge
ogrmerge.py -single -f GeoJSON -o 03_merge/all.geojson 02_unpack/*.shp
vi .gitignore # gitignoreファイルに03_mergeを追加
```

↓ 次にベクトルタイル変換します。投影法がJGD2011の経緯度（EPSG:6668）なので注意喚起のメッセージがでますが、経緯度で入力しているのでそのまま進みます。
ここは -e の代わりに -o にしてpmtilesでも出力出来たのですが、一つのファイルが50MBを超えてしまいgit pushが出来ませんでした。仕方がないのでフォルダ形式（-e）でしかもズームレベルは10までとしておきます（11までは出来ましたが、あまりズームレベルが大きいとこちらもgit pushで失敗してしまった）。レイヤ名はとりあえずbndとしておきました。

```bash
tippecanoe -e 04_tiles/zxy-s --no-tile-compression --no-feature-limit --no-tile-size-limit -Z8 -z10 -L bnd:03_merge/all.geojson
```

↓ 最後に、修正したものをgitに追加して、コミットしたあとにレポジトリにプッシュします。これまではGitHub desktopを使っていたのでコマンドをしていませんでしたが、ラズベリーパイからのプッシュなのでコマンドを使いました。GitHubのアカウントとパスワードの入力を求められますが、パスワードではもうだめなようでGitHubのページからTokenを取得して入力しました。

```bash
git add .gitignore
git add 04_tiles
git commit -m "tiles"
git push
```

## Step. 3： GitHubページの準備
### ページ設定
GitHub レポジトリのGitHubページ設定をします。今回はルートディレクトリからの表示としました。 https://ubukawa.github.io/estat01/ からページが見られます。

https://ubukawa.github.io/estat01/04_tiles/zxy-s/{z}/{x}/{y}.pbf でズームレベル9-10のタイルが見られます。

ホストしたタイルを [Maputnik Editor](https://maputnik.github.io/editor/) を使ってざっと眺めてみました。下図は京都のあたり。いくつかの地域を見てみましたが、場所によっては複数の町が一つのポリゴンになっていたりしまいた。**注意書きにあったとおり、住居表示や地番区域をもれなくチェックするという趣旨には使いにくいかもしれません**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/ac311d27-761c-bd43-1acb-8cd4460bf937.png)

↓青森のあたりですが、全国のデータあるのはありがたいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/120684ca-b8f7-a849-591a-a335097182fc.png)

### htmlの準備
htmlファイルも作ってGitHubページにアップします。以下の様な地図が見えました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/29fd4a36-6d8d-b476-2f6d-fceed76bf382.png)

htmlソースは以下の通りです。MapLibre GL JSと関係のプラグインを使っています。

```html:map.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Test- estat </title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://ubukawa.github.io/cmv-test/maplibre-gl@2.4.0/maplibre-gl.js'></script>
<link href='https://ubukawa.github.io/cmv-test/maplibre-gl@2.4.0/maplibre-gl.css' rel='stylesheet' />
<link href='https://ubukawa.github.io/cmv-test/watergis/maplibre-gl-export@1.3.8/maplibre-gl-export.css' rel='stylesheet' />
<script src='https://ubukawa.github.io/cmv-test/watergis/maplibre-gl-export@1.3.8/maplibre-gl-export.js'></script>
<link href='https://ubukawa.github.io/cmv-test/watergis/maplibre-gl-legend@1.2.8/maplibre-gl-legend.css' rel='stylesheet' />
<script src='https://ubukawa.github.io/cmv-test/watergis/maplibre-gl-legend@1.2.8/maplibre-gl-legend.js'></script>
  
  
<style>
body { margin:0; padding:0; }
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}
</style>
</head>
<body onload="popupFunction()">
 
<div id='map'></div>

<script>
function popupFunction() {
   alert("町の境界は国勢調査用のものであり、住居表示や地番地区の境界と必ずしも一致しません。")
}

var map = new maplibregl.Map({
  container: 'map', 
  attributionControl: true,
  hash: true, 
  //renderWorldCopies: false,
  style: 'https://gsi-cyberjapan.github.io/optimal_bvmap/style/std.json', // style file path
  center: [139.77961, 35.67736], // center [lng, lat]
  zoom: 13, // zoom level at loading
  maxPitch: 85,
  maxZoom: 4, // min zoom
  maxZoom: 22 // max zoom
});

map.on('load', function(){
  map.addSource('estat',{
    type: 'vector',
    tiles: ['https://ubukawa.github.io/estat01/04_tiles/zxy-s/{z}/{x}/{y}.pbf'],
    minzoom:8,
    maxzoom:10
  });
  map.addLayer({
    'minzoom':8, 
    'maxzoom':17, 
    'id':'machi-l', //町字
    'type':'line',
    'source':'estat',
    'source-layer': 'bnd',
    'paint':{
      'line-color':'#663399',
      'line-width': 2
    }
  })
  map.addLayer({
    'minzoom':13, 
    'maxzoom':17, 
    'id':'machi-label', //町字
    'type':'symbol',
    'source':'estat',
    'source-layer': 'bnd',
    'layout':{
        'text-field': ['get','S_NAME'],
        'text-font': ['NotoSerifJP-SemiBold'],
        'text-size': 10
    },
    'paint':{
      'text-color':'#663399'
    }
  })
  //legend
  const legend_target = {
    'machi-l':'eStatライン',
    'machi-label':'eStatラベル'
  };
  map.addControl(new MaplibreLegendControl(legend_target, {
    showDefault: false,
    onlyRendered: true,
    reverseOrder: false
  }), 'bottom-left');
})
  
//UI
//map.addControl(new maplibregl.AttributionControl({customAttribution: "GSI Map Vector." , compact: true}));
map.addControl(new maplibregl.AttributionControl({customAttribution: "<br />町の境界については総務省統計局のデータを変換して使っています" }));
map.addControl(new maplibregl.NavigationControl(), 'bottom-right');
map.addControl(new maplibregl.ScaleControl() );

//Export
map.addControl(new MaplibreExportControl({
  PageSize: Size.A4,
  PageOrientation: PageOrientation.Portrait,
  Format: Format.PNG,
  DPI: DPI[96],
  //Crosshair: true,
  PrintableArea: true,
  Local: 'en'
}), 'top-right');



//debug
//map.showTileBoundaries = true;
map.showTileBoundaries = false;
map.showCollisionBoxes = false;

</script>
 
</body>
</html>
```

# まとめ
県別のe-Stat 統計地理情報システム・小地域（町丁・字等）データ （国政調査2020、町丁・字等を全国マージしてベクトルタイル化しました。さらに、ウェブ地図で可視化をすることが出来ました。

なお、データの扱いについては、注意が必要で、統計データ用の境界であり住居表示や地番地区の境界と必ずしも一致しないことを再度リマインドしておきます。

（出典）
政府統計の総合窓口(e-Stat)（https://www.e-stat.go.jp/）からダウンロードしたデータを加工して利用（ベクトルタイルに変換）。 e-Stat地理空間情報データ（小地域　国勢調査　2020年　小地域（町丁・字等）（JGD2011）　世界測地系経緯度座標・Shapefile）

# 参考ページ

https://www.e-stat.go.jp/