読者です 読者をやめる 読者になる 読者になる

/var/log/laughingman7743.log

I thought what I'd do was, I'd pretend I was one of those deaf-mutes or should I?

Elasticsearchに空間データを突っ込む

Elasticsearch Python GIS

例のごとく国土交通省のデータをダウンロードしてきてElasticsearchに突っ込んで検索してみます。

国土数値情報ダウンロードサービス

GDALのドキュメント*1を参照するとogr2ogrコマンドでシェープファイルを直接Elasticsearchに投入できそうですが、 マッピング定義をあれこれ変更したりしていろいろやってみましたがGeoShape形式での投入はできず。。。
C++で実装されているのでとりあえず深掘りするのはやめて、GeoJSON形式に変換してPythonスクリプトから投入することにします。

以下の国土交通省のページから日本全国の行政区域データをサウンロードしてきます。

国土数値情報 行政区域データの詳細

シェープファイルファイルのGeoJSON変換は以下のコマンドでできます。

変換するとFeatureCollectionという一塊のJSONオブジェクトとして出力されます。 Features配列内のFeatureオブジェクトを1レコードとして登録すると良さそうなのですが、一塊のJSONオブジェクトかつかなりのファイルサイズで、 そのままパースするとメモリがいくらあっても足りない感じです。JavaStAX的なストリーミング処理でJSONをパース出来ると良さそうですね。
PythonでそのようなJSONパーサーを探してみると、ijson*2というライブラリが見つかります。 これを使ってStAX的なJSONパース処理を書いてみました。メモリ使用量も抑えられて素敵ですね。 Elasticsearchへの投入処理はBulkAPI*3を利用します。

curlコマンドで以下のマッピング定義を登録、Pythonスクリプトを実行してデータを投入します。 投入先のインデックスはjp_city、typeはFeatureCollectionとしています。 マッピング定義は以下です。

投入が終わったら適当に日本のへそでも検索してみましょう。

問題なく検索できているようです。

最近ではKibanaがWMSに対応*4したりと、ElasticsearchでGIS的なことがやりやすくなっています。 クラスタが組みやすいので、PostgreSQL(PostGIS)よりも検索性能よかったりするかもしれません。 ElasticsearchをバックエンドにしたモダンなGISなんて素敵ですね。

Enjoy!