Building a Route Search Function with Amazon Location Service
Tags: amazonlocationservice, awsamplify, maplibre, vue
Published: 2021-10-25 13:18:06

![img](https://day-journal.com/memo/images/try-062_10.png)
<br>

### I built a route search function with Amazon Location Service :tada:  

Amazon Location Service is a service for building location-based applications within AWS. At present, five types of functions are available: map display function, address search function, route search function, geofence function, and tracking function. This time, I added a route search function and built a map application!

<br>

Advance Preparation
- Amazon Location Service settings up to the map display function

This is a continuation of the previous article I wrote.

[Building a Map Application with Amazon Location Service, MapLibre GL JS, AWS Amplify, and Vue.js](https://dev.to/aws-builders/building-a-map-application-with-amazon-location-service-maplibre-gl-js-aws-amplify-and-vuejs-2m48)
<br>

## Configure Amazon Location Route calculators
First, configure the Amazon Location Route calculators in the AWS console.

<br>

Click on "Route calculators".
![img](https://day-journal.com/memo/images/try-062_01.png)

Click "Create route calculator".
![img](https://day-journal.com/memo/images/try-062_02.png)

Enter the route search name and select the data to be used. This time, we chose "SampleRoute".
![img](https://day-journal.com/memo/images/try-062_03.png)

Click on the created route calculator.
![img](https://day-journal.com/memo/images/try-062_04.png)

Copy the "Name" and "ARN" displayed here to use them in future settings.
![img](https://day-journal.com/memo/images/try-062_05.png)

This completes the configuration of Amazon Location Route calculators :thumbsup: 
<br>

## Frontend
Next, let's build the map application.  

Once you have configured the map display function of Amazon Location Service, you only need to change "MapPane.vue".

<br>

execution environment
- node v16.3.0  
- npm v7.15.1  

<br>

Install the AWS SDK for JavaScript package in advance.

```sh
npm install aws-sdk
```

<br>

Overall composition

![img](https://day-journal.com/memo/images/try-062_06.png)


#### package.json

```json
{
  "name": "amazon-location-app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@aws-amplify/ui-vue": "^1.0.12",
    "aws-amplify": "^4.1.1",
    "aws-sdk": "^2.935.0",
    "core-js": "^3.6.5",
    "maplibre-gl": "^1.14.1-rc.2",
    "vue": "^2.6.11",
    "vue-router": "^3.2.0",
    "vuetify": "^2.4.0",
    "vuex": "^3.4.0"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-plugin-router": "~4.5.0",
    "@vue/cli-plugin-vuex": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "sass": "~1.32.0",
    "sass-loader": "^10.0.0",
    "vue-cli-plugin-vuetify": "~2.4.1",
    "vue-template-compiler": "^2.6.11",
    "vuetify-loader": "^1.7.0"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}
```

<br>

/src/components

#### MapPane.vue

```vue
<template>
    <div class='mapPane'>
        <div id='map'></div>
    </div>
</template>

<script>
    import maplibregl from 'maplibre-gl'
    import { Auth, Signer } from 'aws-amplify'
    import awsconfig from '../aws-exports'
    import Location from 'aws-sdk/clients/location'
    let map;

    export default {
        name: 'MapPane',
        data() {
            return {
                credentials: null,
                client: null,
                params: null,
            }
        },
        mounted: async function () {
            this.credentials = await Auth.currentCredentials()
            this.mapCreate()
            this.addRouteSearch()
        },
        methods: {
            mapCreate: function() {
                map = new maplibregl.Map({
                    container: 'map',
                    style: 'sample',
                    center: [139.7648, 35.6794],
                    zoom: 15,
                    bearing: 64.8,
                    pitch: 60,
                    hash: true,
                    transformRequest: this.transformRequest,
                });

                map.addControl(new maplibregl.NavigationControl());
            },
            transformRequest: function (url, resourceType) {
                if (resourceType === 'Style' && !url.includes('://')) {
                    url = `https://maps.geo.${awsconfig.aws_project_region}.amazonaws.com/maps/v0/maps/${url}/style-descriptor`
                }
                if (url.includes('amazonaws.com')) {
                    return {
                        url: Signer.signUrl(url, {
                            access_key: this.credentials.accessKeyId,
                            secret_key: this.credentials.secretAccessKey,
                            session_token: this.credentials.sessionToken,
                        }),
                    }
                }
                return { url }
            },
            addRouteSearch : function() {
                this.client = new Location({
                    credentials: this.credentials,
                    region: awsconfig.aws_project_region
                });
                this.params = {
                    CalculatorName: 'SampleRoute',
                    DeparturePosition: [139.7558, 35.6767],
                    DestinationPosition: [139.8160, 35.6830],
                    IncludeLegGeometry: true,
                }
                this.client.calculateRoute (this.params, (err, data) => {
                    const routes = data.Legs[0].Geometry.LineString
                    map.on('load', function () {
                        map.addSource('route_sample', {
                            'type': 'geojson',
                            'data': {
                                'type': 'Feature',
                                'properties': {},
                                'geometry': {
                                    'type': 'LineString',
                                    'coordinates': routes
                                }
                            }
                        });
                        map.addLayer({
                            'id': 'route_sample',
                            'type': 'line',
                            'source': 'route_sample',
                            'layout': {
                                'line-join': 'round',
                                'line-cap': 'round'
                            },
                            'paint': {
                                'line-color': '#FF0000',
                                'line-width': 10,
                                'line-opacity': 0.5
                            }
                        });
                    });
                })
            }
        }
    }
</script>

<style scoped>
    #map {
        z-index: 0;
        height: 800px;
    }
</style>
```

<br>

Load the Amazon Location Service.

```javascript
import Location from 'aws-sdk/clients/location'
```

<br>

Configure the Amazon Location Service and route search settings, specifying the "Name" of the route search you created in CalculatorName. This time, set the start and endpoints to the Tokyo Station area.

```javascript
this.client = new Location({
    credentials: this.credentials,
    region: awsconfig.aws_project_region
});
this.params = {
    CalculatorName: 'SampleRoute',
    DeparturePosition: [139.7558, 35.6767],
    DestinationPosition: [139.8160, 35.6830],
    IncludeLegGeometry: true,
}
```

<br>

Use Amazon Location Route calculators to draw the route search results on a map.

```javascript
this.client.calculateRoute (this.params, (err, data) => {
    const routes = data.Legs[0].Geometry.LineString
    map.on('load', function () {
        map.addSource('route_sample', {
            'type': 'geojson',
            'data': {
                'type': 'Feature',
                'properties': {},
                'geometry': {
                    'type': 'LineString',
                    'coordinates': routes
                }
            }
        });
        map.addLayer({
            'id': 'route_sample',
            'type': 'line',
            'source': 'route_sample',
            'layout': {
                'line-join': 'round',
                'line-cap': 'round'
            },
            'paint': {
                'line-color': '#FF0000',
                'line-width': 10,
                'line-opacity': 0.5
            }
        });
    });
})
```
<br>

## Configure Amplify roles
Finally, add the Amazon Location Route calculators policy to the Amplify role.

<br>

Search for the role that is used for the login function. Select "amplify-xxxxx-authRole".

![img](https://day-journal.com/memo/images/try-062_07.png)

Click "Add Inline Policy".

![img](https://day-journal.com/memo/images/try-062_08.png)

Select "JSON" to set the policy, and set the "ARN" of the map you created to "Resource."

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Routes",
            "Effect": "Allow",
            "Action": "geo:CalculateRoute",
            "Resource": "arn:aws:geo:us-west-2:xxxxx:route-calculator/SampleRoute"
        }
    ]
}
```

![img](https://day-journal.com/memo/images/try-062_09.png)

This completes the role configuration for Amplify :thumbsup: 

<br>

Let's check with a simple local server.

```shell
npm run serve
```

<br>

Startup a local server and try logging in. You can now see the Amazon Location Route calculators :bulb: 

![img](https://day-journal.com/memo/images/try-062_00.gif)  

#### I was able to build a route search function with Amazon Location Service :thumbsup: 

Using Amazon Location Service, I confirmed that it is easy to build a route search. There are various options available, so I hope you will try them out using this sample as a reference. I will continue to explore other functions as well :muscle: