MySQLにシェープファイルをインポートするツール(shp2mysql)を作った

# はじめに

令和元年冬休みの宿題として、MySQLにシェープファイルをインポートするツール「shp2mysql」を作りました。
正確には、シェープファイルからインポート用のSQLを生成するツールです。インポートはmysqlコマンドを使います。

[shp2mysql](https://github.com/hajime-miyauchi/shp2mysql)

シェープファイルはGISで標準的に使われているファイル形式です。

インポートしたデータを[MySQL Workbench](https://www.mysql.com/jp/products/workbench/)で確認するとこんな感じです。

![スクリーンショット 2019-12-30 21.53.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22360/8d1e5ed0-674a-3299-c0e8-a0dad10393c4.png)

# このツールを作ろうと思ったきっかけ

現状、MySQLにシェープファイルをインストールするにはGDALをインストールし、付属するogr2ogrを使う必要がありました。

* [MySQL 8.0にシェープファイルをインポートしてみる](https://qiita.com/miyauchi/items/c8349e1e6339bdf26a20)
* [MySQLに対応したogr2ogr(GDAL)をインストールする方法まとめ](https://qiita.com/miyauchi/items/87921eb3ad630db1624a)

GDALは優れたツールですが、目的が「MySQLにシェープファイルをインポートする」だけであれば、導入ハードルが高めでした。

その点、shp2mysqlは「MySQLにシェープファイルをインポートする」ことに特化している分、導入ハードルが低めです。

また、ogr2ogrと異なりshp2mysqlはMySQLに接続しません。
SQLを生成し、実際の取り込み自体はmysqlコマンドに任せます。

これは下記のメリットがあります。

* SQLを確認し、必要があれば編集した上で実行できる。
    * 将来的にMySQLのSQLに変更があった場合などにも対応しやすい。
* MySQLの認証方式の変更に左右されない。
    * GDALではデフォルトの認証方式に対応していないため、MySQLの認証方式を変更する必要がある。

このツールで、MySQLのGIS機能を使う人が増えてくれたら良いなと思っています。

# インストール方法

リリースページからファイルをダウンロードします。

https://github.com/hajime-miyauchi/shp2mysql

## Windowsの場合

リリースページの「shp2mysql.exe」をダウンロードしてそのまま使えます。

## Linuxの場合

リリースページの「shp2mysql-*.tar.gz」をダウンロードして解凍して下記コマンドを実行します。

```
$ ./configure
$ make
$ sudo make install
```

場合によってはgettext(iconv)が必要になるかもしれないので、yumなどでインストールしておいてください。

```
$ yum install gettext-devel
```

# シェープファイルの準備

下記のようなサイトからダウンロードします。

* [e-stat](https://www.e-stat.go.jp/)
    * [ダウンロード方法](https://youtu.be/2eBWFQizBjU)
* [国土数値情報](http://nlftp.mlit.go.jp/ksj/)

手っ取り早くデータを用意したい人は下記コマンドで愛知県の境界データがダウンロードできます。

```
$ wget -O A002005212015DDSWC23.zip "https://www.e-stat.go.jp/gis/statmap-search/data?dlserveyId=A002005212015&code=23&coordSys=1&format=shape&downloadType=5"
$ unzip A002005212015DDSWC23.zip
```

# 使い方

さきほどダウンロードしたe-statのデータの場合、こんな感じです。

```
$ shp2mysql -s 4612 -W CP932 h27ka23.shp > h27ka23.sql
```

生成されたh27ka23.sqlをmysqlコマンドを使って実行(インポート)します。
ファイル名でテーブルが作られて、データがインサートされます。

```
$ mysql -u データベースのユーザ名 -p データベース名 < h27ka23.sql
```

インサートされたデータを見てみます。

```
$ mysql -u データベースのユーザ名 -p データベース名
mysql> SELECT
    -> pref, city, s_area, pref_name, city_name, s_name,
    -> ST_AsText(geom), ST_SRID(geom)
    -> FROM h27ka23 LIMIT 1;
```

実行結果はこんな感じです。

```
| pref | city | s_area | pref_name | city_name | s_name             | ST_AsText(geom)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | ST_SRID(geom) |
+------+------+--------+-----------+-----------+--------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------+
| 23   | 101  | 001005 | 愛知県    | 千種区    | 青柳町５丁目       | MULTIPOLYGON(((35.160771346643 136.938842145444,35.1608301437881 136.938424291226,35.1608501173003 136.938334470847,35.1610470210929 136.938370604812,35.1610455594512 136.938417110451,35.1612019205203 136.938464933458,35.16155916329 136.938529179109,35.1615545646458 136.938555475691,35.1617364712544 136.938598441145,35.161741167614 136.938548840332,35.161911770243 136.93857200556,35.1619180171412 136.938523470471,35.1623067540192 136.938606284437,35.1622885707429 136.938711581907,35.1622335970064 136.939177415621,35.1621481339206 136.939721847138,35.1617339281151 136.939613455624,35.1617441005151 136.93955496258,35.1614778024844 136.939500052065,35.161417934312 136.939533684759,35.1606909879029 136.93936841024,35.160771346643 136.938842145444))) |          4612 |
```

MySQL Workbenchを使うと冒頭の通り、インポート結果を図で確認できます。

![スクリーンショット 2019-12-30 21.53.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22360/8d1e5ed0-674a-3299-c0e8-a0dad10393c4.png)

属性データもインポートされていることが確認できます。国勢調査のデータなのでエリアごとの人口なども確認できます。

![スクリーンショット 2019-12-30 21.59.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22360/02173ffa-d020-8eaf-e728-ecd431401f8e.png)

# 最後に

shp2mysqlのことでおかしな動作や気づいた点があればコメント欄等でぜひ教えて下さい。

# この記事のライセンス
[![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by/4.0/88x31.png)](http://creativecommons.org/licenses/by/4.0/deed.ja)
この記事は[CC BY 4.0（クリエイティブ・コモンズ 表示 4.0 国際 ライセンス）](http://creativecommons.org/licenses/by/4.0/deed.ja)の元で公開します。