マーカーと情報ウィンドウの表示と削除[GoogleMapsAPIVersion3]

前回の「地図の表示と緯度経度の取得[GoogleMapsAPIVersion3]」で、地図を表示して緯度経度を取得して表示するところは終わりました。
今回は、マーカーとふきだし(情報ウィンドウというようですが、ふきだしのほうが直感的な気がしませんか?)を表示させます。

マーカーの表示と削除

今度はマーカーを表示します。緯度経度取得と順序が逆なような気がしますが、気にしません。
単純にマーカーを表示するだけなら何ともないけど、消すこと考えるとv3からはちょっと考えておかなければならないみたいです。
v2では、
map.clearOverlays();
一発で追加したマーカーが消えたらしいのですが、v3で廃止になったとの事です。
なので配列で表示したマーカーを全部持っておかないとダメみたいです。

javascriptの頭で配列を作っておいて、

var marker_ary = new Array();

マーカーを表示する際に配列を使うようにして、

//マーカー表示
function MarkerSet(lat,lng){
	var marker_num = marker_ary.length;
	var marker_position = new google.maps.LatLng(lat,lng);
	marker_ary[marker_num] = new google.maps.Marker({
		map: map, 
		position: marker_position
	});
}

配列につっこまれたマーカーを一つずつ削除していく

//マーカー削除
function MarkerClear() {
	//表示中のマーカーがあれば削除
	if(marker_ary.length > 0){
		//マーカー削除
		for (i = 0; i <  marker_ary.length; i++) {
			marker_ary&#91;i&#93;.setMap();
		}
		//配列削除
		for (i = 0; i <=  marker_ary.length; i++) {
			marker_ary.shift();
		}
	}
}
&#91;/javascript&#93;
でざっくり消せるようです。配列の削除も忘れずにやります。

ずいぶん面倒くさくなりました。
v2時代は知らないんですけどね。

これで、どこからでもMarkerSet()に緯度経度を渡してやると、さくっとマーカーが表示され、MarkerClear()を読んでやるときれいさっぱり消えてなくなります。
動作確認の為、ボタンを押したら地図の中央にマーカーが表示されるようにします。

&#91;javascript&#93;
//地図の中央にマーカー
function setMarker(){
	var mapCenter = map.getCenter();

	//マーカー削除
	function MarkerClear();

	//マーカー表示
	function MarkerSet(mapCenter.lat(),mapCenter.lng());
}
&#91;/javascript&#93;

表示処理と

&#91;html&#93;
<div><input type="button" value="地図中央にマーカー" onclick="setMarker()" onkeypress="setMarker()" /></div>
[/html]

ボタンを設置します。

出来上がったサンプルがこちら

[html]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
	var map;
	var marker_ary = new Array();
	function initialize() {
		var latlng = new google.maps.LatLng(34.985458, 135.757755);
		var myOptions = {
			zoom: 8,
			center: latlng,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};
		map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
	}

	//地図中央の緯度経度を表示
	function getMapcenter() {
		//地図中央の緯度経度を取得
		var mapcenter = map.getCenter();

		//テキストフィールドにセット
		document.getElementById("keido").value = mapcenter.lng();
		document.getElementById("ido").value = mapcenter.lat();
	}

	//地図の中央にマーカー
	function setMarker() {
		var mapCenter = map.getCenter();

		//マーカー削除
		MarkerClear();

		//マーカー表示
		MarkerSet(mapCenter.lat(),mapCenter.lng());
	}

	//マーカー表示
	function MarkerSet(lat,lng){
		var marker_num = marker_ary.length;
		var marker_position = new google.maps.LatLng(lat,lng);
		marker_ary[marker_num] = new google.maps.Marker({
			map: map, 
			position: marker_position
		});
	}

	//マーカー削除
	function MarkerClear() {
		//表示中のマーカーがあれば削除
		if(marker_ary.length > 0){
			//マーカー削除
			for (i = 0; i <  marker_ary.length; i++) {
				marker_ary&#91;i&#93;.setMap();
			}
			//配列削除
			for (i = 0; i <=  marker_ary.length; i++) {
				marker_ary.shift();
			}
		}
	}
</script>
</head>
<body onload="initialize()">
	<div id="map_canvas" style="width:600px; height:600px"></div>
	<div>
		経度<input type="text" size="20" id="ido" value="" />
		緯度<input type="text" size="20" id="keido" value="" />
		<input type="button" value="地図中央の緯度経度" onclick="getMapcenter()" onkeypress="getMapcenter()" />
	<div>
	<div><input type="button" value="地図中央にマーカー" onclick="setMarker()" onkeypress="setMarker()" /></div>
</body>
</html>
[/html]

→<a href="/sample/gmap/gmap_sample03.html" target="_blank">動作サンプル</a>

無事動きました。
ボタンを押したら、地図中央にマーカーが表示されます。
地図をドラッグして表示範囲を変更してからもう一度ボタンを押すと、前に表示されていたマーカーが消えて、地図中央に新しいマーカーが表示されます。

