「Google Maps API」改め「Google Maps Platform」を使った話

# はじめに
今更ながら最近、Google Maps Platform（旧Google Maps API）を使う機会があったので、備忘録がてらに書いていきたいと思います。

# Google Maps Platformとは
Google Maps Platformとは、Googleが提供するWeb地図サービスです。
Google Maps Platformを使うことで、Google Mapで利用できる様々な機能をウェブサイトやアプリに埋め込むことができます。

# 実際に使ってみた
今回はGoogleMap上にアイコンがあってクリックすると画像と説明文が表示されるお城の紹介マップを作っていきたいと思います。

## 必要な物
- クレジットカード登録しているGoogleアカウント
- APIキー
- HTML
- JavaScript

上記があれば基本のカスタマイズはできますが今回は下記も使います。

- Json　→　お城情報をJsonに格納したいので用意します。
- CSS → 無くても大丈夫ですが、見た目を良くするために用意します。
- アイコンに使う画像 → オリジナルアイコンを表示するのに使います。

## APIキーの取得
まずは、Google Mapをカスタマイズするためには、APIキーというものが必要になってきます。
[Google Maps Platformの公式サイト](https://cloud.google.com/maps-platform/?hl=ja "Google Maps Platformの公式サイト")にアクセスします。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287163/b643f965-54d4-0e1d-7e70-027472dc464c.png)
使ってみるを選択します。
Googleにログインをしていない場合はログイン画面が表示されるのでログインします。
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287163/57ee645f-027b-61a4-71af-f3665bb3c060.png)
今回必要なAPIを選択します。
今回はマップのカスタマイズなのでマップを選択します。
各機能の内容はこちらになります。

マップ
主な機能
・マップ
・ストリートビュー

ルート
主な機能
・ルート
・距離行列
・道路

プレイス
主な機能
・場所の詳細
・現在の場所
・場所の検索
・ジオコーディング
・位置情報
・タイムゾーン
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287163/2728a5a3-8145-62ba-bf2a-c5e0a93044a3.png)
プロジェクト名の入力と規約に同意します。
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287163/784a3849-9555-efcb-6676-93ca359b8afe.png)
課金を有効にしていないアカウントを使用するとこのようにクレジットカードの登録の画面になります。
Google Maps Platform APIを使用するためには有効にしないと使うことが出来ません。
![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287163/b6c511f5-9dfb-335a-4de9-39f004c1f37a.png)
課金登録するとこのようにAPIの有効化の画面が表示されるので有効化します。
有効化すると「YOUR API KEY」が出てきます。こちらを使用していきます。
ただ、このままではAPI KEYがわかる人が自由に利用できてしまうので、制限をかけていきます。
![キャプチャ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287163/d7d14f55-ebb4-8103-84e1-7b1d9838f448.png)
認証情報から、先ほど作ったAPI keyを選択します。
![キャプチャ7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287163/8db47b80-90fc-4544-dbcf-155f4ad3c126.png)
アプリケーションの制限でAPI keyと今回使用するものを紐づけます。
今回は、ウェブサイトで使いたいのでHTTPリファラー（ウェブサイト）を選択しています。
項目を追加の部分で今回使うドメイン名を選択します。
APIの制限を設定します。
使うAPIキーが決まっていたら使うAPIキーだけを有効にすることが出来ます。
全て設定したら保存を選択します。

## HTMLの作成
次にHTMLを作成していきます。

```HTML:index.html
<!DOCTYPE html>
  <head>
    <meta charset="UTF-8">
    <title>日本のお城</title>
    <link rel="stylesheet" href="style.css">
  </head>
　<body>
  　<div id="map">Now Loading...</div>
　　<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  　<script type="text/javascript" src="map.js"></script>
　　<script async defer src="https://maps.googleapis.com/maps/api/js?key=先ほど取得したAPIキー&language=ja&region=JP&callback=initMap"></script>
　</body>
</html>
```
重要なのはここ→`<div id="map">Now Loading...</div>`
ここでGoogleMapを呼び出す処理を書いています。
本来は、JavaScriptだけで完結できますが今回はjsonを使うのでjqueryも読み込んでいます。

