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つ目が北東に当たる点の緯度経度を指定になります。
【参考サイト】
コメントが承認されるまで時間がかかります。