2014年11月 3日

隠居のスマホ備忘録:山旅ロガーを使う。(2)測定結果を Google Map に表示する


 前回、スマホのアプリ山旅ロガーを使う方法について記録した。
 このトラッキング測定結果は、GPX というファイルとKML という形式のファイルでPC に送信することができる。GPX ファイルについては、ネットにあまり自分がやりたいことにぴったり来る情報がない。KMLファイルは、XML ファイルの一種のようなので、多少馴染みがあるので、こちらでトライしてみることにした。
 PC への送信方法は、メールにファイルを添付する方法と Bluetooh で送信する方法がある。PC の近くでの作業では、どちらをとっても大差はない。

測定結果をPCに送信する
測定結果ファイルの機能ボタンをタップすると 左の画面で「共有・出力」ボタンをタップすると;クリックすると大きな写真になります。 ファイル送信方法の選択画面;クリックすると大きな写真になります。"
測定結果一覧で該当ファイルの機能ボタンをタップすると、上のような画面になる。 左の画面で「共有・出力」ボタンをタップすると右の画面になる。 上の画面で Gmail または Bluetooth を選択して、指示に従いPC に送信する。


上の真ん中のスクリーンショットにあるように、KMLファイルを出力するときには、3つの形式から選択できる。
  • ①トラッキングしたルート(ライン)のみを表示する。
  • ② ①に時刻をつける
  • ③ 測定地点にマーカーを立て、時刻と text を表示する

 このような KMLファイルをPC に取り込んで、Google Maps API 表示するサンプルを見つけた。
 このサンプルコードを参考に、自宅から栂・美木多駅までの測定結果の ② の形式KMLファイルを取り込んだHTMLページを作成すると次のように表示された。


 上の地図は、Google Map の機能を持っているので、ストリートビューが見られるなど、駅から自宅までの道案内に有用かもしれない。

 同じトラッキングデータを上の ③ の形式で取り込んで、上のサンプルコードの kml アドレスを変更して Google Map に表示してみると、測定地点のマーカが連なって表示される。
 この時のKMLファイルの中身を覗く方法がわからなかったが、KMLがXMLファイルの一種であることにヒントを得て、XML notepadで開いてみると、これで編集できることが分かった。(もちろん、秀丸のようなテキスト・エディタでもできる)
 だが、固有のタグについては、かなりの学習が必要なようだ。とりあえず、分かりそうなタグに見当をつけて、試行錯誤を繰り返して見た。

 そのようにして作ってみた地図を下に表示する。


  この地図では、もともと38個あったマーカーを間引きして9個にし、
  • 地点1を"自宅"の文字に置き換え、
  • 駅への通り道にある風邪を引いた時などにお世話になる清水内科近く(15の地点)にはGoogle サーチの結果リンクを、
  • 24の地点(池のそば)のマーカ(24の地点)には、その地点で撮った水鳥の写真を表示するリンクを、
  • 終点の栂・美木多駅には、泉北高速鉄道のサイトで表示される栂・美木多駅ページヘのリンク
を挿入してみた。
  写真表示には、撮った写真をかっこ良く表示させる、Google Maps API を使って地図を作成する時に使っている、lightbox のコードを追加してみると上手く動いてくれた。

 上の地図のためのコードは、以下である。

<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:v=\"urn:schemas-microsoft-com:vml\">
<head> 
<meta name=\"viewport\" content=\"initial-scale=1.0, user-scalable=no\" />

<!-- jQuery lightbox2.51 -->
<script type=\"text/javascript\" src=\"http://n-shuhei.net/atelier/Jquery2.51/js/jquery-1.7.2.min.js\"></script>
<script type=\"text/javascript\" src=\"http://n-shuhei.net/atelier/Jquery2.51/js/lightbox.js\"></script>
<link rel=\"stylesheet\" type=\"text/css\" href=\"http://n-shuhei.net/atelier/Jquery2.51/css/lightbox.css\" media=\"screen\" />

