Google Maps APIの使い方

Google Maps APIについて業務で使うことになったので予習もかねて使い方をまとめておきます。

## 動作環境
Maps JavaScript API version 3.37

## コンストラクタ
#### <font color="Navy">google.maps.Map(mapDiv:Node, opts?:MapOptions )</font>
**Node**
地図を表示する位置を指定します。
DIV要素でマップを配置する場所を用意しておいて、`document.getElementById()`を利用してその要素への参照を渡してあげます。

**MapOptions**
地図を表示する際のオプションを指定します。
オプションには、`center`と`zoom`は必須項目となっています。

centerには座標を指定します。
zoomには0~22までのズームレベルを指定します。

具体的なズームレベルについては以下の記事が参考になります。
[Google Maps APIのズームレベルまとめ](https://qiita.com/SnowMonkey/items/795779913be692c12a0b)


#### サンプル
```sample.html
<body>
<style>
#map {
    height: 100%;
}
html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}
</style>
<div id="map"></div>
<script>
    var map;
    function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
            center: {lat: -34.397, lng: 150.644},
            zoom: 8
        });
    }
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=(APIキー)&callback=initMap"></script>
</body>
```

## マーカーをつける
#### <font color="Navy">google.maps.Marker</font>

マーカーをつけるにはMarkerクラスを利用します。

```javascript:markerをつける
var marker = new google.maps.Marker({
  position: {lat: 35.665498, lng: 139.75964},
  map: map
});
```

<img width="722" alt="スクリーンショット 2019-06-01 15.16.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/e39c40c7-3b68-c0d2-26a8-ff8efb1ece74.png">



mapには、Mapクラスのインスタンスを渡します。

##### 複数のマーカーをつける場合
作成したいマーカー分のMarkerインスタンスを生成します。

```javascript:複数マーカーをつける
function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 14,
        center: {lat: 35.665498, lng: 139.75964}
    });

    var markers = locations.map(function(location) {
      return new google.maps.Marker({
        position: location,
        map: map,
      });
    });
}
var locations = [
        {lat: 35.665498, lng: 139.75964},
        {lat: 35.681382, lng: 139.76608399999998},
        {lat: 35.675069, lng: 139.763328}
]
```
<img width="632" alt="スクリーンショット 2019-06-01 14.21.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/dd04a8c6-2c3b-b505-ba8e-5851019c4588.png">



座標はこちらを参考にしました。
[山手線停車駅の座標一覧](https://qiita.com/butchi_y/items/3a6b70b38e13dc56ef13)


## 吹き出しをつける
マーカーに吹き出しをつけることも出来ます。

#### <font color="Navy">google.maps.InfoWindow</font>

```javascript:吹き出しを表示
var infowindow = new google.maps.InfoWindow({
    content: '新橋駅'
});
infowindow.open(map, marker);
```
![スクリーンショット 2019-07-13 11.43.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/090752c2-c4ab-75a4-0a87-9d299b529f0a.png)

##### 吹き出しの中にHTML

吹き出しの中にはHTMLを書くことも出来ます。
Nodeをcontentに渡せばそのHTMLが表示されます。

```javascript:吹き出しの中にHTML
var box = '<div class="box">' + 
              '<p>新橋駅</p>' +
          '</div>'
var infowindow = new google.maps.InfoWindow({
    content: box
});
infowindow.open(map, marker);
```

![スクリーンショット 2019-07-13 11.47.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/a76f9e1f-630e-7e2e-74ba-de908e70a079.png)



## イベント処理

各種イベント処理についてです。
Google Maps APIでクラス化したインスタンスに対して`addListener`を利用することでイベント処理を行うことが可能です。


### clickイベント
クリックした時に処理を実行します。
こんな感じです。

```javascript:clickイベント
map.addListener('click', function(e) {
  alert(e.latLng);
});
```
<img width="1434" alt="スクリーンショット 2019-06-01 14.14.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/bc2ee11e-f2a7-bfd4-c64d-acd93efa1f90.png">

**markerに対しても設定可能です。**

```javascript:markerにclickイベント
function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: 35.665498, lng: 139.75964}
  });

  var marker = new google.maps.Marker({
    position: {lat: 35.665498, lng: 139.75964},
    map: map,
  });

  marker.addListener('click', function() {
    alert(marker.getPosition());
  });
}
```
<img width="974" alt="スクリーンショット 2019-06-01 14.20.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/d2a1ccd7-0845-f73f-3e0a-f6265dc6191d.png">

### dragイベント
地図を移動させる際にイベント発火します。
少しでも移動させるたびにイベント発火するので重たい処理をするのは注意です。

```javascript:dragイベンド
map.addListener('drag', function(e) {
   document.getElementById("latlng").innerHTML = map.getCenter();
});
```
<img width="1440" alt="スクリーンショット 2019-06-01 14.47.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/cc77a43c-66f9-7729-82db-2d3dee234e35.png">

### center_changedイベント
先ほどのdragイベントと似ています。
中心位置が変更になった際に発火するイベントです。

```javascript:center_changedイベント
map.addListener('center_changed', function(e) {
  document.getElementById("latlng").innerHTML = map.getCenter();
});
```
### bounds_changedイベント
こちらは地図を動かしたり、ズーム値を変更した際に発火します。

```javascript:bounds_changedイベント
map.addListener('bounds_changed', function(e) {
  document.getElementById("latlng").innerHTML = map.getCenter();
  document.getElementById("zoom").innerHTML = map.getZoom();
});
```

<img width="1440" alt="スクリーンショット 2019-06-01 14.53.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/cf4827c0-3d7b-1401-f323-ffc126319757.png">

### idleイベント
このイベントは地図を動かしたり、ズーム値を変えたりして落ち着いた状態になった際に発火するイベントです。
drag、center_changed、bounds_changedイベントでは操作中すぐにイベント発火しましたが、idleイベントでは少し待ってから処理が稼働するので安定します。

```javascript:idleイベント
map.addListener('idle', function(e) {
  alert("座標:" + map.getCenter() + " ズーム値:" + map.getZoom());
});
```

<img width="1439" alt="スクリーンショット 2019-06-01 14.58.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/ab87580b-beef-47ce-2882-0a98e0320b32.png">


## その他クラス
### Circle
指定した範囲の円を作成します。

```javascript:Circleクラス
var circle = new google.maps.Circle({
  map: map ,
  center: {lat: 35.665498, lng: 139.75964},
  radius: 500,
});
```

rediusには円の半径を指定します。メートル単位です。

<img width="1438" alt="スクリーンショット 2019-06-01 15.06.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/e0b480ee-b5d9-d9fb-f01b-297436336970.png">

### Polygon
ポリゴンを作成します。

```javascript:Polygonクラス
var polygon = new google.maps.Polygon({
    map: map,
    paths:[
      {lat: 35.672557, lng: 139.752634},
      {lat: 35.669437, lng: 139.765691},
      {lat: 35.660302, lng: 139.764317},
      {lat: 35.665253, lng: 139.751786}
    ],
});
```
<img width="1440" alt="スクリーンショット 2019-06-01 15.13.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/982a1bf7-d15f-bf17-deb6-c00fdaf8bbf6.png">


## 参考
[Google Maps JavaScript API V3 Reference](https://developers.google.com/maps/documenta<img width="1440" alt="スクリーンショット 2019-06-01 14.53.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406169/dd078c3e-df89-7f87-8a32-abc4a3109be6.png">
tion/javascript/reference/)
[Maps JavaScript API公式](https://developers.google.com/maps/documentation/javascript/tutorial)
[Google Maps APIのズームレベルまとめ](https://qiita.com/SnowMonkey/items/795779913be692c12a0b)
[山手線停車駅の座標一覧](https://qiita.com/butchi_y/items/3a6b70b38e13dc56ef13)