運転分析・運転支援のAPIを使用してドライブシミュレータを作成してみる

# はじめに
HEREでエンジニアをしておりますkekishidaと申します。
HEREでは**Route Matching API**というGPSトレースをベースに運転分析・運転支援を行うAPIサービスを提供しています。　こちらは文字通り、走行時に取得したGPSトレースをもとにHERE Platformが管理する道路データに基づいてルートを”マッチング”させるサービスです。しかしながら、そのサービス名だけでは語ることができないほどの多くの機能を有しています。以下にそれらの具体例をあげます。

- **（GPSトレースをもとに）** ETA（到着予定時刻）を計算する。
- **（GPSトレースをもとに）** 地図属性情報（交通標識、信号など）を可視化する。
- **（GPSトレースをもとに）** エレクトロニックホライズン（前方道路予測）サービスを提供する。
- **（GPSトレースをもとに）** 交通違反を検知する。（トラック規制情報を含む）

https://developer.here.com/documentation/route-matching/dev_guide/index.html

この様な豊富な機能の認知度が低い（？）ことから、この度僭越ながら、機能のご紹介も兼ねて、簡易的なドライブシミュレータ作成にチャレンジしてみました！この記事では、このドライブシミュレータアプリで使用したAPIの詳細についてAPIテストツールでもあるPostmanを使用して説明できればと思います！

# アプリイメージ
## 初期画面
 　サンプルとして作成しておりますアプリはHERE Maps API for JavascriptとReactをベースになります。初期画面では、以下のイメージの様に日本地図上に車のアイコンを表示させています。そして走行を記録したGPXファイルをドラッグアンドドロップするか、クリックしてファイルを選択することで、Route Matching APIが呼び出されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/30d29b5c-a13b-efd7-34ec-e12ceacdab99.png)
## 走行ルートと地図のマッピング
　読み込んだGPXファイルをもとにRoute Matching APIがHERE Platformで管理する道路データに基づいてその軌跡を描画するためのデータを返送します。このアプリではその軌跡を地図上に描き、その経路上を均等に１００個のチェックポイントへと分割し、地図上にグリーンのマーカーとして表示させます。更に右側のペインにはHERE Reverse Geocoding APIを呼び出すことで各地点の住所情報を表示させます。（これらの情報はドライブシミュレーションをするために使用します。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/3cea4ada-aff6-9ede-bc3d-5c82f0b85bfe.png)
## 前方予測とETA(到着予定時刻）算出
　右側のペインのそれぞれのチェックポイントをクリックすることで各地点での運転状況をシミュレーションすることができます。下記イメージでは、クリックした地点より前方に２つの一時停止サインが存在することを示しています。また、その地点から目的地までのETA(到着予定時刻）を**渋滞状況などを加味した上**でを表示しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/1428586a-58a3-eb3f-d577-a4526b173286.png)
## 残経路情報の俯瞰
更に2D表示にすると、今後通過する経路で想定されるさまざまな交通情報を俯瞰的に表します。（簡易的なエレクトロニックホライズン機能）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/411b1cad-c3b5-020a-47ec-176476e319e1.png)

上記でご紹介した機能のほとんどは、Route Matching APIが提供する機能の一部分をそのまま利用しているだけのものになります。
また特筆したい部分としては、事前に取得したGPSトレースを**運転分析**するだけではなく、決められた走行ルートを走るユースケースにおいては**運転支援**として利用することが可能なところにあります。
# 事前準備
まず、HERE APIのアカウント取得については、以下の記事が参考になりますので、ぜひご参照ください。

https://qiita.com/kekomat/items/d2e29bac84a27c1ec521

https://qiita.com/Akira-Isegawa/items/a31be5893e362c6f10c3

ちなみに、以下の章で必要となるものは、API KEYのみになります。
# Route Matching APIを叩いてみよう！
　実は以前にも以下の様なQiitaの記事でRoute Matching APIを取り上げていただいております。（ありがとうございます！！）

https://qiita.com/Kanahiro/items/7d588f238df9be1e8eea

https://qiita.com/ShinagawaJP/items/7c806d6d0ea1cf7dbbba

@Kanahiroさんの記事内に以下のコメントがありました。。
 