<script type=\"text/javascript\" src=\"http://maps.googleapis.com/maps/api/js?sensor=false&hl=ja\"></script>
<script type=\"text/javascript\">
  function initialize() {
    var initPos = new google.maps.LatLng(34.490435, 135.482852);
    var myOptions = {
      noClear : true,
      center : initPos,
      zoom : 15,
      mapTypeId : google.maps.MapTypeId.ROADMAP
    };
    var map_canvas = new google.maps.Map(document.getElementById(\"map_canvas\"), myOptions);
    
    var kmlUrl = \"http://n-shuhei.net/atelier/maps/KML-test/141025P.kml\";
    var kmlLayer = new google.maps.KmlLayer(kmlUrl);
    kmlLayer.setMap(map_canvas);
  }

</script>
  </head>

<body onload=\"initialize()\">
  <div id=\"map_canvas\" style=\"width:100%; height:500px\"></div>
</body>
</html>


 ここで、指定しているKMLファイルは、テキストコードは以下である。実際の編集は、XML notepad で作業している。


<?xml version=\"1.0\" encoding=\"utf-8\"?>
<kml xmlns=\"http://www.opengis.net/kml/2.2\">
  <Document>
    <name><![CDATA[2014-10-25 09:15:02]]></name>
    <description><![CDATA[自宅ー駅:2014-10-25 09:15~2014-10-25 09:33]]></description>
    <Placemark>
      <name>自宅</name>
      <description>2014-10-25 09:15:02:</description>
      <TimeStamp>
        <when>2014-10-25T00:15:02.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.48277,34.490517,30</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>5</name>
      <description>2014-10-25 09:16:44</description>
      <TimeStamp>
        <when>2014-10-25T00:16:44.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.48332,34.49017,37</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>10</name>
      <description>2014-10-25 09:18:55</description>
      <TimeStamp>
        <when>2014-10-25T00:18:55.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.48485,34.489635,33</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>15</name>
      <description><![CDATA[<a href=\"https://plus.google.com/104149416183172006475/about?gl=jp&hl=ja\">清水内科</a>]]></description>
      <TimeStamp>
        <when>2014-10-25T00:21:05.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.48608,34.488583,45</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>20</name>
      <description>2014-10-25 09:23:15</description>
      <TimeStamp>
        <when>2014-10-25T00:23:15.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.48712,34.487377,48</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>24</name>
      <description><![CDATA[<a href=\"http://n-shuhei.net/atelier/photo_birds/DSC04864.JPG\" title=\"\" rel=\"lightbox[]\">マガモ交雑種</a>]]></description>
      <TimeStamp>
        <when>2014-10-25T00:25:00.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.48792,34.486824,46</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>29</name>
      <description>2014-10-25 09:27:12</description>
      <TimeStamp>
        <when>2014-10-25T00:27:12.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.48877,34.48632,54</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>35</name>
      <description>2014-10-25 09:30:48</description>
      <TimeStamp>
        <when>2014-10-25T00:30:48.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.49054,34.485283,53</coordinates>
      </Point>
    </Placemark>
    <Placemark>
      <name>38</name>
      <description><![CDATA[<a href=\"http://www.semboku.jp/station/toga_mikita/outline/\">栂・美木多駅</a>]]></description>
      <TimeStamp>
        <when>2014-10-25T00:33:30.000Z</when>
      </TimeStamp>
      <Point>
        <coordinates>135.48999,34.484875,61</coordinates>
      </Point>
    </Placemark>
  </Document>
</kml>


 もう少し高度な加工ができそうであるが、一段の学習が必要のようだ。痴呆予防には役立つかもしれないので、もうちょっと遊んでみたいと思っている。

2014年10月17日

隠居のパソコン備忘録:Youtubeをページ内で再生させるYouTube Player API を試してみる


 9月の終わりにあった和泉の国ジャズストリートで録画した Videoをブログにアップした。その時、ブログのページ内で再生できるようにしたかったが、方法が見つからず、YouTube にリンクするしかなかった。YouTube の画面はかなり noisy である。

 最近、ひょんなことで、ブログのページ内で録画を YouTube の機能を使って再生できることが分かった。私的な旅行地図などを作るときに使っている Google Maps API(Application Program Interface) と同じように、Javascript を使う。Codeを自ら作り出す能力はないから、他人様のコードのパクリである。Javascript だから少しぐらいは自分で改訂することが出来る。
 今回は、YoheiM.netYoutubeをサイト内で再生させるYoutube APIの使い方を参考にさせていただいた。

YouTube Player API で表示する動画


 上の YouTube 埋め込みプレーヤは、次のような Javascript コードで実現している。
 青太字部分は、YouTube に登録されたファイル名である。

<div id="player"></div>
<script>

    var tag = document.createElement('script');
   tag.src = "https://www.youtube.com/iframe_api";
  var firstScriptTag = document.getElementsByTagName('script')[0];
   firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

   var player;
   function onYouTubeIframeAPIReady() {

  player = new YT.Player('player', {
    height: '390',
    width: '640',
    videoId: 'rL--g6q7zu4',
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    }
  });
}

function onPlayerReady(event) {
}


function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.ENDED) {
    alert('finish');
  }
}
</script>

追記(2015/10/26): Youtube の Webページヘ内で再生させるのに、上のコードでは、Internet Explorer では表示されないことが、最近になって分かった。現在では Yutube が iframe を使ったコードを提供しており、更に便利にWebページ内に埋め込むことが可能になっている。方法など詳細については、別に記録したいと思う。
 現在は、新しい埋め込みコードで、表示している。



2012年9月30日

隠居のパソコン備忘録: ブログ(MT4)に、動画(You tube)をアップロードする


 ブログに動画を載せたい場合がある。Jazz street での楽団演奏の録画や水鳥の動きなどである。このごろのデジタルカメラは、動画撮影機能がついているのが普通である。
 今年も開催された和泉の国ジャズストリートでは、Nikon Coolpix P510 で、SLMC(泉陽高校軽音楽部)の演奏を録画した。設定は、初期設定のままである。初期設定では、HD 1080p(1920x1080) となっている。それ以外のファイルに関する情報は取説には記載されていない。
 デジカメで撮った写真や動画は、Picasa3 でパソコンにとり込む。取り込んだファイルの拡張子は、写真の場合 .jpg であるが、動画は .MOV となっている。ファイルの種類は、Quick Time ムービーとなっている。
 これでは、Microsoft のWindows Media Player では再生できない。Quick Time ムービーは、Apple が開発したソフトだから無理もない。撮影した動画をタイトルをつけたりして編集するのは、フリーのソフト(Windows XP service pack2 に付属している)である moviemaker を使っている。
 デジカメで撮った動画の最初は、Canon IXY900IS であった。これでの動画の形式は、Microsoft の AVI ファイルだったので、moviemaker で編集することができた
どうやら、Canon と Nikon はこんなところでも張り合っているらしい。

 使い慣れた moviemaker で編集するためには、MOV を AVI に形式変換しなければならない。今年の冬に、ハシビロガモの集団採餌行動を NikonD7000 で録画編集した時には、ファイルの形式変換は、AVS video converter を使用した。今回も、AVI に形式変換し、moviemaker に読み込んで見ると、次のようなメッセージが出てファイルを読み込めない。
ファイルの再生に必要なコーデックがコンピュータにインストールされていないため、aviファイルを読み込むことができません。必要なコーデックを既にダウンロードしてインストールしている場合は、Windows ムービー メーカーを閉じてから再度開始し、もう一度ファイルを読み込んでください。

 必要なコーデックというのを探すソフトを導入して、探してみたが要領がよく分からない。AVS video converter の最新バージョンをインストールして動かそうとしたが、確か以前は無料(お試し期間中?)だったのが有料になっている。しかも、結構高い。それで、試行錯誤してみると FREESTUDIO というパッケージの中に、Free AVI Video Converterというソフトがあるのがわかった。
 このソフトで MOV を AVI に形式変換してみると、今度は moviemaker で変換後のファイルを読み込むことができた。タイトルをつけるなどの簡単な編集をして、レンタルサーバーにアップロードし、ブログ本文からリンクすると再生するようになった。

 和泉の国ジャズストリートでのランブリンフェローズという楽団のデキシーを、Sanyo(現在、この会社名はなくなっている) の PCM レコーダーで録音した .mp3ファイル を Yahoo Media Playerを使ってブログに記載しようと再調査していると、Yahoo Media Player は Yahoo webplayer と名前が変わって、動画(You Tube)も簡単にアップロードできるようになっている。
アップロードの方法は簡単である。Yahoo が提供するつぎのような JavaScript を、ブログのHTML <head> 部に置く。Instruction では、<body>部の下部におけとあるが、Movable Typeでは、 上手くいかなかった。 
<script type="text/javascript"> var YWPParams = { theme: "silver" }; </script>
<script type="text/javascript" src="http://webplayer.yahooapis.com/player.js"></script> 
上の行は、ブログで表示するときに、枠を黒ではなく、灰色にするために入れたスクリプトである。なくても問題はない。
 YouTubeの動画をブログで表示するには、次のようなコードを挿入したい場所に、記述するだけでよい。
<a href="http://www.youtube.com/watch?v=elg9OjDJIB8&feature=youtu.be"><img alt="DSCN0641.jpg" src="http://n-shuhei.net/atelier/photo_senboku/DSCN0641.jpg" width="200" height="133" /></a>

イメージファイル部分をテキストにしても問題はない。イメージ写真にすると、真ん中に再生アイコンが表示される。

 ブログ上にYouTube の動画を表示するには、もちろんYouTube に動画をアップロードしておく必要がある。今まで、YouTube に動画をアップロードした経験はないが、それほど難しい作業ではない。
  YouTube にアクセスすると YouTube は Google の一部になっているので、すでにGoogle にアカウント(普通は、gmailのアドレスがID )を持っておれば、マイチャネル(登録チャネル)が表示されるようだ。

upload00.JPG


 右上のツールタグの【アップロード】をクリックすると下のスクリーンショットようになる。
upload01.JPG

 PC にある動画(この場合、hashibiro.wmv というファイル:形式は、ほとんどOK のようだ)を選んで、アップロードすると、下のような画面となり、YouTube のファイル名(URL)が右上に表示される。
upload03.JPG
 下の Sample画像は、ブログの中に、次のように上のURL 組み込んで表記している。
<a href="http://www.youtube.com/watch?v=v4kdwpAnmGM&feature=context-gau"><img alt="ハシビロガモ動画" src="http://n-shuhei.net/atelier/photo_birds/120208_0181-thumb-150x100.jpg" width="200" height="133" /></a>

Sample 動画(YouTube)
ハシビロガモ動画

2012年8月26日

隠居のパソコン備忘録: Google Maps API JS V3 での地図でマーカー地点をズームイン・アウトする


 V3 にバージョンアップした Google Maps JS API で旅行地図などを作成することをいろいろとトライしている。
 当サイト内の Studio YAMAKO のオーナーは、お住まいの横浜近郊はもちろんのこと、海外をも含めて様々なところを旅行され、それぞれの地点での綺麗な写真をブログにUPされている。
 旅行先を一枚の地図で表示することは無理なので、海外旅行については、その都度旅行先の地図を作って表示させてもらっているが、国内旅行については、年度別に、一枚の日本地図にプロットしている。(例:2011年旅行地図) だが、これでは地図が大まかすぎて、訪問先地点毎に、コントロールを使って、ズームインと地図の移動をする必要がある。

 それで何か良いサンプルはないかと探ってみると、Google Maps API links に、V2 で作成されたMike Williams' tutorial の The Basics - Part 3: Loading the data from an XML file with added "Zoom To, Zoom In, Zoom Out links in infowindow V3 に書き換えたサンプルコードが見つかった。
 2011年旅行地図では、隠居のパソコン備忘録: Google Maps API JS V3 でXML ファイルを読み込むに記録したサンプルコードを使った。今回のコードは、そのコードに、Zoom in・out の機能を付け加えたものである。呼び込んでくる XML ファイルは、同じ形式である。サンプルコードには、XML ファイルに zoom というタグが組み込まれていたが、なしでも機能するようである。
 2012年の旅行地図では、このコードを使った。見た目は、2011年旅行地図と変わらないが、地点をクリックして出てくる吹きだし(infowindow)に、表示される Zoom to [+] [-] をクリックすると、その地点が地図の中心となる。 さらに、[+] をクリックしていくと、Zoom が一段ずつUPする。2011年旅行地図に比べれば、少し改良された。
 下は、そのコードである。


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
    <title>Google Maps Javascript API v3 Example: Loading the data from an XML</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript" src="http://xxxxxxxxxx/JSlibrary/downloadxml.js"></script>
<style type="text/css">
html, body { height: 100%; } 
</style>
<script type="text/javascript"> 
//<![CDATA[
      // this variable will collect the html which will eventually be placed in the side_bar 
      var side_bar_html = ""; 
      // arrays to hold copies of the markers and html used by the side_bar 
      // because the function closure trick doesnt work there 
      var gmarkers = []; 
     // global "map" variable
      var map = null;
// A function to create the marker and set up the event window function 
function createMarker(latlng, name, html, zoom) {
    var contentString = html;
    // add the zoom links
    contentString += '<br><a  href="javascript:map.setCenter(new google.maps.LatLng('+latlng.toUrlValue(6)+')); map.setZoom('+zoom+');">Zoom To</a>';
    contentString += ' - <a  href="javascript:map.setCenter(new google.maps.LatLng('+latlng.toUrlValue(6)+')); map.setZoom(parseInt(map.getZoom())+1);">[+]</a>';
    contentString += ' - <a  href="javascript:map.setCenter(new google.maps.LatLng('+latlng.toUrlValue(6)+')); map.setZoom(parseInt(map.getZoom())-1);">[-]</a>';

    var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        icon: new google.maps.MarkerImage('http://labs.google.com/ridefinder/images/mm_20_blue.png'),         
        zIndex: Math.round(latlng.lat()*-100000)<<5
        });
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
        });
    marker.MyZoom = zoom;
    // save the info we need to use later for the side_bar
    gmarkers.push(marker);
    // add a line to the side_bar html
    side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><br>';
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
  google.maps.event.trigger(gmarkers[i], "click");
}
function initialize() {
  // create the map
  var myOptions = {
    zoom: 8,
    center: new google.maps.LatLng(34.717876,137.851424),
    mapTypeControl: true,
    mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  map = new google.maps.Map(document.getElementById("map_canvas"),
                                myOptions);
  google.maps.event.addListener(map, 'click', function() {
        infowindow.close();
        });
      // Read the data from example.xml
      downloadUrl("http://xxxxxxxx/xxxxxxxxx/xxxx/V3_yamako_2012.xml", function(doc) {
        var xmlDoc = xmlParse(doc);
        var markers = xmlDoc.documentElement.getElementsByTagName("marker");
        for (var i = 0; i < markers.length; i++) {
          // obtain the attribues of each marker
          var lat = parseFloat(markers[i].getAttribute("lat"));
          var lng = parseFloat(markers[i].getAttribute("lng"));
          var point = new google.maps.LatLng(lat,lng);
          var html = markers[i].getAttribute("html");
          var label = markers[i].getAttribute("label");
          var zoom = markers[i].getAttribute("zoom");
          if (!zoom) zoom = 15;
          // create the marker
          var marker = createMarker(point,label,html,zoom);
        }
        // put the assembled side_bar_html contents into the side_bar div
        document.getElementById("side_bar").innerHTML = side_bar_html;
      });
    }

var infowindow = new google.maps.InfoWindow(
  { 
//    size: new google.maps.Size(150,100),
    maxWidth: 450
  });

    // This Javascript is based on code provided by the
    // Community Church Javascript Team
    // http://www.bisphamchurch.org.uk/   
    // http://econym.org.uk/gmap/
    // from the v2 tutorial page at:
    // http://econym.org.uk/gmap/basic3.htm 
//]]>

</script> 
  </head> 

<body style="margin:0px; padding:0px;" onload="initialize()"> 
    <!-- you can use tables or divs for the overall layout --> 
     <table border="1"> 
<tr>
<td bgcolor="#FFFFCC" align="center" colspan="2"><font color="#000000"><strong><big>Yamako 国内旅行地図:2012年
</big></strong><br /></font></td></tr>      
<tr> 
        <td> 
           <div id="map_canvas" style="width: 780px; height: 820px"></div> 
        </td> 
        <td width = 220 valign="top"  bgcolor="#ffffe0" style="text-decoration: underline; color: #000000; font-size: small;" >
           <div id="side_bar"></div> 
        </td> 
      </tr> 
    </table> 


    <noscript><p><b>JavaScript must be enabled in order for you to use Google Maps.</b> 
      However, it seems JavaScript is either disabled or not supported by your browser. 
      To view Google Maps, enable JavaScript by changing your browser options, and then 
      try again.</p>
    </noscript> 

  </body> 
</html> 


2012年7月29日

隠居のパソコン備忘録: Google Maps API V3 で Polyline を描く


 自作地図を作成するのに便利していた Google Maps API のバージョンが、 V2 から V3 に大幅に変更され、来年5月には V2 で作成した地図が動かなくなりそうだということは、隠居のパソコン備忘録:Google Maps API V3 で旅行地図を作成するで、記録した。

 Studio YAMAKO のオーナーが、この2~3年に海外旅行した時の地図には、旅程を表す Polyline を表示している。これも、V3 になると書き換えなければならない。V2 では、XML ファイルに訪れた地点の経度・緯度を書き込んでおくと Polyline を描いてくれる sample code があったが、V3 では、そのような sample code は、ヒットしなかった。
 【Google Maps JavaScript API V3の使い方】というサイトに、【ポリラインの表示】というぺーじがあり、polyline を描くための訪問地点の経度・緯度を Javascript に直接記入する方法が紹介されていた。このサンプル・コードを参考に、先日記録した【Google Maps API JS V3 でXML ファイルを読み込む】の Javascript コードに追加してみると上手く動くことが分かった。老人の備忘録として、「トルコ周遊8日間の旅」の地図のコードを記録としておきたい。下のコードの青字部分が Polyline 表示のために追加した部分である。
 訪問地点の経度・緯度は、V2 のときに使っていた XML ファイルの中からコピーしてきた。記述する部分は少ないので、XML ファイルにする必要性はあまりない。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
    <title>Google Maps Javascript API v3 Example: Loading the data from an XML</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript" src="http://n-shuhei.net/JSlibrary/downloadxml.js"></script>

<style type="text/css">
html, body { height: 100%; } 
</style>

<script type="text/javascript"> 
//<![CDATA[
// this variable will collect the html which will eventually be placed in the side_bar 
      var side_bar_html = ""; 

      // arrays to hold copies of the markers and html used by the side_bar 
     // because the function closure trick doesnt work there 

      var gmarkers = []; 

     // global "map" variable
      var map = null;

// A function to create the marker and set up the event window function 
function createMarker(latlng, name, html) {
    var contentString = html;
    var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        zIndex: Math.round(latlng.lat()*-100000)<<5
        });

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
        });

    // save the info we need to use later for the side_bar
    gmarkers.push(marker);

    // add a line to the side_bar html
    side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><br>';
}

