隠居のGoogle Maps: (続)Google Maps API を使って野鳥出現地点をカスタム・マーカーでプロットする
それで、もとに戻って、自由度の高い Google Maps API を応用することを再度試みることにした。右フレームにおいている【京都・滋賀・奈良近辺私的観光地図】のような方式に変えれば、XML ファイルに位置情報と写真へのリンクを追加するだけで、プロット地点を増やしていけることが分かっている。ただ、先のエントリーのように、プロット地点に立てるマーカーを鳥のアイコンにする方法が、乏しい知識ではなかなかわからなかった。マーカーを任意のものに変える方法は色々と紹介されているが、外部のXML ファイルを呼びこんでくるようなコードは紹介されていなかった。
いろいろとトライしているうちに、どうやら使えそうにコードが、Google から紹介されているのを見つけた。このコードを応用して追加・訂正することで カスタム・マーカー ができたので、忘れないうちに記録しておくことにした。
仕樣は【野鳥の写真サムネイル】の種別名欄に、【撮影地点地図】 というボタンを置き、これをクリックすると新しい画面が開き、小鳥のマーカーが地図上にプロットされる。このマーカーか、右フレームの地名をクリックすると、その地点で撮影した野鳥の写真が吹きだしに表示される仕組みである。
そして、ここが肝心なのだが、新しい写真とその撮影地点は、XML ファイルで容易に追加することができるようにしたことである。カワラヒワの撮影地点地図を例にとって、以下、順を追って記録する。
- まず、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);
- このコードを入れた 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>
- 上の JavaScript で青色文字で示したのは、以下の3箇所である。
- マーカーに使うアイコン
- 地図の中心となる経度・緯度と地図の縮尺の大きさ
- 呼びこんでくる XML ファイル
- 呼びこんでくる XML ファイルには、
- マーカーを立てる位置(経度・緯度)
- リンクする写真のサーバー内のありか
- ラベル(地図の右フレームに表示する地名)
- マーカーを立てる経度・緯度の値は10進法でなければならない。これは、【隠居のGoogle Maps: Picasa を使って野鳥出現地点をプロットする】で記載した方法(2. および 3.)のように Picasa のウェブアルバムで行うと、アルバムにある写真をクリックすると、右フレームに10進法の経度・緯度が表示される。
Picasa の写真プロパティで表示される EXIF では、表示は 60進法になっている。 Picasa のウェブアルバムの助けを借りるのは、そのためである。 - リンクする写真のありか(例えば、 http://n-shuhei.net/xxxx/xxxx/xxxxx.jpg )は、【野鳥の写真サムネイル】で、種別表示をして写真サムネイルの下に表示されているリンク先のエントリーのソースからコピーしてくる。これが、少々煩わしいが、仕方ない。なにかいい方法がないか考えてみたい。
このようにして作成した小鳥マーカーが表示された地図のサンプルは、以下である。
Example: - 【野鳥の写真サムネイル】の種別名欄に、【撮影地点地図】 というボタンを置き、これをクリックするとこの地図が、新しい 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> 部分に次のように読み込み、
、【撮影地点地図】 というボタンをクリックすると地図が新しい window に開くように、<body> 部の適切な位置に、次のコードを置いた。<script type="text/javascript" src="http://n-shuhei.net/atelier/xxxxx/xxxxxxxxx/pup_kawarahiwa.js"></script>
<input type="button" value="撮影地点地図" onClick="open_win_kawarahiwa()">
- 作成した地図は、まだカワラヒワだけであるが、順次時間を見て増やしていきたいと思う。泉北ニュータウンのごく限られた地域ではあるが、記録としては面白いのではないかと思っている。
カワラヒワのプロット地図