2011年3月21日月曜日

GPSの経路ログ表示にGoogle Maps API V3 を使う (その6:吹出しに高度と住所をいれる)

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

前回のその5:センターマークの表示からの続きで,今回は Google Maps の与えられた座標点の高度と住所をを得るサービス(Elevation ServiceGeocoder)を使って,アイコン (Marker) の吹出し (InfoWindow) に高度情報と住所情報を付加してみよう(住所は別に得る方法もあるが,それは叉の機会に…)。ここでの内容はGoogle Maps APIで、あそ~ぶを参考にさせていただいた。感謝感謝。

今回もまずは 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;
    var Elevation_flag = false;

// initialize function
    var centerLatLng = new google.maps.LatLng(35.0, 136.5);
    function initialize() { ........ }
// --------------------------------------------------
    function setCenterMarker(map) { ........ }
    function clearCenterMark() { ........ }
    function showCenterMark() { ........ }
// --------------------------------------------------
    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 setInfoWindow(marker,message) {
        deleteInfoWindow();
        var infowindow = new google.maps.InfoWindow({content: message});
        if (Elevation_flag) {
            getElevation(marker.getPosition(),infowindow);
        }
        infowindow.open(map,marker);
        infowindowsArray.push(infowindow);
    }
    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 消去"> 
<input style="color:red" onclick="showCenterMark();" type=button value="Center 表示"> 
<input style="color:blue" onclick="clearIcons();" type=button value="Icons 消去"> 
<input style="color:red" onclick="showIcons();" type=button value="Icons 表示"> 
<input style="color:black" onclick="clearElevation();" type=button value="NO Addr/Alt on InfoWindow"> 
<input style="color:magenta" onclick="showElevation();" type=button value="ADD Addr/Alt on InfoWindow"> 
</div>
<div id="map_canvas" style="width: 100%; height: 96.5%; position:absolute; top:21px; left:0px"></div>
</body>
</html>

ここでの追加は,まず global 変数として,Elevation_flagを定義してる。Elevation_flag は,後で高度情報と住所を吹出しに書くか書かないかの切り替えができるようにするための変数である。

今回は吹出しの中に与えられた座標点の高度と住所を入れるので,吹出しを書いている setInfoWindow() 関数の中から,高度と住所を得る関数 getElevation() を呼び出している。ここで,上記の Elevation_flagtrue の際だけ関数を呼びに行っている。

肝心の getElevation() 関数は,その上に定義してある。前半で geocoder を呼び出して住所情報を得て,後半で ElevationService を呼び出して高度を得ている。InfoWindow の表示内容は,geocoderElevationService のそれぞれの呼び出しに対するコールバック関数の中で,infowindow.getContent(); でコンテンツを呼び出し,中身を加えてから infowindow.setContent(infoMessage); を使って内容を置き換えている。

最後に web ページにボタンを配置している。使い方としては,web ページの住所などの情報を加えるボタン(ADD)を押しておいてから,アイコン(Marker)をクリックすると,出てくる吹出しに住所などの情報が入る。住所などの情報を書かないボタンを押しても,すぐには住所などの情報は消えない。新たに吹出しを書き直す時から住所などの情報を書かなくなる。

さて,これがとりあえずの完成形である(いっぱい省略してあるが…)。これだけの事が書いてあっても,文字がずらーっと並んでいるだけでは,わかるものもわからないっ!!というご意見が聞こえそうである。そこで,サンプルを web 上に置いておいた。「GPSの経路ログ表示にGoogle Maps API V3 を使う」のサンプル。ソースコードは,ブラウザの「ページのソース」などで見れる。ちなみに,サンプルページは皆さんがどれだけ見に来たかを知りたいので,アクセスログを取っている。なにとぞご理解を…

サンプルサイトでの操作の仕方
 サンプルのサイトを開くと,地図を読み込む。しかし,これが意外と時間がかかる。状況によっては経路線の描画途中で止まったりする。そんな時にはリロード(再読込)してみてほしい。読込みがうまくいったら,アイコンを押すと(ここでは出発点がバイク,終点を赤い押しピンにしている),その地点の情報を出してくれる。最初から住所が入っているが,これは Perl で自動で web ページを作る際に,Yahoo のリバースジオコーダーサービスを使って得たものである。
サンプルページの「ADD Addr/Alt on InfoWindow」ボタンを押してから,アイコンをクリックすると,吹出し(InfoWindow)の中に住所(Google の逆ジオコーディングで得たもの)と,高度,緯度経度が表示される。これもちょっと時間がかかる時があるので,ご注意を。

アイコンの消去,センターマークの消去のボタンを押すと,画面上からアイコンが消えたり,センターマークが消えたりする。これは完全に抹殺したわけじゃないので,それぞれの表示ボタンを押せば再び表示される。また,センターマークは地図をドラッグしてもちゃんと中心に居続ける。ドラッグ当初にはちょっと消えていたり,ドラッグにすばやく反応しないが…。その辺りはちょっといまいちやなぁ…。

さらに,地図上の適当な点(アイコンや経路線がない所)をクリックすると,その点の座標と住所も出すようにしてある。これは黄色の押しピンで表示される。Google の逆ジオコーディングは,若干ずれた表示がでることがあるが,まぁ,これだけ表示してくれれば御の字であろう。このアイコンの吹出しを消すには吹出しの右上の [X] を押せばよいが,アイコン自体を消すには,右上の方にある「Point Icon 消去」ボタンを押さないといけない。消去ボタンを押すと吹出しごと消してくれる。

追記: これで完成と思っていたが,センターマークの改良をしたので,続きに書いてみた。その7:センターマークの改良に続く)

0 件のコメント: