Building an Address Search Function with Amazon Location Service
Tags: amazonlocationservice, awsamplify, maplibre, vue
Published: 2021-10-27 11:49:25

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

### I built an address 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 the address 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 Place indexes
First, configure the Amazon Location Place indexes in the AWS console.

<br>

Click "Place indexes".
![img](https://day-journal.com/memo/images/try-063_01.png)

Click "Create place indexes".
![img](https://day-journal.com/memo/images/try-063_02.png)

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

Click on the created address search.
![img](https://day-journal.com/memo/images/try-063_04.png)

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

This completes the configuration of Amazon Location Place indexes :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-063_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.addPlaceSearch();
        },
        methods: {
            mapCreate: function() {
                map = new maplibregl.Map({
                    container: 'map',
                    style: 'sample',
                    center: [141.35585, 43.03851],
                    zoom: 14,
                    bearing: 0,
                    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 };
            },
            addPlaceSearch: function() {
                this.client = new Location({
                    credentials: this.credentials,
                    region: awsconfig.aws_project_region,
                });
                this.params = {
                    IndexName: 'SamplePlace',
                    MaxResults: 1,
                    Text: 'サッポロファクトリー',
                };
                this.client.searchPlaceIndexForText(this.params, (err, data) => {
                    const label = data.Results[0].Place.Label;
                    const lng = data.Results[0].Place.Geometry.Point[0];
                    const lat = data.Results[0].Place.Geometry.Point[1];
                    map.on('load', function() {
                        const popup = new maplibregl.Popup({ 
                            offset: 40 
                        })
                        .setText(label);
                        const marker = new maplibregl.Marker({
                            color: '#005773'
                        })
                        .setLngLat([lng, lat])
                        .setPopup(popup);
                        marker.addTo(map);
                    });
                });
            },
        },
    };
</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 address search settings, specifying the "Name" of the address search you created in IndexName. This time, I searched for "Sapporo Factory".

```javascript
this.client = new Location({
    credentials: this.credentials,
    region: awsconfig.aws_project_region
});
this.params = {
    IndexName: 'SamplePlace',
    MaxResults: 1,
    Text: 'サッポロファクトリー',
};
```

<br>

Use Amazon Location Place indexes to draw the address search results on a map.

```javascript
this.client.searchPlaceIndexForText(this.params, (err, data) => {
    const label = data.Results[0].Place.Label;
    const lng = data.Results[0].Place.Geometry.Point[0];
    const lat = data.Results[0].Place.Geometry.Point[1];
    map.on('load', function() {
        const popup = new maplibregl.Popup({
            offset: 40
        })
        .setText(label);
        const marker = new maplibregl.Marker({
            color: '#005773'
        })
        .setLngLat([lng, lat])
        .setPopup(popup);
        marker.addTo(map);
    });
});

```
<br>

## Configure Amplify roles
Finally, add the Amazon Location Place indexes 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-063_07.png)

Click "Add Inline Policy".

![img](https://day-journal.com/memo/images/try-063_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:SearchPlaceIndexForText",
            "Resource": "arn:aws:geo:us-west-2:xxxxx:place-index/SamplePlace"
        }
    ]
}
```

![img](https://day-journal.com/memo/images/try-063_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 Place indexes :bulb: 

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

#### I was able to build an address search function with Amazon Location Service :thumbsup: 

By using Amazon Location Service, I confirmed that it is easy to build an address 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 features as well :muscle: