Studio YAMAKO さんのオーナーが、昨秋、中欧(ドイツ・チェコ・スロバキア・ハンガリー・オーストリア)を旅行したときの写真をコメント付きで、12 回に分けて投稿されている。
これを題材に、
Google Maps API を使って、
旅行地図を作ってみた。今まで、何回か
同じような旅行地図を作成しているが、今回はいくつかの新しい試みをしてみたので、いままでに学習したことも含めて、備忘録として記録しておきたい。
Google Maps API を使って、Web ページ上に自作地図を埋め込むには、
- HTML(CSSを含む): 自分で Web ページが作れる。
- JavaScript: 簡単な文法が分かる。
- XML: タグの意味が分かるなど文法がわかる。
の知識が必要であるが、基本的な文法さえ知っておればなんとかなる。それ以上の細かいことは、ネット上で検索すれば教えてくれるサイトが沢山ある。どのサイトが親切かを知っている方が重要である。私は、英語のページであるが、
w3schools.com を重宝している。体系的によくまとめられており、独習にもってこいである。
また、Google Maps API でWeb ページ上に地図を埋め込むには、サンプル・コードがネット上で提供されているので、これを Copy&Paste して、自分用に修正し利用すればよい。詳細な部分は、理解しようとすると学習に時間がかかる。ただ、自分用に修正するときに、上のような基本的な知識は必要だろう。
サンプル・コードはいろいろなサイトで提供されているが、私は、これも英語のサイトであるが、
"Google Maps API Tutorial" のコードを主として参照させてもらっている。自分のやりたいことが、整理された形で提供されている。
今回、地図上に線を描くサンプル・コードは、XMLファイルを使いたいこともあって、このサイトのコードを自分なりに修正して使用した。
日本語のサイトでは、Ajax Tower の
「Google Maps入門」に多くのサンプル・コードがある。
書籍は、「Google Maps API 徹底活用ガイド」を購入した。Google Maps API の基本的なユティリティが解説されているので、理解を助けてくれる。
今回作った地図は、次のような構成になっている。
- 中欧の全体地図: 訪問した都市に通常マークが表示される。
- このマークをクリックするか、地図の右欄にある地名をクリックすると、吹き出しが表示される。
- 吹き出しの中に表示されている「詳細地図」をクリックすると市街地図にリンクする。
- 各都市間をブルーのラインで訪問順に結んでいる。
- 市街地図:初期に表示する地図のタイプを航空写真にしている。
- 地図の右欄にある場所のチェックボックスをクリックすると番号入りマークが表示される。
- 場所名の下の青字をクリックすると写真が lightbox 形式で表示される。
- いずれの地図にも、地図を拡大・縮小できるコントロール、地図のタイプを切り替えるボタン、地図の縮尺をあらわすスケールが表示されている。
これらの地図は、上記に記したサイトからいただいてきたコードを猿まねで自分なりに修正したものである。
中欧の全体地図は、HTML ファイルのなかにある Javascript で XMLファイルを呼び込んでいる。この Javascript の中で、Google Maps API が提供するユティリティが使われている。 具体的なコードを以下に示す。
全体地図用HTML(include Google Maps API JavaScript)
<!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>
<style type="text/css">
v\:* { behavior:url(#default#VML); }
</style>
<title>Google Maps</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=???????????-TOJLbO9UBLVgjJC7W8hRCNFlWI0Fg132ssdjgyNcr14mm9hSKsn5??????????????_Ypmz1A" charset="utf-8" type="text/javascript"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<!-- POPUP Window -->
<script type="text/javascript" src="http://n-shuhei.net/script/delcash.js"></script>
</head>
<body onunload="GUnload()">
<div align="center">
<table border="1" width="auto" cellspacing="0">
<thead><tr>
<td bgcolor="#FFFFCC" align="center" colspan="2"><font color="#000000"><strong><big>中欧(ドイツ・チェコ・スロバキア・ハンガリー・オーストリア)を巡る旅</big></strong><br /><small>Internet Explorer で問題が出る場合は、キャッシュを消去してください。<input type="button" value="消去方法" onClick="open_win()"></small></font></td></tr>
</thead>
<tbody>
<tr><td><div id="map" style="width: 760px; height: 500px"></div></td>
<td width ="160px" valign="top" style="color: #000000; font-size: small;" align="left">
左の地図は、Google Mapsの機能を持っています。拡大・縮小・移動ができます。下の地名をクリッ
クすると該当位置に吹き出しが出ます。吹き出しの中のリンクをクリックすると詳細地図あるいは
関連投稿に飛びます。<br /><br /><div id="side_bar"></div></td></tr>
</tbody>
</table>
</div>
<noscript><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.
</noscript>
<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.addControl(new GScaleControl());
map.setCenter(new GLatLng(48.810481,14.315529), 6);
// map.setMapType(G_HYBRID_MAP);
// Read the data from xml file
var request = GXmlHttp.create();
request.open("GET", "http://n-shuhei.net/????????/Polyline_ex_1.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;
// ========= Now process the polylines =====================
var lines = xmlDoc.documentElement.getElementsByTagName("line");
// read each line
for (var a = 0; a < lines.length; a++) {
// get any line attributes
var colour = lines[a].getAttribute("colour");
var width = parseFloat(lines[a].getAttribute("width"));
// read each point on that line
var points = lines[a].getElementsByTagName("point");
var pts = [];
for (var i = 0; i < points.length; i++) {
pts[i] = new GLatLng(parseFloat(points[i].getAttribute("lat")),
parseFloat(points[i].getAttribute("lng")));
}
map.addOverlay(new GPolyline(pts,colour,width));
}
// ===========================================================
}
}
request.send(null);
}
else {
alert("Sorry, the Google Maps API is not compatible with this browser");
}
// This Javascript is based on code provided by the
// Blackpool Community Church Javascript Team
// http://www.commchurch.freeserve.co.uk/
// http://www.econym.demon.co.uk/googlemaps/
//]]>
</script>
</body>
</html>
このコードでの学習した点は、114行目あたりの各都市間を訪問順に結んでいるブルーのライン(Google Maps API では、polyline という)を描くための Javascript 挿入することである。この polyline を描くのは、IE8 では次の処理をしなくてもいいらしいが、IE7 以下では、HTML 上部(head 部より前)に、
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
という記述が(斜め書き部分)必要であり、head 部分に次のスタイルを設定する必要がある。
<style type="text/css">
v\:* { behavior:url(#default#VML); }
</style>
呼び込んでくる XML ファイル
<?xml version="1.0" encoding="Shift_JIS"?>
<markers>
<marker lat="49.40187" lng="8.680401" html="Heidelberg <br><a href='http://n-shuhei.net/studio_yamako/?????????/maps_heidelberg.htm' target='_blank'>ハイデルベルク詳細地図</a><br>(2009/11/2)" label="ハイデルベルク" ></marker>
<marker lat="49.379691" lng="10.180206" html="Rothenburg <br><a href='http://n-shuhei.net/studio_yamako/?????????/maps_rothenburg.htm' target='_blank'>ローテンブルク詳細地図</a><br>(2009/11/2)" label="ローテンブルク" ></marker>
<marker lat="47.680125" lng="10.900841" html="Wieskirche <br><a href='http://n-shuhei.net/studio_yamako/?????????/091124_001.jpg' target='_blank'>Photo:ヴィース教会</a><br><a href='http://n-shuhei.net/studio_yamako/?????????/091124_002.jpg' target='_blank'>Photo:ヴィース教会の内部</a><br>(2009/11/2)" label="ヴィース教会" ></marker>
<marker lat="47.546872" lng="10.739136" html="Hohenschwangau <br><a href='http://n-shuhei.net/studio_yamako/?????????/maps_Hohenschwangau.htm' target='_blank'>ホーエンシュヴァンガウ詳細地図</a><br>(2009/11/2)" label="ホーエンシュヴァンガウ" ></marker>
<marker lat="49.014906" lng="12.104187" html="Regensburg <br><a href='http://n-shuhei.net/studio_yamako/?????????/maps_Hohenschwangau.htm' target='_blank'>レーゲンスブルク詳細地図</a><br>(2009/11/2)" label="レーゲンスブルク" ></marker>
<marker lat="50.082701" lng="14.422302" html="Praha <br><a href='http://n-shuhei.net/studio_yamako/?????????/maps_Praha.htm' target='_blank'>プラハ詳細地図</a><br>(2009/11/2)" label="プラハ" ></marker>
<marker lat="48.810481" lng="14.315529" html="Cesky Krumlov <br>詳細は、<br><a href='http://n-shuhei.net/studio_yamako/?????????/08_1653.php' target='_blank'>中欧旅行 その8 チェスキー・クルムロフ</a>で。<br>(2009/11/4)" label="チェスキー・クルムロフ" ></marker>
<marker lat="48.143182" lng="17.112579" html="Bratislava <br>詳細は、<br><a href='http://n-shuhei.net/studio_yamako/?????????/11_0858.php' target='_blank'>中欧旅行 その9 ブラスチラバ</a>で。<br>(2009/11/5)" label="ブラスチラバ" ></marker>
<marker lat="47.495864" lng="19.050293" html="Budapest <br><a href='http://n-shuhei.net/studio_yamako/?????????/maps_Butapest.htm' target='_blank'>ブダペスト詳細地図</a><br>(2009/11/2)" label="ブダペスト" ></marker>
<marker lat="48.20926" lng="16.372633" html="Viena <br><a href='http://n-shuhei.net/studio_yamako/?????????/maps_Viena.htm' target='_blank'>ウィーン詳細地図</a><br>(2009/11/6)" label="ウィーン" ></marker>
<line colour="#0000ff" width="4" html="You clicked the red polyline">
<point lat="50.107368" lng="8.686066" /> <!--フランクフルト-->
<point lat="49.40187" lng="8.680401" /><!--ハイデルベルク-->
<point lat="49.379691" lng="10.180206" /><!--ローテンブルク-->
<point lat="47.680125" lng="10.900841" /><!--ヴィース教会-->
<point lat="47.546872" lng="10.739136" /><!--ホーエンシュヴァンガウ-->
<point lat="49.014906" lng="12.104187" /><!--レーゲンスブルク-->
<point lat="50.082701" lng="14.422302" /><!--プラハ-->
<point lat="48.810481" lng="14.315529" /><!--チェスキー・クルムロフ-->
<point lat="50.082701" lng="14.422302" /><!--プラハ-->
<point lat="48.143182" lng="17.112579" /><!--ブラスチラバ-->
<point lat="47.495864" lng="19.050293" /><!--ブダペスト-->
<point lat="48.20926" lng="16.372633" /><!--ウィーン-->
<point lat="48.112933" lng="16.55777" /><!--ウィーン空港-->
</line>
</markers>
市街地図(例として、プラハ市街図)のHTML(include Google Maps API JavaScript)は、つぎのようなコードである。ここでは、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" >
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" href="http://n-shuhei.net/litebox/???/lightbox.css" type="text/css" media="screen"/>
<script type="text/javascript" src="http://n-shuhei.net/litebox/???//prototype.lite.js"></script>
<script type="text/javascript" src="http://n-shuhei.net/litebox/???/moo.fx.js"></script>
<script type="text/javascript" src="http://n-shuhei.net/litebox/???/litebox-1.0.js" charset="utf-8"></script>
<title>Google Maps JavaScript API map_13</title>
<script src="http://maps.google.co.jp/maps?file=api&v=2&key=ABQIAAAA_--TOJLbO9UBLVgjJC7W8hRCNFlWI0Fg????????????
mm9hSKsn5IFaeCnFgl????????????" charset="utf-8" type="text/javascript"></script>
</head>
<body onload="initLightbox()">
<div align="center">
<table width="auto" border="1" bgcolor="#FFFFCC">
<thead ><tr><td id="th1" colspan="2" align="middle" ><big><strong>プラハ<strong></big></td></tr></thead>
<tbody align="left">
<tr><td>
<div id="map" style="width:730px; height:530px"></div>
</td><td width ="210px" valign="top" style="text-decoration: color: #000000; font-size: small;">左の地図は、Google Mapsの機能を持っています。拡大・縮小・移動ができます。
下のチェックボックスをチェックすると該当位置にマークが立ちます。また、青文字をクリックすると写真がでてきます。<br/><input type="checkbox" name="cb1" onClick="checkbox1clicked()">
1. プラハ城<br /> <a href="http://n-shuhei.net/studio_yamako/????????????/091130_008.jpg" title="プラハ城からの眺め" rel="lightbox[os]">プラハ城からの眺め</a><br />
<input type="checkbox" name="cb2" onclick="checkbox2clicked()"> 2. 聖ヴィート教会<br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091130_003.jpg" title="プラハ城 聖ヴィート教会" rel="lightbox[os]">聖ヴィート教会</a><br />
; <a href="http://n-shuhei.net/studio_yamako/????????????/091130_004.jpg" title="ミュシャのステンドグラス(部分)" rel="lightbox[os]">ミュシャのステンドグラス</a><br />
<a href="http://n-shuhei.net/studio_yamako/????????????/091130_005.jpg" title="聖ヴィート教会の祭壇" rel="lightbox[os]">聖ヴィート教会の祭壇</a><br />
<a href="http://n-shuhei.net/studio_yamako/????????????/091130_006.jpg" title="聖ヴィート教会前景" rel="lightbox[os]">聖ヴィート教会前景</a><br/>
<input type="checkbox" name="cb3" onclick="checkbox3clicked()"> 3. 聖イジー教会<br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091130_007.jpg" title=""聖イジー教会と修道院 rel="lightbox[os]">聖イジー教会と修道院</a><br />
<input type="checkbox" name="cb4" onclick="checkbox4clicked()"> 4. カレル橋<br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091130_009.jpg" title="カレル橋 水害の跡" rel="lightbox[os]">カレル橋 水害の跡</a><br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091130_010.jpg" title="カレル橋" rel="lightbox[os]">カレル橋</a><br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091130_011.jpg" title="カレル橋の聖像" rel="lightbox[os]">カレル橋の聖像</a><br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_003.jpg" title="モルダウ川河畔" rel="lightbox[os]">モルダウ川河畔</a><br />
<input type="checkbox" name="cb5" onclick="checkbox5clicked()"> 5. 旧市街入口<br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_004.jpg" title="旧市街入口" rel="lightbox[os]">旧市街入口</a><br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_005.jpg" title="プラハ城を望む" rel="lightbox[os]">プラハ城を望む</a><br />
<input type="checkbox" name="cb6" onclick="checkbox6clicked()"> 6. 旧市街広場<br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_006.jpg" title="火薬塔" rel="lightbox[os]">火薬塔</a><br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_007.jpg" title="ティーン教会" rel="lightbox[os]">ティーン教会</a><br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_008.jpg" title="旧市庁舎の時計塔" rel="lightbox[os]">旧市庁舎の時計塔</a><br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_009.jpg" title="仕掛け時計" rel="lightbox[os]">仕掛け時計</a><br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_010.jpg" title="ヤン・フス像" rel="lightbox[os]">ヤン・フス像</a><br />
<input type="checkbox" name="cb7" onclick="checkbox7clicked()"> 7. レギー橋<br/>
<a href="http://n-shuhei.net/studio_yamako/????????????/091203_002.jpg" title="プラハ城を眺める" rel="lightbox[os]">プラハ城を眺める</a><br />
<br />参照記事:<a href="http://n-shuhei.net/studio_yamako/????????????/01_1623.php" target="_blank">中欧旅行 その6 プラハ(1)</a></td></tr></tbody></table></div>
<!-- 番号入りマーカーを表示する。-->
<script type="text/javascript">
//<![CDATA[
var map;
var marker1, marker2, marker3, marker4, marker5, marker6, marker7;
map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.addControl(new GScaleControl());
map.setCenter(new GLatLng(50.086473,14.410651),14);
map.setMapType(G_HYBRID_MAP);
var markerIcon1 = new GIcon();
markerIcon1.image = "http://n-shuhei.net/????????????/Markers/marker1.png";
// markerIcon1.shadow = "./img/shadow.png";
markerIcon1.iconSize = new GSize(35, 40);
// markerIcon1.shadowSize = new GSize(70, 56);
markerIcon1.iconAnchor = new GPoint(18, 40);
var markerIcon2 = new GIcon(markerIcon1, "http://n-shuhei.net/????????????/Markers/marker2.png");
var markerIcon3 = new GIcon(markerIcon1, "http://n-shuhei.net/????????????/Markers/marker3.png");
var markerIcon4 = new GIcon(markerIcon1, "http://n-shuhei.net/????????????/Markers/marker4.png");
var markerIcon5 = new GIcon(markerIcon1, "http://n-shuhei.net/????????????/Markers/marker5.png");
var markerIcon6 = new GIcon(markerIcon1, "http://n-shuhei.net/????????????/Markers/marker6.png");
var markerIcon7 = new GIcon(markerIcon1, "http://n-shuhei.net/????????????/Markers/marker7.png");
var opt1 = {icon:markerIcon1};
var opt2 = {icon:markerIcon2};
var opt3 = {icon:markerIcon3};
var opt4 = {icon:markerIcon4};
var opt5 = {icon:markerIcon5};
var opt6 = {icon:markerIcon6};
var opt7 = {icon:markerIcon7};
marker1 = new GMarker(new GLatLng(50.088814,14.395523), opt1);
marker2 = new GMarker(new GLatLng(50.090755,14.400759), opt2);
marker3 = new GMarker(new GLatLng(50.091023,14.402025), opt3);
marker4 = new GMarker(new GLatLng(50.086473,14.410651), opt4);
marker5 = new GMarker(new GLatLng(50.086129,14.413869), opt5);
marker6 = new GMarker(new GLatLng(50.087382,14.4208), opt6);
marker7 = new GMarker(new GLatLng(50.081186,14.410672), opt7);
var marker1_is_displayed = 0;
var marker2_is_displayed = 0;
var marker3_is_displayed = 0;
var marker4_is_displayed = 0;
var marker5_is_displayed = 0;
var marker6_is_displayed = 0;
var marker7_is_displayed = 0;
function checkbox1clicked() {
if (marker1_is_displayed == 0) {
map.addOverlay(marker1);
marker1_is_displayed = 1;
} else {
map.removeOverlay(marker1);
marker1_is_displayed = 0;
}
}
function checkbox2clicked() {
if (marker2_is_displayed == 0) {
map.addOverlay(marker2);
marker2_is_displayed = 1;
} else {
map.removeOverlay(marker2);
marker2_is_displayed = 0;
}
}
function checkbox3clicked() {
if (marker3_is_displayed == 0) {
map.addOverlay(marker3);
marker3_is_displayed = 1;
} else {
map.removeOverlay(marker3);
marker3_is_displayed = 0;
}
}
function checkbox4clicked() {
if (marker4_is_displayed == 0) {
map.addOverlay(marker4);
marker4_is_displayed = 1;
} else {
map.removeOverlay(marker4);
marker4_is_displayed = 0;
}
}
function checkbox5clicked() {
if (marker5_is_displayed == 0) {
map.addOverlay(marker5);
marker5_is_displayed = 1;
} else {
map.removeOverlay(marker5);
marker5_is_displayed = 0;
}
}
function checkbox6clicked() {
if (marker6_is_displayed == 0) {
map.addOverlay(marker6);
marker6_is_displayed = 1;
} else {
map.removeOverlay(marker6);
marker6_is_displayed = 0;
}
}
function checkbox7clicked() {
if (marker7_is_displayed == 0) {
map.addOverlay(marker7);
marker7_is_displayed = 1;
} else {
map.removeOverlay(marker7);
marker7_is_displayed = 0;
}
}
//]]>
</script>
</body>
</html>
この市街地図での学習点は、最初の表示を航空写真と地図の合成(HYBRID)にすることと、番号入りのマークを表示することである。
番号入りのマークを表示する方法については、
以前のエントリーで記録している。
これだけのことをするために、基礎知識の少ない老人には、ずいぶん学習しなければならないことが多かった。痴呆予防には有効かもしれない。
稲葉 一浩
毎日コミュニケーションズ
売り上げランキング: 105350
おすすめ度の平均:
さらっと流しつつテンコ盛りの内容
前半は簡単。後半は難解。
Google Maps をゴリゴリいじってみたい人に