京アニ「Kanon」舞台探訪

−横浜編 第15話−



舞台探訪者の心得
 ・探訪先では、地元の人の迷惑にならないように行動する。
 ・観光地でない場所や公共施設でない場所への探訪,撮影には十分注意する。
 ・探訪者の多い場所での行動は控えめに。


 舞編、エンディング。
 …なんですが、ほぼ学校内のシーンばかりのため、使われた横浜の背景は1枚だけ。

 第15話 「ひびわれた協奏曲〜concerto〜」




病室の窓から見える外の風景

 舞の回想シーンにて。
 場所は、奇しくも佐佑里さんの回想シーンから少し上ったところです。
 [地図で見てみる]

 舞編、感動のエンディング。

 そして…、内心誰しもが思ったこと。
 「今回も原因はオマエか、祐一!」

 前回へ<< >>次回へ


今回から探訪記で使用しているGoogle Maps APIのJavaScriptに手を加えてみたので、それを公開します。

1.データ部の作成
 今まではJavaScrptプログラムの中に直接、マップの位置データ,情報ウィンドウ内のコメント等を埋め込んでいましたが、今回作成効率を上げるために、データ部分を分離することにしました。
 分離するデータは、JSON形式とします。JSONと聞くと難しいような気がしますが、中身は単にJavaScriptの配列(構造体)記述と同じ形式です。シンプルでいながら、ハッシュ配列も使える強力な仕様です。
 「諸君、私はExcelが好きだ」、というわけで、まずExcelで元データを作ります。



 ここで、
 ・「中心座標」はマップの中心座標
・0〜10の番号の行が地図上のマーカの座標データとコメントのデータ
です。
 この位置座標は、いつものように↓のような自作地図を作って、得た座標データをコピー&ペーストして作っています。
 http://www7a.biglobe.ne.jp/~uso9000/hatena/ichi.htm

 次に、元データに対して文字列連結演算子を使って、表右側のようにJSON形式に変換します。この時、オートフィル機能を使ってお手軽に行を増やしてデータを作って行きます。
 変換後のJSON形式のデータが、↓です。

{ POINTS_NUM: 10,
cent_dat: [ { "x": "139.648225307464", "y": "35.4402972610952" } ],
point_dat: [
  { "x": "139.64529633522", "y": "35.4389926563963", "txt": "<table border=0><tr><td><img src='yokohama2_0s.jpg' /></td><td><div class='infowin'>商店街入り口(7年前)<br /><br /><a href='kanon-tv3-4.htm#txt0' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.648984372615", "y": "35.4407430508192", "txt": "<table border=0><tr><td><img src='yokohama4_1s.jpg' /></td><td><div class='infowin'>あゆと祐一、7年前<br /><br /><a href='kanon-tv3-4.htm#txt1' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.650030434131", "y": "35.4411079846871", "txt": "<table border=0><tr><td><img src='yokohama4_2s.jpg' /></td><td><div class='infowin'>祐一を待つあゆ(7年前)<br /><br /><a href='kanon-tv3-4.htm#txt2' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.645695984363", "y": "35.439115032275", "txt": "<table border=0><tr><td><img src='yokohama4_3s.jpg' /></td><td><div class='infowin'>商店街入り口(7年前)<br /><br /><a href='kanon-tv3-4.htm#txt3' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.649252593517", "y": "35.440850127395", "txt": "<table border=0><tr><td><img src='yokohama4_4s.jpg' /></td><td><div class='infowin'>あゆを見送る祐一(7年前)<br /><br /><a href='kanon-tv3-4.htm#txt4' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.648775160312", "y": "35.440660011744", "txt": "<table border=0><tr><td><img src='yokohama4_5s.jpg' /></td><td><div class='infowin'>手をふるあゆ(7年前)<br /><br /><a href='kanon-tv3-4.htm#txt5' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.647973179817", "y": "35.4402251478196", "txt": "<table border=0><tr><td><img src='yokohama4_6s.jpg' /></td><td><div class='infowin'>名雪のもとに戻る祐一(7年前)<br /><br /><a href='kanon-tv3-4.htm#txt6' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.650097489356", "y": "35.4411800971718", "txt": "<table border=0><tr><td><img src='yokohama4_7s.jpg' /></td><td><div class='infowin'>Bパート冒頭<br /><br /><a href='kanon-tv3-4.htm#txt7' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.648276269435", "y": "35.4403650038103", "txt": "<table border=0><tr><td><img src='yokohama4_8s.jpg' /></td><td><div class='infowin'>商店街を歩く祐一<br /><br /><a href='kanon-tv3-4.htm#txt8' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" },
  { "x": "139.647814929485", "y": "35.4402011100467", "txt": "<table border=0><tr><td><img src='yokohama4_9s.jpg' /></td><td><div class='infowin'>あゆと秋子さん遭遇<br /><br /><a href='kanon-tv3-4.htm#txt9' onClick='map.closeInfoWindow()'>⇒旅行記へ</a></div></td></tr></table>" }
] }

 これをExcelからコピー&ペーストで切り出してテキストファイルにし、FTPでWebサーバにアップします。
 以上でデータ部の作成は完了です。

