Google Maps APIで特定の範囲をマップ内に収める

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つ目が北東に当たる点の緯度経度を指定になります。
 

【参考サイト】

 

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2024年3月
 12
3456789
10111213141516
17181920212223
24252627282930
31