消す事まで考えると、緯度経度を取得するより面倒くさいってどうなんでしょう、コレ。


参考サイト
<a href="http://alfa.way-nifty.com/blog/2010/04/googlemap-v3-2-.html" target="_blank">http://alfa.way-nifty.com/blog/2010/04/googlemap-v3-2-.html</a>
<a href="http://kaions.blog102.fc2.com/blog-entry-1019.html" target="_blank">http://kaions.blog102.fc2.com/blog-entry-1019.html</a>




<h2>ふきだしの表示と削除</h2>
GoogleMapsAPIVersion3から、ふきだしが複数表示できるようになったそうです。
これはこれでありがたいのかもしれませんが、今回の用途だと隣接する地点のふきだしが重なったらかなり煩わしいので、一つにします。
別のマーカーがクリックされたら、前にクリックされたマーカーのふきだしは閉じたいのです。

<a href="http://googlemaps.googlermania.com/google_maps_api_v3/map_example_singleInfoWindow.html" target="_bank">http://googlemaps.googlermania.com/google_maps_api_v3/map_example_singleInfoWindow.html</a>

を読んでみると、マーカーを表示するときに、そのマーカーがクリックされたら…というイベントを仕込んでおくイメージみたい。
となると、マーカー表示時に、ふきだしに表示するデータを仕込んでおく必要があるという事ですね。

とりあえず一歩ずつ行きます。

まずは、ふきだしを表示させます。消すことは考えません。
マーカー表示部分を少し改造して、ふきだしの内容と、マーカーがクリックされたときにふきだしを表示するイベントを仕込みます。

[javascript]
//マーカー表示
function MarkerSet(lat,lng,text){
	var marker_num = marker_ary.length;
	var marker_position = new google.maps.LatLng(lat,lng);
	var markerOpts = {
		map: map, 
		position: marker_position
	};
	marker_ary[marker_num] = new google.maps.Marker(markerOpts);

	//textが渡されていたらふきだしをセット
	if(text.length>0){
		var infoWndOpts = {
			content : text
		};
		var infoWnd = new google.maps.InfoWindow(infoWndOpts);
		google.maps.event.addListener(marker_ary[marker_num], "click", function(){
			//情報ウィンドウを開く
			infoWnd.open(map, marker_ary[marker_num]);
		});
	}
}

そして、マーカー表示指令時に、情報ウィンドウに表示するテキストを渡してやるようにします。
とりあえず、testと表示させます。

//地図の中央にマーカー
function setMarker() {
	var mapCenter = map.getCenter();

	//マーカー削除
	MarkerClear();

	//マーカー表示
	MarkerSet(mapCenter.lat(),mapCenter.lng(),'test');
}

出来上がったサンプルがこちら

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
	var map;
	var marker_ary = new Array();
	function initialize() {
		var latlng = new google.maps.LatLng(34.985458, 135.757755);
		var myOptions = {
			zoom: 8,
			center: latlng,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};
		map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
	}

	//地図中央の緯度経度を表示
	function getMapcenter() {
		//地図中央の緯度経度を取得
		var mapcenter = map.getCenter();

		//テキストフィールドにセット
		document.getElementById("keido").value = mapcenter.lng();
		document.getElementById("ido").value = mapcenter.lat();
	}

	//地図の中央にマーカー
	function setMarker() {
		var mapCenter = map.getCenter();

		//マーカー削除
		MarkerClear();

		//マーカー表示
		MarkerSet(mapCenter.lat(),mapCenter.lng(),'test');
	}

	//マーカー削除
	function MarkerClear() {
		//表示中のマーカーがあれば削除
		if(marker_ary.length > 0){
			//マーカー削除
			for (i = 0; i <  marker_ary.length; i++) {
				marker_ary&#91;i&#93;.setMap();
			}
			//配列削除
			for (i = 0; i <=  marker_ary.length; i++) {
				marker_ary.shift();
			}
		}
	}

	function MarkerSet(lat,lng,text){
		var marker_num = marker_ary.length;
		var marker_position = new google.maps.LatLng(lat,lng);
		var markerOpts = {
			map: map, 
			position: marker_position
		};
		marker_ary&#91;marker_num&#93; = new google.maps.Marker(markerOpts);

		//textが渡されていたらふきだしをセット
		if(text.length>0){
			var infoWndOpts = {
				content : text
			};
			var infoWnd = new google.maps.InfoWindow(infoWndOpts);
			google.maps.event.addListener(marker_ary[marker_num], "click", function(){
				//情報ウィンドウを開く
				infoWnd.open(map, marker_ary[marker_num]);
			});
		}
	}
</script>
</head>
<body onload="initialize()">
	<div id="map_canvas" style="width:600px; height:600px"></div>
	<div>
		経度<input type="text" size="20" id="ido" value="" />
		緯度<input type="text" size="20" id="keido" value="" />
		<input type="button" value="地図中央の緯度経度" onclick="getMapcenter()" onkeypress="getMapcenter()" />
	<div>
	<div><input type="button" value="地図中央にマーカー" onclick="setMarker()" onkeypress="setMarker()" /></div>