## JavaScriptの作成
次にJavaScriptを作成していきます。

```JavaScript:map.js
//初期値
var map;
var marker = [];
var data = [];
var windows = [];
var currentInfoWindow = null;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), { //GoogleMapを呼び出す処理
    //GoogleMapの初期値を設定
    center: { lat: 38.6460251, lng: 140.3427782 }, //中心点（緯度・経度）
    zoom: 6.13, //拡大率
    clickableIcons: false, //GoogleMapの標準のクリック機能をOFFにする。
    // GoogleMapのスタイルを変更
    styles: [
      {
		    "stylers": [
		      { "visibility": "simplified" }
		    ]
		  },
		  {
		    "featureType": "water",
		    "elementType": "geometry.fill",
		    "stylers": [
		      { "hue": "#003bff" }
		    ]
		  },{
		    "featureType": "road.highway",
		    "stylers": [
		      { "visibility": "off" }
		    ]
		  },{
		    "featureType": "landscape",
		    "stylers": [
		      { "color": "#dbe8e5" }
		    ]
		  },{
        "featureType": "poi.park",
        "elementType": "labels.text",
		    "stylers": [
		      { "color": "#e6e6e6","visibility": "off" }
		    ]
		  },{
		    "featureType": "water",
		    "stylers": [
		      { "color": "#8ecdf0" }
		    ]
		  },{
		    "featureType": "transit.line",
		    "stylers": [
		      { "visibility": "off" }
		    ]
		  },{
        "featureType": "poi.business",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      }
    ]
  });
  //お城情報を読み込み
  $.ajax({
    url: "castles.json",
    success: function (json) {
      for (var i = 0; i <= json.length - 1; i++) {
        data.push(
          {
            'location': json[i].location,
            'name': json[i].name,
            'lng': json[i].lng,
            'lat': json[i].lat,
            'pic': json[i].pic,
            'comment': json[i].comment
          }
        );
      };
      for (var i = 0; i < data.length; i++) {
        //吹き出しの追加
        markerLatLng = { lng: data[i]['lng'], lat: data[i]['lat'] };
        marker[i] = new google.maps.Marker({
          position: markerLatLng,
          map: map,
          icon: 'icon.png' //オリジナルのアイコン名
        });
        function markerEvent(i) {
          marker[i].addListener('click', function () { // マーカーをクリックしたとき
            //開いているウィンドウがある場合は閉じる
            if (currentInfoWindow) {
              currentInfoWindow.close();
            }
            windows[i].open(map, marker[i]); // 吹き出しの表示
            currentInfoWindow = windows[i];
          });
        }
        windows[i] = new google.maps.InfoWindow({ //吹き出しの中身
          content: '<p class="location">' + data[i]['location'] +'&nbsp;'+ data[i]['name'] + '</p><img class="pic" src="' + data[i]['pic'] + '"/><p>' + data[i]['comment'] + '</p></div>'
        });
        markerEvent(i); // マーカーにクリックイベントを追加
      }
    }
  });
  //ajax
}
```
こんな感じで、JavaScriptを用意します。
各項目を見ていくと、

```js
center: { lat: 38.6460251, lng: 140.3427782 }, //中心点（緯度・経度）
zoom: 6.13, //拡大率
clickableIcons: false, //GoogleMapの標準のクリック機能をOFFにする。
```
ここでマップの初期値を設定します。

```js
    // GoogleMapのスタイルを変更
    styles: [
      {
            "stylers": [
              { "visibility": "simplified" }
            ]
          },
          {
            "featureType": "water",
            "elementType": "geometry.fill",
            "stylers": [
              { "hue": "#003bff" }
            ]
          },{
            "featureType": "road.highway",
            "stylers": [
              { "visibility": "off" }
            ]
          },{
            "featureType": "landscape",
            "stylers": [
              { "color": "#dbe8e5" }
            ]
          },{
        "featureType": "poi.park",
        "elementType": "labels.text",
            "stylers": [
              { "color": "#e6e6e6","visibility": "off" }
            ]
          },{
            "featureType": "water",
            "stylers": [
              { "color": "#8ecdf0" }
            ]
          },{
            "featureType": "transit.line",
            "stylers": [
              { "visibility": "off" }
            ]
          },{
        "featureType": "poi.business",
        "elementType": "labels.text",
        "stylers": [
          {
            "visibility": "off"
          }
        ]
      }
    ]
  });
```

