Elastic Stack 7.5.0 の Elastic Maps で GeoJSON+矩形フィルタリング

投稿遅れて申し訳ありません（深謝）

[Elastic Stack (Elasticsearch) Advent Calendar 2019](https://qiita.com/advent-calendar/2019/elasticsearch)の4日目の記事になります。
普段触ってないサービスについてQiita初稿で触れてみようと思い立ったものの、いわゆるGIS（地理情報システム）はかれこれ5年ほどご無沙汰で、普段は検索・自然言語処理界隈の人であります。深堀しきれてない点はツッコミいただければ幸い。

#  TL;DR
* Elastic Maps は docker-compose でシュッと試せる
* 7.5.0 では kibana.yml であれこれしたりゴリゴリクエリ書かなくても、KibanaのGUI上でかなりの操作が完結できる。
* 色んなデータソースをさくっとマッピングして集計できるのがスゴみ

#  Elastic Maps とは

公式 (https://www.elastic.co/jp/products/maps) の概要説明は以下のとおり。

> Kibanaのマップアプリは、複数の異なるインデックスを複層レイヤーとして1つのビューに表示します。同一の地図上に多数のインデックスレイヤーを重ねることで、リアルタイムに一括で検索したり、絞り込むことが可能です。セキュリティオペレーションセンターで、静的なサーバーの位置情報と、動的な攻撃位置情報を同時に監視することもできます。気になる情報があればマップを拡大。独立したドキュメントとして高精度な詳細が表示されます。
> ...

Webサービスで地図といえば GoogleMaps や Yahoo!地図が思い浮かびます。Webサイトに地図を表示するユースケースでは、見た目のカスタマイズを含めて広く一般に利用されているかと思います。
一方で、複数のデータソースを組み合わせたり、フィルタリング・集計をしたい時にはいくつかのAPIを組み合わせる等した実装が必要です。Elastic Maps を使うと、このようなユースケースがサクッと実現できそうです。
ここでは年々目に見えた被害を出しつつある"災害"に関連したいくつかの情報をマッピングするところまで試してみます。

#  まずは環境を立ち上げる

Elastic Stack は Dockerイメージが提供されています。お好みの環境で以下のファイルを作成して立ち上げましょう。
前提として、ElasticsearchとKibanaの7.5.0を開発(お試し)用に立ち上げる最低限の設定としています。
Githubからシュッと持ってきたい方は [こちら](https://github.com/yukinarian/ESAC2019-Elasticsearch-Kibana-7.5.0.git)

```docker:docker-compose.yml
version: '2.2'
services:

  # https://www.elastic.co/guide/en/elasticsearch/reference/7.5/docker.html
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.5.0
    environment:
      - discovery.type=single-node
      - cluster.name=es-docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic

  # https://www.elastic.co/guide/en/kibana/7.5/docker.html
  kibana:
    image: docker.elastic.co/kibana/kibana:7.5.0
    volumes:
      - ./kibana.yml:/usr/share/kibana/config/kibana.yml
    ports:
      - 5601:5601
    networks:
      - elastic

volumes:
  data01:
    driver: local

networks:
  elastic:
    driver: bridge

```

```yml:kibana.yml
elasticsearch.hosts: "http://elasticsearch:9200"
server.host: "0.0.0.0"

i18n.locale: "ja-JP"
```
2ファイル置かれたディレクトリで `docker-compose up` を唱えると、イメージの取得からDockerネットワーク作成等が行われて、ブラウザからKibanaにアクセスできるようになります。

```docker:command
$ docker-compose up
Creating network "esac2019-elasticsearch-kibana-750_elastic" with driver "bridge"
Creating volume "esac2019-elasticsearch-kibana-750_data01" with local driver
Creating esac2019-elasticsearch-kibana-750_elasticsearch_1 ... done
Creating esac2019-elasticsearch-kibana-750_kibana_1        ... done
...
```
http://localhost:5601/ にアクセスし、左メニューのマップアイコンを選択すると Elastic Map の画面が表示されます。![1206_001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/8b44b33b-e553-2b35-4e45-328a4209fe0f.png)

#  地図上にデータを追加する

以下のとおり、Elastic Maps にはいくつかの方法で地図上にマッピングするデータを追加することができます。![1206_002.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/0f7b6af5-4afa-cb72-74e4-cb6d2acb7153.gif)
以前のバージョンでは日本の都道府県領域を表示するレイヤを追加するだけでも自前でGeoJSONを用意する、設定で読み込ませるなど手間がかかりましたが、ベクターシェイプからサクッと指定できるようになっています。便利。

今回は、今年猛威をふるった台風19号の進路情報をふまえて、近所で逃げるならここか？を見繕うために緊急避難場所やAED設置施設の情報をマッピングします。必要なGeoJSONデータは以下サイトからそれぞれ取得します。

[国立情報学研究所 デジタル台風](http://agora.ex.nii.ac.jp/digital-typhoon/)
[G空間情報センター 指定緊急避難場所データ](https://www.geospatial.jp/ckan/dataset/hinanbasho)
[G空間情報センター AEDデータ](https://www.geospatial.jp/ckan/dataset?tags=AED)
[G空間情報センター 都道府県別1kmメッシュ](https://www.geospatial.jp/ckan/dataset/npli-pref-1km)

![1206_003.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/78c8102e-ed16-48b3-3651-a9bedc687503.gif)

#  データを絞り込む

フィルタで使いたい属性は、GeoJSONインポート時に "Fields to display in tooltip" で指定しておくのがポイントです。
台風19号の情報を読み込む時に pressure, time, wind を指定してみましたが、例えば「風速40m以上」に絞って地図上に表示する、といったことができます。KQLで条件を指定するのみ。これまた便利。

![1206_004.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/56c78dc6-3d07-cac7-27ac-6d022458da52.png)

ひととおりデータのインポートが終わり、いったん"保存"しました。ぐぐっと分析用の地図っぽくなります。
![1206_005.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/25ba0126-5aa9-1154-32fb-38dd1894e24b.png)

この状態になると、KQLやLuceneのクエリ以外に、地図上で矩形領域を指定した絞り込みができるようになります。これが強力で、地図上で指定した任意の区間でさくっとフィルタをかけることができます。ざっくりこのあたりのエリアのスポットは～という指定ができます。
緯度経度を指定してクエリを書くことを考えるとやや絶望しそうになるオペレーションが一発で済みます！
![1206_004.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146846/23dd2603-bcba-7418-b6d3-2e71b4ab89de.gif)

画面で作ったフィルタは、ElasticsearchのクエリDSLとしてフィルタの編集から詳細にいじることも可能です。
自分で作ったデータをマッピングしてフィルタを重ねていくなど、夢が広がります。

#  終わりに

Elastic Maps は他にもセキュリティ分析、地図データを交えたログ分析、位置情報監視・BI、地理空間分析と、Elasticsearchとの組み合わせが非常によいプロダクトだと思います。久しぶりに地図サービスの一端に触れ、世の中便利になっているなーを実感できました。あと、Kibanaが便利すぎてやばいので、何か分析したくなったらとりあえずKibanaに突っ込んでみましょう！

---
（免責）本格的にお使いになる場合は、Elastic Stackの設定、利用するデータの権利・ライセンスをご確認・検証の上でお願いいたします。