GoogleMapに複数のマーカーを表示する

GoogleMapに対象店舗と周辺店舗を表示させたいと思ったため調べたことを記録します。
当記事は、主にJavascriptの記述についての記載になるためGoogleMapのAPIキー取得等に関する記述は省略します。
条件としては以下のとおりです。

・地図の中心に対象店舗が表示される。（マーカーを立てる）
・対象店舗を中心として半径５km以内にある店舗にもマーカーを表示する。
・対象店舗と周辺店舗はマーカーの色を分ける。
・周辺店舗のマーカーをクリックしたときには吹き出しが表示される。
・吹き出しには店舗名が入っており、店名をクリックすると該当店舗の詳細ページに遷移する。

![Gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700117/8b572b62-7e76-ffd4-fd9f-83bd6472ea55.gif)

### 開発環境
ruby 2.6.5
Ruby on Rails 6.0.3.3
OS: macOS Catalina

### はじめに
GoogleMapApiの使い方に関してこちらの記事がわかりやすくまとめてあり参考にさせていただきました。
[Google Maps APIの使い方](https://qiita.com/YutaSaito1991/items/ec0c089d354ec9b8a7e0)

### 実装コード
コードは以下のとおりです。

```js

  let map;
  let mainMarker;
  let marker =[];
  let infoWindow = [];

function initMap(){
  let markerData = gon.places;
  let latlng = {lat: gon.latitude, lng: gon.longitude};
  // 初期位置の指定
  map = new google.maps.Map(document.getElementById('map'), {
  center: latlng,
  zoom: 14
  });

  // 初期位置にマーカーを立てる
  mainMarker = new google.maps.Marker({
    map: map,
    position: latlng
  });

  // 近隣店舗にマーカーを立てる
  for (var i = 0; i < markerData.length; i++) {
    const image = "https://maps.google.com/mapfiles/ms/icons/yellow-dot.png";
    const id = markerData[i]['id'];
    // 緯度経度のデータを作成
    let markerLatLng = new google.maps.LatLng({lat: markerData[i]['latitude'], lng: markerData[i]['longitude']});
    // マーカーの追加
    marker[i] = new google.maps.Marker({
      position: markerLatLng,
      map: map,
      icon: image,
    });

    // 吹き出しの追加
    infoWindow[i] = new google.maps.InfoWindow({
    // 吹き出しに店舗詳細ページへのリンクを追加
    content: `<a href=/laundries/${id}>${markerData[i]['name']}</a>`
    });

    markerEvent(i); 
  }

  // マーカークリック時に吹き出しを表示する
  function markerEvent(i) {
    marker[i].addListener('click', function() {
      infoWindow[i].open(map, marker[i]);
    });
  }
}

document.addEventListener('turbolinks:load', function(){
  initMap();
});
```

１つずつ見ていきます。
<b>1.変数の定義<b/>

```js
 let map;
 let mainMarker;
 let marker =[];
 let infoWindow = [];
```
対象店舗と周辺店舗のマーカーを分けたかったため2つ変数を用意しました。``marker``には周辺店舗の情報が複数入るため配列にしています。``infoWindow``も同様に、各店舗のマーカーに対して吹き出しを付けたいため配列にしています。


<b>2.地図の作成〜マーカーを立てる<b/>

```js
  let markerData = gon.places;
  let latlng = {lat: gon.latitude, lng: gon.longitude};
  // 初期位置の指定
  map = new google.maps.Map(document.getElementById('map'), {
  center: latlng,
  zoom: 14
  });

  // 初期位置にマーカーを立てる
  mainMarker = new google.maps.Marker({
    map: map,
    position: latlng
  });
```

latlngという変数を定義して店舗の緯度と経度を指定しています。
``gon``というのはgemの１つでrailsで定義した変数を、javascriptで使える変数に変換してくれます。
(https://github.com/gazay/gon)
 ``new google.maps.Map``とすることで新しく地図を作成し、オプションで中心地やズームレベルを指定します。
地図の作成に関しては[Let'sプログラミング](https://www.javadrive.jp/google-maps-javascript/gmap2/index2.html)やMaps JavaScriptAPIの[ドキュメント](https://developers.google.com/maps/documentation/javascript/overview?hl=ja#zoom-levels)を参考にさせていただきました。

次に作成した地図にマーカーを立てていきます。
こちらも``new google.maps.Marker``でマーカーを作成してどのmapにマーカーをたてるか、どこにマーカーを立てるかを指定することでマーカーを立てることができます。


<b>3.周辺店舗にマーカーを立てる + 吹き出しを追加する<b/>

```js

for (var i = 0; i < markerData.length; i++) {
    const image = "https://maps.google.com/mapfiles/ms/icons/yellow-dot.png";
    const id = markerData[i]['id'];
    // 緯度経度のデータを作成
    let markerLatLng = new google.maps.LatLng({lat: markerData[i]['latitude'], lng: markerData[i]['longitude']});
    // マーカーの追加
    marker[i] = new google.maps.Marker({
      position: markerLatLng,
      map: map,
      icon: image,
    });

    // 吹き出しの追加
    infoWindow[i] = new google.maps.InfoWindow({
    // 吹き出しに店舗詳細ページへのリンクを追加
    content: `<a href=/laundries/${id}>${markerData[i]['name']}</a>`
    });

    markerEvent(i); 
  }

  // マーカークリック時に吹き出しを表示する
  function markerEvent(i) {
    marker[i].addListener('click', function() {
      infoWindow[i].open(map, marker[i]);
    });
  }
```

行っていることとしては```let markerData = gon.places;```で定義した変数の値を１つずつ取り出してマーカーと吹き出しを追加しています。
そしてマーカーの色を変えたかったため``image``という定数にアイコンを定義して``icon: image``で定義したアイコンを使用しています。
``new google.maps.LatLng({lat: markerData[i]['latitude'], lng: markerData[i]['longitude']});``
とすることでそれぞれの要素の緯度経度に対してマーカーを立てるように指定します。

続いて吹き出しを追加します。
``content``で吹き出しの中に入れる文字を指定できます。
今回は各店舗名を表示+クリックすることで詳細ページに遷移をさせたかったため、aタグを使いました。
最後に吹き出しを作成しただけでは表示されないため``addListener``を利用してマーカーがクリックされたときに吹き出しが開くようにしました。


以上、GoogleMapに複数マーカーを表示する方法でした。