Building a Map Application with Amplify Geo and Vue.js
Yasunori Kirimoto
Posted on November 15, 2021
I built a map application using Amplify Geo and Vue.js 🎉
Amplify Geo was officially released to the public the other day, so I got to try it out.
Amplify Geo is a feature of AWS Amplify that allows you to build Amazon Location Service easier!
Advance Preparation
- Setting up AWS Amplify and Vue.js to the login feature
Building a login function with AWS Amplify, Amplify UI Vue, and Vue 3
Setting up Amplify Geo
First, we will configure Amplify Geo.
Add location feature (map)
If you only need a location function (geocoding), you can implement it with these two commands as same as the map function!
Amazon Location Service requires AWS console configuration and role configuration, but Amplify Geo does all of that for you!
amplify add geo
amplify push
This completes the configuration of Amplify Geo.
Frontend
Next, let's build the actual map application.
Once Amplify and Vue.js are configured, it's just a matter of adding a new "MapPane.vue" and changing some of the code.
execution environment
- node v16.10.0
- npm v7.24.0
Install MapLibre GL JS v1 and MapLibre GL JS Amplify, a wrapper library, in advance.
npm install maplibre-gl@1.15.2
npm install maplibre-gl-js-amplify
Overall composition
package.json
{
"name": "amplify-geo",
"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-components": "^1.9.2",
"aws-amplify": "^4.3.4",
"core-js": "^3.6.5",
"maplibre-gl": "^1.15.2",
"maplibre-gl-js-amplify": "^1.1.2",
"vue": "^3.0.0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-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",
"@vue/compiler-sfc": "^3.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
/src
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'maplibre-gl/dist/maplibre-gl.css'
import {
applyPolyfills,
defineCustomElements
} from '@aws-amplify/ui-components/loader';
import Amplify from 'aws-amplify';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
applyPolyfills().then(() => {
defineCustomElements(window);
});
const app = createApp(App);
app.config.isCustomElement = tag => tag.startsWith('amplify-');
app.use(store).use(router).mount('#app');
Load MapLibre GL JS.
import 'maplibre-gl/dist/maplibre-gl.css'
/src/views
Home.vue
<template>
<div class="home">
<h2>Amplify Geo</h2>
<MapPane></MapPane>
<amplify-sign-out></amplify-sign-out>
</div>
</template>
<script>
import MapPane from '@/components/MapPane.vue'
export default {
name: 'Home',
components: {
MapPane
}
}
</script>
Set the map component.
<MapPane></MapPane>
Loads the map component.
import MapPane from '@/components/MapPane.vue'
export default {
name: 'home',
components: {
MapPane
}
}
/src/components
MapPane.vue
<template>
<div class='mapPane'>
<div id='map'></div>
</div>
</template>
<script>
import { createMap, drawPoints } from 'maplibre-gl-js-amplify';
export default {
name: 'MapPane',
data() {
return {
}
},
mounted: async function () {
this.mapCreate();
},
methods: {
mapCreate: async function() {
const map = await createMap({
container: 'map',
center: [139.7648, 35.6794],
zoom: 15,
bearing: 64.8,
pitch: 60,
hash: true,
});
map.on('load', function () {
drawPoints('pointsSource',
[
{
coordinates: [139.7646, 35.6827],
title: 'Point01',
address: 'Main Points',
},
{
coordinates: [139.7720, 35.6768],
title: 'Point02',
},
{
coordinates: [139.7607, 35.6759],
},
],
map,
{
showCluster: true,
unclusteredOptions: {
showMarkerPopup: true,
defaultColor: '#005773'
},
clusterOptions: {
showCount: true,
fillColor: '#005773'
},
}
);
});
}
}
}
</script>
<style scoped>
#map {
z-index: 0;
height: 800px;
}
</style>
Load the map and marker functions in MapLibre GL JS Amplify.
import { createMap, drawPoints } from 'maplibre-gl-js-amplify';
Set up the map in MapLibre GL JS Amplify.
const map = await createMap({
container: 'map',
center: [139.7648, 35.6794],
zoom: 15,
bearing: 64.8,
pitch: 60,
hash: true,
});
Set the marker in MapLibre GL JS Amplify.
drawPoints('pointsSource',
[
{
coordinates: [139.7646, 35.6827],
title: 'Point01',
address: 'Main Points',
},
{
coordinates: [139.7720, 35.6768],
title: 'Point02',
},
{
coordinates: [139.7607, 35.6759],
},
],
map,
{
showCluster: true,
unclusteredOptions: {
showMarkerPopup: true,
defaultColor: '#005773'
},
clusterOptions: {
showCount: true,
fillColor: '#005773'
},
}
);
Let's check with a simple local server.
npm run serve
Start up a local server and try logging in 💡
I was able to build a map application using Amplify Geo combined with Vue.js 👍
Using Amplify Geo eliminates the need to configure roles and settings in the AWS console, making it easier to build than using Amazon Location Service as it is. However, when customizing beyond the existing functions, MapLibre GL JS needs to be directly loaded and developed, and it seems that more complex customization can be done by using it in combination with the necessary parts of Amplify Geo. I'll keep exploring this 👍
Posted on November 15, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2021