メインコンテンツまでスキップ

自身のサイトにGoogle Mapを埋め込む

このページでは、Google Mapを自身のサイトに埋め込み、フロントエンドから位置情報を更新する方法を説明します。

概要

Kuroco のコンテンツにはGoogle Mapの位置情報を保存するための拡張形式が準備されています。 Kuroco管理画面から位置情報を入力する場合は、Kuroco管理画面のコンテンツ編集画面で表示される地図上の位置をクリックするだけで位置情報を指定できますが、フロントエンドでマップを表示する場合や、指定した位置情報を保存するインターフェースを提供する場合にはAPIを利用した実装が必要になります。 このチュートリアルでは、フロントエンドにGoogle Mapsのインターフェースを表示し、位置情報を更新する方法を説明します。

前提条件

備考

このページはKurocoでのプロジェクトが構築済みであることを前提としています。
まだ構築していない場合は、下記のチュートリアルを参照してください。
Kurocoビギナーズガイド

備考

本チュートリアルではNuxt.js のバージョン v2.15.8 を利用しています。

GoogleMapの設定

GCPで新しいプロジェクトを作成

まず、Google Cloud Platform(GCP)で新しいプロジェクトを作成します。 Google Cloud Platformにログインし、ヘッダー部のプロジェクトプルダウンをクリックしてください。
表示されたポップアップ上部の「新しいプロジェクト」をクリックします。

Image from Gyazo

新しいプロジェクト設定画面で、任意のプロジェクト名を入力し、「作成」をクリックします。

Image from Gyazo

以上で新しいプロジェクトが作成されました。

APIの有効化

続いてGCPのコンソールで必要なAPIを有効にします。

まずGCPコンソールのヘッダー部のプルダウンから作成したプロジェクトを選択します。

Image from Gyazo

続いてサイドバーから「APIとサービス」- 「有効なAPIとサービス」を選択してください。

Image from Gyazo

サイドバーから「ライブラリ」を選択するとAPIライブラリページが表示されます。

Image from Gyazo

ここで「Places API」と「Maps JavaScript API」を検索しそれぞれAPIを有効にしてください。

Image from Gyazo

Image from Gyazo

次にAPIキーを発行します。サイドバーから「認証情報」を選択し、「+認証情報を作成」をクリックします。

Image from Gyazo

APIキーを選択します。

Image from Gyazo

これにより、APIキーが生成されます。後で使用しますので控えてください。

Image from Gyazo

許可ドメインの設定

ウェブサイトのドメインをAPIキー登録することで、APIの使用を制御します。これにより、他のウェブサイトからの不正アクセスが防げます。

認証情報の画面内にて、先ほど作成したAPIキーの右にあるボタンから「APIキーを編集」を選択します。

Image from Gyazo

APIキーに任意の名前を入力し、アプリケーションの制限の設定から「ウェブサイト」を選択します。

Image from Gyazo

「ADD」ボタンをクリックし、利用する予定のサイトのドメインを入力、「完了」をクリックします。

Image from Gyazo

Kurocoの設定

コンテンツ定義の設定

Kurocoのコンテンツ定義で拡張項目の任意の箇所に、以下の項目を設定します。

項目名入力値
項目名地図(googleマップ)
識別子gmap
項目設定地図

Image from Gyazo

エンドポイントの作成

Kurocoのコンテンツからマップの位置情報を取得するエンドポイントを作成します。
以下のように入力してください。

項目名入力値
パス/rmcs-api/(API ID)/map/details/{topics_id}
モデルコンテンツ - Topics - details
APIリクエスト制限(閲覧を許可するグループまたはメンバーフィルタを選択)
キャッシュ86400
topics_group_id(表示するコンテンツのコンテンツ定義ID)

Image from Gyazo

次に、マップの位置情報更新用のエンドポイントを作成します。
以下のように入力してください。

項目名入力値
パス/rmcs-api/(API ID)/map/update/{topics_id}
モデルコンテンツ - Topics - update
APIリクエスト制限(変更を許可するグループまたはメンバーフィルタを選択)
topics_group_id(更新したいコンテンツのコンテンツ定義ID)
use_columnsgmap