// This function picks up the click and opens the corresponding info window
function myclick(i) {
  google.maps.event.trigger(gmarkers[i], "click");
}

function initialize() {
  // create the map
  var myOptions = {
    zoom: 6,
    center: new google.maps.LatLng(39.436193,29.86908),
    mapTypeControl: true,
    mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }

  map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

  google.maps.event.addListener(map, 'click', function() {
        infowindow.close();
        });

      // Read the data from hachi.xml
      downloadUrl("V3_maps_Turkey.xml", function(doc) {
        var xmlDoc = xmlParse(doc);
        var markers = xmlDoc.documentElement.getElementsByTagName("marker");
        for (var i = 0; i < markers.length; i++) {

          // obtain the attribues of each marker
          var lat = parseFloat(markers[i].getAttribute("lat"));
          var lng = parseFloat(markers[i].getAttribute("lng"));
          var point = new google.maps.LatLng(lat,lng);
          var html = markers[i].getAttribute("html");
          var label = markers[i].getAttribute("label");

          // create the marker
          var marker = createMarker(point,label,html);
        }

      // put the assembled side_bar_html contents into the side_bar div
        document.getElementById("side_bar").innerHTML = side_bar_html;

// Polyline 表示の追加 ここから     
    var drivePlan = [
      new google.maps.LatLng(40.010787, 26.279297),
      new google.maps.LatLng(39.317035, 26.703644),
      new google.maps.LatLng(37.947176, 27.342567),
      new google.maps.LatLng(37.914409, 29.120979),
      new google.maps.LatLng(37.882441, 32.485199),
      new google.maps.LatLng(38.376115, 34.002686),
      new google.maps.LatLng(38.533127, 34.433899),
      new google.maps.LatLng(38.627063, 34.720917),
      new google.maps.LatLng(38.772019, 35.490303),
      new google.maps.LatLng(41.013066, 28.975067),
      new google.maps.LatLng(40.010787, 26.279297)
    ];
    var drivePath = new google.maps.Polyline({
      path: drivePlan,
      strokeColor: "#FF0000",
      strokeOpacity: 1.0,
      strokeWeight: 2
    });
      drivePath.setMap(map);
// ここまで 

      });
    }

