2011年3月19日土曜日

GPSの経路ログ表示にGoogle Maps API V3 を使う (その5:センターマークの表示)

その1:KML 形式ファイルを作る に目次があります。

前回のその4:吹出し(InfoWindow)の表示からの続きで,今回は地図の中心部にセンターマークを表示させる。センターマークなので,地図を動かしてもいつも地図の中心にいないといけない。そのためにちょっとした指示を記述している(ここでの方法がベストとは思えないのだが,今の私にはこの方法しか思いつかなかった…)。
追記その7:センターマークの改良で,独立した KML ファイルを用いた,地図に連動した動きをしないセンターマークについて書いた。

今回もまずは 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 map;
    var wps = [ ........ ];
    var ctaLayer = new google.maps.KmlLayer('http://xxxx.yyyy.zzzz.jp/map_data.kml');
    var markersArray = [];
    var infowindowsArray = [];

    var centerMark;
    var cm_flag = false;

// initialize function
    var centerLatLng = new google.maps.LatLng(35.0, 136.5);
    function initialize() {
        var myOptions = {
            ........
        }
        map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

        ctaLayer.setMap(map);
        setWPMarkers(map, wps);
        setCenterMarker(map);
    }
// --------------------------------------------------
    function setCenterMarker(map) {
        var centermarkImage = './center_mark.png';
        var image = new google.maps.MarkerImage(centermarkImage, new google.maps.Size(32,32),
        new google.maps.Point(0,0),  new google.maps.Point(16,16));
        var myLatLng = map.getCenter();
        var centerMarker = new google.maps.Marker({
            position: myLatLng,  map: map,
            icon: image,  zIndex: 1000
        });
        centerMark = centerMarker;
        cm_flag = true;
        google.maps.event.addListener(map, 'center_changed', function() {
            if (cm_flag) {
                centerMarker.setMap(null);
                centerMarker.setPosition(map.getCenter());
                centerMarker.setMap(map);
            }
        });
    }

    function clearCenterMark() {
        centerMark.setMap(null);
        cm_flag = false;
    }

    function showCenterMark() {
        centerMark.setPosition(map.getCenter());
        centerMark.setMap(map);
        cm_flag = true;
    }
// --------------------------------------------------
    function setInfoWindow(marker,message) { ........ }
    function attachMessage(marker, message) { ........ }
    function deleteInfoWindow() { ........ }
// --------------------------------------------------
    function setWPMarkers(map, locations) { ........ }
// --------------------------------------------------
    function clearIcons() { ........ }
    function showIcons() { ........ }
// --------------------------------------------------
</script>
</head>

<body bgcolor="#D0D0D0" onload="initialize()">
<div>
<input style="color:blue" onclick="clearCenterMark();" type=button value="Center Mark 消去"> 
<input style="color:red" onclick="showCenterMark();" type=button value="Center Mark 表示"> 
<input style="color:blue" onclick="clearIcons();" type=button value="WayPoint Icon 消去"> 
<input style="color:red" onclick="showIcons();" type=button value="WayPoint Icons 表示"> 
</div>
<div id="map_canvas" style="width: 100%; height: 96.5%; position:absolute; top:21px; left:0px"></div>
</body>
</html>

 ここでの追加は,まず global 変数として,centerMark (centerMarkerと間違わないように),cm_flag の2つを定義してる。centerMark は後でセンターマークを表示・非表示の切り替えができるように保存するための変数である。cm_flag はセンターマークが表示されているかどうかを表すフラグである。こんなのを定義しないでもいけそうな気もするけど,今回はこれでうまくいったので,この作戦のままにしておこう。JavaScript はちょっと何かを変更するとすぐに動かなくなるから,うまくいってるを変更するのってためらわれる…。

 次は initialize() 関数の中で,地図の描画,KML ファイルで指定した経路の表示,アイコンの表示,の後にセンターマークの表示を書いている。センターマークの表示をしている setCenterMarker() 関数は,基本的にアイコンの表示と同じである。画像ファイルの URL を指定して,画像のサイズ,原点,スナップポイントを指定して,google.maps.Marker として定義するだけである。ここでの注目点は,表示座標の緯度経度として,map.getCenter() を指定している点である。これは表示されている地図の中心の緯度経度を求める関数であり,その点にセンターマークを表示せよ,と指示していることになる。
後は,setCenterMarker() 関数内で定義された centerMarker 変数を global 変数の centerMark に代入し,cm_flag 変数を表示されていることを表す true にセットしてる。

 また,地図を見ている人が地図の表示位置をずらしてもいつもセンターマークが中央にくるようにしないといけない。そのための処理が setCenterMarker() 関数の中に書いてある。それが google.maps.event.addListener の部分である。ここでは,センターマークが表示されている時に(cm_flagtrue の時に),mapcenter_changed がアクティブになったら(地図をドラッグして動かしたら中心が移動するので,center_changed がアクティブになる),一度センターマークを消し,地図の中心座標を求め直して,もう一度センターマークを表示する,という作業をさせている。

しかし,きっと地図とは異なるレイヤー(Google Maps API では MapPanes と呼ぶらしい)に描画出来ればいちいち移動なんて考えなくてもいいと思うのだが,異なる MapPanes に描画する方法がわからなかった。もし将来わかったらこの部分は変更したいと思っている。
追記)カスタムオーバーレイというのを使って,異なる MapPanes にセンターマークを書けたのだが…(一番下の追記を見よ)

他には,web に設置したボタンでセンターマークの表示・非表示のための関数 clearCenterMark()showCenterMark() が定義されている。

その6:吹出しに高度を住所をいれるに続く)

追記)2011/3/29に,異なる MapPanes に描画する作戦をちょっとだけテストしてみた。カスタムオーバーレイを使って,一番上に描画される floatPane にセンターマークを描いてみたが,地図をドラッグするとセンターマークもやっぱり一緒に動いてしまった。拡大・縮小すると地図を描画しなおすので,再び中央に来るのだが…。うーん,いまいちわからず…。

0 件のコメント: