概要
個人的な興味で、ベクトルタイル活用の可能性を試してみたいと思い、Elasticsearchでの検索結果をMapboxのバイナリベクトルタイル形式にして配信するというよくわからないタイルサーバーをNodejsで作って、オープンソースプロジェクトとして公開してみました。作ったリポジトリは以下の通り。
- elastic2mvt: z/x/yと検索クエリを受け取ってバイナリベクトルタイルを1枚だけ生成するモジュール
- es_tileserv: NodejsのExpressで構築したElasticsearch用のベクトルタイル配信サーバー
こういう使い方がそもそも可能なのかも含めて、かなり試験的で、手探りでAPI仕様など考えていますので、今後ここで書いた以上に内容がガラッと変わる可能性がありますが、もし何かアイデアなどいただけたらと思い、ツールの紹介をします。
長くなりそうなので、ソースコードの説明はここではしませんので、ご興味のある方は各自ご覧ください。不明点があればリポジトリにIssueください。
使い方
DockerでElasticsearchも含めて、全て起動できるように設定しています。タイルサーバーのDockerイメージもDocker hubに上げていますので、最新のソースコードで実行する場合は以下のようにすれば、Elasticsearchと配信サーバーがpm2で立ち上がります。
git clone git@github.com:JinIgarashi/es_tileserv.git
cd es_tileserv
npm run docker:start
もしソースコードを修正したら、npm run docker:build
すれば最新のイメージをビルドします。
テストデータとしてケニアのナロックタウンの建物ポリゴンデータだけ用意しました。以下のコマンドでElasticsearchにインデックスを作ります。ogr2ogrを使いますので、GDALが入っていない場合はインストールをお願いします。
cd sample-data
./insert_test_data.sh
次のようにして、osm_building_narok
というインデックスができていればOKです。
ogrinfo ES:http://localhost:9200
INFO: Open of `ES:http://localhost:9200'
using driver `Elasticsearch' successful.
1: osm_building_narok (Multi Polygon)
APIの仕様について
サーバーを立ち上げたあと、http://localhost:8080/docsをブラウザで開くとSwaggerでAPIを試せます。
/api/tile/{z}/{x}/{y}.{ext}
というAPIを使います。Try it out
ボタンを押して、デフォルトのExampleのままExecuteを押して、200が返れば成功しています。
これだけだとよくわからないので、ブラウザで以下のURLを叩いてみます。
http://localhost:8080/api/tile/14/9824/8241.pbf?indices=%5B%7B%22name%22%3A%22osm_building_narok%22%2C%22geometry%22%3A%22geometry%22%2C%22query%22%3A%7B%22term%22%3A%7B%22building%22%3A%22school%22%7D%7D%7D%5D
8241.pbf
がダウンロードされましたので、QGIS3.14以上のバージョンでドラッグ&ドロップしてみてみます。なんかポリゴンが表示されました!QGISのダウンロードはこちらから。
でももっと動的に画面動かしながらベクトルタイルを見たいということで、QGISのベクトルタイル機能でみてみます。
URLには次のものを指定してみます。学校だけではつまらないのでとりあえず、検索条件なしで設定します。
http://localhost:8080/api/tile/{z}/{x}/{y}.pbf?indices=[{"name":"osm_building_narok","geometry":"geometry"}]
ブラウザパネルのVector Tiles
に表示されました。
追加したベクトルタイルを表示する前に、ケニアのナロックタウンの場所をQGISで表示しておきましょう。ここではMaptiler PluginのBasicを追加してみます。アクセスキーは事前に取得お願いします。
思いっきりズームしましょう。人口5万人程度の小さなマサイ族の街です。なんでこのナロックタウンをサンプルデータとして選んだかというと、自分が以前住んで仕事してたから。
さてここで、作成したベクトルタイルを地図に追加します。ブラウザパネルのVector Tile
のelastic MVT test
をダブルクリックすれば良いです。
QGISにElasticsearchからのベクトルタイルがちゃんと表示されました!
ターミナルを見るとログがちゃんと出ていて動いているらしいことがわかります。
es_tileserv_1 | 06:18:20 2|es_tileserv | GET /api/tile/13/4914/4121.pbf?indices=[%7B%22name%22:%22osm_building_narok%22,%22geometry%22:%22geometry%22%7D] 200 51.559 ms - 0
es_tileserv_1 | 06:18:20 1|es_tileserv | GET /api/tile/13/4914/4122.pbf?indices=[%7B%22name%22:%22osm_building_narok%22,%22geometry%22:%22geometry%22%7D] 200 53.046 ms - 0
今後の展望
- フロントエンドでMapboxGL JSを使って動的に検索ワードを変えつつ、ベクトルタイルを地図に表示したい。
- もしできたら、
es_tileserv
で検索して表示するMapbox GL JSのプラグインを作りたい。 - Elasticsearchのいろんな検索に対応できるようにAPIの仕様を洗練させたい(自分はElasticsearchは素人同然なので検索ワードのAPIへの指定方法とかかなり手探りで作りました。)。
一昨日くらいから突貫で作ったので、いろいろと突っ込みどころがあるかと思いますが、もし何かAPI仕様について良い案や、こんな使い方もできるんではというアイデアなどありましたら、GithubのリポジトリにIssueください。
よろしくお願いします。