2011年3月30日水曜日

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

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

前回のその6:吹出しに高度と住所をいれるで一応の完成と思っていたが,画面をドラッグした時のセンターマーク挙動が気に入らなかった。そこで,センターマークの表示を改良してみた。その点を書いてみよう。

今回もまずは web ページの html ファイルを表示しよう。今回も,前回からの変更点を赤色の文字で表示している。今回も既出の部分の多くは省略してある。これが現時点での最終形である。ここでは KML ファイルや,センターマークの画像の指定が適当なので,それらを正しい値にすると,うまく表示されるはず。しかし,実際にはこの html ファイルを Perl のスクリプトで書きだす,ってのを作るのが面倒だった…

<!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 cmLayer = new google.maps.KmlLayer('http://xxxx.yyyy.zzzz.jp/centerMark.kml', {preserveViewport:true});
    var markersArray = [];
    var infowindowsArray = [];
    var Elevation_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);
        cmLayer.setMap(map);
        google.maps.event.addListener(map, 'click', function(mouseEvent) {
            setTrackMarkers(map, mouseEvent.latLng);
        });
    }
// --------------------------------------------------
    function setCenterMarker(map) { } ← これは今回削除した
    function clearCenterMark() {
        cmLayer.setMap(null);
    }

    function showCenterMark() {
        cmLayer.setMap(map);
    }
// --------------------------------------------------
    function getElevation(latlng, infowindow) { ........ }
    function clearElevation() { ........ }
    function showElevation() { ........ }
// --------------------------------------------------
    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 消去"> 
<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>

ここで何を変更したか,だが,前々回(GPSの経路ログ表示にGoogle Maps API V3 を使う (その5:センターマークの表示) )では,センターマークを Google Maps API v3Marker として JavaScript で作成し,地図がドラッグされる度にセンターマークを中央に描き直す,という作業をしていた。

 しかし,ここでは異なる作戦を用いている。それは,経路とは別にセンターマークの情報だけを書いた KML ファイルを用意し,新たな KmlLayer として地図上に表示させている。そのため,global 変数として cmLayer を定義している。ここで大切なのは {preserveViewport:true} の部分。もし,この {preserveViewport:true} がないと,地図に KML ファイルの内容を表示する際に表示範囲やズームを KML ファイルに合わせて変更してしまう。これがあれば KML ファイルの内容に合わせて表示範囲やズームを変更したりしない。通常はなしでよいが,今回センターマークのために用意した KML ファイルは以下のようなもので,緯度経度によって指定される物が全然ない。そのため,範囲を自動で変更されるととんでもない地図になってしまった(試しにやってみるとよいかも)。ご注意あれ。
(センターマーク用の KML ファイル)
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
<description>
<![CDATA[<p>Center Marker</p>]]>
</description>
<Folder>
        <name>Screen Overlays</name>
        <visibility>0</visibility>
        <ScreenOverlay>
                <name>Simple crosshairs</name>
                <visibility>0</visibility>
                <Icon>
                <href>http://hippo.matsup.mydns.jp/images/center_mark.png</href>
                </Icon>
                <overlayXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
                <screenXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
                <rotationXY x="0.5" y="0.5" xunits="fraction" yunits="fraction"/>
                <size x="0" y="0" xunits="pixels" yunits="pixels"/>
        </ScreenOverlay>
</Folder>
</Document>
</kml>
(センターマーク以外に場所を示すものがない。特に緯度経度の情報がない)

 この KML ファイルが割り当てられた cmLayerinitialize 関数の中で描画している。描画させるには cmLayer.setMap(map); とするだけなので簡単である。さらに,これらをボタンで表示したり消したりしたいので,clearCenterMark 関数と showCenterMark 関数を定義しなおしている。ここで,setCenterMarker 関数は,今回は必要ない(消しておく方がよい。ここでは前回との比較で青で表示してあるだけである)。

 これで作った改良版の地図がサンプルページmap2.html として置いてある。今回もサンプルページは皆さんがどれだけ見に来たかを知りたいので,アクセスログを取っている。なにとぞご理解を。この地図で全体をドラッグしてもセンターマークはビクともしない。これが私が求めていたものだった。意外と簡単にできるのであった…。カスタムオーバーレイとかいろいろ探っていたけど,こんなに簡単に実現できてしまうとは…。

さて,こんどこそ,これがとりあえずの完成形である。後は暖かくなったら(もう十分暖かい気もするが…)実際にバイクで走ってみて,その記録を地図にするだけである。なんとか今回の投稿が皆さんの役に立ちますように…。
追記: これで完成と思っていたが,InfoWindow の表示ルーチンの改良をしたので,続きに書いてみた。その8:InfoWindowの改良に続く)

0 件のコメント: