Google Maps APIで指定した複数のマーカーをマップ内に収める方法を調べたのでメモしておきます。
サンプルコード
以前投稿したGoogle Maps APIで表示しているマーカーを切り替えるをベースにして、マーカーを切り替えた際に表示しているマーカに合わせてマップの表示を調整してみます。
jsonファイルを以下のように記述します。
{ "data": [ { "name": "AKIBAカルチャーズZONE", "latlng": { "lat": 35.699519, "lng": 139.770388 }, "category": "tokyo" }, { "name": "秋葉原ガチャポン会館", "latlng": { "lat": 35.701861, "lng": 139.771220 }, "category": "tokyo" }, ~ 略 ~ { "name": "ソフマップなんば店", "latlng": { "lat": 34.662616, "lng": 135.505246 }, "category": "osaka" } ] }
categoryでtokyoかosakaを指定して、それぞれでマーカーと地図表示の切り替えを行うようにします。
HTMLに切り替えようのタブを用意します。
この辺りは前回の記事と同じです。
HTML
<ul class="map-tab"> <li class="map-tab_item" data-category="">ALL</li> <li class="map-tab_item" data-category="tokyo">東京</li> <li class="map-tab_item" data-category="osaka">大阪</li> </ul> <div id="map"></div>
最後にJavaScriptです。
JavaScript
var ready = { api: false, ajax: false }; var map; var mapData; var mapOptions = { center: { // 地図の緯度経度 lat: 35.700000, lng: 139.772000 }, zoom: 17, // 地図の拡大率 scrollwheel: false, // ホイール操作で拡大縮小させるかどうか mapTypeControl: false, // マップ切り替えのコントロールを表示するかどうか streetViewControl: false // ストリートビューのコントロールを表示するかどうか } $(function() { $.ajax({ url: 'data.json', cache: false }) .then( function (data) { mapData = data['data']; ready['ajax'] = true; generate_map(); }, function () { console.log('取得に失敗しました。'); } ); $('[data-category]').on('click', function() { var category = $(this).data('category'); change_category(category); }); }); /** * Google Maps APIの準備完了後の処理 */ function api_ready() { ready['api'] = true; generate_map(); } /** * 地図を生成する */ function generate_map() { if(ready['api'] && ready['ajax']) { map = new google.maps.Map(document.getElementById('map'), mapOptions); add_marker(); } } /** * 地図にマーカーを追加する */ function add_marker() { for (var i = 0; i < mapData.length; i++) { var item = mapData[i]; // マーカーの設置 var marker = new google.maps.Marker({ position: item['latlng'], map: map }); // 吹き出しの生成 var ins = '<div class="map-window">'; ins += '<p class="map-window_name">' + item['name'] + '</p>'; ins += '</div>'; var infoWindow = new google.maps.InfoWindow({ content: ins }); // マーカーのイベント設定 add_event_to_marker(marker, infoWindow, i); } map_adjust(''); } /** * マーカーにイベントを追加する * @param {object} marker (required) マーカーの情報 * @param {object} infoWindow (required) 吹き出しの情報 * @param {number} index (required) 地図情報のインデックス番号 */ function add_event_to_marker(marker, infoWindow, index) { var item = mapData[index]; item['marker'] = marker; item['infoWindow'] = infoWindow; // マーカークリック時に吹き出しを表示する item['marker'].addListener('click', function(e) { infoWindows_hide(); item['infoWindow'].open(map, item['marker']); }); } /** * 吹き出しを非表示にする */ function infoWindows_hide() { for (var i = 0; i < mapData.length; i++) { mapData[i]['infoWindow'].close(); } } /** * 地図上のマーカー表示を切り替える * @param {object} category (required) 表示するマーカーのカテゴリ */ function change_category(category) { // 表示されている吹き出しを非表示にする infoWindows_hide(); // カテゴリ別に切り替える場合 if(category !== '') { for (var i = 0; i < mapData.length; i++) { var item = mapData[i]; item['marker'].setVisible(false); if(item['category'] === category) { item['marker'].setVisible(true); } } // 全件表示の場合 } else { for (var i = 0; i < mapData.length; i++) { mapData[i]['marker'].setVisible(true); } } map_adjust(category); } /** * 地図の表示エリア調整 */ function map_adjust(category) { var latMin = 90; var latMax = -90; var lngMin = 180; var lngMax = -180; var c = 0; for (var i = 0; i < mapData.length; i++) { var thisCategory = mapData[i]['category']; if(thisCategory === category || category === '') { var thisLat = mapData[i]['latlng']['lat']; var thisLng = mapData[i]['latlng']['lng']; latMin = Math.min(latMin, thisLat); latMax = Math.max(latMax, thisLat); lngMin = Math.min(lngMin, thisLng); lngMax = Math.max(lngMax, thisLng); c++; } } if(c > 0) { var min = new google.maps.LatLng(latMin, lngMin); var max = new google.maps.LatLng(latMax, lngMax); var latLngBounds = new google.maps.LatLngBounds(min, max); map.fitBounds(latLngBounds); } }
マーカーに合わせた地図の調整は134~161行目で行っています。
143~154行目で地図上に表示する各マーカーの緯度と経度を比較して、緯度と経度の最小値と最大値を取得、156~159行目でその値を使ってマーカーが地図に収まるように地図の表示を調整しています。
158行目google.maps.LatLngBounds()を使うことで、指定した矩形をマップ内に収めるように調整できます。
パラメータの1つ目が矩形の南西に当たる点の緯度経度を指定、2つ目が北東に当たる点の緯度経度を指定になります。
【参考サイト】
コメントが承認されるまで時間がかかります。