var infowindow = new google.maps.InfoWindow(
  { 
//    size:  new google.maps.Size(200,50)
  });

//]]>

</script> 
  </head> 

<body style="margin:0px; padding:0px;" onload="initialize()"> 

<table border="1"> <tr>
<td bgcolor="#FFFFCC" align="center" colspan="2"><font color="#000000"><strong><big>「洞窟ホテルに泊まる!トルコハイライト周遊8日間」の旅</big></strong></font></td></tr>      
<tr><td> 
    <div id="map_canvas" style="width: 800px; height: 600px"></div> 
    </td> 
    <td width = 200 valign="top" bgcolor="#ffffcc" >
左の地図は、Google Mapsの機能を持っています。拡大・縮小・移動ができます。下の地名をクリックすると該当位置に吹き出しが出ます。吹き出しの中のリンクをクリックすると詳細地図あるいは関連投稿に飛びます。<br /><br />
    <div id="side_bar"style="text-decoration: underline; color: #000000; font-size: small;"></div> 
    </td></tr></table> 

    <noscript><p><b>JavaScript must be enabled in order for you to use Google Maps.</b> 
      However, it seems JavaScript is either disabled or not supported by your browser. 
      To view Google Maps, enable JavaScript by changing your browser options, and then 
      try again.</p>
    </noscript> 

  </body> 
</html> 


2012年7月21日

隠居のパソコン備忘録: Google Maps API JS V3 でXML ファイルを読み込む

 
 自作地図を作成するのに便利していた Google Maps API のバージョンが、 V2 から V3 に大幅に変更され、来年5月には V2 で作成した地図が動かなくなりそうだということは、隠居のパソコン備忘録:Google Maps API V3 で旅行地図を作成するで、記録した。

  V2 で作成した多くの地図では、外部ファイルである XML ファイルを読み込んでマーカを立てる地点やマーカをクリックすると出てくる吹きだしの中に、リンク先などの情報を表示していた。年間の旅行先などマーカが順次増える場合には、XML ファイルに経度・緯度や必要なリンクを書き足すだけでいいので便利をしていた。
 今まで V2 で作成してきた地図を V3 にバージョンアップして XML ファイルを読み込むためのサンプル・コードを探し回したが、適切なコードが見つからなかった。一から、作成する能力はからきしない。途方に暮れて、上のブログに記録した前回の方法で、XML ファイルを使わず直接 JavaScript に書き込むことも挑戦しかけたが途方も無い作業のようなのでやめて、今までの XML ファイルが使えそうなサンプル・コードで、再度粘ってみることにした。

 拝借したサンプル・コードは、上のブログに記録した前回の方法ときにも拝借した、【Using the Google Maps API v3】 というページにある【lLoading the data from an XML file translated to v3】のソース・コードである。
 V3 のGoogle Maps API にXML ファイルを読み込む方法は、多くの場合、前回に lightbox 2.51 の導入で紹介した JavaScript のライブラリー jQuery が使われている。拝借したサンプル・コードでは、jQuery ではなく、downloadxml.js というライブラリーが使われている。どうも、jQuery の方が本流らしいが、私にとっては、V3 で今までの XML ファイルが使えるサンプル・コードの方がありがたい。
 一週間以上かなりの時間を使って粘った甲斐があって、下のようなコードで XML が読み込めるようになった。
 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
    <title>Google Maps Javascript API v3 Example: Loading the data from an XML</title> 
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript" src="http://n-shuhei.net/XXXXX/XXX/XXXXX/downloadxml.js"></script>

<style type="text/css">
html, body { height: 100%; } 
</style>

<script type="text/javascript"> 
//<![CDATA[
// this variable will collect the html which will eventually be placed in the side_bar 
      var side_bar_html = ""; 

      // arrays to hold copies of the markers and html used by the side_bar 
     // because the function closure trick doesnt work there 

      var gmarkers = []; 

     // global "map" variable
      var map = null;

// A function to create the marker and set up the event window function 
function createMarker(latlng, name, html) {
    var contentString = html;
    var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        zIndex: Math.round(latlng.lat()*-100000)<<5
        });

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
        });

    // save the info we need to use later for the side_bar
    gmarkers.push(marker);

    // add a line to the side_bar html
    side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><br>';
}

