Nuxt.jsでGoogle Places APIの結果をGoogle Mapに反映させる

## 概要
Nuxt.jsで現在地のGoogle Mapを表示させた後、Google Places APIで各種お店の情報を反映する実装のサンプルを記載します。

## 参考にしたものや留意点
* 今回、vue2-google-mapsというライブラリを使用しています。vue2-google-mapsについては、@ta1nakamuraさんの[nuxt.js & vue2-google-maps](https://qiita.com/ta1nakamura/items/e1f9e6ca6f203ce69547)の内容を参考にさせて頂いています。
* vue2-google-mapsにて、Google Maps APIのライブラリを呼び出すときの留意点は、[vue google maps FAQ](https://github.com/xkjyeah/vue-google-maps/wiki/vue-google-maps-FAQ)の「Where is my google?」の項を参考にしています。
* 現在地の取得後、Google Mapsのロード完了時にGoogle Places APIを呼び出します。実装は[Google Mapsのロード(表示)完了後に何らかの処理を行う方法](http://lifelog.main.jp/wordpress/?p=1785)を参考にしています。
* Google Places APIの呼び出しについては、[新プランの Places API を調べてみました](https://maps.multisoup.co.jp/blog/3211/)の「NearBy Search」を参考にしています。

## サンプルソース

```vue: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>

```
## 画面表示
APIの取得が成功したら以下のような感じで、Mapが表示されます。
<img width="498" alt="スクリーンショット 2019-10-24 2.40.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32098/ec02c102-0d39-9cbd-e29c-6945949b90cb.png">