Amazon Location Service のルート検索を有効活用する

この記事はMIERUNE Advent Calendar 2021 7日目の記事です。今回は弊社で作成しているAmazon Location Serviceのサンプルページでルート検索機能の改修をおこなったのでそちらのご紹介となります！

## はじめに
今回、社内ハッカソンで作成していたAmazon Location Service(以下ALS)のサンプルのルート検索機能を改修しました。
これまで、クリックでの位置指定によるルート検索は実装してありました。ただ、検索したルートを地図上に表示するのみで他の情報が活用できていなかったり、検索時に送ることができる他のパラメータも使えていなかったためある程度利用できるような形に改修しました。


## 今回実装したもの

- ジオコーディングからルート検索をする
- 移動手段の指定に対応する(travelMode)
- 移動距離・移動時間・今その場所を出発した時の到着時間を表示する

公開中のサンプルですでに本番環境にあげてますので以下のリンクからお試しください！

https://als.mierune.io/

### ジオコーディングからルート検索をする
> ジオコーディングとは？
住所や地名から緯度経度といった地理座標を付与することです。
例えば北海道札幌市中央区北２条東４丁目１−２であれば43.06538020912533, 141.36177722064892のように経度、緯度の情報として返すものです

ALSのジオコーディングについてはの記事でご紹介していますのでジオコーディングに関してはそちらをご覧ください。
今回はスタート地点・ゴール地点のそれぞれに検索ボックスを用意し、地図から選ぶボタンをクリックしている際は緯度経度情報を直接表示、検索ボックスに文字列が入力された際はその検索ボックスの文字列を基にジオコーディングを行い、緯度・経度を取得するという形にしています。
基本的にジオコーディング単体・ルート検索単体と変わりないのでコードは省略します。

### 移動手段の指定に対応する(travelMode)
ALSのルート検索にはtravelModeという指定が存在します。これらのtravelModeは移動速度と道路の互換性に影響します。
travelModeはCar,Truck,Walkingの３種類です。ただし指定をしていない場合はCarが自動選択されます。
今回は選択用のUIを準備し、設定可能にしています。

```js
const params = {
    CalculatorName: 'TestRoute',
    DeparturePosition: lonlat_s,
    DestinationPosition: lonlat_e,
    IncludeLegGeometry: true,
    // TravelMode指定
    TravelMode: travelMode
};
// ルート検索
client.calculateRoute(params, (err, data) => {
    console.log(data);
})
```

### 移動距離・移動時間・今その場所を出発した時の到着時間を表示する
ALSは移動距離・移動時間を取得することが可能です。

```js
const params = {
    CalculatorName: 'TestRoute',
    DeparturePosition: lonlat_s,
    DestinationPosition: lonlat_e,
    IncludeLegGeometry: true,
    // 現時刻に出発するか  
    DepartNow: true,
    // TravelMode指定
    TravelMode: travelMode
};
// ルート検索
client.calculateRoute(params, (err, data) => {
    console.log(data);
})
```

DepertNowをtrueにしておくと現時刻で出発する扱いとなります。

```json
{
    "Legs": […],
    "Summary": {
      "DataSource": "Here",
      "Distance": 3.507,
      "DistanceUnit": "Kilometers",
      "DurationSeconds": 734,
      "RouteBBox": [
        139.7357575,
        35.658321,
        139.758313,
        35.671696
      ]
    }
}
```

上記でリクエストした際の返り値はこのようになっているのですが、Distanceが距離をあらわしており、DistanceUnitがDistanceの単位をあらわしています。（この例だと3.507kmです)
また、DurationSecondsは移動にかかる時間(sec)が帰ってきているため下記のコードなどで整形してあげます。

```js
const calcDuration = (seconds) => {
    /* 時間のフォーマット */
    if (seconds < 60) {
        return seconds + '秒';
    } else if (seconds < 3600) {
        return Math.floor(seconds / 60) + '分' + (seconds % 60) + '秒';
    } else {
        let hour = Math.floor(seconds / 3600);
        let min = seconds % 3600;
        return hour + '時間' + Math.floor(min / 60) + '分' + (min % 60) + '秒';
    }
}
```

また現在出発した時にかかる時間(sec)を取得できているのでせっかくなので到着時間を算出します。
Dayjsというライブラリを使って算出します

```js
import 'dayjs/locale/ja';
import dayjs from 'dayjs';

dayjs.locale('ja');

const arrival =  dayjs()
    .add(route.durationSeconds, 'seconds')
    .format('HH:mm')
```

そんなことを色々とやって

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275457/84224c5c-967a-6543-9eba-b7db8f4e8d44.png)

このように

- ジオコーディングからルート検索をする
- 移動手段の指定に対応する(travelMode)
- 移動距離・移動時間・今その場所を出発した時の到着時間を表示する

が対応できました


## おわりに
Amazon Location Serviceを利用することで簡単にルート検索機能を作れるだけではなくAmazon Location Serviceにある他のサービスとの併用や各種パラメータ・レスポンスの活用によって様々なことがかなり簡単に行えます。

また、今回利用していませんがフェリー・有料道路を避けるオプションやトラックの寸法・重量に対する制限へ対応したオプションなども存在しており、それに応じたルートを提供してくれますので様々なユースケースが見つけられるのではないかと思っています。

今後もアプリケーションは更新していきます！
（今後も更新のタイミングでQiitaなどでお伝えできるかと思います）

https://als.mierune.io/

# おまけ
今回のサンプルサイトは社内ハッカソンにて制作されたものです
そんな会社風土に憧れるという方、一緒に働いてみませんか？

https://mierune.co.jp/recruit