概要
Nuxt.jsで現在地のGoogle Mapを表示させた後、Google Places APIで各種お店の情報を反映する実装のサンプルを記載します。
参考にしたものや留意点
- 今回、vue2-google-mapsというライブラリを使用しています。vue2-google-mapsについては、@ta1nakamuraさんのnuxt.js & vue2-google-mapsの内容を参考にさせて頂いています。
- vue2-google-mapsにて、Google Maps APIのライブラリを呼び出すときの留意点は、vue google maps FAQの「Where is my google?」の項を参考にしています。
- 現在地の取得後、Google Mapsのロード完了時にGoogle Places APIを呼び出します。実装はGoogle Mapsのロード(表示)完了後に何らかの処理を行う方法を参考にしています。
- Google Places APIの呼び出しについては、新プランの Places API を調べてみましたの「NearBy Search」を参考にしています。
サンプルソース
MapComponent.vue
<template>
<div>
<GmapMap
:center="maplocation"
:zoom="15"
:draggable="true"
map-type-id="roadmap"
style="width: 500px; height: 300px"
ref="mapRef"
>
<GmapMarker v-for="m in makers"
:position="m.position"
:title="m.title"
:clickable="true"
:draggable="false"
:icon="m.icon"
:key="m.id">
</GmapMarker>
</GmapMap>
</div>
</template>
<script>
export default {
data() {
return {
maplocation:{lat:0, lng:0},
makers:[]
}
},
async mounted() {
// 現在地の取得
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position){
let coords = position.coords;
// 緯度経度を取得
this.maplocation.lat = coords.latitude;
this.maplocation.lng = coords.longitude;
// 地図読み込み完了時のイベント
this.$gmapApiPromiseLazy().then(() => {
google.maps.event.addListenerOnce(this.$refs.mapRef.$mapObject, 'idle',
function() { this.setPlaceMakers() }.bind(this)
);
});
}.bind(this),
function(error) {
// エラーの場合は東京駅周辺に移動
this.maplocation.lat = 35.6813092;
this.maplocation.lng = 139.7677269;
}
);
} else {
// 現在地取得不可の場合は東京駅周辺に移動
this.maplocation.lat = 35.6813092;
this.maplocation.lng = 139.7677269;
}
},
methods: {
setPlaceMakers() {
let map = this.$refs.mapRef.$mapObject
let placeService = new google.maps.places.PlacesService(map);
// Places APIのnearbySearchを使用する。
placeService.nearbySearch(
{
location: new google.maps.LatLng(this.maplocation.lat, this.maplocation.lng),
radius: 500,
type: ['restaurant']
},
function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
results.forEach(place => {
// デフォルトのアイコンが大きめなので縮小
let icon = {
url: place.icon, // url
scaledSize: new google.maps.Size(30, 30), // scaled size
origin: new google.maps.Point(0,0), // origin
anchor: new google.maps.Point(0, 0) // anchor
};
let maker = {
position: place.geometry.location,
icon: icon,
title: place.name,
id: place.place_id
};
this.makers.push(maker);
});
}
}.bind(this)
);
}
}
}
</script>