このブログを検索

大文字小文字を区別する 正規表現

Atelierで“W3Schools”が含まれるブログ記事

2010年6月24日

隠居のGoogle Maps API: データ用XML ファイルの編集

 友人や私が旅行に行ったところなどをプロットする地図を、Google Maps API を使って作成しブログに埋め込んでいる。
 作成する自分用の地図はいろいろとあるが、プロットする地点が少しずつ増えていく旅行地図--例えば、Studio YAMAKO 【国内旅行:2009】などでは、本体の Javascript はいじらずに、行った地点の経度・緯度などのデータを XML ファイルに追加して呼び込んでいる。

 ところがいつも使っているエディタの【秀丸】できちんと XML の文法に則ってファイルを作成しているはずなのに、Google Maps API が読み込んでくれない。原因を乏しい知識のなかでググって見たが、なかなか解決策が見当たらないまま1週間くらいが過ぎてしまった。ひょんなことから、完全な解決ではないが、原因がわかったので、この間に学習したことを備忘録として記録しておきたい。

 XML fileにエラーがある場合、Internet Explorer でこのファイルを開く(フォルダー⇒該当ファイルを右クリック⇒プログラムから開くで出るセレクトボックスから、Internet Explorer を指定する)と、次のようなメッセージがでて開けない。
Internet Explorer
XML_01.JPG
  Google Chromeでは、次のようなメッセージが出る。
Google Chrome
XML_02.JPG

ここで出てくるライン( line) とは、開始タグと終了タグで囲まれたテキストが行を表していると思われる。 それで推定すると、どうやら最後の行の外に、余計な何かが附加されているようである。

いつも使っているエディタの【秀丸】でXML fileを眺めつすがめつしてみたが、よくわからない。
【秀丸】XML_05.JPG
この表示の最後にある [EOF] は、End Of File のことであり、【秀丸】特有のものである。後で分かったことだが、この[EOF] が問題であった。

XML の文法が正しいかどうかは、W3CSchool のXML のセクションにある validator で確認できる。 この validator で【秀丸】で表示されるコードを確認すると no error と表示される。

XML file の中身は、Notepad でも確認できる。IE でエラーとなった XML file をNotepad で開いてみると、下のように【秀丸】の [EOF]部分が黒い四角形の文字となっている。Notepad で、この黒い四角形の文字を削除して保存して、IE で実行してみるとエラーは起こらない。
Notepad XML_07.JPG


 再度、"秀丸 EOF"でググってみると、【秀丸】への理解が十分でなかったことが判明した。【秀丸】の設定で、 [EOF] を保存しない、読み込むときに EOF制御文字を無視するとすると(【秀丸】で「その他」⇒「ファイルタイプ別の設定」⇒「保存の対象」「その他」「保存読み込み」で設定できる)、IE での展開でエラーは起こらなくなった。

 これらを調査するなかで、XML エディタとして【XML Notepad 2007】というユティリティがあることが分かった。今まで、XML file のエディタとしては便宜的に【秀丸】を使ってきたが、これが問題であった。まだ十分に理解出来ているとはいえないが、XML に特化した【XML Notepad 2007】を使うと下のスクリーンショットで分かるように非常に簡便となる。
 今後は、Google Maps API で使うXML file の作成は、このユティリティを使っていくつもりである。
【XML Notepad 2007】
XML_04.JPG

2010年1月29日

Google Maps API で旅行地図を作る:線画を描くなど

 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 の基本的なユティリティが解説されているので、理解を助けてくれる。

 今回作った地図は、次のような構成になっている。
  1. 中欧の全体地図: 訪問した都市に通常マークred-dot.pngが表示される。
    1. このマークをクリックするか、地図の右欄にある地名をクリックすると、吹き出しが表示される。
    2. 吹き出しの中に表示されている「詳細地図」をクリックすると市街地図にリンクする。
    3. 各都市間をブルーのラインで訪問順に結んでいる。
  2. 市街地図:初期に表示する地図のタイプを航空写真にしている。
    1. 地図の右欄にある場所のチェックボックスをクリックすると番号入りマークが表示される。
    2. 場所名の下の青字をクリックすると写真が lightbox 形式で表示される。
  3. いずれの地図にも、地図を拡大・縮小できるコントロール、地図のタイプを切り替えるボタン、地図の縮尺をあらわすスケールが表示されている。

   これらの地図は、上記に記したサイトからいただいてきたコードを猿まねで自分なりに修正したものである。
