筆ポリゴンを例にGISデータをPostGISにインポートしてみる

5 min read読了の目安(約4500字

はじめに

農林水産省統計部から「筆ポリゴン」(https://www.maff.go.jp/j/tokei/porigon/)が提供されています。

筆ポリゴンは全国の農地を筆レベルで生成したポリゴンのセットです。農林水産省ウェブサイトによると、空中写真から起こしているようです。「筆」とは登記上の土地の単位ですが、登記情報を基にしたものではないでしょうから、「筆レベル」と見た方がいいです。でもよく作ったものだと。

今回は、FreeBSD上でPostGISに叩き込んでみます。この際、GDAL/OGRのうちOGRを使います。

OGRとは

GDALはGISデータの相互変換のためのライブラリです。しばしばGDAL/OGRとも呼ばれ、こう名乗る場合は、GDALはラスタデータ用、OGRはベクタデータ用と分けて考えます(GDALにOGRが合併した経緯があったはずです)。

単にGDALという場合は、ラスタデータ用とベクタデータ用の両方を含むようにとらえている場合と、ラスタデータ用しかとらえていない場合があり、OGRは若干かわいそうです。

ファイル名に漢字が入っている

この節はFreeBSDのみの話です。

筆ポリゴンは都道府県ごとにZIPファイルで提供されていますが、ZIPファイル名、抽出した際のディレクトリ名、ファイル名、の全てで漢字が使われています。

文字コードは ShiftJIS です。

どうもunzipには、-Oオプションで文字コード指定ができるようなのですが、困ったのが、FreeBSDのunzipには、-Oオプションが無いのです。

あきらけかけていたところで https://qiita.com/s_mitu/items/6ea3cfcf0dbc9408f8a6 を発見。PackagesでなくPortsから入れることにして、オプションにICONVを指定するとOKとのこと。

ところがインストールして、単にunzip (引数、パラメータ無し)で実行して使用法を見ても、-Oオプションが出てこない。おかしいと思ったら、/usr/bin/unzipを実行していました。/usr/local/bin/unzipとフルパス指定すると、-Oオプションが出てきました。

本節についてまとめると、次のようになります。

  • PortsからICONVオプションで入れるとOK
  • 入る先は /usr/local/bin/unzip で、/usr/bin/unzipとは別物

OGR

対応フォーマットの確認

% ogrinfo --formsts
...
  PGDUMP -vector- (w+v): PostgreSQL SQL dump
...

PostgreSQLのダンプ形式であるPGDUMPというフォーマットがあると思います。(w+v)というのは、書き込みと更新とに対応しているベクタのフォーマットであることを示しています。https://live.osgeo.org/archive/8.0/ja/quickstart/gdal_quickstart.html に説明があります。

PGDUMPのオプション

OGRは多数のフォーマットを扱えるため、フォーマットごとのオプションを確認する必要があります。

PGDUMP については
https://gdal.org/drivers/vector/pgdump.html にあります。

ここで、"Dataset Creation Options"と"Layer Creation Options"に分かれていることに注意して下さい。オプション指定が異なるためです。

また、まさかの環境変数についても説明があります。

環境変数 PG_USE_COPYYESにしておくと、INSERTでなくCOPYを使ってくれます。

ogr2ogr

ogr2ogrは、ベクタデータから別のベクタデータに変換するプログラムです。

引数を見てみましょう。

ogr2ogr [(オプション)] (変換先ファイル) (元ファイル)

「変換先」と「元」の順番に注意して下さい。何かを何かに変換するプログラムの引数は、「元」「先」の順になることが多いのですが、ここでは逆です。

また、ここでは「ファイル」と表現していますが、GDAL/OGRは、必ずしも「ファイル」だけしか扱えないわけではありません。接続文字列を指定することで、データベースを変換元にしたりできます。

次に、若干のオプションを見ていきましょう。

  • -s_srs - 元ファイルの空間参照系、指定が無ければ自動判別します。
  • -a_srs - 変換先ファイルの空間参照系を指定しますが、座標系変換は行いません。
  • -t_srs - 指定された空間参照系に座標変換を行ったうえで変換先ファイルに保存します。

フォーマット特有のオプションは、NAME=VALUEで指定しますが、いくつかの種類があります。

  • -dsco NAME=VALUE - "Dataset Creation Option" を指定します。
  • -lco NAME=VALUE - "Layer Create Option"を指定します。
  • -oo NAME=VALUE - "Open Options"を指定します。
  • -doo NAME=VALUE - 変換先ファイルを開くためのオプションを指定します(更新時のみ有効)。

上でPGDUMPフォーマットの説明(本当はドライバの説明)で"Dataset Creation Options"と"Layer Creation Options"とに分かれていることに注意する必要があるとしたのは、このためです。たとえば、"Layer Creation Options"で指定すねきものを-dscoで指定すると、そのようなオプションは無い、と言われ、結構混乱します。

元ファイルの中身の文字コードがUTF-8でない場合

PostgreSQLは、基本的にUTF=8を使いますが、元ファイルがUTF-8でない場合、そのままogr2ogrにかけると、文字化けします。

元ファイルの文字コードを設定するのは、"Open Options"のENCODINGです。https://gdal.org/drivers/vector/pgdump.html を参照して下さい。

 -oo ENCODING=CP932

とします。

使ったオプション

次のオプションを使いました。

  • -lco CREATE_TABLE=OFF - テーブルを作らない (shp2pgsql-aオプション)
  • -lco GEOMETRY_NAME=geom - ジオメトリ名をgeomにする (shp2pgsqlのデフォルト)
  • -t_srs EPSG:4326 - EPSG:4326に座標変換
  • -nln g_poly_raw - 新しいレイヤの名前 (New Layer Name) に g_poly_rawを指定 (PGDUMPの場合はレイヤ名=テーブル名)

するっとできたように書いているけど実は違う

こういうオプションを使うとうまくいくよ!と、するっとできたように書いていますが、実際は、単一ファイルに対してコマンドを実行して、できあがったファイルを見て、求めているものになったかどうかを確認し、違っているとオプションを変更する、という試行錯誤を結構しています。

たとえば、文字コードについても、とりあえずできあがったファイルをlessで見て、あー文字化けしてるわ、と気づいて、対応法を探したりしています。

特にスクリプトで多数のファイルを自動変換する前には、長時間かけてできたPGDUMP形式データが使い物にならなかったら、結構がっかりするので、しっかり検討して下さい。

その他のogr2ogrのオプション等

その他のogr2ogrのオプションのまとめは https://qiita.com/tohka383/items/d3d1bf80db2cfb416330 で作ってくれています。

shp2pgsqlを使わないのはなんで?

FreeBSDのPackagesから入れると、shp2pgsqlが付いてきません。Portsから入れたら、ビルドはしてくれるけどインストールしてくれないので、ビルドツリーから抜き出して使うことになります。

あと、shp2pgsqlはシェープファイルの空間参照系を見てくれないのがあります。対してogr2ogrは、*.prjファイルを読んでくれます。

筆ポリゴンは、平面直角座標系を使っていて、統一してひとつのテーブルに入れると大変なことになりますが、ogr2ogrで、*.prjファイルを見つつ、EPSG:4326等に座標変換を行ったダンプファイルを得た方が使いやすいです。

出来上がったファイルを叩き込む

わざわざ言わなくてもわかると思いますが、次のコマンドで叩き込んでくれます。

psql -d (データベース名) -f (ファイル名)

おわりに

筆ポリゴンをPostGISに叩き込む方法、もう少し具体的に言うと、日本語を含むZIPファイルへの対応(FreeBSD独自)と、ogr2ogrのオプションについて紹介しました。

後半のogr2ogrについては、手動でやるより、スクリプトを組んで、たくさんのファイルを一括して変換することができます。

今回は筆ポリゴンでしたが、国土数値情報等のGISデータセットはあります。それとか独自にお持ちのデータもあるかも知れません。これらのデータを、とりあえずPostGISに積んでおいて、必要な時にファイルに取り出したり、QGISからつなげて使うといいかも知れません。

本記事のライセンス

クリエイティブ・コモンズ・ライセンス
この記事は クリエイティブ・コモンズ 表示 4.0 国際 ライセンス の下に提供されています。