[jismesh-raster]地域メッシュデータをかんたんに可視化しよう

## TL;DR

https://github.com/Kanahiro/jismesh-raster

- 地域メッシュデータのCSVからかんたんに位置情報つきTIFを作れるツールをつくったよ
- `pip install jismesh-raster`でインストールできるよ

## サンプル

- CSVは[全国の人流オープンデータ](https://www.geospatial.jp/ckan/dataset/mlit-1km-fromto)のデータ（2019年1月休日昼間）を全国分結合して作成した（234571レコード）
  - https://github.com/Kanahiro/mesh1km-pop/blob/master/csv2geojson.py これを使って得られる`mesh_population_df`をCSVで書き出し
- QGISで等量10区分により色分け
- 背景はOSM（©️OpenStreetMap Contributors）
- ファイルサイズ25.6MB, 解像度2485x2578
- 処理時間は30秒程度だった（MBP16inch 2019）

![スクリーンショット 2021-08-28 22.30.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/64517620-43d0-2e01-06c5-ddc64b79d4fc.png)
![スクリーンショット 2021-08-28 22.31.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/d15b22f4-1ee2-f951-c0f2-574c80b064d8.png)


## はじめに

- 標準地域メッシュは、経緯度を一定のルールで均等に分割して得られるメッシュです
- メッシュの形状自体に意味はなく、紐付けられる集計値が重要なので、ベクターデータよりラスターデータが適している（わざわざベクターデータにして頂点の座標を保持する必要はないということです）
- 本スクリプトでは、1 つメッシュに 1 ピクセルを割り当て、同時に適切な位置情報を付与したワールドファイルを出力します

## 対応メッシュ

標準地域メッシュおよび分割地域メッシュに対応しています

### 標準地域メッシュ

| メッシュ番号 | 詳細          | メッシュコード |
| ------------ | ------------- | -------------- |
| 1            | 80km メッシュ | 4 桁           |
| 2            | 10km メッシュ | 6 桁           |
| 3            | 1km メッシュ  | 8 桁           |

### 分割地域メッシュ

3 次メッシュを基準し、任意の回数 4 分割して得られるメッシュ

| メッシュ番号 | 詳細          | メッシュコード |
| ------------ | ------------- | -------------- |
| 4            | 500m メッシュ | 9 桁           |
| 5            | 250m メッシュ | 10 桁          |
| 6            | 125m メッシュ | 11 桁          |

## インストール

```sh
pip install jismesh-raster
```

## 使い方

### コマンド

```
必須項目:
  csvfile 読み込むCSVファイル
  output  データの保存先絶対パス

optional arguments:
  --meshcol  メッシュコードのカラムを0から始まる番号、デフォルトは0
  --valuecol 値のカラムを0から始まる番号、デフォルトは1
  --method 集計方法、mean, median, min, max, stddev, sum
  --nodata   データがないメッシュにセットする値、デフォルトは-9999.0
  --noheader CSVにヘッダーが無い場合に入力
```

### 具体例

以下の形式の CSV を例とする（出典：[全国の人流オープンデータ](https://www.geospatial.jp/ckan/dataset/mlit-1km-fromto)）

```csv
mesh1kmid,prefcode,citycode,year,month,dayflag,timezone,population
53394519,13,13101,2019,01,0,0,13533
53394519,13,13101,2019,01,0,1,5818
53394519,13,13101,2019,01,2,2,26039
53394528,13,13101,2019,01,0,0,27561
53394528,13,13101,2019,01,1,2,57219
53394528,13,13101,2019,01,2,0,73526
```

-   上記 CSV は`meshdata.csv`、出力する TIF ファイルを`mesh.tif`とする
-   メッシュコードのカラムは左端から数えて 1 列目の`mesh1kmid`、メッシュ画像にしたい値は 8 列目の`population`である
-   このスクリプトでは 0 をスタートとして数えるので、`0`列目、`7`列目と読み替える
-   もし複数行にわたって同一のメッシュコードが存在する場合は、その`合計値`を求める
-   データが存在しない部分の値は`-999999.0`とする

```sh
jismesh-raster meshdata.csv mesh.tif --meshcol 0 --valuecol 7 --method sum --nodata -999999.0
```

-   `meshcol`のデフォルト値は`0`なので、今回の場合省略出来る
-   `nodata`のデフォルト値は`-9999.0`なので、それでもよければ省略出来る

```sh
jismesh-raster meshdata.csv mesh.tif --valuecol 7 --method sum
```

-  CSV の複数行にわたって同一のメッシュコードが存在する場合に methodを指定されていないとエラーとなる

以下のような CSV の場合

```csv
53394519,13533
53394519,5818
53394519,26039
53394528,27561
53394528,57219
53394528,73526
```

-   ヘッダー行が無い場合は`noheader`オプションを指定する
-   `valuecol`のデフォルト値は`1`なので、上記の場合省略出来る

```sh
jismesh-raster meshdata.csv mesh.tif --method mean --noheader
```

## 出力データと仕様

-   .tif ファイル
    -   拡張子は必ずしも`.tif`ではなく、コマンド引数で指定したファイル名となる
    -   Float32
    -   Single band
    -   GeoTiff ではないことに留意（ヘッダーは書き込まれていない）
    -   CSV に存在するメッシュが全て含まれる最小の解像度となる
-   .tfw ファイル
    -   .tif ファイルと同名で書き出される
    -   経緯度で設定されている（つまり CRS は`EPSG:4326`）