中欧の全体地図は、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&amp;v=2&amp;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 &lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/maps_heidelberg.htm' target='_blank'&gt;ハイデルベルク詳細地図&lt;/a&gt;&lt;br&gt;(2009/11/2)" label="ハイデルベルク" ></marker>
<marker lat="49.379691" lng="10.180206" html="Rothenburg &lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/maps_rothenburg.htm' target='_blank'&gt;ローテンブルク詳細地図&lt;/a&gt;&lt;br&gt;(2009/11/2)" label="ローテンブルク" ></marker>
<marker lat="47.680125" lng="10.900841" html="Wieskirche &lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/091124_001.jpg'  target='_blank'&gt;Photo:ヴィース教会&lt;/a&gt;&lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/091124_002.jpg'  target='_blank'&gt;Photo:ヴィース教会の内部&lt;/a&gt;&lt;br&gt;(2009/11/2)" label="ヴィース教会" ></marker>
<marker lat="47.546872" lng="10.739136" html="Hohenschwangau &lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/maps_Hohenschwangau.htm' target='_blank'&gt;ホーエンシュヴァンガウ詳細地図&lt;/a&gt;&lt;br&gt;(2009/11/2)" label="ホーエンシュヴァンガウ" ></marker>
<marker lat="49.014906" lng="12.104187" html="Regensburg &lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/maps_Hohenschwangau.htm' target='_blank'&gt;レーゲンスブルク詳細地図&lt;/a&gt;&lt;br&gt;(2009/11/2)" label="レーゲンスブルク" ></marker>
<marker lat="50.082701" lng="14.422302" html="Praha &lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/maps_Praha.htm' target='_blank'&gt;プラハ詳細地図&lt;/a&gt;&lt;br&gt;(2009/11/2)" label="プラハ" ></marker>
<marker lat="48.810481" lng="14.315529" html="Cesky Krumlov &lt;br&gt;詳細は、&lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/08_1653.php' target='_blank'&gt;中欧旅行 その8 チェスキー・クルムロフ&lt;/a&gt;で。&lt;br&gt;(2009/11/4)" label="チェスキー・クルムロフ" ></marker>
<marker lat="48.143182" lng="17.112579" html="Bratislava &lt;br&gt;詳細は、&lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/11_0858.php' target='_blank'&gt;中欧旅行 その9 ブラスチラバ&lt;/a&gt;で。&lt;br&gt;(2009/11/5)" label="ブラスチラバ" ></marker>
<marker lat="47.495864" lng="19.050293" html="Budapest &lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/maps_Butapest.htm' target='_blank'&gt;ブダペスト詳細地図&lt;/a&gt;&lt;br&gt;(2009/11/2)" label="ブダペスト" ></marker>
<marker lat="48.20926" lng="16.372633" html="Viena &lt;br&gt;&lt;a href='http://n-shuhei.net/studio_yamako/?????????/maps_Viena.htm' target='_blank'&gt;ウィーン詳細地図&lt;/a&gt;&lt;br&gt;(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&amp;v=2&amp;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)にすることと、番号入りのマークを表示することである。
 番号入りのマークを表示する方法については、以前のエントリーで記録している。
これだけのことをするために、基礎知識の少ない老人には、ずいぶん学習しなければならないことが多かった。痴呆予防には有効かもしれない。

 
Google Maps API徹底活用ガイド
稲葉 一浩
毎日コミュニケーションズ
売り上げランキング: 105350
おすすめ度の平均: 3.5
4 さらっと流しつつテンコ盛りの内容
3 前半は簡単。後半は難解。
4 Google Maps をゴリゴリいじってみたい人に


2008年8月 3日