// This function picks up the click and opens the corresponding info window
function myclick(i) {
  google.maps.event.trigger(gmarkers[i], "click");
}

function initialize() {
  // create the map
  var myOptions = {
    zoom: 12,
    center: new google.maps.LatLng(35.377556,134.534862),
    mapTypeControl: true,
    mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }

  map = new google.maps.Map(document.getElementById("map_canvas"),
                                myOptions);

  google.maps.event.addListener(map, 'click', function() {
        infowindow.close();
        });

      // Read the data from hachi.xml
      downloadUrl("hachi.xml", function(doc) {
        var xmlDoc = xmlParse(doc);
        var markers = xmlDoc.documentElement.getElementsByTagName("marker");
        for (var i = 0; i < markers.length; i++) {

          // obtain the attribues of each marker
          var lat = parseFloat(markers[i].getAttribute("lat"));
          var lng = parseFloat(markers[i].getAttribute("lng"));
          var point = new google.maps.LatLng(lat,lng);
          var html = markers[i].getAttribute("html");
          var label = markers[i].getAttribute("label");

          // create the marker
          var marker = createMarker(point,label,html);
        }

        // put the assembled side_bar_html contents into the side_bar div
        document.getElementById("side_bar").innerHTML = side_bar_html;
      });
    }

var infowindow = new google.maps.InfoWindow(
  { 
//    size:  new google.maps.Size(200,50)
  });

    // This Javascript is based on code provided by the
    // Community Church Javascript Team
    // http://www.bisphamchurch.org.uk/   
    // http://econym.org.uk/gmap/
    // from the v2 tutorial page at:
    // http://econym.org.uk/gmap/basic3.htm 

//]]>

</script> 
  </head> 

<body style="margin:0px; padding:0px;" onload="initialize()"> 

    <!-- you can use tables or divs for the overall layout --> 
    <table border="1"> 
<tr>
<td bgcolor="#FFFFCC" align="center" colspan="2"><font color="#000000"><strong><big>ハチ高原近辺私的観光地図</big></strong><br /></font></td></tr>      
<tr> 
        <td> 
           <div id="map_canvas" style="width: 800px; height: 600px"></div> 
        </td> 
        <td width = 200 valign="top"  bgcolor="#ffffe0" style="text-decoration: underline; color: #000000; font-size: small;" >
<!--<td valign="top" style="width:150px; text-decoration: underline; color: #4444ff;">-->
           <div id="side_bar"></div> 
        </td> 
      </tr> 
    </table> 

    <noscript><p><b>JavaScript must be enabled in order for you to use Google Maps.</b> 
      However, it seems JavaScript is either disabled or not supported by your browser. 
      To view Google Maps, enable JavaScript by changing your browser options, and then 
      try again.</p>
    </noscript> 

  </body> 
</html> 
サンプル地図

 試行錯誤は、拡張子の前につける . (ピリオド)が抜けていたり、ファイルのアップロード先を間違ったりなど実に単純なミスの連続であった。
 とくに、Geekなぺーじの【Google MAPS JavaScript APIでのデバッグ】にも書かれているように、日本語コードで最後までつまづいた。V2 のときには、Shift-JIS でも OK だったXML ファイルが、UTF-8 でないとエラーを起こすというより、全く読んでくれない。
 この試行錯誤のお陰で、Google Maps API について、少し理解が深まったが、JavaScript に十分な知識がない老人にはやっぱり難解な世界である。中断していた JavaScript の学習も再開せねばと思うが、なにしろやりたいことが多すぎる。
 来年5月までに、順次 V2 の地図を V3 にしていくつもりである。

2012年7月17日

隠居のパソコン備忘録: jQuery lightbox (同一画面上に拡大写真をかっこよく表示する)を導入する


 先日来、個人的地図作成サービス Google Maps API V3 を学習してきた。このサービスを使って、加賀地方旅行地図を作成したことを記録している。このサービスを学習中に、jQuery という JavaScript のライブラリーが、いろいろな JavaScript ソフトを導入するときに使われていることが分かった。

 この JavaScript ライブラリーの jQuery を使って、拡大写真の表示を同一画面上に表示する JavaScript の lightbox が新しいバージョン(Version 2.51)になっていることも分かった。(従来のライブラリーは、prototype.js )
 これを、先の加賀地方旅行地図での写真表示に使って見ることにした。