**”実はRoute Matching APIにはプラグインでは扱いきれていない非常に多くの計算パラメータが存在し、その中から汎用的な引数のみを採用しています。すべてを使いこなすのは難しいですが、それだけ高機能で多様なユースケースをサポートしていると言えます。”**

実際、このAPIの引数の数が膨大で使いこなすのが難しいことが難点です。（うんざりするくらいのオプションの数です。。。）

https://developer.here.com/documentation/route-matching/api-reference.html

ということで、まず最初に、このRoute Matching APIを使いこなす上で理解しなくてはならない`routeMatch`というオプションからスタートしたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/5a1c0497-dd2e-2175-c919-9856f0792583.png)

おそらく、上記を読んだだけではイメージすることが難しいと思いますので、こちらのオプションについて補足解説してみたいと思います。

* routeMatch=1
いわゆるマップマッチングを提供するサービスで、取得したGPSトレースをもとに、HERE Platformが管理する道路情報から最適と思われるルートを返送します。以下のイメージではオレンジの線がGPSトレース（あえてフリーハンドの線を描いてみました。）を示し、この線が地図上に描かれていると想像してください。一方、ブルーの線はAPIが返送したデータを元に描かれたイメージです。（あえて角張った線を描いてみました。）つまり典型的なマップマッチング機能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/1f656d72-08c6-13b0-eeae-a4b75955310d.png)

* routeMatch=2
こちらが、あまり知られていないと思われるETAトラッキングモードになります。

（１）まず、あらかじめ通過したい地点（最終地点を含む）を設定します。
　　　（HeaderにAPIの引数として渡します。）
（２）その上で、現在地点までのGPSトレースをBodyとしてポストします。


そうすることで、最終地点（ゴール）までのETA（到着予定時刻）、現在地点までのマップマッチング情報および、これから走行するルート情報が返送されます。
以下の図を使用して、説明したいと思います。図の例では、このルートを10時に出発し、**B地点**に10時20分に到着しております。その時点で現在地までのGPSトレースをもとにAPIを呼び出すと、E地点(ゴール)には11時10分に到着するとアップデートされます。更に**D地点**に10時50分に到着し、再び現在地までのGPSトレースをもとにAPIを呼び出すと、E地点(ゴール)には11時5分に到着するとアップデートされます。これがETAトラッキングモードになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/139a5f91-56a9-77e7-b939-eb619441beba.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/ca3ebc27-e046-c269-65eb-108423c08cdf.png)
特筆すべき点としては、**今まで走った走行ルート**と**これから走る走行ルート**が一つのAPIコールで同時にアップデートされることにあります。（アプリ開発者のロジックがとてもシンプルになります。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/cf378344-303b-5d6a-9a94-76f90bf47ff7.png)

もう一つ強調したい点としては、地図属性情報の同時取得です。Route Matching APIでは`routeMatch`オプションが１であろうが２であろうが、GPSトレースをもとにそのルートに関連する地図属性情報を同時に取得することが可能です。以下のイメージではマップマッチングしたルートに対して複数の地図属性レイヤから情報を取り出し、それらを地図上に反映させているイメージになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/c78c868d-b610-0de2-6e7d-275bd9d8463a.png)

つまり、このETAトラッキングモードを使用して、これから走る走行ルートに対して地図属性を取得するように設定すると、簡易的なエレクトロニックホライズン(前方予測）機能が可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/f0441e2c-7096-8127-4b9f-e0ac096e8ee9.png)
再掲載になりますが、アプリのイメージは以下の様な形になります。（これから起こりうる交通イベントを俯瞰的に伝えています。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/411b1cad-c3b5-020a-47ec-176476e319e1.png)
さて、説明が長くなってしまいました。それではAPIを叩いてみましょう。
## 走行ルートと地図のマッピング
本章の冒頭で紹介した通り、`routeMatch`オプションを**１**に設定することでマップマッチングのオプションとなります。マップマッチングするには、HTTP Headerのwaypointというパラメータにマップマッチングさせたい緯度経度情報を入力する方法と、GPSトレースファイルをBodyにアタッチする方法がありますが、サンプルアプリでは後者を使用しています。
(黒塗りしています`apiKey`はそれぞれ取得致しましたものを設定してください。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/363b3e39-6a8b-140f-4b23-c8c2ef3d4172.png)
すなわち、与えている引数は`routeMatch=1&mode=fastest;car;traffic:disabled`プラスAPI KEYになります。
さらに、以下のイメージはGPXファイルをBodyにアタッチしたイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/8a03fb02-0d21-e1ca-72cb-b44f1e939607.png)
こちらのサンプルでは、８６００行強のJSONデータが返送されます。主な要素は、`route, warnings, language`になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/b286a670-0484-d55e-da1e-da56452154aa.png)
 Route Matching APIが導き出した軌跡を描く上で重要な要素は、以下赤枠内の`shape`内の配列に含まれる緯度経度になります。これらがlink毎のマップマッチングの軌跡になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/a4f54cf1-d302-2fcf-e734-f9aa67c62908.png)