色やデフォルトの建物のピンの有無を設定しています。
stylersの設定は、[Styling Wizard](https://mapstyle.withgoogle.com/ "Styling Wizard")というジェネレーターを使って設定すると簡単に設定することができます。

```js
  $.ajax({
    url: "castles.json",
    success: function (json) {
      for (var i = 0; i <= json.length - 1; i++) {
        data.push(
          {
            'location': json[i].location,
            'name': json[i].name,
            'lng': json[i].lng,
            'lat': json[i].lat,
            'pic': json[i].pic,
            'comment': json[i].comment
          }
        );
      };
```
castles.jsonからお城情報を取得します。

```js
      for (var i = 0; i < data.length; i++) {
        //吹き出しの追加
        markerLatLng = { lng: data[i]['lng'], lat: data[i]['lat'] };
        marker[i] = new google.maps.Marker({
          position: markerLatLng,
          map: map,
          icon: 'icon.png' //オリジナルのアイコン名
        });
```
マップ上にデータの数だけピンを追加します。

```js
        function markerEvent(i) {
          marker[i].addListener('click', function () { // マーカーをクリックしたとき
            //開いているウィンドウがある場合は閉じる
            if (currentInfoWindow) {
              currentInfoWindow.close();
            }
            windows[i].open(map, marker[i]); // 吹き出しの表示
            currentInfoWindow = windows[i];
          });
        }
        windows[i] = new google.maps.InfoWindow({ //吹き出しの中身
          content: '<p class="location">' + data[i]['location'] +'&nbsp;'+ data[i]['name'] + '</p><img class="pic" src="' + data[i]['pic'] + '"/><p>' + data[i]['comment'] + '</p></div>'
        });
        markerEvent(i); // マーカーにクリックイベントを追加
      }
    }
  });
  //ajax
}
```

ピンをクリックしたときの処理と吹き出しの中の処理です。

## JSONの作成
次にJSONを作成していきます。

```JSON:castles.json
[
  {
    "location": "青森県",
    "name": "弘前城",
    "lng": 140.4619917,
    "lat": 40.6074557,
    "pic": "./img/castle01.png",
    "comment": "歴史的な品位ある城とやぐら。2,600 本を超える桜の木、緑豊かな庭園、水堀に囲まれている。"
  }, {
    "location": "長野県",
    "name": "松本城",
    "lng": 137.9667664,
    "lat": 36.2386563,
    "pic": "./img/castle02.png",
    "comment": "黒い壁で知られる壮大な 16 世紀の城。歴史的な武器の展示がある。"
  }, {
    "location": "福井県",
    "name": "丸岡城",
    "lng": 136.269825,
    "lat": 36.1523361,
    "pic": "./img/castle03.png",
    "comment": "一向一揆の備えとして柴田勝家が甥の勝豊に1576年に築かせた平山城。歴代城主ゆかりの品を展示する歴史民俗資料館がある。"
  }, {
    "location": "愛知県",
    "name": "犬山城",
    "lng": 136.9335313,
    "lat": 35.3891543,
    "pic": "./img/castle04.png",
    "comment": "戦国時代にできた風格のある城。難攻不落の丘の上に建ち、木曽川を一望。"
  }, {
    "location": "滋賀県",
    "name": "彦根城",
    "lng": 136.2496573,
    "lat": 35.2764564,
    "pic": "./img/castle05.png",
    "comment": "17世紀建立の城。美しい庭園や博物館で知られ、一般向見学も実施。"
  }, {
    "location": "兵庫県",
    "name": "姫路城",
    "lng": 134.6897633,
    "lat": 34.8395982,
    "pic": "./img/castle06.png",
    "comment": "姫路を象徴する美しい城。1613 年頃の完成。白い城壁、連立式天守、堀、廊下、桜が有名。"
  }, {
    "location": "島根県",
    "name": "松江城",
    "lng": 133.0485046,
    "lat": 35.4751745,
    "pic": "./img/castle07.png",
    "comment": "堀尾吉晴が築城した五層の城。日本に現存する数少ない江戸時代の城の一つ。"
  }, {
    "location": "岡山県",
    "name": "備中松山城",
    "lng": 133.6202921,
    "lat": 34.809073,
    "pic": "./img/castle08.png",
    "comment": "標高約480メートルの臥牛山に建つ、現存する天守を擁する山城として国内一の高さを誇る近世城郭。天守、二重櫓、土塀は重要文化財指定。"
  }, {
    "location": "香川県",
    "name": "丸亀城",
    "lng": 133.7980924,
    "lat": 34.2859616,
    "pic": "./img/castle09.png",
    "comment": "標高約66mの亀山に築かれた平山城。本丸、二の丸、三の丸、帯曲輪、山下曲輪がある。日本の100名城にも選ばれた。"
  }, {
    "location": "愛媛県",
    "name": "伊予松山城",
    "lng": 132.5630103,
    "lat": 33.2194535,
    "pic": "./img/castle10.png",
    "comment": "公園の中に建つ 17 世紀の城。現在の城は復元されたもの。徒歩、リフト、ロープウェイのいずれかでアクセス。"
  }, {
    "location": "愛媛県",
    "name": "宇和島城",
    "lng": 132.5630103,
    "lat": 33.2194535,
    "pic": "./img/castle11.png",
    "comment": "鶴島城と呼ばれる秀麗な天守は、当時のまま現存する貴重なもの。"
  }, {
    "location": "高知県",
    "name": "高知城",
    "lng": 133.5292942,
    "lat": 33.5607211,
    "pic": "./img/castle12.png",
    "comment": "1603年に築城され、のちに修復された5階建ての城。城内には歴史的展示物や美術品、物見櫓がある。"
  }
]
```
都道府県名・お城の名前・緯度・経度・紹介文・画像の情報を入力しています。

## CSSの作成
最後にCSSを作成していきます。

```CSS:style.css
html,body,div#map {
  height: 100%;
}
.gm-style-iw.gm-style-iw-c {
  max-width: 250px !important;
}
img.pic {
  display: block;
  width: 100%;
  height: auto;
  margin: 1em 0;
}
```
マップ・吹き出し・吹き出し内の画像の大きさを設定しています。

## 完成品
https://takaha-k.github.io/QiitaGoogleMap/demo.gif

アップロード制限でgifが載せられなかったのでこちらにアップロードしました。


# 今後の課題点
作ってみて今後の課題点が見つかったので書き記したいと思います。

- JSONで管理しているため簡単に情報を投稿できないのでなにかしらの投稿できる方法を考えたい。
- 位置情報を緯度と経度をしているので住所から導き出したい。

# 最後に
今回参考にしたサイトになります。
[公式ドキュメント](https://developers.google.com/maps/documentation/?_ga=2.21111227.-1243872170.1576030716 "公式ドキュメント")
[mapに複数のマーカーを立てる - Google maps API -](https://kigiroku.com/frontend/gmap2.html "mapに複数のマーカーを立てる - Google maps API -")
[Google Maps APIを使って複数のマーカーと吹き出しを設置してみる](https://www.tam-tam.co.jp/tipsnote/javascript/post7755.html "Google Maps APIを使って複数のマーカーと吹き出しを設置してみる")
[Google Maps JavaScript APIの使い方まとめ](https://lab.syncer.jp/Web/API/Google_Maps/JavaScript/ "Google Maps JavaScript APIの使い方まとめ")
[【Google Maps API】地図デザインの変更と「Styling Wizard」の使い方](https://www.granfairs.com/blog/staff/google-maps-api-04 "【Google Maps API】地図デザインの変更と「Styling Wizard」の使い方")


:christmas_tree: [FORK Advent Calendar 2019](https://qiita.com/advent-calendar/2019/fork "FORK Advent Calendar 2019")
:arrow_left: 14日目　[ハンド Web アセンブル](https://4009.jp/post/2019-12-14-wasm/ "ハンド Web アセンブル") @dashimakitamago 
:arrow_right: 16日目　@Kodak_tmo さんお願いします。