サンプル画像

 インストールについては、Lightbox2 のページから、Lightboxv2.51 をダウンロードし、PC のどこかのフォルダ(例えば、lightbox2.51 を作成し )に解凍する。
  上のページの【How to use】を参考に、ブログをアップロードしているサーバーに新しいフォルダー(例えば、lightbox2.51 )を作成し、ファイル転送ソフト(私の場合、FFFTP )を使ってサーバーにアップロードする。解凍したフォルダーをまるままアップロードしても問題は無いと思う。ただ、サーバーに余裕がない場合には、先ほどのページを参考に、必要なファイルのみをアップロードしたほうが良い。このあたりは、【アクアラングウエスタンver.9.2】というページを参照させてもらった。

 このようにして、lightbox2 が動作するのを確認の上で、次のようなカスタマイズを行った。
  • 初期値では、写真を表示する画面の背景色は黒であるが、これを好きな色に変えるには、lightbox.css の冒頭にある次の青字部分を変更する。
    /* line 6, ../sass/lightbox.sass */
    #lightboxOverlay {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 9999;
      background-color: #408080; 元は、black;
      filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=85);
      opacity: 0.85;
      display: none;
    }
    


  • 写真ページを閉じるボタンを close.png(close.png) から、自作の closelabel.gif(closelabel.gif) に変更した。変更は、lightbox.js の50行目あたりある次の青字部分を変更した。なお、赤字部分で示したように、imageのありかは、絶対パスで書いておいたほうが無難なようである。
      LightboxOptions = (function() {
        function LightboxOptions() {
          this.fileLoadingImage = 'http://n-shuhei.net/xxxxx/Jquery2.51/images/loading.gif';
          this.fileCloseImage = 'http://n-shuhei.net/xxxxx/Jquery2.51/images/closelabel.gif';
          this.resizeDuration = 700;
          this.fadeDuration = 500;
          this.labelImage = " photo  "; 元は、Image 
          this.labelOf = "of";
        }
    


 この Jquery lightbox2 を、Movable Type 4 で作ったブログの写真(多分1000枚以上ある)の表示に適用した。(従来は、prototype.js の lightbox 2.0 ) Movable Type に適用するには、テンプレートのヘッダーにある lightbox 2.0 の Javascript 表示を lightbox 2.51 のコードに置き換えるだけで、すべての写真表示が新しい lightbox2.51 の表示となるので極めて楽ちんである。(つまり、HTML でのコードは、 lightbox 2.0 でも lightbox2.51 でも同じである。)

2012年7月12日

隠居のパソコン備忘録:Google Maps API V3 で旅行地図を作成する


 Google が提供する自分好みの地図を作成できるサービス Maps JavaScript API の バージョンUP(V2 ⇒ V3)が2009年5月に発表されている。最近になって、V2 は廃止され、V3 がリコメンドされていることを知った。プロ向けと思われる【Google Deveopers】というサイトにある【Google Maps JavaScript API V3】 のページには、次のような記載がある。
注: このページに記載されている Google Maps JavaScript API バージョン 3 は、正式な JavaScript API となりました。JavaScript API バージョン 2 は、Google の廃止ポリシーにより正式に廃止されました。アップデート、拡張された新しいバージョンに、コードを移行することをおすすめします。

さらに、Deprecated(非推奨という意味か?) と記されている V2 のページには、次の記載がある。
Note: The Google Maps JavaScript API Version 2 has been officially deprecated as of May 19, 2010. The V2 API will continue to work until May 19, 2013. We encourage you to migrate your code to version 3 of the Maps JavaScript API.

なんと来年5月には、動かなくなりそうだ。私のサイトには、V2 作成した地図を数多く掲載している。慌てて、V3 の学習を始めた。V2 に比べると大幅に変更になっている。サンプルコードをパクリして、作成してきた地図を、基本的な知識が乏しい老人が、今までのコードをバージョンアップするのは至難の技に思われる。それで、今までのコードのバージョンアップは諦めて、ネットで紹介してくれているV3 版のサンプルコードを頼りに、新しく書いて見ることにした。

 ようやくたどり着いたのが、7月10日に収載した【加賀地方旅行地図】である。この地図を例として、作成方法を備忘録として記録しておきたい。

 やりたいことは、
  1. 旅行した地域をカバーする地図を表示する。
  2. 観光した地点にマーカーを立てる。
  3. マーカーをクリックすると吹きだし(infowindow) がでる。
  4. infowindow には、撮った写真の表示や観光地点のURL へリンクを表示できるようにする。
  5. 地図の枠外に訪問地点名を表示し、クリックすると地図上の該当マーカに、infowindow が表示するようにする。
  6. できあがった地図は、私のブログ(Movable Type 4)で、エントリーとして機能するようにする。

 このような地図は、Google Maps API V2 では、できていたのであるが、V3 では初めての試みである。
 ささやかな JavaScript の知識か持たない私の技術では、これを一から作成することは困難である。Sample コードをネットで探し回したところ、【Using the Google Maps API v3】 というページに、要望にあったコード(Mike Williams' tutorial The Basics - Part 2: Adding a clickable sidebar translated to v3)を見つけることができた。Mike Williams' tutorial は、V2 の地図を作成するときにほとんど丸写しに近く参照させていただいたサイトである。残念ながら、このサイトでの V3 によるサンプルコードはない。このV2 でのコードをどなたかが、V3 に translate されたコードである。

 このサンプルコードをもとに、作成した旅行地図 のコードは、以下のとおりである。
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
<title>Google Maps Javascript API v3 Example: Adding a clickable sidebar</title><script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<style type="text/css">
  html, body { height: 100%; } 
</style>

<script type="text/javascript"> 

//<![CDATA[

    var side_bar_html = ""; 
    var gmarkers = []; 
    var map = null;

function initialize() {
    var myOptions = {
    zoom: 10,
    center: new google.maps.LatLng(36.338359,136.446075),
    mapTypeControl: true,
    mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }

  map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  google.maps.event.addListener(map, 'click', function() {
   infowindow.close();
   });

  var point = new google.maps.LatLng(36.056871,136.355095);
  var marker = createMarker(point,"永平寺","<a href='./travel-eiheiji.html' target='_blank'>永平寺 写真サムネイル画像</a>")

  var point = new google.maps.LatLng(36.237628,136.125712);
  var marker = createMarker(point,"東尋坊","<a href='./travel-tojinbo.html' target='_blank'>東尋坊  写真サムネイル画像</a>")

  var point = new google.maps.LatLng(36.228506,136.175559);
  var marker = createMarker(point," そば処あおき","<a href='http://fukui-shop.net/soba/208449/' target='_blank'>URL: そば処あおき</a>")

  var point = new google.maps.LatLng(36.243996,136.374664);
  var marker = createMarker(point," 山中温泉","<a href='./travel-yamanaka.html' target='_blank'>山中温泉 写真サムネイル画像</a><br /><a href='http://yoshinoyairokuen.jp/viewpoint/map_aki_fuyu.pdf' target='_blank'>PDF: 山中温泉案内図</a><br /><a href='http://www.daiwaresort.co.jp/kajikasou/' target='_blank'>URL: 河鹿荘ロイヤルホテル</a>")

  var point = new google.maps.LatLng(36.322871,136.294327);
  var marker = createMarker(point," 鴨池観察館","<a href='./travel-kamoike.html' target='_blank'>鴨池観察館 写真サムネイル画像</a><br /><a href='http://park15.wakwak.com/~kamoike/' target='_blank'>URL: 鴨池観察館</a>")

  var point = new google.maps.LatLng(36.56098,136.658249);
  var marker = createMarker(point," 金沢21世紀美術館","<a href='./travel-21seiki.html' target='_blank'>金沢21世紀美術館 写真サムネイル画像</a><br /><a href='http://ja.wikipedia.org/wiki/%E9%87%91%E6%B2%A221%E4%B8%96%E7%B4%80%E7%BE%8E%E8%A1%93%E9%A4%A8' target='_blank'>URL: 金沢21世紀美術館</a>")

  document.getElementById("side_bar").innerHTML = side_bar_html;
}
var infowindow = new google.maps.InfoWindow(
  { 
    size: new google.maps.Size(150,50)
  });

function myclick(i) {
  google.maps.event.trigger(gmarkers[i], "click");
}

function createMarker(latlng, name, html) {
    var contentString = html;
    var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        zIndex: Math.round(latlng.lat()*-100000)<<5
        });

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
        });

    gmarkers.push(marker);

   side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a>  ';
}
 
//]]>

</script> 

</head> 

<body style="margin:0px; padding:0px;" onload="initialize()"> 
     <table border="1"> 
      <tr> 
        <td> 
           <div id="map_canvas" style="width: 720px; height: 650px"></div> 
        </td>
      </tr><tr>   
        <td valign="top" style="width:720px; font-size:small; color: #4444ff;"><strong>観光場所:クリックすると該当場所に吹きだしがでます。</strong><div id="side_bar"> </div> 
        </td> 
      </tr> 
    </table> 

    <noscript><p><b>JavaScript must be enabled in order for you to use Google Maps.</b> 
      However, it seems JavaScript is either disabled or not supported by your browser. 
      To view Google Maps, enable JavaScript by changing your browser options, and then 
      try again.</p>
    </noscript> 

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script> 
 </body> 
</html> 


 このコードについて、若干補足して記録しておきたい。
  • マーカーを立てる経度・緯度の数値は、「Google マップ 地図検索」で検索した地点に出てくるマーカを右クリックすると出てくるポップアップにある「この場所について」をクリックすると 検索文字を入れるボックスに表示される。
  • infowindow の中に表示するURLや写真ページヘのリンクは、HTMLコードを書く要領で書けば良い。
  • side-bar は サンプルコードでは 地図の右枠外であるが、HTMLコードでテーブルを作成する要領で(</tr><tr> ) 行を変えれば、地図の下枠外に表示できる。


 なお、写真の表示に、ブログで使ってきた lightbox (当ブログで使っている写真表示手法)のコードを書いても、Google Maps API というJavaScript の中で、lightbox というJavaScript を使うことになり、うまく表示されない。もう少し勉強すればできるのかもしれないが、次善の策として、ワンクッションおいてサムネイル画像を表示することにした。なお、lightbox については、今回の学習中に、jQuery.js という JavaScript のライブラリーを使ったバージョンが出ていることが分かった。(従来は、prototype.js を使っていた)
