2018年11月8日に開催した「クロコラボ #18 Google Maps APIを使ってみよう」のレポートです。今年の7月16日からGoogle Maps APIのサービス内容が変更され、新しくGoogle Maps Platformとなりました。

大きな変更点は、Google Maps APIはマップ、ルート、プレイスの3つサービスに簡素化されたことと、使用量に応じて料金が発生するようになったことだそうです。これにより、APIがきちんと設定されていないと「このページではGoogleマップが正しく読み込まれませんでした。」と表示され、Google Mapsを見れなっています。

画像:濃いグレーで覆われたGoogle Maps

APIキーの取得と制限

Google Maps APIを使うには、まずAPIキーが必要です。APIキーの取得には、次のページを参考にさせていただきました。

ページの中でも書かれていますが、アプリケーションの制限を忘れないようにしないと大変なことになりそうですね。勉強会では公開するサイトではないので、IPアドレスで制限をしました。

マップとルートを使ってみる

今までAPIを使うときは、サイトでその場所にロゴマークを表示するのにマーカーを表示したり、ジェネレーターでカラーを変更する程度だったので、次のようなことができるかを試したかったのです。

  • 複数のマーカーを表示できるか
  • マーカーに文字を付けれるか
  • 複数のルートを表示できるか(スタイルは変えれるか)

APIの有効化

APIキーの取得内の記事でもありましたが、Googe Cloud Platformで使用するAPIを有効にします。今回は、マップとルートを使うので、「Maps JavaScript API」と「Directions API」を有効にしました。有効にしたAPIはいつでもダシュボードから無効にできます。

マップの表示

次のサイトを参考にさせていただきました、

実際に作ったマップはこちら。しばらくテストで表示しておいてみます。無料枠超えそうなら(そんだけアクセスがあればむしろすごいけど)画像に変えるかもしれません。

このマップでは、次のことを試しています。

  • 地図のカラーを変更
  • 複数マーカーを表示(文字はつけれなかった、画像はSVGもOK)
  • 複数のルートを表示
  • ルートのスタイル(線の色、透過、線幅)を変更
  • マーカークリックでインフォウィンドウ(吹き出し)の表示
  • 画面幅に応じて表示領域(zoom)を変更

HTML

ID「p-map」に地図を表示します。

<div id="p-map"></div>

Google Maps APIの読み込みと設定するJavaScriptの読み込み。[APIキー]には取得したAPIキーをいれます。

<script async defer src="https://maps.googleapis.com/maps/api/js?[APIキー]&callback=initialize"></script>
<script type='text/javascript' src='./js/mapstyle.js'></script>

CSS

クラス「p-map__window」は、マーカーをクリックして表示される吹き出しのスタイルです。

#p-map {
    width: 100%;
    height: 600px;
}
.p-map__window{
    width: 80px;
   text-align: center;
}

mapstyle.js

var windowWidth; //ウィンドウ幅
var zoom = 13; //拡大の比率
var centerLating = {lat:33.836653, lng:132.736130}; //地図の中心デフォルト
var map;
var marker = [];
var data = [];
var windows = [];
var currentInfoWindow = null;

// リサイズの変数 -------------
$(window).on('resize', function() {
  windowWidth = $('body').innerWidth();
  if(windowWidth >= 768){
    zoom = 13; 
  } else {
    zoom = 12;
  }
}).trigger('resize');

function initialize() {
  // マップの基本設定−−−−−−−−−−−−−
  var myOptions = {
      center: centerLating, //中心点
      zoom: zoom, //拡大の比率 1〜21 小数点だとドラッグするとズームされる
      mapTypeId: google.maps.MapTypeId.ROADMAP, //地図のタイプを指定する(ROADMAP:デフォルトの道路地図、SATELLITE:航空写真、YBRID:通常のビューと航空写真の混合、TERRAIN:物理的なマップ),
      styles: [スタイルのjsonを貼り付ける]
  }
  map = new google.maps.Map(document.getElementById('p-map'), myOptions);

  // ルート地点の変数−−−−−−−−−−−−−
  var ary = [
    { // 松山空港から目的地
      "start" :  new google.maps.LatLng(33.829061, 132.704098),
      "end" : new google.maps.LatLng(33.836255, 132.769006),
      "color" : "#45A1CF"
    },
    { // JR松山駅から目的地
      "start" :  new google.maps.LatLng(33.840394, 132.751300),
      "end" : new google.maps.LatLng(33.836255, 132.769006),
      "color" : "#DA6272"
    }
  ]
  // ルートの表示−−−−−−−−−−−−−
  for(var i in ary){
    fCalcRoute(ary[i]['start'], ary[i]['end'], ary[i]['color']);
  }

  // マーカーの表示−−−−−−−−−−−−−
  $.getJSON("./js/mapdata.json", function(json){
    for (var i = 0; i <= json.length-1; i++) {
      data.push({
        'name': json[i].name,
        'lat': json[i].lat,
        'lng': json[i].lng,
        'icon': json[i].icon,
        'sizeX': json[i].sizeX,
        'sizeY': json[i].sizeY
      });
    };
    for (var i = 0; i < data.length; i++) {
      // マーカーの追加−−−−−−−−−−−−−
      markerLatLng = {lat: data[i]['lat'], lng: data[i]['lng']};
      marker[i] = new google.maps.Marker({
        position: markerLatLng,
        map: map,
        title: data[i]['name'],
        icon: new google.maps.MarkerImage(
          data[i]['icon'],
          new google.maps.Size(data[i]['sizeX'], data[i]['sizeY']),    //マーカー画像のサイズ
          new google.maps.Point(0,0) //位置(0,0で固定)
        ),
      });
      // ウィンドウの内容の追加−−−−−−−−−−−−−
      windows[i] = new google.maps.InfoWindow({ // 吹き出しの追加
      content: '<div class="p-map__window">' + data[i]['name'] + '</div>'
      });
      markerEvent(i); // マーカーにクリックイベントを追加
    }
  });

  // クリックイベントの追加−−−−−−−−−−−−−
  // マーカークリックでInfoWindow表示
  function markerEvent(i) {
    marker[i].addListener('click', function() { // マーカーをクリックしたとき
      if (currentInfoWindow) {
        currentInfoWindow.close();
      }
      windows[i].open(map, marker[i]); // 吹き出しの表示
      currentInfoWindow = windows[i];
    });
  }

  // リサイズでズーム変更−−−−−−−−−−−−−
  google.maps.event.addDomListener(window, "resize", function() {
    google.maps.event.trigger(map, "resize");
    map.setZoom(zoom);
  });
}

