2011年3月16日水曜日

GPSの経路ログ表示にGoogle Maps API V3 を使う (その3:アイコン(Marker)の表示)

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

前回のその2:KMLファイルの中身を地図に表示するの続きで,地図上にアイコン(Google の KML では Marker と呼ばれる)を描画しよう。

目標は,
(1) 出発点や終点,停留点などにアイコンを表示させる。
(2) それぞれのアイコンをクリックすると吹出しがでて,その地点の情報やコメントを見せてくれる。
(3) 写真を撮った場所では,写真のサムネイルを表示して,写真を置いているサイトにリンクを張りたい。
としてみた。今回はアイコンを表示する部分について述べよう。吹出しの表示については次回述べる。

以下に今回の 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 = [
        ['経路1:出発点',35.0,136.5,1,'motorcycling',27,2,
        '<div id="wp_desc" style="font-size:12px; width:220px">
        lt;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 ctaLayer = new google.maps.KmlLayer('http://xxxx.yyyy.zzzz.jp/map_data.kml');
    var markersArray = [];

    // initialize function
    var centerLatLng = new google.maps.LatLng(35.0, 136.5);
    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);
    }
// --------------------------------------------------
    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);
        }
    }
// --------------------------------------------------
// Removes the Icons from the map, but keeps them in the array
    function clearIcons() {
        if (markersArray) {
            for (i in markersArray) {
                markersArray[i].setMap(null);
            }
        }
    }

// Shows any Icons currently in the array
    function showIcons() {
        if (markersArray) {
            for (i in markersArray) {
                markersArray[i].setMap(map);
            }
        }
    }

// Deletes all markers in the array by removing references to them
    function deleteIcons() {
        if (markersArray) {
            for (i in markersArray) {
                markersArray[i].setMap(null);
            }
            markersArray.length = 0;
        }
    }
</script>
</head>

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

まず,最初の赤い部分にある var wps = [ .... を見て欲しい。この部分はアイコンを表示したい点の情報を配列という形で与えている。それぞれの点の情報も配列になっているので,2次元配列の構成になっている。各点の情報は,点の名前,緯度,経度,アイコン表示の重要度,アイコンファイルの名前,hotSpot(アイコン内のどの点を与えられた緯度経度に当てはめるか)の x 座標,hotSpot の y 座標 (左下を原点にしたもの),吹出しに書くコメント,である。ここでアイコンの名前はGoogle Maps APIで使えるアイコン一覧の中の「Googleマップで使われているアイコン一覧」に出てくるアイコンのファイル名から拡張子(「.png」って部分)を除いたものである(画像を右クリックして画像の情報を見ると名前やサイズがわかる)。最初にも書いたが,吹出しの表示については次回述べる。

var wps = [ .... の少し下に var markersArray = []; というのあるが,これはアイコンを Marker として定義した後にいれるための配列である。関数の外で定義しているので,global 変数という形になっている。ここではカラの配列として定義してある。

initialize() 関数の最後にある setWPMarkers(map, wps); は下の方で定義した関数であり,wps という配列で与えられた WayPoint の各点に Marker を描画する,という関数を呼び出して WayPoint にアイコンを描画させている。

次に現れる3つの関数,clearIcons()showIcons()deleteIcons(),はそれぞれ markersArray 配列に登録されているアイコンを非表示にする関数,再び表示するための関数,アイコンを配列から完全に消し去る関数であり,この例では web ページに配置したボタンから,clearIcons()showIcons()を呼び出して使っている。アイコンを非表示にする関数は,setMap の引数として null を与えている。こうすることで画面上から消すことができる。逆に setMap の引数に map を指定すると再び描画される。

 setWPMarkers(map, locations) 関数が実際に各 WayPoint にアイコンを表示する関数である。引数として locations と書かれた部分に wps を代入しているので,var points = locations[i]; で定義される points は配列 wps の各行が代入される。従って,points[0] で WayPoint の名前が与えられ,points[1] がその点の緯度,points[2] が経度,などを表している。この例では,for 文を使って全ての点に対してアイコンを表示している。Google Maps API v3 での Marker については,Marker クラスに,使える関数メソッド)やクリックした際に発生するイベント指定できるオプションについての記述がある。

 変数 icon_url はアイコン画像の URL を,変数 icon_shadow_url はアイコンの影の画像の URL を与えている。pushpin の場合だけは,7色ある押しピン画像に対して影画像は1個なので,if 文で影画像の URL を与え直している。image 変数と shadow 変数はそれぞれ MarkerImage クラスと呼ばれる種類の変数であり,アイコンの画像を定義している。例では,アイコンのサイズは 32 x 32 pixel で,左上の (0, 0) の点を基準に,x 方向右向きに points[5],y 方向下向きに (32-points[6]) の点を指定された緯度経度の点に置く,となっている。影画像の場合は,サイズが 59 x 32 pixel となっている他は同じ設定としている。shape 変数は,アイコンのクリック可能な領域の形状を定義し,アイコンのこの領域をクリックすると「アイコンがクリックされた」と判断される。ここでは三角形として定義している。myLatLng 変数はアイコンを表示する点の緯度と経度である。

 これらの変数を用いて最後に var marker = new google.maps.Marker({..... でアイコンを描画している。markergoogle.maps.Marker と定義すると,その時点でアイコンが描画される。オプションには,表示する緯度経度や,アイコン画像,影画像などを指定している。zIndex はアイコンが重なった時に,どの順番に表示するか,という変数であり,zIndex が大きいほど上に表示されるらしい。

こうしてアイコンを描画するのだが,描画されたアイコンを表す変数 marker を,アイコン用の配列 markersArray に加えている。これにより,clearIcons() 関数や showIcons() 関数でアイコンの表示・非表示を切り替えれるようにしている。

最後に,web ページにボタンを表示して,アイコンの表示・非表示をコントロールしている。わかりやすいようにボタン内の文字に色をつけている。また,地図を表示する領域の縦方向を少し狭くしている。これはアイコンの表示・非表示ボタンを置くスペースを確保するためであり,地図の大きさを縦方向にブラウザ・ウィンドウの 96.5 % まで減らしている。

追記)何故かわからないが,地図の上に配置したボタンが地図に覆い隠されてしまった。仕方ないので,地図を表示する <div> のスタイルに position 指定を加え,地図がボタンと重ならないように少し下げて表示するようにしておいた

その4:吹出し(InfoWindow)の表示に続く)

0 件のコメント: