DEV Community

Cover image for Building an Address Search Function with Amazon Location Service
Yasunori Kirimoto for AWS Community Builders

Posted on • Edited on

Building an Address Search Function with Amazon Location Service



I built an address search function with Amazon Location Service 🎉

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!

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

Configure Amazon Location Place indexes

First, configure the Amazon Location Place indexes in the AWS console.

Click "Place indexes".
img

Click "Create place indexes".
img

Enter the address search name and select the data to be used. This time, we chose "SamplePlace."
img

Click on the created address search.
img

Copy the "Name" and "ARN" displayed here for future settings.
img

This completes the configuration of Amazon Location Place indexes 👍

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".

execution environment

  • node v16.3.0
  • npm v7.15.1

Install the AWS SDK for JavaScript package in advance.

npm install aws-sdk
Enter fullscreen mode Exit fullscreen mode

Overall composition

img

package.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"
  ]
}
Enter fullscreen mode Exit fullscreen mode

/src/components

MapPane.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>
Enter fullscreen mode Exit fullscreen mode

Load the Amazon Location Service.

import Location from 'aws-sdk/clients/location'
Enter fullscreen mode Exit fullscreen mode

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".

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

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

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);
    });
});

Enter fullscreen mode Exit fullscreen mode

Configure Amplify roles

Finally, add the Amazon Location Place indexes policy to the Amplify role.

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

img

Click "Add Inline Policy".

img

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

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Routes",
            "Effect": "Allow",
            "Action": "geo:SearchPlaceIndexForText",
            "Resource": "arn:aws:geo:us-west-2:xxxxx:place-index/SamplePlace"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

img

This completes the role configuration for Amplify 👍

Let's check with a simple local server.

npm run serve
Enter fullscreen mode Exit fullscreen mode

Startup a local server and try logging in. You can now see the Amazon Location Place indexes 💡

img

I was able to build an address search function with Amazon Location Service 👍

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 💪

Top comments (0)