Vue.js + Google maps javascript apiで面積を算出

#目標
Vue.js,Google maps javascript apiを用いて,面積を算出したい!
（イメージとしては、スー●（大手不動産会社)HPの検索画面みたいな。分かり辛い...)
https://suumo.jp/edit/app/suumo_iphone.html

Vue.jsで実装している例が少なかったんで、投稿してみた。

##方法
おおむね2通り。

- DrawingManagerを使用する方法（簡便）
- 自前でピンを設置し、ポリゴンを作成する方法

今回は前者(Drawing Manager）を採用した。
右記を参考に実装を進める。https://maps.multisoup.co.jp/blog/2612/

##Google Map APIの読み込み
外部jsをindex.html内で読み込む。🔺この際URL末尾に"&libraries=geometry"を追加すること。

```html
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
```

[参考]http://kbn1053.hatenablog.com/entry/2018/04/21/001651

この方法だと、Vue.jsの全コンポネント内でjsが読み込まれレスポンス低下の原因に。今回は目を瞑っておく、、、
こだわる方は下記がわかりやすい。

https://qiita.com/diggy-mo/items/fb02a69c92138cf2d4a4

##ソースコード
領域を指定すれば面積が計算される

```vuejs

<template>
  <div>
    <v-row>
      <v-col cols="8" >
        <h4>
          <span>範囲を選択しましょう</span>
          <v-btn icon @click="attention=true">
            <v-icon>mdi-help-circle-outline</v-icon>
          </v-btn>
        </h4>
      </v-col>
      <v-spacer></v-spacer>
      <v-col>
        <v-btn small color="blue" dark @click="clear_polygon">リセット</v-btn>
      </v-col>
    </v-row>
    
    <div id="map" :style="{width:'100%',height:'60vh'}"/>
    
    <v-container v-if="this.polygon">
      <v-card  raised>
        <v-card-text>
          <div class="text--primary title">あなたの指定した領域は、{{Math.round(calc_result)}}m^2 ({{Math.round(calc_result * 0.518231)}}畳)</div>
          <v-btn color="blue" dark block>選択完了</v-btn>
        </v-card-text>
      </v-card>
    </v-container>

  </div>
</template>

<script>
export default {
  data: function(){
    return{
      map: null,
      lat: 40.5
      lng: 140.4,
      zoom: 15,
      DrawingManager: null,
      polygon: null,
      calc_result: null,
    }
  },
  mounted(){
    this.loadMap()
    this.attention = true;
  },
  watch:{
    polygon:function(){
      this.calc_area()
      console.log("watch: polygon is changed")
    }
  },
  methods:{
    async loadMap(){
      // googleMapを初期化
      console.log("runnnig")
      this.map = new window.google.maps.Map(document.getElementById("map"), {
        center: { lat: this.lat, lng: this.lng },
        zoom: this.zoom,
      });
      //window.google.maps.event.addListener(this.map, 'click', this.click_listener);
      this.init_DrawingManager()
      this.DrawingManager.setMap(this.map);
      this.polygon_listener()
    },
    init_DrawingManager(){
      this.DrawingManager = new window.google.maps.drawing.DrawingManager({
        drawingMode: window.google.maps.drawing.OverlayType.PAN,
        drawingControl: true,                            
        drawingControlOptions: {
          position: window.google.maps.ControlPosition.TOP_CENTER, 
          drawingModes: ['polygon']
        },
        //マーカーのプション
        markerOptions: {
          icon: {
            url: '../common/img/ms/pin_02.png',
            scaledSize: new window.google.maps.Size(40, 40)
          }
        },
        //ポリゴンのオプション
        polygonOptions: {
          fillColor: '#afeeee',
          fillOpacity: 1,
          strokeWeight: 5,
          clickable: false,
          editable: true,
          zIndex: 1
        },
      });
    },
    polygon_listener(){
      var vm = this
      window.google.maps.event.addListener(this.DrawingManager, 'polygoncomplete', function(polygon) {
        let polygonPath = polygon.getPath()
        vm.polygon = polygonPath
      });
    },
    async calc_area(){
      var area = await window.google.maps.geometry.spherical.computeArea(this.polygon);
      console.log(area)
      this.calc_result = area
    },
    clear_polygon(){
      this.DrawingManager.setMap(null);
      this.polygon = null;
      this.calc_result = null
      this.loadMap()
    }
  }
}
</script>

<style>

</style>
```