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.
Enter the address search name and select the data to be used. This time, we chose "SamplePlace."
Click on the created address search.
Copy the "Name" and "ARN" displayed here for future settings.
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
Overall composition
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"
]
}
/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>
Load the Amazon Location Service.
import Location from 'aws-sdk/clients/location'
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: 'サッポロファクトリー',
};
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);
});
});
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".
Click "Add Inline Policy".
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"
}
]
}
This completes the role configuration for Amplify 👍
Let's check with a simple local server.
npm run serve
Startup a local server and try logging in. You can now see the Amazon Location Place indexes 💡
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)