概要
ElasticSearchに入れたGeoJSONデータをGeoServerで配信し、QGISで表示するのを試してみました。
以下のアプリをDockerを使ってセットアップしていきます。
- GeoServer 2.16.2
- ElasticSearch 7.9.3
- Kibana 7.9.3
Dockerのセットアップ
Dockerがインストールされていない場合は、まず公式サイトに従って、インストールしてください。
GeoServerとElasticSearch、Kibanaを起動
起動方法
まず、本記事で扱う一連のファイルをJinIgarashi/docker-geoserver-elasticgeoに置いてあります。
以下のようにするとGeoServerなど一連のアプリが立ち上がります。
git clone git@github.com:JinIgarashi/docker-geoserver-elasticgeo.git
cd docker-geoserver-elasticgeo
docker-compose up
Dockerで起動するアプリについて
docker-composeで起動すると、GeoServerは8600ポート、ElasticSearchは9200ポート、Kibanaは5601ポートで立ち上がります。
GeoServerの設定はkartoza/docker-geoserverのデフォルトの.env
とdocker-compose.yml
から流用しており、ElasticSearchの設定は公式のものをそのまま使っていますが、ノード数は一つだけにしています。
但し、GeoServerにElasticGeoというエクステンションを入れる必要があるため、独自にDockerfileを以下のように作っています。
FROM kartoza/geoserver:2.16.2
RUN wget https://github.com/ngageoint/elasticgeo/releases/download/2.16.0-RC1/elasticgeo-2.16.0.zip -O elasticgeo.zip
RUN unzip -o elasticgeo.zip -d /usr/local/tomcat/webapps/geoserver/WEB-INF/lib/
EXPOSE 8080
ElasticGeoのjarファイルをGeoServerのWEB-INF
フォルダに置いてあげるだけでインストールは終了です。なお、ElasticGeoは現時点で最新のGeoServer2.18では動きませんので、2.16.2を使います。
ElasticSearchの確認
ターミナルで以下のように実行して結果が返って来ればElasticSearchが無事インストールされています。
$ curl http://localhost:9200
{
"name" : "es01",
"cluster_name" : "es-docker-cluster",
"cluster_uuid" : "W_ho6j3NSZWQvuL7CfNnXg",
"version" : {
"number" : "7.9.3",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "c4138e51121ef06a6404866cddc601906fe5c868",
"build_date" : "2020-10-16T10:36:16.141335Z",
"build_snapshot" : false,
"lucene_version" : "8.6.2",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
KibanaでGeoJSONをインポート
ブラウザでKibanaを開く
http://localhost:5601
にアクセスします。下みたいな画面がでればOKです。
GeoJSONをElasticSearchにアップロードします
ここでは、私がボランティアで一緒に仕事をしているルワンダの水道公社の水道メーターのポイントデータ5万件超をアップロードしてみます。
Add layer
をクリックします。
Select a file to upload
のスペースにお手持ちのGeoJSONをドラッグ&ドロップすると、自動で読み込まれますのでImport file
を続けてクリックするとインデックスの作成が始まります。
Add layer
ボタンに変わったら続けてクリックします。Layer Settingsに適当に入力してSaveします。私は名前だけrw_connections
として後はデフォルトのままにしました
KibanaのGeoJSONの最大サイズは50MBまで
Kibanaの最大サイズの制限50MBを超える場合はogr2ogr
で下みたいなコマンドでやるとインポートできます。但しogr2ogrでインポートした場合はKibanaでインデックスパターンを自分で作ってあげないといけません。
ogr2ogr -progress -lco BULK_SIZE=5000000 -f "Elasticsearch" http://localhost:9200 connections.geojson -skipfailures
GeoServerの設定
いよいよデータの準備ができたのでGeoServerの設定をします。
http://localhost:8600/geoserver
にアクセスします。お馴染みの画面が出てきます。
以下のデフォルトのユーザーIDとパスワードでログインします。
- ID: admin
- Password: myawesomegeoserver
ストアを作ります。ElasticGeoが設定されているので、Vector Data Sources
にElasticsearchという選択肢が出ていますので、それを選びます。
Kibanaでアップロードしたインデックスの情報を入力します。
- Data Source Name: 任意の名前をつけます
- elasticsearch_host: Dockerのコンテナ名の
es01
を入れます - elasticsearch_port: 9200を入れます
- index_name: connectionsとします
それ以外はデフォルトのままで、Saveをクリックします。
次に、ElasticSearchのレイヤを追加します。きちんとストアの設定ができていれば、以下のような画面が表示されますので、Publish
をクリックします。
レイヤの編集画面になりますが、今回は全てデフォルトのままでBBOXだけ設定してあげてから、レイヤを作ります。
Layer PreviwでできたGeoServerレイヤを見てみます。
QGISでデータを表示する
GeoServerでElasticSearchのデータを配信できるようになったので、QGISで表示してみます。
今回は現時点で最新のQGIS3.16を使います。
QGISを起動したら、ブラウザパネルのWFS / OGC API
で右クリックして新しい接続
をクリックします。
- 名称に
elasticsearch
- URLに
http://localhost:8600/geoserver/elasticsearch/wfs
- バージョンに
1.0.0
- 地物の最大数に
10000
のように記入し、OKをクリックします。
WFSのURLがわからなかったら、下のようなURLをブラウザで開くとOnlineResource
というところで指定するURLを確認できます。
http://localhost:8600/geoserver/elasticsearch/ows?service=WFS&version=1.0.0&request=getcapabilities
<Service>
<Name>WFS</Name>
<Title/>
<Abstract/>
<Keywords/>
<OnlineResource>http://localhost:8600/geoserver/elasticsearch/wfs</OnlineResource>
ブラウザパネルにconnections
レイヤが表示されました。connections
をダブルクリックしてレイヤを追加します。
QGIS3.16でWFSレイヤをちゃんと表示できました。Kibanaでは表示した地物の情報をポップアップなどでは見れませんが、GeoServer経由でQGISで表示させてあげるとちゃんと属性情報も見れます。
まとめ
- ElasticSearchに投入したGISデータはGeoServerにElasticGeo拡張を入れることで、WFS/WMS配信できる
- WFS/WMSの配信方式に乗っかってQGISで表示できる
- QGIS以外でもLeaflet、OpenLayers、Mapbox GL JSなどでもElasticSearchのデータをGeoServer経由で扱える(本記事の対象外)
ElasticSearchでのGISデータの扱いが、GeoServerを使うことでより身近になると感じました。