Amazon Location ServiceとMapLibre GL JSとAWS AmplifyとVue.jsを組み合わせてマップアプリケーションを構築してみました!
先日Amazon Location Serviceが正式に一般公開されました。去年のGeoSaturday 2020 Onlineでプレビュー版をさわったくらいだったので、だいぶ乗り遅れた感ありますが色々と探ってみました!
Amazon Location Serviceとは、AWS内で利用できる位置情報アプリケーションを構築するためのサービスになります。現時点の機能として、地図表示機能・住所検索機能・ルート検索機能・ジオフェンス機能・トラッキング機能の5種類を利用できます。今回は、地図表示機能を利用しマップアプリケーションを構築してみました。
事前準備
- AWS AmplifyとVue.jsのログイン機能までの設定
以前書いた記事からの続きで説明します。
AWS AmplifyとAmplify UI VueとVue.jsでログイン機能を構築してみた
Amazon Location Mapsの設定
はじめに、AWSコンソールでAmazon Location Mapsの設定をします。
「Maps」をクリックします。
「Create map」をクリックします。
マップ名の入力とマップを選択します。今回は「sample」としました。
作成されたマップをクリックします。
ここで表示されている「Name」と「ARN」を今後の設定で利用するのでコピーしておきます。
これでAmazon Location Mapsの設定は完了になります。
フロントエンド
次に、実際にマップアプリケーションを構築していきます。
AmplifyとVue.jsの構成ができていると、基本的には「MapPane.vue」を新規で追加するのと、コードを一部変更するのみになります。
実行環境
- node v16.3.0
- npm v7.15.1
事前に、MapLibre GL JSのパッケージをインストールします。
npm install maplibre-gl
全体構成
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",
"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
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'
// MapLibre GL JSのCSSを読み込み
import 'maplibre-gl/dist/maplibre-gl.css'
// Amplify読み込み
import '@aws-amplify/ui-vue'
import Amplify from 'aws-amplify'
import awsconfig from './aws-exports'
Amplify.configure(awsconfig)
Vue.config.productionTip = false
new Vue({
router,
store,
vuetify,
render: h => h(App)
}).$mount('#app')
MapLibre GL JSを読み込みます。
// MapLibre GL JSのCSSを読み込み
import 'maplibre-gl/dist/maplibre-gl.css'
/src/views
Home.vue
<template>
<div class="home">
<v-container>
<v-row>
<v-col>
<h1>Amazon Location Service</h1>
</v-col>
</v-row>
<v-row>
<v-col>
<MapPane></MapPane>
</v-col>
</v-row>
<v-row>
<v-col>
<!--ログアウトコンポーネント-->
<amplify-sign-out></amplify-sign-out>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
// マップコンポーネント読み込み
import MapPane from '@/components/MapPane.vue'
export default {
name: 'home',
components: {
MapPane
}
}
</script>
<style>
.home {
padding-top: 100px;
}
</style>
マップコンポーネントを設定します。
<v-row>
<v-col>
<MapPane></MapPane>
</v-col>
</v-row>
マップコンポーネントを読み込みます。
// マップコンポーネント読み込み
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>
// MapLibre GL JSを読み込み
import maplibregl from 'maplibre-gl'
// Amplify読み込み
import { Auth, Signer } from 'aws-amplify'
import awsconfig from '../aws-exports'
export default {
name: 'MapPane',
data() {
return {
credentials: null,
}
},
mounted: async function () {
// 認証情報取得
this.credentials = await Auth.currentCredentials()
// マップオブジェクト生成
this.mapCreate();
},
methods: {
// マップオブジェクト生成
mapCreate: function() {
// Amazon Location Maps読み込み
const 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());
},
// Amazon Location Maps設定
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 }
},
}
}
</script>
<style scoped>
#map {
z-index: 0;
height: 800px;
}
</style>
MapLibre GL JSとAmplifyを読み込みます。
// MapLibre GL JSを読み込み
import maplibregl from 'maplibre-gl'
// Amplify読み込み
import { Auth, Signer } from 'aws-amplify'
import awsconfig from '../aws-exports'
認証情報を取得します。
// 認証情報取得
this.credentials = await Auth.currentCredentials()
styleに作成したマップの「Name」を指定します。
// Amazon Location Maps読み込み
const 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,
});
Amazon Location Mapsを読み込む設定をします。
// Amazon Location Maps設定
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 }
},
Amplifyのロール設定
最後にAmplifyのロールにAmazon Location Mapsのポリシーを追加します。
ログイン機能で利用しているロールを検索します。「amplify-xxxxx-authRole」を選択します。
「インラインポリシーの追加」をクリックします。
「JSON」を選択しポリシーを設定します。Resourceは作成したマップの「ARN」を設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "MapsReadOnly",
"Effect": "Allow",
"Action": [
"geo:GetMapStyleDescriptor",
"geo:GetMapGlyphs",
"geo:GetMapSprites",
"geo:GetMapTile"
],
"Resource": "arn:aws:geo:us-west-2:xxxxx:map/sample"
}
]
}
名前を任意で設定します。今回は「amazon-location-maps」としました。
ポリシーが作成されているのを確認します。
これでAmplifyのロール設定は完了になります。
簡易ローカルサーバーで確認してみます。
npm run serve
ローカルサーバーを立ち上げて、ログインしてみます。Amazon Location Mapsの表示を確認できました。
Amazon Location ServiceとMapLibre GL JSとAWS AmplifyとVue.jsを組み合わせてマップアプリケーションを構築できました!
事前にAmplifyを導入すると、Amazon Location Serviceを手軽に構築することができました。ただ、ロールの設定が別途必要だったり、選択できるスタイルが限定されている等(アレをアレするとスタイル設定変更できたりするのですが…)まだまだ進化できる部分がありそうです。他の機能についても引き続き探っていきたいと思います!
MapLibre GL JSとVue.jsについて、他にも記事を書いています。よろしければぜひ。
tags - MapLibre GL JS
tags - Vue.js