jQuery 版lightbox については、稿を改めて記録したい。

 作成した地図を、MT4 のブログにエントリーするには、<iframe>をつかって次のようにブログの中に取り込めば良い。
<iframe src="http://n-shuhei.net/atelier/maps/travel-kaga.html" width="740" height="700" scrolling="NO" frameborder="0"></iframe>


 なお、ブログの右フレームに載せている地図は、Google Maps API V2 で作成しているが、ここでは、xml ファイルを使っている地図が多い。V3 でのXML との連携についても学習しなければならない。おかげで、当分痴呆にはならないだろうが。

2011年2月19日

隠居の探鳥ウォーク:泉北ニュータウン栂地区で観察した水鳥をプロットしてみた

 【隠居のGoogle Maps: (続)Google Maps API を使って野鳥出現地点をカスタム・マーカーでプロットする】で記録した方法で、泉北ニュータウンなどで観察・撮りためた水鳥の撮影地点をプロットしてみた。(一部は除く) これは、【野鳥の写真サムネイル】の【大阪泉州の池・川などで撮った写真】に、【撮影地点地図】というボタンを置いて、これをクリックすると Google Map の形式で観察地点にカルガモ(水鳥を代表させている)マークが表示されるようにした。     

 先のエントリーでも記録しているが、この地図を作成するには、以下の項目を実施しなければならない。結構時間がかかる作業であるが、記録としては面白いのではないかと思っている。
  1. 掲載する写真を集めた Picasa のWeb Album を作成する。
    アップロードする写真は【野鳥の写真サムネイル】を参考にしながら、ソースからすでにレンタル・サーバーにアップしている写真のファイル名を選択する。
  2. Google Maps API の JavaScript に呼びこんでくる XML file を作成する。ここで必要なタグは、10進法の経度(lat)・緯度(ing)、表示する写真のファイル名(html)、場所名(label) である。
    私の場合、XMLnotepad でもととなるファイルを開き、新しい名前で保存する。
  3. 経度・緯度は、Web Album の写真の情報をC&P する。経度・緯度情報がない場合は、Google Map で撮影地点情報を取得し、Web Album にある該当写真に10進法の経度・緯度の場所情報を付加する。
  4. 表示する写真のファイル名は、【野鳥の写真サムネイル】のソースからC&P する。また、label の地名も【野鳥の写真サムネイル】のソースから取得する。
  5. 【撮影地点地図】となる Google Maps API のJavaScript を含むHTMLを作成する。(もととなるソースを新しい名前で保存する。) ソースをいじる箇所は、
    • 地図のタイトル名
    • 立てるマーカーの画像ファイル名
    • 地図の中心とする経度・緯度と縮尺
    • 呼びこんでくる XML file名
  6. 【野鳥の写真サムネイル】ソースHTMLに、地図を表示させるボタンを設置するコードを挿入する。
  7. このボタンをクリックすると、新しいウィンドウを開き【撮影地点地図】を表示する JavaScript を作成する。このJavaScript は、 ひとつの地図につきひとつの JavaScript が必要であり、【野鳥の写真サムネイル】ソースHTMLと同じフォルダー(サーバー)におき、【野鳥の写真サムネイル】ソースHTMLの<head> 部に JS file を呼びこんでくるコードを挿入する。


 このようにして作成した撮影地点地図は、水鳥だけでなく、【カワラヒワ】 【ホオジロ】 【ツグミ】 でも作成した。随時、時間を見て追加していく予定である。また、従来の地図に新しく撮った写真地点も追加する予定である。

2011年1月29日

隠居のGoogle Maps: (続)Google Maps API を使って野鳥出現地点をカスタム・マーカーでプロットする

 先にエントリーした【隠居のGoogle Maps: Picasa を使って野鳥出現地点をプロットする】の方法では、プロットする地点を追加しようとすると、そこで記録した 4. 以降のかなり厄介な作業を、一からやり直さなければならないことが分かった。これでは不便である。

 それで、もとに戻って、自由度の高い Google Maps API を応用することを再度試みることにした。右フレームにおいている【京都・滋賀・奈良近辺私的観光地図】のような方式に変えれば、XML ファイルに位置情報と写真へのリンクを追加するだけで、プロット地点を増やしていけることが分かっている。ただ、先のエントリーのように、プロット地点に立てるマーカーを鳥のアイコンにする方法が、乏しい知識ではなかなかわからなかった。マーカーを任意のものに変える方法は色々と紹介されているが、外部のXML ファイルを呼びこんでくるようなコードは紹介されていなかった。

 いろいろとトライしているうちに、どうやら使えそうにコードが、Google から紹介されているのを見つけた。このコードを応用して追加・訂正することで カスタム・マーカー ができたので、忘れないうちに記録しておくことにした。

 仕樣は【野鳥の写真サムネイル】の種別名欄に、【撮影地点地図】 というボタンを置き、これをクリックすると新しい画面が開き、小鳥のマーカーが地図上にプロットされる。このマーカーか、右フレームの地名をクリックすると、その地点で撮影した野鳥の写真が吹きだしに表示される仕組みである。
