LoginSignup
4
2

More than 1 year has passed since last update.

Amazon Location ServiceとLeafletとAWS AmplifyとVue.jsを組み合わせてマップアプリケーションを構築してみた

Last updated at Posted at 2021-06-24



Amazon Location ServiceとLeafletとAWS AmplifyとVue.jsを組み合わせてマップアプリケーションを構築してみました :tada:

前回投稿した記事のLeafletバージョンを構築してみました :thumbsup:

Amazon Location Serviceとは、AWS内で利用できる位置情報アプリケーションを構築するためのサービスになります。現時点の機能として、地図表示機能・住所検索機能・ルート検索機能・ジオフェンス機能・トラッキング機能の5種類を利用できます。今回は、地図表示機能を利用しマップアプリケーションを構築してみました!


事前準備


Amazon Location Mapsの設定

はじめに、AWSコンソールでAmazon Location Mapsの設定をします。


「Maps」をクリックします。
画像

「Create map」をクリックします。
画像

マップ名の入力とマップを選択します。今回は「sample」としました。
画像

作成されたマップをクリックします。
画像

ここで表示されている「Name」と「ARN」を今後の設定で利用するのでコピーしておきます。
画像

これでAmazon Location Mapsの設定は完了になります :thumbsup:


フロントエンド

次に、実際にマップアプリケーションを構築していきます。

AmplifyとVue.jsの構成ができていると、基本的には「MapPane.vue」を新規で追加するのと、コードを一部変更するのみになります。


実行環境

  • node v16.3.0
  • npm v7.15.1


事前に、Leafletのパッケージをインストールします。また、ベクトルタイルを表示するためにMapbox GL Leafletのパッケージと、Mapbox GL JSのOSSバージョンのパッケージもインストールします。

npm install leaflet
npm install mapbox-gl-leaflet
npm install mapbox-gl@1.13.0


全体構成

画像

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",
    "leaflet": "^1.7.1",
    "mapbox-gl": "^1.13.0",
    "mapbox-gl-leaflet": "^0.0.15",
    "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'

// LeafletとMapbox GL JSのOSSバージョンのCSSを読み込み
import 'leaflet/dist/leaflet.css'
import 'mapbox-gl/dist/mapbox-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')


LeafletとMapbox GL JSのOSSバージョンを読み込みます。

// LeafletとMapbox GL JSのOSSバージョンのCSSを読み込み
import 'leaflet/dist/leaflet.css'
import 'mapbox-gl/dist/mapbox-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>
    // LeafletとMapbox GL Leafletを読み込み
    import L from 'leaflet'
    import 'mapbox-gl-leaflet'
    // 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 sample = L.mapboxGL({
                    style: 'sample',
                    attribution: '© 2021 HERE',
                    transformRequest: this.transformRequest,
                });
                // マップ読み込み
                const map = L.map('map', {
                    center: [35.681, 139.767],
                    zoom: 14,
                    zoomControl: true,
                    layers: [sample]
                });

                //背景レイヤ
                const Map_BaseLayer = {
                    'sample': sample
                };
                //レイヤ設定
                L.control.layers(
                    Map_BaseLayer,
                    null
                ).addTo(map);
            },
            // 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>


LeafletとMapbox GL LeafletとAmplifyを読み込みます。

// LeafletとMapbox GL Leafletを読み込み
import L from 'leaflet'
import 'mapbox-gl-leaflet'
// Amplify読み込み
import { Auth, Signer } from 'aws-amplify'
import awsconfig from '../aws-exports'


認証情報を取得します。

// 認証情報取得
this.credentials = await Auth.currentCredentials()


styleに作成したマップの「Name」を指定します。

// Amazon Location Maps読み込み
const sample = L.mapboxGL({
    style: 'sample',
    attribution: '© 2021 HERE',
    transformRequest: this.transformRequest,
});
// マップ読み込み
const map = L.map('map', {
    center: [35.681, 139.767],
    zoom: 14,
    zoomControl: true,
    layers: [sample]
});

//背景レイヤ
const Map_BaseLayer = {
    'sample': sample
};
//レイヤ設定
L.control.layers(
    Map_BaseLayer,
    null
).addTo(map);


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のロール設定は完了になります :thumbsup:


簡易ローカルサーバーで確認してみます。

npm run serve


ローカルサーバーを立ち上げて、ログインしてみます。Amazon Location Mapsの表示を確認できました :bulb:

画像

Amazon Location ServiceとLeafletとAWS AmplifyとVue.jsを組み合わせてマップアプリケーションを構築できました :thumbsup:

事前にAmplifyを導入すると、Amazon Location Serviceを手軽に構築することができました。ただ、ロールの設定が別途必要だったり、選択できるスタイルが限定されている等(アレをアレするとスタイル設定変更できたりするのですが...)まだまだ進化できる部分がありそうです。他の機能についても引き続き探っていきたいと思います :thumbsup:


LeafletとVue.jsについて、他にも記事を書いています。よろしければぜひ。
tags - Leaflet
tags - Vue.js

やってみたシリーズ :grinning:
tags - Try
AWS AmplifyとAmplify UI VueとVue.jsでログイン機能を構築してみた




book

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2