隠居のお勉強:JavaScript(13) onerror

 梅雨明けから酷暑の日が続き、屋外での活動はほとんどできない。特に、ここ大阪堺市は全国的に見ても暑い都市で連日最高気温が35℃を超えている。老齢を自覚して、クーラーの効いた部屋で過ごすようにしている。

 幸いウェブを開いておれば退屈することはない。JavaScript の学習がおろそかになっていたので、例によって W3Schools の tutorial で再開することにした。今回は、前回に続いてエラー処理の script である。

 onerror イベントハンドラーは、エラーをキャッチしてメッセージを出す古くからの標準的な方法である。

 次はその使い方サンプルである。
<html>
<head>
<script type="text/javascript">
onerror=handleErr;
var txt="";

function handleErr(msg,url,l)
{
txt="There was an error on this page.\n\n";
txt+="Error: " + msg + "\n";
txt+="URL: " + url + "\n";
txt+="Line: " + l + "\n\n";
txt+="Click OK to continue.\n\n";
alert(txt);
return true;
}

function message()
{
adddlert("Welcome guest!");
}
</script>
</head>

<body>
<input type="button" value="View message" onclick="message()" />
</body>

</html>



上のスクリプトは、alert("Welcome guest!"); とすべきとろころが、adddlert("Welcome guest!"); となっているので、下のボタンをクリックするとスクリプトがエラーとなり、onerror イベントハンドラーが働き、エラーが表示される。



この間違ったスクリプトを訂正すると、"Welcome guest!" と本来のメッセージが表示され、エラーは表示されない。次のボタンをクリックしてみてください。



2008年7月27日

隠居のお勉強:JavaScript(12) throw

 MT のバージョンを 3.35 から 4.1 へアップグレードするのにずいぶん時間をとられて、続けていた JavaScript のお勉強がほったからしになっていた。
 過去の JavaSCript のエントリーを見直していると、 4.1 へアップグレードによってリンク切れを起こしていたり、必要なスクリプトがサーバーにアップされていなかったりしていた。それらを修復しながら復習することができた。

 W3School tutorial の続きで、今回は throw の勉強である。
  throw statement によって、例外処理ができる。前回の try....catch と一緒に使うと適切なエラー・メッセージによってプログラムを流すことができる。
 以下の例では、変数x に値を求め、x が 0 より小さかったり、10 より大きかったり、数字以外の文字がインプットされた場合に、それぞれにあったエラーを表示する。
 
<html>
<body>
<script type="text/javascript">
var x=prompt("Enter a number between 0 and 10:","");
try
{ 
if(x>10)
  {
  throw "Err1";
  }
else if(x<0)
  {
  throw "Err2";
  }
else if(isNaN(x))
  {
  throw "Err3";
  }
}
catch(er)
{
if(er=="Err1")
  {
  alert("Error! The value is too high");
  }
if(er=="Err2")
  {
  alert("Error! The value is too low");
  }
if(er=="Err3")
  {
  alert("Error! The value is not a number");
  }
}
</script>
</body>
</html>


 上の例を実行するボタンを作ってみた。Script は外部化し<head> 部で呼び出している。 

 

 ボタンをクリックしたときに、上の js を実行するためには、関数化しておかねばならない。作った関数は以下である。
// throwEx sample
function throwEx()
{
  ・
  ・
(上の青字部分)
  ・
  ・
}


これを<body> で実行するボタン(上のボタン)を置く、HTML は、次のコードである。
<input type="button" onclick="throwEx()" value="throw statement Sample" />


2008年4月28日

隠居のお勉強:JavaScript(11) try...catch

 サンデー毎日なのに結構なにやかやと時間をとられて、お勉強がすすんでいない。例によって、W3Schools の tutorial にしたがって、次のステップに進もうと思う。

 ネットでいろいろと調べてみると、try... catch という構文は、Ajaxでほぼ必須になっているらしい。私のJavaScript の勉強は、Web ページをもう少し動的にしたいという、だいそれた願望に基づいているから、Ajax に必須なら、特に力を入れて勉強したいと思う。

 try...catch の構文の文法は、次のように解釈できる。
try{エラーをキャッチしたいcodeの実行}
catch(err){エラーをキャッチしたときの処理内容}


 Script を書いていて、プログラムにバグがないかどうかを確認するときなどに使うらしい。エラーの内容を表示するようにしておくと、バグの箇所と特定するのに役に立つということである。本格的に JavaScript プログラムを書くことはまだまだ先のことであろうが、おぼえておきたい。

 W3Schools には、例示として次のようなコードが示されている。