//ルートを表示する関数
function fCalcRoute(start, end, color) {
  // ルート表示 設定
  rendererOptions = {
    draggable: true, //ドラッグ操作の有効/無効を設定する
    preserveViewport: true //境界のボックスにセンタリングされズームするかどうか(地図の中心とズームの設定がないと、ビューポートは変更されない)
  };
  var directionsDisplay =  new google.maps.DirectionsRenderer(rendererOptions);
  directionsDisplay.setOptions({
    polylineOptions: { //ルートの形状
      strokeColor: color, //色
      strokeOpacity: 0.8, //透過
      strokeWeight: 6 //線幅
    }, 
    suppressMarkers: true, //true:マーカー非表示
    suppressInfoWindows: true //true:ルート線非表示
  });
  var directionsService =  new google.maps.DirectionsService();
  var request = {
    origin: start, //出発場所
    destination: end, //到着場所
    travelMode: google.maps.DirectionsTravelMode.DRIVING, //交通手段を指定する(DRIVING:運転ルート、WALKING:徒歩ルート、BICYLING:自転車ルート)
    unitSystem: google.maps.DirectionsUnitSystem.METRIC, //単位km表示
    optimizeWaypoints: true, //最適化された最短距離にする
    avoidHighways: false, //高速道路(false:使用しない)
    avoidTolls: false //有料区間(false:使用しない)
  };
  directionsService.route(request,
    function(response,status){
      if (status == google.maps.DirectionsStatus.OK){
        directionsDisplay.setDirections(response);
      }
    }
  );
  directionsDisplay.setMap(map);
}

マップの基本設定の「style」で、カラーをグレーに変更しています。[スタイルのjsonを貼り付ける] という箇所は、Styling WizardでJSONを生成できるので、コピペしました。(長くなるので別のJSONファイルにして読み込みたかったんだけど、苦戦中です)

mapdata.json(マーカーの情報)

「sizeX」「sizeY」は、マーカーのサイズを指定するのに使っています。今回は全て同じサイズですが、マーカーごとにサイズを変えることもあるので、値を設定できるようにしています。

[
  {
    "name": "松山空港",
    "lat": 33.829061,
    "lng": 132.704098,
    "icon": "./images/baseline-local_airport-24px.svg",
    "sizeX": 24,
    "sizeY": 24
  },
  {
    "name": "JR松山駅",
    "lat": 33.840394,
    "lng": 132.751300,
    "icon": "./images/baseline-directions_subway-24px.svg",
    "sizeX": 24,
    "sizeY": 24
  },
  {
    "name": "UDCM",
    "lat": 33.836255,
    "lng": 132.769006,
    "icon": "./images/baseline-place-24px.svg",
    "sizeX": 24,
    "sizeY": 24
  }
]

料金について

Google Cloudに料金表がありますが、実際の費用がどのくらいになるか、いまいちよくわかりません。どれくらいのアクセスがあるとどのくらいの費用がかかるかは、料金計算ツールで確認ができるようです。

はじめに1年間お試し期間があり、$300までは無料で試せるようになっています。日本円ではこの記事を書いた時点では¥33,602になっていました。それに加えて、月々$200のクレジットが配布されるそうです。

画像:クレジット残高 ¥33,602、残り日数 346日
Google Cloud Platform お支払いの概要ページより

割り当て、予算とアラート

無料分があるとはいえ、それを超えてしまわないか、突然高額請求がくるのではないかという心配が頭をよぎります。そういうときには、割り当てやアラートを設定しておくことで、高額になることを防げそう。次の記事では、割り当ての設定方法が紹介されています。

また、お支払いの「予算とアラート」で、設定した予算を越えると通知がくるように設定できるので、こちらも設定しておくとよさそう。

ちなみに、今回の勉強会でリロードしまくったので、リクエスト数はそれぞれ

  • Maps JavaScript API:249
  • Directions API:36

でした。料金は¥189。もちろん無料分から使われるので、支払いはありません。

まとめ

Google Maps たのしい!

ソースは少しごちゃごちゃしていて汎用的ではないかもしれません。とりあえず、いろいろと設定できることがわかったので、

  • カラー設定のJSONを別ファイルにして読み込みたい
  • マーカーをクリックすると、その地点から目的地のルートが表示できるようにしたい
  • アニメーションをつけてみたい

といったこともやってみたいなと思いました。ぼちぼち試していきます。

有料化されたといっても、試せるようにクレジットを配布してくれているので、ありがたいですね。Googleさん、ありがとうございます!