</body>
</html>

動作サンプル

とりあえず動きました。

地図中央に表示されたマーカーをクリックしたら、ふきだしが表示されます。
地図を移動させて新しいマーカーを表示させて、マーカーをクリックすると、新しいふきだしが表示されます。
前に表示されたふきだしは消えません。どんどん表示されて、しまいに画面がふきだしだらけになります。

今度は、ちゃんと消す処理を追加します。
基本はマーカーと同じで、表示したふきだしを記録しておいて、新しいふきだしを表示する前に削除します。

例のごとく、頭で現在開いている情報ウィンドウ(ふきだし)を覚えておくための変数を指定しておきます。

var currentInfoWindow

で、マーカー表示部分を改修。
開いている情報ウィンドウがないか確認して、情報ウィンドウを開き、開いた情報ウィンドウはちゃんと覚えておくと。

function MarkerSet(lat,lng,text){
	var marker_num = marker_ary.length;
	var marker_position = new google.maps.LatLng(lat,lng);
	var markerOpts = {
		map: map, 
		position: marker_position
	};
	marker_ary[marker_num] = new google.maps.Marker(markerOpts);

	//textが渡されていたらふきだしをセット
	if(text.length>0){
		var infoWndOpts = {
			content : text
		};
		var infoWnd = new google.maps.InfoWindow(infoWndOpts);
		google.maps.event.addListener(marker_ary[marker_num], "click", function(){

			//先に開いた情報ウィンドウがあれば、closeする
			if (currentInfoWindow) {
				currentInfoWindow.close();
			}

			//情報ウィンドウを開く
			infoWnd.open(map, marker_ary[marker_num]);

			//開いた情報ウィンドウを記録しておく
			currentInfoWindow = infoWnd;
		});
	}
}

で、できました。

</html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
	var map;
	var marker_ary = new Array();
	var currentInfoWindow

	function initialize() {
		var latlng = new google.maps.LatLng(34.985458, 135.757755);
		var myOptions = {
			zoom: 8,
			center: latlng,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};
		map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
	}

	//地図中央の緯度経度を表示
	function getMapcenter() {
		//地図中央の緯度経度を取得
		var mapcenter = map.getCenter();

		//テキストフィールドにセット
		document.getElementById("keido").value = mapcenter.lng();
		document.getElementById("ido").value = mapcenter.lat();
	}

	//地図の中央にマーカー
	function setMarker() {
		var mapCenter = map.getCenter();

		//マーカー削除
		MarkerClear();

		//マーカー表示
		MarkerSet(mapCenter.lat(),mapCenter.lng(),'test');
	}

	//マーカー削除
	function MarkerClear() {
		//表示中のマーカーがあれば削除
		if(marker_ary.length > 0){
			//マーカー削除
			for (i = 0; i <  marker_ary.length; i++) {
				marker_ary&#91;i&#93;.setMap();
			}
			//配列削除
			for (i = 0; i <=  marker_ary.length; i++) {
				marker_ary.shift();
			}
		}
	}

	function MarkerSet(lat,lng,text){
		var marker_num = marker_ary.length;
		var marker_position = new google.maps.LatLng(lat,lng);
		var markerOpts = {
			map: map, 
			position: marker_position
		};
		marker_ary&#91;marker_num&#93; = new google.maps.Marker(markerOpts);

		//textが渡されていたらふきだしをセット
		if(text.length>0){
			var infoWndOpts = {
				content : text
			};
			var infoWnd = new google.maps.InfoWindow(infoWndOpts);
			google.maps.event.addListener(marker_ary[marker_num], "click", function(){

				//先に開いた情報ウィンドウがあれば、closeする
				if (currentInfoWindow) {
					currentInfoWindow.close();
				}

				//情報ウィンドウを開く
				infoWnd.open(map, marker_ary[marker_num]);

				//開いた情報ウィンドウを記録しておく
				currentInfoWindow = infoWnd;
			});
		}
	}
</script>
</head>
<body onload="initialize()">
	<div id="map_canvas" style="width:600px; height:600px"></div>
	<div>
		経度<input type="text" size="20" id="ido" value="" />
		緯度<input type="text" size="20" id="keido" value="" />
		<input type="button" value="地図中央の緯度経度" onclick="getMapcenter()" onkeypress="getMapcenter()" />
	<div>
	<div><input type="button" value="地図中央にマーカー" onclick="setMarker()" onkeypress="setMarker()" /></div>
</body>
</html>

動作サンプル

無事動きました。

うーん。なんか面倒ですね。
マーカーとふきだしの表示と削除だけでえらいコードが増えてしまいました。

以前までのシンプル&エコがどこへやら…。
若干の不安を覚えつつ、次のステップへすすみます。

マーカーと情報ウィンドウの表示と削除[GoogleMapsAPIVersion3]” への1件のフィードバック

コメントを残す

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

CAPTCHA