2013年7月8日月曜日

最寄り駅を教えろ!Google Maps APIでマッシュアップ


今回は、Google Maps APIとHeartRails Expressの最寄駅情報取得 APIを連携させて クリックした場所の最寄り駅を取得してみます。


いわゆるマッシュアップというやつですね。

まずはGoogle Maps APIですが、これは思ったより簡単に使えます。
version3になってから、APIキーも無しで使うことが出来るようになり、何の準備もなくScriptを書き始められます。


ScriptタグでGoogle Map APIのJavaScriptを読み込みます。

<script type="text/javascript"
 src="http://maps.google.com/maps/api/js?v=3&sensor=false">
</script>

Body要素の中にMapを表示するためのdiv要素を配置しておきます。
<div id="map_canvas"></div>


Mapを表示するための関数を書きます。
この関数をbody要素のonloadなどに仕込んで利用します。
function initialize() {
 //表示位置
 var myLatitude = 35.147055906927214;//経度
 var myLongitude = 139.150131046772;//緯度
 //Mapの表示位置、表示方法などの設定値
 var mapOptions = {
  center: new google.maps.LatLng(myLatitude, myLongitude),
  zoom: 15,//初期のズームレベル
  mapTypeId: google.maps.MapTypeId.ROADMAP
 };
 //Mapを表示するdiv要素と設定値を渡す
 var map = new google.maps.Map(
  document.getElementById("map_canvas"),mapOptions);

 //Mapがクリックされた時のリスナーを登録
 google.maps.event.addListener(map, 'click', clickMap);
}



次に、HeartRails Expressの最寄駅情報取得 APIを利用します。

とてもシンプルなAPIで、URLに以下のように経度緯度のパラメータをつけてリクエストを投げると、最寄駅の情報を返してくれます。
レスポンスはXMLとJSONの二択でそれぞれURLが異なり、今回はJSONを使います。
http://express.heartrails.com/api/json?method=getStations&x=135.0&y=35.0


返ってくるJSONの構造は、responseフィールドの中に、stationフィールドがあり、その中に3つぐらいの駅情報が配列として入っています。
都市部などで多いと10ぐらい入っていたりもしますが、基準はよく分かりません。
駅までの距離が近い順に格納されていて、見つからない場合は空っぽのようです。

これをAjaxで拾ってくれば終わりかと思ったのですが、まったくうまくいきません。

NETWORK_ERR: XMLHttpRequest Exception 101

とか文句を言ってまったく相手にしてくれない。
結構な時間悩みに悩んだんですが、普通にクロスドメインはダメなんですね。

で、JSONPに行き着いた訳ですが、これ完全にscriptタグの悪用なのではないでしょうか。

クロスドメインでデータの読み込みが出来ないブラウザの仕様を回避するために、動的にappendChildしたscriptタグから外部scriptファイルを読み込むふりをして、外部データを拾ってきてしまうという。。
なんだか詐欺みたいな仕様です。

その詐欺師コードが以下。
function clickMap(event) {
 heartrailsURL = "http://express.heartrails.com/api/json?method=getStations&";
 heartrailsURL += "x=" + event.latLng.lng() + "&";
 heartrailsURL += "y=" + event.latLng.lat() + "&";
 heartrailsURL += "jsonp=getStation";//JSONPのコールバック関数
 var script = document.createElement('script');
 script.src = heartrailsURL;
 document.body.appendChild(script);
}

//コールバック関数
function getStation(result) {
 var resultStr = "";
 for(i = 0; i < result["response"]["station"].length; i++) {
  resultStr += result["response"]["station"][i].line + " ";
  resultStr += result["response"]["station"][i].name;
  resultStr += "駅までの距離:" + result["response"]["station"][i].distance + "\n";
 }
 alert(resultStr);
}

普通に動きました。

Google Maps APIがテーマだったのですが、何よりJSONPに感動しました。

0 コメント:

コメントを投稿