Google Mapはインターネット上で地図を閲覧する際の事実上の標準的なサービスになっています。これらは自分のサイトに埋め込んだりすることもでき、マーカーの表示などが可能になっています。一方で、JavaScriptから操作するなど、より柔軟な機能を利用するにはGoogle Map APIを利用します。
Google Map APIを利用するにはAPIキーを取得する必要があります。割とざっくり説明しますので、詳細は他サイトを当たってください。クレジットカードの入力など支払方法の設定は省略します。
Googleアカウントにログインしたのち、次のURLにアクセスします。
https://console.cloud.google.com/?hl=ja
新しいプロジェクトを作成し、そのプロジェクトを選択します。左上の[ナビゲーションメニュー](横線が3つのところ)をクリックし、[API とサービス]をクリックします。
ダッシュボードで、[APIとサービスを有効化]をクリックします。マップカテゴリの[Maps JavaScript API]をクリックし、[有効にする]をクリックします。[API とサービス]の[認証情報]>[認証情報を作成]>[API キーを作成]をクリックします。するとAPIキーが表示されるのでこれで作成したことになります。
APIキーを取得したら、次に期間あたりの割り当て数を設定します。[APIとサービス]から[フィルタ]とあるところの[Maps JavaScript API]>[割り当て]に進み、割り当て名の[上限]を設定していきます。Map loads per dayというのは1日でのAPIキーの使用回数という意味で、その上限を入力します。
簡単なひな形を示します。[APIキー]のところを取得したAPIキーで置き換えます。
<!DOCTYPE html><html lang="ja"><head><meta charset="UTF-8"><title>東京</title><script src="http://maps.google.com/maps/api/js?key=[APIキー]&language=ja"></script><style>html { height: 100% }body { height: 100% }#map { height: 100%; width: 100%}</style></head><body><div>35.6630204,139.6739709,18z</div><div id="map"></div><script>var MyLatLng = new google.maps.LatLng(35.6630204,139.6739709);var Options = { zoom: 18, //地図の縮尺値 center: MyLatLng, //地図の中心座標 mapTypeId: 'roadmap' //地図の種類};var map = new google.maps.Map(document.getElementById('map'), Options);</script></body></html>地図をクリックしたときに、緯度経度を取得するようにしてみます。GoogleMapAPIを使わない場合でもクリックで表示されますが、マーカーの追加とクリップボードへコピーする機能を追加します。
以下のコードをひな形のscriptの最後に追加します。
function getClickLatLng(lat_lng, map) { // 座標を表示 document.getElementById('data').textContent = "[ " + lat_lng.lat() + ", " + lat_lng.lng() + ", 1 ],"; document.getElementById('lat').textContent = lat_lng.lat(); document.getElementById('lng').textContent = lat_lng.lng(); CopyData(); // クリップボードにコピー // マーカーを設置 var marker = new google.maps.Marker({ position: lat_lng, map: map }); // 座標の中心をずらす map.panTo(lat_lng);}// クリックイベントを追加map.addListener('click', function(e) { getClickLatLng(e.latLng, map);});map.addListenerメソッドでクリック時のイベントを追加しています。data, lat, lngをもつIDに緯度経度の情報を出力しています。
クリップボードにコピーするCopyData()を次に示します。
// 緯度経度データをクリップボードにコピーfunction CopyData(){ var range = document.createRange(); range.selectNode(document.getElementById('data')); var selection = getSelection(); selection.removeAllRanges(); selection.addRange(range); document.execCommand('copy'); selection.removeAllRanges();}JavaScriptでは直接テキストをクリップボードへはコピーできません。data IDテキストを選択した状態にしてコピーし、その後選択を解除しています。
マーカーを複数設置していきます。
以下のコードをひな形のscriptの最後に追加します。
// カスタマムマーカーのリストvar markers = [ [ 35.6056853, 139.7373023 ], [ 35.6059993, 139.7385683 ], [ 35.6069933, 139.7385253 ],];// 複数のマーカーを配置for (var m of markers){ var marker = new google.maps.Marker({ map: map, position: { lat: m[0], lng: m[1] } });}長方形を配置するサンプルを示します。
以下のコードをひな形のscriptの最後に追加します。
// カスタマムマーカーのリストvar markers = [ { position : { lat: 35.6056853, lng: 139.7373023 } }]; // 複数のマーカーを配置for (var m of markers){ var marker = new google.maps.Marker({ map: map, position: m.position });}var ox, oy, r, ax, ay, bx, by, cx, xy, dx, dy;var x = 1.7;var y = 5.5;var arcDegree = 28.5;//19インチディスプレイ上で1cmが1単位になるようにrを調整する。var r = 0.0000709;var kSw = 1.28;//stretch width. 緯度・経度比を均一にするためのx座標にかける補正。var ang = Math.PI*arcDegree/180;ox = 139.95275740797763;oy = 39.02582026394864;ax = ox + r * (Math.cos(ang)*x - Math.sin(ang)*y) * kSw;ay = oy + r * (Math.sin(ang)*x + Math.cos(ang)*y);bx = ox + r * (Math.cos(ang)*-x - Math.sin(ang)*y) * kSw;by = oy + r * (Math.sin(ang)*-x + Math.cos(ang)*y);cx = ox + r * (Math.cos(ang)*-x - Math.sin(ang)*-y) * kSw;cy = oy + r * (Math.sin(ang)*-x + Math.cos(ang)*-y);dx = ox + r * (Math.cos(ang)*x - Math.sin(ang)*-y) * kSw;dy = oy + r * (Math.sin(ang)*x + Math.cos(ang)*-y);var myPolygon = new google.maps.Polygon({ path: [ new google.maps.LatLng(ay, ax), new google.maps.LatLng(by, bx), new google.maps.LatLng(cy, cx), new google.maps.LatLng(dy, dx) ], strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: "#FF0000", fillOpacity: 0.35});myPolygon.setMap(map);各座標用の設定値は自分のディスプレイ上でズーム18のときに、1cmを1単位としたものです。横幅1.7cm、高さ5.5cm、28.5度回転するようにして配置しています。
長方形をクリックしたときにalertを表示するようにしてみます。リスナーを設定する関数を用意します。
function SetLitsener(polygon, msg) { google.maps.event.addListener(polygon, 'click', () => { alert(msg); });}ポリゴンを引数として以下の関数を呼び出せば追加できます。
SetLitsener(myPolygon, "長方形をクリックしました。");この方法はポリゴンとメッセージを結びつけるためにクロージャという技法を用いています。一見google.maps.event.addListenerを直接呼び出して良さそうですが、その場合はmsg変数の最後に割り当てた値が常に使われてしまい、意図したとおりに動作しません。
長方形の上にテキストを表示するにはMapLabelライブラリが必要です。
ライブラリの内容を直接ファイルに書き込むには以下のコードになります。
(function(){/* Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.*/var d="prototype";function e(a){this.set("fontFamily","sans-serif");this.set("fontSize",12);this.set("fontColor","#000000");this.set("strokeWeight",4);this.set("strokeColor","#ffffff");this.set("align","center");this.set("zIndex",1E3);this.setValues(a)}e.prototype=new google.maps.OverlayView;window.MapLabel=e;e[d].changed=function(a){switch(a){case "fontFamily":case "fontSize":case "fontColor":case "strokeWeight":case "strokeColor":case "align":case "text":return h(this);case "maxZoom":case "minZoom":case "position":return this.draw()}};function h(a){var b=a.a;if(b){var f=b.style;f.zIndex=a.get("zIndex");var c=b.getContext("2d");c.clearRect(0,0,b.width,b.height);c.strokeStyle=a.get("strokeColor");c.fillStyle=a.get("fontColor");c.font=a.get("fontSize")+"px "+a.get("fontFamily");var b=Number(a.get("strokeWeight")),g=a.get("text");if(g){if(b)c.lineWidth=b,c.strokeText(g,b,b);c.fillText(g,b,b);a:{c=c.measureText(g).width+b;switch(a.get("align")){case "left":a=0;break a;case "right":a=-c;break a}a=c/-2}f.marginLeft=a+"px";f.marginTop="-0.4em"}}}e[d].onAdd=function(){var a=this.a=document.createElement("canvas");a.style.position="absolute";var b=a.getContext("2d");b.lineJoin="round";b.textBaseline="top";h(this);(b=this.getPanes())&&b.mapPane.appendChild(a)};e[d].onAdd=e[d].onAdd;e[d].draw=function(){var a=this.getProjection();if(a&&this.a){var b=this.get("position");if(b){b=a.fromLatLngToDivPixel(b);a=this.a.style;a.top=b.y+"px";a.left=b.x+"px";var b=this.get("minZoom"),f=this.get("maxZoom");if(b===void 0&&f===void 0)b="";else{var c=this.getMap();c?(c=c.getZoom(),b=c<b||c>f?"hidden":""):b=""}a.visibility=b}}};e[d].draw=e[d].draw;e[d].onRemove=function(){var a=this.a;a&&a.parentNode&&a.parentNode.removeChild(a)};e[d].onRemove=e[d].onRemove;})()使い方は以下のようになります。
var mapLabel1 = new MapLabel({ text: '2', position: MyLatLng, map: map, fontSize: 20, align: 'left'});mapLabel1.set('position', MyLatLng);MyLatLngはテキストを表示する緯度経度の情報になっています。ひな形で示していますが、以下のような方法で指定します。これを長方形の位置に合わせて設定します。
var MyLatLng = new google.maps.LatLng(35.6630204,139.6739709);