Image from Gyazo

フロントエンドの実装

npmモジュールの"vue2-google-maps" をインストール

"vue2-google-maps"というnpmモジュールをインストールします。これはGoogle MapsのVue.jsコンポーネントを提供します.

npm install vue2-google-maps

GCP KEYをconfigに記載

生成されたAPIキーを、ウェブサイトの設定ファイル(通常はconfigファイル)に記述します。これにより、ウェブサイトがAPIを利用できるようになります。
Nuxt.jsで実装している場合、.env などに以下のように記載してください。

.env
BASE_URL=https://sample-service-site.g.kuroco.app
GCP_KEY=**************************************
ヒント

.envファイルの内容をデプロイ時に利用する際は、GitHubのシークレットに登録した内容をGitHubActionsで読み込んで使用します。 詳しくはKurocoビギナーズガイドを参照してください。

上記の設定を読み込むため、nuxt.config.js 内に以下のように追記してください。

nuxt.config.js
export default {
env: {
GCP_KEY: process.env.GCP_KEY
},

plugins/ ディレクトリにvue2-google-maps.client.js というファイルを追加し、以下のように記載してください。

/plugins/vue2-google-maps.client.js
import Vue from 'vue';
import * as VueGoogleMaps from 'vue2-google-maps';

Vue.use(VueGoogleMaps, {
load: {
key: process.env.GCP_KEY,
libraries: 'places'
}
});

nuxt.config.js のpluginsディレクティブ内に以下のように追記してください。

nuxt.config.js
    plugins: [
// (中略)
'@/plugins/vue2-google-maps.client'
]

GoogleMapを表示するページの実装

ウェブサイトにGoogle Mapを表示してみましょう。 vue2-google-maps のコンポーネントの<GmapMap><GmapMarker> を使用し、以下のように実装します。

/pages/map/details/_id.vue
<template>
<div class="container">
<h3>
地図(googleマップ)
</h3>
<form id="topics_edit" @submit.prevent="update">
<div>
<GmapMap
ref="gmap"
:center="mapCenter"
:zoom="gmap_zoom"
:map-type-id="gmap_type"
style="width: 500px; height: 300px"
>
<GmapMarker
v-if="markPlace"
:position="markPlace"
/>
</GmapMap>
</div>
</form>
</div>
</template>

<script>
export default {
async asyncData({ $axios, route }) {
const id = route.params.id;
const url = `/rcms-api/3/map/details/${id}`;

const contents = await $axios
.$get(url)
.then((response) => {
if (response.details) {
return response.details;
}
return {};
})
.catch((error) => {
console.log(error);
return {};
});
// Googleマップの初期状態をセット
let mapCenter = { lat: 35.66107078220203, lng: 139.7584319114685 };
let markPlace = null;
if (contents.gmap?.gmap_x && contents.gmap?.gmap_y) {
const lat = Number(contents.gmap.gmap_y);
const lng = Number(contents.gmap.gmap_x);
mapCenter = { lat, lng };
markPlace = { lat, lng };
}

return {
mapCenter,
markPlace,
id,
contents,
errors: []
};
},
computed: {
gmap_zoom() {
return Number(this.contents.gmap?.gmap_zoom) || 15;
},
gmap_type() {
return this.contents.gmap?.gmap_type || 'roadmap';
}
}
};
</script>
注意

利用するエンドポイントのURLはご自身のものに調整してください。

実行結果は以下のようになります。
Image from Gyazo

GoogleMapの位置情報を更新するページの実装

続いて、フロントエンドから位置情報を更新できるようにしてみましょう。 vue2-google-maps のコンポーネントの<GmapAutocomplete> を用いると、Googleマップの検索フィールドの逐次検索機能を利用することが出来ます。

/pages/map/edit/_id.vue
<template>
<div class="container">
<h3>
地図(googleマップ)
</h3>
<div>
地図上をクリックすると設定される位置が変わります。ズームなどの状態も設定できます。
</div>
<form id="topics_edit" @submit.prevent="update">
<div>
<form onsubmit="return false;">
<GmapAutocomplete
:options="{fields: ['geometry']}"
:select-first-on-enter="true"
@place_changed="setPlace"
/>
<GmapMap
ref="gmap"
:center="mapCenter"
:zoom="gmap_zoom"
:map-type-id="gmap_type"
style="width: 500px; height: 300px"
@click="mark($event)"
@zoom_changed="gmap_zoom = $event"
@maptypeid_changed="gmap_type = $event"
>
<GmapMarker
v-if="markPlace"
:position="markPlace"
/>
</GmapMap>
</form>
</div>
<input
type="submit"
value="保存"
>
</form>
</div>
</template>

<script>
export default {
async asyncData({ $axios, route }) {
const id = route.params.id;
const url = `/rcms-api/3/map/details/${id}`;

const contents = await $axios
.$get(url)
.then((response) => {
if (response.details) {
return response.details;
}
return {};
})
.catch((error) => {
cosole.log(error);
return {};
});
// Googleマップの初期状態をセット
let mapCenter = { lat: 35.66107078220203, lng: 139.7584319114685 };
let markPlace = null;
if (contents.gmap?.gmap_x && contents.gmap?.gmap_y) {
const lat = Number(contents.gmap.gmap_y);
const lng = Number(contents.gmap.gmap_x);
mapCenter = { lat, lng };
markPlace = { lat, lng };
}

return {
mapCenter,
markPlace,
id,
contents,
errors: []
};
},
computed: {
gmap_zoom: {
get() { return Number(this.contents.gmap?.gmap_zoom) || 15; },
set(val) { this.contents.gmap.gmap_zoom = String(val); }
},
gmap_type: {
get() { return this.contents.gmap?.gmap_type || 'roadmap'; },
set(val) { this.contents.gmap.gmap_type = val; }
}
},
methods: {
setPlace(place) {
if (place.geometry) {
this.markPlace = {
lat: place.geometry.location.lat(),
lng: place.geometry.location.lng()
};
if (place.geometry.viewport) {
this.$refs.gmap.fitBounds(place.geometry.viewport);
} else {
this.$refs.gmap.panTo(place.geometry.location);
}
}
},
mark(event) {
this.markPlace = {
lat: event.latLng.lat(),
lng: event.latLng.lng()
};
},
async update() {
const params = {
gmap: {
gmap_x: '',
gmap_y: '',
gmap_zoom: (this.contents?.gmap?.gmap_zoom || 15),
gmap_type: (this.contents?.gmap?.gmap_type || 'roadmap')
}
};
if (this.markPlace) {
params.gmap.gmap_x = String(this.markPlace.lng);
params.gmap.gmap_y = String(this.markPlace.lat);
}
await this.$axios.post(
'/rcms-api/3/building/update/' + this.$route.params.id,
params
).then((response) => {
if (response.data.errors?.length) {
console.log(response.data.errors);
}
this.errors = [];
}).catch((error) => {
console.log(error);
});
}
}
};
</script>
注意

利用するエンドポイントのURLはご自身のものに調整してください。

実行結果は以下のようになります。
Image from Gyazo

保存ボタンをクリックするとピンを立てた位置やズームの状態などがKurocoのDBに書き込まれます。

注意

上記のサンプルコードでは簡単のため、非ログイン状態でもページが表示されるようになってますが、通常はログインしてから更新をおこないます。ログインについては以下をご参照ください。
KurocoとNuxt.jsで、ログイン画面を構築する

以上で、Google Mapをあなたのウェブサイトに埋め込み、ウェブサイト上からKuroco管理画面と同様に位置情報を変更する事ができるようになりました。これらの手順によって、ウェブサイトのユーザーに素晴らしい地図体験を提供できます。


サポート

お探しのページは見つかりましたか?解決しない場合は、問い合わせフォームからお問い合わせいただくか、Slackコミュニティにご参加ください。