JavaScriptで住所・ランドマークから最寄り駅を求める

(1/1)
JavaScript ES6 がIE以外のブラウザで利用できるようになった。このバージョンではクラス宣言もできる。
そこで今回は、「PHPで住所・ランドマークから最寄り駅を求める」で紹介したPHPサーバサイド・プラグラムを、JavaScriptを使ってクライアント・サイドに移植してみる。PHP環境が無くてもブラウザさえあれば、Googleマップ上で喫茶店を検索できるようになる。

サンプル・プログラムの実行例

JavaScriptで住所・ランドマークから最寄り駅を求める

サンプル・プログラムのダウンロード

圧縮ファイルの内容
stationsearch.htmlサンプル・プログラム本体。
pahooGeoCode.js住所・緯度・経度に関わるクラス pahooGeoCode。

サンプル・プログラムの流れ

JavaScriptで住所・ランドマークから最寄り駅を求める
プログラムの流れは、「JavaScriptで『ぐるなび』を使って喫茶店を探す」とほぼ同じだが、WebAPIを JSONP形式で呼び出す点が異なる。コールバック関数は、最初に呼ばれるユーザー関数 drawMap の中で動的に生成してやる。

JSONはJavaScriptでデータを扱うのに便利な形式だが、セキュリティ上の問題から、異なるドメインの間ではデータの受け渡しができない仕様になっている。これを回避するのが JSONP で、呼び出し時に非同期処理のためのコールバック関数を記述することができる。
逆に言えば、悪意のある第三者がJSONPを呼び出すことができる。ここでは触れないが、サーバサイドでJSONPを用意する場合、機密情報の受け渡しは行わないようにしよう。

解説:クラスファイル

住所やランドマークから緯度・経度を求める処理は、「JavaScriptでWebAPIを利用して住所から緯度・経度を求める」で作成したクラス pahooGeoCode を利用する。
クラスファイル "pahooGeoCode.js" の配置、各種WebAPI用のアプリケーションIDの設定方法については、「準備、クラスについて」を参照してほしい。

「HeartRails Geo API:最寄駅情報取得API」による最寄り駅探索

HeartRails Geo API:最寄駅情報取得API」は、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は JSON(P) で戻すという形である。今回使う入力パラメータと出力結果のデータ構造の一部を以下に記す。
WebAPI
URL
https://express.heartrails.com/api/json

入力パラメータ
フィールド名 要否 内  容
method 必須 メソッド名
getStations:最寄駅情報取得API
input_coordinates_mode 任意 入力パラメータに含まれる緯度/経度の測地系を指定
1:日本測地系
2:世界測地系(デフォルト)
x 必須 検索地点の経度(小数表記)
y 必須 検索地点の緯度(小数表記)
jsonp 任意 JSON形式のデータを受け取るためのコールバック関数名
出力パラメータ (JSON)
フィールド名 内  容
response station[] name最寄駅名
prev前の駅名(始発駅の場合は null)
next次の駅名(終着駅の場合は null)
x最寄駅の経度(世界測地系)
y最寄駅の緯度(世界測地系)
distance指定の場所から最寄駅までの距離(精度は 10m)
postal最寄駅の郵便番号
prefecture最寄駅の存在する都道府県名
line最寄駅の存在する路線名

解説:最寄り駅検索API

 177: /**
 178:  * 最寄り駅検索APIのURLを取得する
 179:  * @param   Float  latitude  緯度(世界測地系)
 180:  * @param   Float  longitude 経度(世界測地系)
 181:  * @return  String URL 最寄り駅検索APIのURL
 182: */
 183: function getURL_Heartrails(latitude, longitude) {
 184:     url = 'https://express.heartrails.com/api/json?method=getStations&y=' + latitude + '&x=' + longitude + '&jsonp=getHeartrails';
 185:     return url;
 186: }
 187: 
 188: /**
 189:  * 最寄り駅検索API:JSONPコールバック関数
 190:  * @param   Float  latitude  緯度(世界測地系)
 191:  * @param   Float  longitude 経度(世界測地系)
 192:  * @param   Array  items[]   情報を格納する配列
 193:  * @return  Object(hit=>ヒットした施設数, errmsg=エラーメッセージ, url=>APIのURL)
 194: */
 195: function getHeartrails(json) {
 196:     PGC.items = [];
 197:     var n = 1;
 198:     //レスポンス・チェック
 199:     if (json.response.station.length > 0) {
 200:         json.response.station.forEach(function(val) {
 201:             var obj = new Object();
 202:             obj.id          = String.fromCodePoint('A'.charCodeAt(0+ n - 1);
 203:             obj.title       = val.name;
 204:             obj.line        = val.line;
 205:             obj.distance    = val.distance;
 206:             obj.latitude    = parseFloat(val.y);
 207:             obj.longitude   = parseFloat(val.x);
 208:             obj.description = `
 209: ${obj.title}(${obj.line})<br />距離:${obj.distance}
 210: `;
 211:             PGC.items.push(obj);
 212:             n++;
 213:         });
 214:         PGC.pp.error  = false;
 215:         PGC.pp.errmsg = '';
 216:         PGC.pp.hits   = n;
 217: 
 218:     //APIエラー
 219:     } else {
 220:         PGC.pp.error  = true;
 221:         PGC.pp.errmsg = 'エラー:範囲内に最寄り駅がない.';
 222:         PGC.pp.hits   = 0;
 223:     }
 224: 
 225:     //Googleマップ描画
 226:     var distance = parseInt($('#distance').val());
 227:     var zoom = distance2zoom(distance);
 228:     PGC.drawGMap(GMAPID, $('#latitude').val(), $('#longitude').val(), $('#type').val(), zoom, PGC.items);
 229: 
 230:     //一覧表作成
 231:     $('#results').html(makeTable(PGC.items));
 232: 
 233:     //エラーメッセージ
 234:     $('#errmsg').html(PGC.pp.errmsg);
 235: }
 236: 
 237: /**
 238:  * 最寄り駅検索APIを利用して指定座標の近くにある駅を検索し
 239:  * Googleマップにマッピングし、一覧表を表示する
 240:  *
 241:  * @param   なし
 242:  * @return  なし
 243: */
 244: function drawMap() {
 245:     var url = getURL_Heartrails($('#latitude').val(), $('#longitude').val());
 246:     var target = document.createElement('script');
 247:     target.charset = 'utf-8';
 248:     target.src = url;
 249:     target.onerror = function() {
 250:         PGC.pp.error  = true;
 251:         PGC.pp.errmsg = 'エラー:最寄り駅検索APIの呼び出しができない.';
 252:         PGC.pp.hits   = 0;
 253:         //エラーメッセージ
 254:         $('#errmsg').html(PGC.pp.errmsg);
 255:     };
 256:     document.body.appendChild(target);
 257: }

HeartRails Geo API:最寄駅情報取得API」を XMLHttpRequest によって呼び出し、最寄り駅情報をオブジェクト配列 items に格納するのが、ユーザー関数 getHeartrails である。

関数 getHeartrails では、WebAPIの応答を JSON.parse を使って解釈し、オブジェクト配列 items に格納してゆく。
Googleマップに描画する際に必要になるので、要素 description には、最寄り駅名、路線名、距離を代入する。

最後に、Googleマップへの描画、一覧表の作成、エラーメッセージの表示を行い、コールバックを完了する。

参考サイト

(この項おわり)
header