2.JavaScriptの作成
 今回作成したJavaScriptを下記↓に示します。
 ※下記のJavaScriptは、商業利用以外の私的利用については、コピーおよび使用は自由にしていただいてかまいません。
 ※使用する場合、全角スペースは半角スペースに変換して下さい。

var map;
var markers = [];
var points = [];
var i;
var httpObj;

function startUp() {
  map = new GMap2(document.getElementById("mymap"));
  map.addControl(new GMapTypeControl());
  map.addControl(new GLargeMapControl());
  map.addControl(new GScaleControl());

  var msec = (new Date()).getTime();
  httpObj = GXmlHttp.create();
  httpObj.open("GET", "./kanon3_dat1.txt?cache="+msec);
  httpObj.onreadystatechange = function () {
    if ( (httpObj.readyState == 4) && (httpObj.status == 200) ) {
      setMap();
    }
  }
  httpObj.send(null);
}

function setMap() {
  eval("var mapData = "+httpObj.responseText);
  map.setCenter(new GLatLng(mapData.cent_dat[0].y, mapData.cent_dat[0].x), 17);

  for (i = 0; i < mapData.POINTS_NUM; i++) {
    points[i] = new GLatLng(mapData.point_dat[i].y, mapData.point_dat[i].x);
    addMarker(points[i], i, mapData.point_dat[i].txt);
  }
  var polyline = new GPolyline(points, "#99FFFF", 3, 0.5);
  map.addOverlay(polyline);  
}

function addMarker(latlng, num, comment) {
  var icon = new GIcon();
  icon.image = "../markers/marker"+num+".png";
  icon.iconSize = new GSize(20,34);
  icon.shadow = "http://www.google.com/mapfiles/shadow50.png";
  icon.shadowSize = new GSize(37, 34);
  icon.iconAnchor = new GPoint(10, 34);
  icon.infoWindowAnchor = new GPoint(20, 10);
  markers[num] = new GMarker(latlng, icon);
  map.addOverlay(markers[num]);
  var f = function() {
    markers[num].openInfoWindowHtml(comment);
  }
  GEvent.addListener(markers[num], "click", f);

  var marker_field = document.getElementById('mark'+ num);
  var fzoom = function() {
    f();
    map.panTo(latlng);
    map.setZoom(18);
  }
  marker_field.onmousedown = fzoom;
}

if (GBrowserIsCompatible()) {
  onload=startUp;
  onunload=GUnload;
}

詳しい説明をすると長くなるので、以下、ポイントを絞って解説します。

今回のポイントは、13行目からの下記の部分です。

  var msec = (new Date()).getTime();
  httpObj = GXmlHttp.create();
  httpObj.open("GET", "./kanon3_dat1.txt?cache="+msec);
  httpObj.onreadystatechange = function () {
    if ( (httpObj.readyState == 4) && (httpObj.status == 200) ) {
      setMap();
    }
  }
  httpObj.send(null);

 この部分が実行されると、先にWebサーバ上にアップされたデータ部を、Googleのサーバが読み込みます。
 (そのため、このJavaScriptは、ローカルではデバッグ出来ないという副産物が付くのですが…)
 読み込みに成功すると、

    if ( (httpObj.readyState == 4) && (httpObj.status == 200) ) {
      setMap();
    }

 ↑のif文の中の、setMap関数が実行されます。setMap関数中ではどうなるかというと、

  eval("var mapData = "+httpObj.responseText);
  map.setCenter(new GLatLng(mapData.cent_dat[0].y, mapData.cent_dat[0].x), 17);

 1行目で変数mapDataにサーバが読みとったJSON形式のデータを代入し、
 2行目でmapDataからマップの中心データを読み込んで、マップの中心座標をセットします。

 次に、setMap関数中では、

  for (i = 0; i < mapData.POINTS_NUM; i++) {
    points[i] = new GLatLng(mapData.point_dat[i].y, mapData.point_dat[i].x);
    addMarker(points[i], i, mapData.point_dat[i].txt);
  }

 mapData変数中のマーカの個数分だけループを繰り返して、マップ中にマーカをセットします。
 最後のsetMap関数中の、

  var polyline = new GPolyline(points, "#99FFFF", 3, 0.5);
  map.addOverlay(polyline);  

 は、マーカ間にラインを引くための処理です。

 以上のように、このJavaScriptは、マップが変わった時にでも15行目の↓の部分のファイル名だけを変更すれば良いようになっています。

  httpObj.open("GET", "./kanon3_dat1.txt?cache="+msec);

3.HTML(XML)の作成
 探訪記のメイン部分である、XMLファイルの記述は従来とほとんど変わっていません。
 が、1点だけ、ヘッダに↓の記述を追記する必要があります。

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xml:lang="ja" lang="ja">
<style type="text/css">
v\:* {
behavior:url(#default#VML);
}
</style>

 これは、Google Mapsが、Internet Explorerでマップ上のラインを引くためにVMLの機能を使う必要があるため、だそうです。

 以上、どこまで役に立つかわかりませんが、JavaScriptの公開でした。

 前回へ<< >>次回へ