あとは、これらの線をMaps API for Javascriptを使用して地図上に描いていくだけになります。

https://developer.here.com/documentation/examples/maps-js/geoshapes/polyline-on-the-map

## 前方予測とETA(到着予定時刻）算出
本章の冒頭で紹介した通り、`routeMatch`オプションを**２**に設定することででETAトラッキングモードになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/b8a680cb-3fd0-f378-67f7-3343a1dbba43.png)
すなわち、`routeMatch=2&departure=now&waypoint0=35.61187009796092,139.63422727784106&waypoint1=35.61273141555407,139.63960642210498&attributes=TRAFFIC_SIGN_FCn(*)&routeMatch2PlannedWayPointReachRadius=1000&mode=fastest;car;traffic:enabled`プラスAPI KEYとなります。
`routeMatch=1`の時よりパラメータ数が多くなっています。注意点としては、通過したい経路がより多い場合はこちらの`waypoint0, waypoint1,...waypointn`の数を適宜増やすことです。また、注目する部分としては`attributes`というパラメータに`TRAFFIC_SIGN_FCn(*)`という地図属性情報レイヤを追加していることです。（地図属性情報レイヤを増やすほどに前方予測したい情報要素を増やすことができます。）

以下は`routeMatch=1`と同じくGPXファイルをBodyにアタッチしたイメージですが、こちらでアタッチするGPSトレースはあくまで現在地点までのGPSトレースということをご留意ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/8a03fb02-0d21-e1ca-72cb-b44f1e939607.png)
こちらのサンプルでは、９２００行強のJSONデータが返送されます。`routeMatch=1`オプションと比較して主要素が増えております。`route, warnings, language`以外に`matchedRoute,matchedWarnings`という要素が返送されます。
既にお気づきかもしれませんが、こちらの`route warnings`が本章の冒頭で説明しました”**これから走る走行ルート**"で、`matchedRoute,matchedWarnings`が”**今まで走った走行ルート**”のデータになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/27608828-17bc-96f1-81cb-1247d31a59a2.png)

今まで走った走行ルート(`matchedRoute`)及びこれから走る走行ルート(`route`)の軌跡については、`routeMatch=1`と同様の構造で`link`配列要素内の`shape`の緯度経度によって線を描くことが可能です。

本題の前方予測とETA(到着予定時刻）については、それぞれ`route`内の別要素を参照します。
まず、前方予測ですが、以下赤枠内がに示される`TRAFFIC_SIGN_FCN`がそのルート上に関連する地図属性情報になります。地図属性情報は同じ`link`配列要素内に存在する`shape`情報と同レベルで提供されるため、その緯度経度情報を元にそのまま地図上にマッピングできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/309dcde0-0c93-4d71-5d02-1c6cb5354dc1.png)

地図属性情報表については以下のページにその詳細が記載されてます。

https://developer.here.com/documentation/route-matching/dev_guide/topics/here-map-content.html

ETA(到着予定時刻）については、summary内のarrivalがそれに該当します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104985/6272b657-b365-716b-73bf-280395017ec6.png)

以上の様なアプローチで前方予測とETA(到着予定時刻）算出を実現することが可能になりました。

# おわりに
いかがでしたでしょうか？HERE Route Matching APIには今回ご紹介した内容以外にも、交通違反検知、有料道路料金計算、その他多くの地図属性情報を反映さることが可能で、多様なユースケース（UBI:利用ベース自動車保険など）に対応することができます。是非こちらの記事を参考にRoute Matching APIをご利用いただければ幸いです。個人的には、今後より使いやすいドライブシミュレータとなる様改造を進めていきたいと思います。ここまで読んでいただきましてありがとうございました！