そして、ここが肝心なのだが、新しい写真とその撮影地点は、XML ファイルで容易に追加することができるようにしたことである。カワラヒワの撮影地点地図を例にとって、以下、順を追って記録する。

  1. まず、XML ファイルを呼びこんで地図にマーカーを立てるもととなる html コード(Google Maps API の JavaScript が含まれている。)を用意する。このオリジナルは、Google Maps API Tutorial からいただいたもので、【道東ドライブ:Google Maps API Traial_3】のエントリーで紹介している。
    このHTML コードの中で、使用している JavaScript は、以下のようなものである。
    
    <script type="text/javascript">
        //<![CDATA[
    
        if (GBrowserIsCompatible()) {
          // this variable will collect the html which will eventualkly be placed in the side_bar
          var side_bar_html = "";
        
          // arrays to hold copies of the markers and html used by the side_bar
          // because the function closure trick doesnt work there
          var gmarkers = [];
          var htmls = [];
          var i = 0;
    
          // A function to create the marker and set up the event window
          function createMarker(point,name,html) {
            var marker = new GMarker(point);
            GEvent.addListener(marker, "click", function() {
              marker.openInfoWindowHtml(html);
            });
            // save the info we need to use later for the side_bar
            gmarkers[i] = marker;
            htmls[i] = html;
            // add a line to the side_bar html
            side_bar_html += '<a href="javascript:myclick(' + i + ')">' + name + '</a><br>';
            i++;
            return marker;
          }
    
          // This function picks up the click and opens the corresponding info window
          function myclick(i) {
            gmarkers[i].openInfoWindowHtml(htmls[i]);
          }
    
    
          // create the map
          var map = new GMap2(document.getElementById("map"));
          map.addControl(new GLargeMapControl());
          map.addControl(new GMapTypeControl());
          map.setCenter(new GLatLng( 43.745305,144.431763), 9);
    
    
          // Read the data from example.xml
          var request = GXmlHttp.create();
          request.open("GET", "http://n-shuhei.net/xxxx/xxx/trial.xml", true);
          request.onreadystatechange = function() {
            if (request.readyState == 4) {
              var xmlDoc = request.responseXML;
              // obtain the array of markers and loop through it
              var markers = xmlDoc.documentElement.getElementsByTagName("marker");
              
              for (var i = 0; i < markers.length; i++) {
                // obtain the attribues of each marker
                var lat = parseFloat(markers[i].getAttribute("lat"));
                var lng = parseFloat(markers[i].getAttribute("lng"));
                var point = new GLatLng(lat,lng);
                var html = markers[i].getAttribute("html");
                var label = markers[i].getAttribute("label");
                // create the marker
                var marker = createMarker(point,label,html);
                map.addOverlay(marker);
              }
              // put the assembled side_bar_html contents into the side_bar div
              document.getElementById("side_bar").innerHTML = side_bar_html;
            }
          }
          request.send(null);
        }
    
        else {
          alert("Sorry, the Google Maps API is not compatible with this browser");
        }
    
        //]]>
        </script>
    

    上のコードの赤字部分を、下のコードと置き換えれば、標準マーカーを小鳥のアイコン(この場合、カワラヒワのアイコン)で表示できることが分かった。この時、用いるイメージは、必ずしも .png ファイルだけではなく .gif ファイル、.jpg ファイルでもOKである。
    
    // Create birds marker icon
           var birdIcon = new GIcon(G_DEFAULT_ICON);
           birdIcon.image = "http://n-shuhei.net/Libraly/Icon/birds/kawarahiwa.gif";
           birdIcon.iconSize = new GSize(20, 34);
                    
    // Set up our GMarkerOptions object
           markerOptions = { icon:birdIcon };
    
    // A function to create the marker and set up the event window
          function createMarker(point,name,html) {
          var marker = new GMarker(point,birdIcon);
    

  2. このコードを入れた JavaScript は以下のようになる。
    
    <script type="text/javascript">
        //<![CDATA[
    
        if (GBrowserIsCompatible()) {
    // this variable will collect the html which will eventualkly be placed in the side_bar
        var side_bar_html = "";
        
    // arrays to hold copies of the markers and html used by the side_bar
    // because the function closure trick doesnt work there
        var gmarkers = [];
        var htmls = [];
        var i = 0;
    
    // Create birds marker icon
        var birdIcon = new GIcon(G_DEFAULT_ICON);
         birdIcon.image = "http://n-shuhei.net/xxxxxxx/Icon/birds/kawarahiwa.gif";
           birdIcon.iconSize = new GSize(20, 34);
                    
    // Set up our GMarkerOptions object
           markerOptions = { icon:birdIcon };
    
    // A function to create the marker and set up the event window
        function createMarker(point,name,html) {
        var marker = new GMarker(point,birdIcon);
         GEvent.addListener(marker, "click", function() {
          marker.openInfoWindowHtml(html);
            });
    
    // save the info we need to use later for the side_bar
        gmarkers[i] = marker;
        htmls[i] = html;
    
    // add a line to the side_bar html
        side_bar_html += '<a href="javascript:myclick(' + i + ')">' + name + '</a><br>';
            i++;
        return marker;
          }
    
    // This function picks up the click and opens the corresponding info window
        function myclick(i) {
            gmarkers[i].openInfoWindowHtml(htmls[i]);
          }
    
    // create the map
          var map = new GMap2(document.getElementById("map"));
          map.addControl(new GLargeMapControl());
          map.addControl(new GMapTypeControl());
          map.setCenter(new GLatLng(34.48675,135.490608),14);
    
    // Read the data from example.xml
          var request = GXmlHttp.create();
          request.open("GET", "http://n-shuhei.net/atelier/xxxxx/xxxxxxxx/API_kawarahiwa.xml", true);
          request.onreadystatechange = function() {
          if (request.readyState == 4) {
          var xmlDoc = request.responseXML;
    // obtain the array of markers and loop through it
          var markers = xmlDoc.documentElement.getElementsByTagName("marker");
              
          for (var i = 0; i < markers.length; i++) {
    // obtain the attribues of each marker
                var lat = parseFloat(markers[i].getAttribute("lat"));
                var lng = parseFloat(markers[i].getAttribute("lng"));
                var point = new GLatLng(lat,lng);
                var html = markers[i].getAttribute("html");
                var label = markers[i].getAttribute("label");
    // create the marker
                var marker = createMarker(point,label,html);
                map.addOverlay(marker);
              }
    
    // put the assembled side_bar_html contents into the side_bar div
              document.getElementById("side_bar").innerHTML = side_bar_html;
            }
          }
          request.send(null);
        }
    
        else {
          alert("Sorry, the Google Maps API is not compatible with this browser");
        }
    
        //]]>
        </script>
    

  3. 上の JavaScript で青色文字で示したのは、以下の3箇所である。
    • マーカーに使うアイコン
    • 地図の中心となる経度・緯度と地図の縮尺の大きさ
    • 呼びこんでくる XML ファイル
    この3箇所は作成する地図ごとに書き換えねばならない。
  4. 呼びこんでくる XML ファイルには、
    • マーカーを立てる位置(経度・緯度)
    • リンクする写真のサーバー内のありか
    • ラベル(地図の右フレームに表示する地名)
    をリストする必要がある。このファイルの編集には、私は XML Notepad というソフトを使っている。duplicate 機能があるので楽ちんである。
  5. マーカーを立てる経度・緯度の値は10進法でなければならない。これは、【隠居のGoogle Maps: Picasa を使って野鳥出現地点をプロットする】で記載した方法(2. および 3.)のように Picasa のウェブアルバムで行うと、アルバムにある写真をクリックすると、右フレームに10進法の経度・緯度が表示される。
     Picasa の写真プロパティで表示される EXIF では、表示は 60進法になっている。 Picasa のウェブアルバムの助けを借りるのは、そのためである。
  6. リンクする写真のありか(例えば、 http://n-shuhei.net/xxxx/xxxx/xxxxx.jpg )は、【野鳥の写真サムネイル】で、種別表示をして写真サムネイルの下に表示されているリンク先のエントリーのソースからコピーしてくる。これが、少々煩わしいが、仕方ない。なにかいい方法がないか考えてみたい。
     このようにして作成した小鳥マーカーが表示された地図のサンプルは、以下である。
     Example:
  7. 【野鳥の写真サムネイル】の種別名欄に、【撮影地点地図】 というボタンを置き、これをクリックするとこの地図が、新しい Window で開くようにするために、下のような別の JavaScript を使っている。
    // POPUP Window
    
    function open_win_kawarahiwa(){
    window.open("http://n-shuhei.net/atelier/xxxxx/xxxxxxxxx/API_kawarahiwa_m.htm","","
    menubar=no,toolbar=no,location=yes,status=yes,scrollbars=yes,resizable=yes,
    width=950,height=600,left=50,top=50"); }

    この JavaScripr ファイルを、【野鳥の写真サムネイル】の、種別表示をしているページのHTML の <head> 部分に次のように読み込み、
    <script type="text/javascript" src="http://n-shuhei.net/atelier/xxxxx/xxxxxxxxx/pup_kawarahiwa.js"></script>
    、【撮影地点地図】 というボタンをクリックすると地図が新しい window に開くように、<body> 部の適切な位置に、次のコードを置いた。
    <input type="button" value="撮影地点地図" onClick="open_win_kawarahiwa()">

  8. 作成した地図は、まだカワラヒワだけであるが、順次時間を見て増やしていきたいと思う。泉北ニュータウンのごく限られた地域ではあるが、記録としては面白いのではないかと思っている。
     カワラヒワのプロット地図