<html>
<head>
<script type="text/javascript">
var txt=""
function message()
{
try
  {
  adddlert("Welcome guest!");
  }
catch(err)
  {
  txt="There was an error on this page.\n\n";
  txt+="Click OK to continue viewing this page,\n";
  txt+="or Cancel to return to the home page.\n\n";
  if(!confirm(txt))
    {
    document.location.href="http://www.w3schools.com/";
    }
  }
}
</script>
</head>

<body> <input type="button" value="View message" onclick="message()" /> </body>
</html>

 try ブロック部分の adddlert("Welcome guest!"); の adddlert は alert のミススペルでエラーとなるから、catch ブロックの処理を行って、confirm-box を表示させることになる。

 あまり意味はないが、テストのために上のコードを少しいじって、このエントリーに取り込んでみた。下のボタンをクリックしてみてください。 Confirm Box が出るはずです。

    
 なお、この JavaScript 部分を外部ファイル化し、テンプレートの head 部分に読み込んで使うことを試したがうまくいかなかったので、直接 head 部分に書き込んでいる。

2008年4月19日

隠居のお勉強:JavaScript(10) event

 ちょっとサボっていた W3Schools の JavaScript のお勉強を再開した。じつは順序に従って、for..in という構文の学習していたのだが、example の文法がよく理解できない。あとで学習する object のときにも出てくるようなので、スキップすることにした。 object がよく理解できていないことが原因のようなので、その学習の中で理解していくことにした。

 それで今回は、次のステップである event の勉強である。

 Web ページの全ての要素(element)は、JavaScript 関数(function) のトリガーであるイベント(event)となる。例えば、ボタン element の onClick event は、ボタンをクリックすると実行される関数を指示する場合に使用される。イベント(event)は、HTMLタグの中で定義する。

 event には次のようなものがある。
  • マウス・クリック
  • Web ページあるいはイメージのロード
  • Web ページ上のホットスポットにカーソルが乗る。
  • HTML form で input box が選択される。
  • HTML form をサブミットする。
  • 何らかのキーが叩かれる。

 event は通常、関数との組み合わせで使用される。関数は、event が発生する前には実行されない。

 例えば、 onClick event は次のように使われる。
Field1: <input type="text" id="field1" value="おはよう!!">
Field2: <input type="text" id="field2">
Click the button below to copy the content of Field1 to Field2.
<button onclick="document.getElementById('field2').value= document.getElementById('field1').value">Copy Text</button>

 このコードを実行すると次のようになる。Copy Text ボタンをクリックしてみてください。

Field1:
Field2:

Click the button below to copy the content of Field1 to Field2.


 JavaScript で認められている event の一覧を、英語であるが W3Schools から引用加工させていただいて、下のテーブルに記載した。
 詳細は、W3Schools の complete Event reference にある。それぞれの event の使い方を詳しく説明している。

   
Attribute The event occurs when...
onabort Loading of an image is interrupted
onblur An element loses focus
onchange The user changes the content of a field
onclick Mouse clicks an object
ondblclick Mouse double-clicks an object
onerror An error occurs when loading a document or an image
onfocus An element gets focus
onkeydown A keyboard key is pressed
onkeypress A keyboard key is pressed or held down
onkeyup A keyboard key is released
onload A page or an image is finished loading
onmousedown A mouse button is pressed
onmousemove The mouse is moved
onmouseout The mouse is moved off an element
onmouseover The mouse is moved over an element
onmouseup A mouse button is released
onreset The reset button is clicked
onresize A window or frame is resized
onselect Text is selected
onsubmit The submit button is clicked
onunload The user exits the page

2008年4月 7日

