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

0177: /**
0178:  * 最寄り駅検索APIのURLを取得する
0179:  * @param Float  latitude  緯度(世界測地系)
0180:  * @param Float  longitude 経度(世界測地系)
0181:  * @return String URL 最寄り駅検索APIのURL
0182: */
0183: function getURL_Heartrails(latitudelongitude) {
0184:     url = 'https://express.heartrails.com/api/json?method=getStations&y=' + latitude + '&x=' + longitude + '&jsonp=getHeartrails';
0185:     return url;
0186: }
0187: 
0188: /**
0189:  * 最寄り駅検索API:JSONPコールバック関数
0190:  * @param Float  latitude  緯度(世界測地系)
0191:  * @param Float  longitude 経度(世界測地系)
0192:  * @param Array  items[]   情報を格納する配列
0193:  * @return Object(hit=>ヒットした施設数, errmsg=エラーメッセージ, url=>APIのURL)
0194: */
0195: function getHeartrails(json) {
0196:     PGC.items = [];
0197:     var n = 1;
0198:     //レスポンス・チェック
0199:     if (json.response.station.length > 0) {
0200:         json.response.station.forEach(function(val) {
0201:             var obj = new Object();
0202:             obj.id          = String.fromCodePoint('A'.charCodeAt(0) + n - 1);
0203:             obj.title       = val.name;
0204:             obj.line        = val.line;
0205:             obj.distance    = val.distance;
0206:             obj.latitude    = parseFloat(val.y);
0207:             obj.longitude   = parseFloat(val.x);
0208:             obj.description = `
0209: ${obj.title}(${obj.line})<br />距離:${obj.distance}
0210: `;
0211:             PGC.items.push(obj);
0212:             n++;
0213:         });
0214:         PGC.pp.error  = false;
0215:         PGC.pp.errmsg = '';
0216:         PGC.pp.hits   = n;
0217: 
0218:     //APIエラー
0219:     } else {
0220:         PGC.pp.error  = true;
0221:         PGC.pp.errmsg = 'エラー:範囲内に最寄り駅がない.';
0222:         PGC.pp.hits   = 0;
0223:     }
0224: 
0225:     //Googleマップ描画
0226:     var distance = parseInt($('#distance').val());
0227:     var zoom = distance2zoom(distance);
0228:     PGC.drawGMap(GMAPID$('#latitude').val(), $('#longitude').val(), $('#type').val(), zoomPGC.items);
0229: 
0230:     //一覧表作成
0231:     $('#results').html(makeTable(PGC.items));
0232: 
0233:     //エラーメッセージ
0234:     $('#errmsg').html(PGC.pp.errmsg);
0235: }
0236: 
0237: /**
0238:  * 最寄り駅検索APIを利用して指定座標の近くにある駅を検索し
0239:  * Googleマップにマッピングし、一覧表を表示する
0240:  *
0241:  * @param なし
0242:  * @return なし
0243: */
0244: function drawMap() {
0245:     var url = getURL_Heartrails($('#latitude').val(), $('#longitude').val());
0246:     var target = document.createElement('script');
0247:     target.charset = 'utf-8';
0248:     target.src = url;
0249:     target.onerror = function() {
0250:         PGC.pp.error  = true;
0251:         PGC.pp.errmsg = 'エラー:最寄り駅検索APIの呼び出しができない.';
0252:         PGC.pp.hits   = 0;
0253:         //エラーメッセージ
0254:         $('#errmsg').html(PGC.pp.errmsg);
0255:     };
0256:     document.body.appendChild(target);
0257: }

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

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

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

参考サイト

(この項おわり)
header