前回のその8:InfoWindowの改良で一度終わりにしたが,追加の項目ができたので,記載する事にした。 今回追加したのは,表示範囲の自動設定,という内容である。 何かというと,KML 形式のデータを読み込むと地図の表示範囲を KML データがちょうど入るように自動で,中心座標と Zoom が調整される。 その後,手動で拡大や移動をした後に,最初の状態に戻したい時がある。 そのために,ボタンを押すと最初の状態に戻るように(自動で表示範囲を設定し直すように)した,というのが今回の内容である
まずは web ページの html ファイルを表示する。今回も念の為に全部表示しよう。そのために適当に色をつけてある。色は目的ごとにグループ分けしている(つもり)。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Route : EXAMPLE</title>
<link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css"
rel="stylesheet" type="text/css">
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var wps = [
['経路1:出発点',35.0,136.5,1,'motorcycling',27,2,
'<div id="wp_desc" style="font-size:12px; width:220px">
<div id="wp_name">経路1:出発点</div><div id="wp_address">三重県のどっか</div> </div>'],
['経路1:Stay Point',35.0,136.55,2,
'grocerystore',18,4,'<div id="wp_desc" style="font-size:12px; width:220px">
<div id="wp_name">経路1:Stay Point</div><div id="wp_address">三重県のはず</div> </div>']
];
var map;
var centerLatLng = new google.maps.LatLng(35.0, 136.5);
var ctaLayer = new google.maps.KmlLayer('http://xxxx.yyyy.zzzz.jp/map_data.kml');
var cmLayer = new google.maps.KmlLayer(
'http://hippo.matsup.mydns.jp/motorcycle/centerMark.kml', {preserveViewport:true});
var markersArray = [];
var InfoWindowX = new google.maps.InfoWindow;
var Elevation_flag = false;
var trackMarkersArray = [];
var initialBounds = new google.maps.LatLngBounds;
function initialize() {
var myOptions = {
zoom: 11,
center: centerLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scaleControl: true,
scaleControlOptions: { position: google.maps.ControlPosition.BOTTOM_CENTER }
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
ctaLayer.setMap(map);
setWPMarkers(map, wps);
cmLayer.setMap(map);
google.maps.event.addListener(map, 'click', function(mouseEvent) {
setTrackMarkers(map, mouseEvent.latLng);
});
google.maps.event.addListenerOnce(ctaLayer, 'defaultviewport_changed', function() {
initialBounds = ctaLayer.getDefaultViewport();
});
}
// --------------------------------------------------
function clearCenterMark() {
cmLayer.setMap(null);
}
function showCenterMark() {
cmLayer.setMap(map);
}
// --------------------------------------------------
function setWPMarkers(map, locations) {
for (var i = 0; i < locations.length; i++) {
var points = locations[i];
var icon_url = 'http://maps.gstatic.com/intl/ja_jp/mapfiles/ms/micons/'
+points[4]+'.png';
var icon_shadow_url =
'http://maps.gstatic.com/intl/ja_jp/mapfiles/ms/micons/'+points[4]+'.shadow.png';
if (points[4].match(/pushpin/i)) {
icon_shadow_url =
'http://maps.gstatic.com/intl/ja_jp/mapfiles/ms/micons/pushpin_shadow.png';
}
var image = new google.maps.MarkerImage(icon_url, new google.maps.Size(32,32),
new google.maps.Point(0,0), new google.maps.Point(points[5],(32-points[6])));
var shadow = new google.maps.MarkerImage(icon_shadow_url, new google.maps.Size(59,32),
new google.maps.Point(0,0), new google.maps.Point(points[5],(32-points[6])));
var shape = { coord: [16, 0, 0, 32, 32, 32], type: 'poly' };
var myLatLng = new google.maps.LatLng(points[1], points[2]);
var marker = new google.maps.Marker({
position: myLatLng, map: map, shadow: shadow,
icon: image, shape: shape, title: points[0], zIndex: points[3]
});
markersArray.push(marker);
attachMessage(marker, points[7]);
}
}
function clearIcons() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
}
}
function showIcons() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(map);
}
}
}
// --------------------------------------------------
function attachMessage(marker, message) {
google.maps.event.addListener(marker, 'click', function() {
InfoWindowX.setContent(message);
if (Elevation_flag) {
getElevation(marker.getPosition(),InfoWindowX);
}
InfoWindowX.open(map,marker);
});
}
function clearInfoWindow() {
InfoWindowX.close();
}
// --------------------------------------------------
function getElevation(latlng, infowindow) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
latLng: latlng
}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0].geometry) {
var message = infowindow.getContent();
var address = results[0].formatted_address.replace(/^日本, /, '');
var infoMessage = message+"<div id=\"geocoder\" style=\"font-size:12px;\">
<b>Google Info: </b><br>"+address +"</div>";
infowindow.setContent(infoMessage);
}
}
else { alert("Geocoder Service ERROR !!"); }
});
var locations = [latlng];
var elevation = new google.maps.ElevationService();
elevation.getElevationForLocations({
locations: locations
}, function(results, status) {
if (status == google.maps.ElevationStatus.OK) {
if (results[0].elevation) {
var message = infowindow.getContent();
var altitude = results[0].elevation;
var infoMessage = message
+"<div id=\"altitude\" style=\"font-size:12px;\"><b>Google Info: </b>";
infoMessage = infoMessage
+"Altitude: " +altitude +" [m]<br>" + latlng + "<br> </div>";
infowindow.setContent(infoMessage);
}
}
else { alert("Elevation Service ERROR !!"); }
});
}
function clearElevation() {
Elevation_flag = false;
}
function showElevation() {
Elevation_flag = true;
}
// --------------------------------------------------
function setTrackMarkers(map, myLatLng) {
clearTrackIcons();
var icon_url = 'http://maps.gstatic.com/intl/ja_jp/mapfiles/ms/micons/ylw-pushpin.png';
var icon_shadow_url = 'http://maps.gstatic.com/intl/ja_jp/mapfiles/ms/micons/pushpin_shadow.png';
var image = new google.maps.MarkerImage(icon_url, new google.maps.Size(32,32),
new google.maps.Point(0,0), new google.maps.Point(10,31));
var shadow = new google.maps.MarkerImage(icon_shadow_url, new google.maps.Size(59,32),
new google.maps.Point(0,0), new google.maps.Point(10,31));
var trackmarker = new google.maps.Marker({
position: myLatLng, map: map, shadow: shadow,
icon: image, title: 'Track Info', zIndex: 999
});
trackMarkersArray.push(trackmarker);
setTrackInfoWindow(trackmarker);
}
function setTrackInfoWindow(trackmarker) {
var trackinfowindow = new google.maps.InfoWindow({content: ''});
getElevation(trackmarker.getPosition(),trackinfowindow);
trackinfowindow.open(map,trackmarker);
}
function clearTrackIcons() {
if (trackMarkersArray) {
for (i in trackMarkersArray) {
trackMarkersArray[i].setMap(null);
}
}
}
function showTrackIcons() {
if (trackMarkersArray) {
for (i in trackMarkersArray) {
trackMarkersArray[i].setMap(map);
}
}
}
// --------------------------------------------------
function resetBounds() {
map.fitBounds(initialBounds);
}
// --------------------------------------------------
</script>
</head>
<body bgcolor="#D0D0D0" onload="initialize()">
<div>
<input style="color:blue" onclick="clearCenterMark();" type=button value="Center消去">
<input style="color:red" onclick="showCenterMark();" type=button value="Center表示">
<input style="color:blue" onclick="clearIcons();" type=button value="Icon消去">
<input style="color:red" onclick="showIcons();" type=button value="Icon表示">
<input style="color:black" onclick="clearInfoWindow();" type=button value="吹出し消去">
<input style="color:magenta" onclick="showElevation();" type=button value="吹出+Addr/Alt">
<input style="color:black" onclick="clearElevation();" type=button value="NO Addr/Alt">
<input style="color:black" onclick="clearTrackIcons();" type=button value="Pts Icon消去">
<input style="color:black" onclick="resetBounds();" type=button value="領域自動調整">
</div>
<div id="map_canvas" style="width: 100%; height: 95%; position:absolute; top:35px; left:0px"></div>
</body>
</html>
まずは色付けの説明をしておこう。 今回追加したものは緑色太字の部分であり,表示範囲の自動設定に関する部分である。 その他は前回の投稿と同じで,灰色の部分は,JavaScript と直接関係ない部分を表している。青色の部分はアイコン (Marker)関連部分を表し,赤色の部分は吹出し(InfoWindow)に関連する部分を表している。さらに,水色の部分は高度と住所(Google Geocoder と Elevation Service)を示し,オレンジ色の部分はクリックした点の情報を得るためのルーチンを,紫色の部分はセンターマーク関連のルーチンを示している。
各処理について説明したいが,長くなるし,煩雑になるので,以前の説明で済むところは以前の説明のリンクをはろう。
(0) まずは今回追加した部分について書こう。今回追加した部分は緑色太字の部分である。
最初に,変数の定義のところで
var initialBounds = new google.maps.LatLngBounds;として LatLngBounds 型の変数を定義している。これは領域を表す点の角(対角?)を表す変数であり,複数の点を含んでいる。
そして,initialize() ルーチンの最後に以下のようにして initialBounds に値を入れている。
google.maps.event.addListenerOnce(ctaLayer, 'defaultviewport_changed', function() {
initialBounds = ctaLayer.getDefaultViewport();
});
ここでは,KML データを表す ctaLayer に対して,viewport が変更されたら,最初の Bounds を initialBounds に入れている。当初は普通に initialBounds に ctaLayer.getDefaultViewport() を代入していたが,なぜかうまく行かず,このようにしたらうまく行った。
あとは,JavaScript の最後に表示範囲を initialBounds に合わせる fitBounds() という処理を含んだ関数を用意して,
web page に fitBounds() を呼び出すボタンを設置して出来上がり,である。
上記の部分以外は前回の投稿と変わってないが,念の為に書いておこう。
(1) 黒い部分(経路の地図を表示している)は,その2:KMLファイルの中身を地図に表示するを見てもらうのがいいと思う。
Google Maps API v3 で KML ファイルから地図を表示する,部分についてのみ書いているので,わかりやすいと思う。
(2) 次にセンターマークについてだが,この例でのセンターマークは,経路とは別の独立した KML ファイルを用意して,
それを地図上に表示している。詳しくはその7:センターマークの改良を見てほしい。
(3) アイコン (Marker)に関しては,その3:アイコン(Marker)の表示を読んでほしい。
コツとしては,作ったアイコンを global 変数として用意した Marker 用の配列に入れる,という点である。
こうすることで,メモリのダブりもなくなり,それぞれに別々のアイコンを指定することができ,
かつ,後で画面上から消したり,再び表示したりできるようにしやすい。
(4) 吹出し(InfoWindow)に関しては,その8:InfoWindowの改良でを読んで欲しい。
(5) 高度と住所(Google Geocoder と Elevation Service)に関しては,その6:吹出しに高度と住所をいれる を読んでほしい。
そこにも書いたがGoogle Maps APIで、あそ~ぶを参考にさせていただいたので,そちらを見る方がわかりやすいかもしれない。
(6) クリックした点の情報は,特に記述はしてないが,アイコン (Marker)とほぼ同じ内容なので,
その3:アイコン(Marker)の表示を読んで理解してみてほしい。
(7) 経路を表す KML ファイルはその1:KML 形式ファイルを作るに,
センターマークを表す KML ファイルはその7:センターマークの改良に記載があるので,それぞれのページを見てみてほしい。
(8) 今回のサンプル地図がサンプルページに map5.html として置いてある。
具体的な表示のされ方を見てほしい。
0 件のコメント:
コメントを投稿