隠居のお勉強:JavaScript Basic (9) Break and Continue

 JavaScript の勉強が、1週間ほど空いているので再開することにした。

 W3Schools の次のレッスンは、Loop で使う break と continue である。

  • 二つの特殊なコマンド break, continue をloop の中で使うことができる。
    • break コマンドは、loop の途中である条件になれば、その loop を中止する。
    • 例を次に示す。
      <html>
      <body>
      <script type="text/javascript">
      var i=0;
      for (i=0;i<=10;i++)
      {
      if (i==3)
      {
      break;
      }
      document.write("The number is " + i);
      document.write("<br />");
      }
      </script>
      </body>
      </html>

    • 結果は次の通りになる。
      The number is 0
      The number is 1
      The number is 2

    • continue コマンドは、loop の途中である条件になる場合のみloop を実行しないが、loop は続ける。
    • 例を次に示す。
      <html>
      <body>
      <script type="text/javascript">
      var i=0
      for (i=0;i<=10;i++)
      {
      if (i==3)
      {
      continue;
      }
      document.write("The number is " + i);
      document.write("<br />");
      }
      </script>
      </body>
      </html>

    • 結果は次の通りになる。
      The number is 0
      The number is 1
      The number is 2
      The number is 4
      The number is 5
      The number is 6
      The number is 7
      The number is 8
      The number is 9
      The number is 10

 構文は理解できたが、どのような時に使われているのか分からない。

 なお、このようなエントリーを編集するときに、< や > を使う場合には、&lt; &gt; とエンコードしなければならないが、今回から HTML エンコードホームというサービスを使わせてもらうことにした。
 W3Schools などの example コードをこのページのエンコード前ボックスにコピペ(copy & paste)すれば、エンコードされた結果がエンコード後ボックスに表示されるので、これをエントリー編集画面にコピペすればよい。
 今までは、< などを一つずつ&lt; などと書き直していたのでずいぶん楽になった。
 今頃気がつくのは、老齢化現象の一つと思うが。

2008年3月31日

隠居の JavaScript :番号付きリストを降順にする。(追記)

 W3Schools JavaScript Tutorial の Loop の項まで学習して、Customaize History 履歴ページでのリスト番号を降順にする方法に使っている Expert が書いた次の JavaScript が少し理解できるようになったので、私の理解できた範囲でコメント文に記した。
<!--list descend-->
<script>
var o = document.getElementById("hoge");
//getElementById メソッドは指定ID(この場合:"hoge")のエレメント(この場合<ol>を指定する。
//"hoge"は、HTMLの<ol id="hoge"> というように指定している。
var max = o.childNodes.length;
//<ol id="hoge"> 要素内の子ノード(この場合、<li>..</li>)の数を変数 max に与える。参考:AllAbout JavaScript
for(var i = 0;i < max;i ++)
//隠居のお勉強:for loop の例
{
o.childNodes[i].value = max - i;
//子ノード<li>の i 番目に、(最大番号- i )を代入する。結果は、番号が降順になる。
}
</script> 


 なお、 Customaize History 履歴ページの番号降順設定は、上の JavaScript でInternetExplorer(IE) では上手くいっていたが、Mojilla 系の Firefox Netscape では番号が倍になり、原因が突き止められないまま放ってあった。
 今回改めて "childNodes.length" でネットサーチしてみると答えがあった。thescript.com というサイトのフォーラムによると、どうやら Mojilla 系では、 whitespace (空白スペース)をカウントの対象に入れるらしいことが分かった。
 そこで、Customaize History 履歴ページ(MovableType のインデックス・テンプレートで作成している)の編集画面で編集しやすくするために入れていた </li>....<li> の間の空白スペースを削除すると、Mojilla 系でも IE と同じように、綺麗な降順番号を表示するようになった。<li>..</li> のタグ・セット間に必ず空白スペースが入っていたので、偶然数字が倍の偶数になっていたらしい。

 この世界、学習すべきことは五万とある。死ぬまで退屈することはないだろう。

2008年3月30日

隠居のお勉強:JavaScript Basic (8) Loop

 W3Schools JavaScript Tutorial の第8回である。まだ、基礎部分を学習している。使わせてもらっている Expert が書かれた JavaScript を理解するには、まだ当分時間がかかりそうだが、少しずつ理解できる部分もでてきた。

 今回は Loop (ループ)である。ループには、For Loop While Loop がある。

  • for loop は、スクリプトを何回繰り返すかが分かる場合に使用される。
    • Example を次に示す。
      <html>
      <body>
      <script type="text/javascript">
      var i=0;
      for (i=0;i<=10;i++)
      {
      document.write("The number is " + i);
      document.write("<br />");
      }
      </script>
      </body>
      </html>
    • loop は、i=0 からスタートし、i が 10 以下の間、下のコード( document.write() )が繰り返される。i は1回繰り返されるたびに、1 付加される。結果は次のようになる。
      The number is 0
      The number is 1
      The number is 2
      The number is 3
      The number is 4
      The number is 5
      The number is 6
      The number is 7
      The number is 8
      The number is 9
      The number is 10


  • while loop は、特定の条件が true (真)である間ループする実行を求めるときに使われる。
    • Example を次に示す。
      <html>
      <body>
      <script type="text/javascript">
      var i=0;
      while (i<=10)
      {
      document.write("The number is " + i);
      document.write("<br />");
      i=i+1;
      }
      </script>
      </body>
      </html>
    • loop は、i が 10 以下の間、下のコード( document.write() )が繰り返される。結果は、for loop の場合と同じである。


  • do...while loop は、while loop の変種である。この loop は、常に code block を一度は実行する。それ以降は、特定の条件が true (真)である間実行をループする。
    • Example を次に示す。
      <html>
      <body>
      <script type="text/javascript">
      var i=0;
      do
      {
      document.write("The number is " + i);
      document.write("<br />");
      i=i+1;
      }
      while (i<0);
      </script>
      </body>
      </html>
    • 結果は、次の通りである。
      The number is 0

syntax は理解できたが、どのような場合に使われるかがよく分からない。

2008年3月28日

隠居のお勉強:JavaScript Basic (7) 関数

 全く自己満足の世界であるが、W3Schools での JavaScript Tutorial でお勉強を続けてみたい。

 今回は、[JS Functions]の項である。Function は、Example で既に使われているので、今回はおさらいである。
  • Function(関数)とは、イベントあるいは関数が呼び出されるときに実行される再使用可能なコードの集まりである。
    • おさらいのために、今回次のような学習のためのJavaScript を作成した。
    • ブログ・サーバーにおいた LinkButton.js という名前の js ファイル。
      //JavaScript Study Making Link Button
      function link_button()
      {
      var name=prompt("リンクする URL 名を入力ください。","URL");
      if (name!=null && name!="")
      {
      window.open(name);
      }
      }
    • この中で、prompt box に入力された URL を新しいウィンドウに開くという関数 link_button を設定している。
    • この関数を、ページを開いた時に呼び出すために、HTMLの <head> 部(MTのテンプレートで)においた。関数は、 <head> 部にも、 <body> 部にもおくことができるが、<head> 部におく方が賢明なようである。
    • <head> 部に関数を設定している js file を呼び出すためのHTML。<$MTBlogURL$>はMovableType のテンプレート・タグであり、私の場合、http://n-shuhei.net/blog/ を置換するタグである。
      <script type="text/javascript" src="<$MTBlogURL$>LinkButton.js"></script>
    • 呼び出した関数を実行するために、 <body> 部に関数 link_button() を実行させる次のような HTML を記述する。
      <input type="button" value="URL you want" onclick="link_button()" />

    • 右のボタンをクリックするとリンク先のURLを入力できる。  

    • 上の例は、arrgument (引数)がない場合の関数であるが、一般的には、次のような構文となる。
      function functionname(var1,var2,...,varX)
      {
      some code
      }
    • var1,var2 などは関数に取り込まれる変数または値である。 { と } は、関数の始めと終わりを示す。
    • var1,var2 などの引数がない場合にでも、関数名の後ろに () をつけなければならない。
    • 関数名は、小文字なければならない。JavaScript は大文字・小文字の区分が厳格である。


    • 関数ではまた、次のように関数から戻される値(戻り値)を特定する return statement が使われることがある。
      function prod(a,b)
      {
      x=a*b;
      return x;
      }
    • 上の関数を呼び出すときは、次のように2つのパラメータが必要である。
      product=prod(2,3);
    • 関数 prod() からの戻り値は 6 となるが、この値は product という変数で保存される。
    • 関数の中で宣言された変数は、その関数の中だけで使われるローカル変数となる。関数の外で宣言された変数は、グローバル変数と呼ばれ、宣言されたページのどの関数でも使用できる。ページが閉じられたときに消滅する。