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

(1/1)
HeartRails Geo API」は、路線/駅名データ等の地理情報を無償の WebAPI として提供している。
これと、Google マップを描いたり住所から緯度・経度を求める WebAPI「Google Maps API」および、京都の通り名住所から緯度・経度を求める WebAPI「ジオどす IIをマッシュアップすることで、住所やランドマークから最寄り駅を求める PHP プログラムを作ってみることにする。

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

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

サンプル・プログラム

サンプル・プログラムは 2 つの機能を持つ。
1 つは、そのまま実行すると、検索キーワードを入力する画面を表示する機能――[検索]ボタンを押下することで、検索結果を表示する。
もう 1 つは、前述の変数を GET 渡しで呼び出すことで、検索結果のみを表示する機能である。たとえば「東京都千代田区皇居外苑1-1」の最寄り駅を検索する場合は、URL で 'stationsearch.php?query=%93%8C%8B%9E%93s%90%E7%91%E3%93c%8B%E6%8Dc%8B%8F%8AO%89%91%82P%81%7C%82P' と指定してやればよい。

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

PHPで住所・ランドマークから最寄り駅を求める
プログラムの流れは前回のものと同じだが、住所やランドマークから緯度・経度を求める処理は、「PHP で Google を利用して住所から緯度・経度を求める」で作成したクラス pahooGeoCode を利用する。

解説:pahooGeoCode クラス

0024: class pahooGeoCode {
0025:     var $items;      //検索結果格納用
0026:     var $error;      //エラーフラグ
0027:     var $hits;           //検索ヒット件数
0028:     var $webapi;     //直前に呼び出したWebAPI URL
0029: 
0030:     //Google API KEY
0031:     //https://developers.google.com/maps/web/
0032:     var $GOOGLE_API_KEY = '**************************';
0033: 
0034:     //Yahoo! JAPAN Webサービス アプリケーションID
0035:     //https://developers.google.com/maps/documentation/javascript/get-api-key
0036:     var $YAHOO_APPLICATION_ID = '*****************************';
0037: 
0038:     //ジオどすII APIキー
0039:     //http://geodosu.com/user/register
0040:     var $APIKEY_GEODOS = '*****************';

各種WebAPI を使うメソッドは、PHP のクラスを使って定義している。
クラスについては「PHP でクラスを使ってテキストの読みやすさを調べる」で解説している。
クラスファイル "pahooGeoCode.php" は、組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。

2016 年(平成 28 年)6 月頃から、Google Maps API を呼び出すにもキーが必要になった。「Google Maps APIs for Web」にアクセスし、「キーを取得」ボタンをクリックすると無料で取得できる。これをクラス変数 $GOOGLE_API_KEY に代入しておく。また、Google Cloud Console に入り、GoogleMaps JavaScript APIGoogle Maps Geocoding API を有効にする。

WebAPI「ジオどす II」では API キーが必要になる。これは http://geodosu.com/user/register から無料で入手することができる。これをクラス変数 $APIKEY_GEODOS に代入しておく。

今回は使用しないが、Yahoo! JAPAN が提供する Web API を利用する場合は、https://e.developer.yahoo.co.jp/register にアクセスし、無料で Consumer Key を取得できる。これをクラス変数 $YAHOO_APPLICATION_ID に代入しておく。

HeartRails Geo API 最寄駅検索

HeartRails Geo API」は、2015 年(平成 27 年)9 月現在、以下の API を無償公開している。
これらの API は、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は XML で戻るという形である。
  • エリア情報取得 API
  • 都道府県情報取得 API
  • 市区町村情報取得 API
  • 町域情報取得 API
  • 最寄駅情報取得 API
  • 郵便番号による住所検索 API
  • 緯度経度による住所検索 API
  • キーワードによる住所検索 API
  • 「エリア名」 「市区町村名」 「町域名」 の連結コンボボックス
  • 「都道府県名」 「市区町村名」 「町域名」 の連結コンボボックス
  • 「郵便番号」 による住所検索フォーム
WebAPIのURL
URL
http://express.heartrails.com/api/xml

入力パラメータ
項目名 フィールド名 内  容
メソッド名 method string 'getStation' 固定
経度 x float 最寄り駅を取得したい場所の経度(世界測地系)。
緯度 y float 最寄り駅を取得したい場所の緯度(世界測地系)。
応答データ(xml) response station name 駅名 line 路線名 distance 検索地点からの距離 x 経度 y 緯度 prefecture 都道府県 postal 郵便番号 next 次の駅 prev 前の駅

解説:HeartRails Geo APIの呼び出し

0180: /**
0181:  * HeartRails Express のURLを取得する
0182:  * @param double $lat 緯度(世界測地系)
0183:  * @param double $lng 経度(世界測地系)
0184:  * @return string URL
0185: */
0186: function getURL_Heartrails($lat$lng) {
0187:     $res = "http://express.heartrails.com/api/xml?method=getStations&x={$lng}&y={$lat}";
0188: 
0189:     return $res;
0190: }
0191: 
0192: /**
0193:  * HeartRails Express API から必要な情報を配列に格納する
0194:  * @param double $latitude  緯度(世界測地系)
0195:  * @param double $longitude 経度(世界測地系)
0196:  * @return array(ヒットした施設数, メッセージ, APIのURL)
0197:  * @return int ヒット数
0198: */
0199: function getResults_Heartrails($latitude$longitude, &$items) {
0200: //受信データの要素名
0201: $tbl = array(
0202:     'name',            //最寄駅名
0203:     'prev',            //前の駅名 (始発駅の場合は null
0204:     'next',            //次の駅名 (終着駅の場合は null
0205:     'x',            //最寄駅の経度 (世界測地系)
0206:     'y',            //最寄駅の緯度 (世界測地系)
0207:     'distance',    //指定の場所から最寄駅までの距離 (精度は 10 m)
0208:     'postal',        //最寄駅の郵便番号 
0209:     'prefecture',    //最寄駅の存在する都道府県名
0210:     'line'         //最寄駅の存在する路線名
0211: );
0212: 
0213:     $url = $this->getURL_Heartrails($latitude$longitude);   //リクエストURL
0214:     $cnt = 1;
0215: 
0216: //PHP4用; DOM XML利用
0217:     if (! isphp5over()) {
0218:         if (($dom = $this->read_xml($url)) == NULL) {
0219:             return array(FALSE, 'WebAPIのトラブルです.', FALSE);
0220:         }
0221:         $resultset = $dom->get_elements_by_tagname('response');
0222:         $results = $resultset[0]->get_elements_by_tagname('station');
0223:         //検索結果取りだし
0224:         foreach ($results as $element) {
0225:             foreach ($tbl as $name) {
0226:                 $node = $element->get_elements_by_tagname($name);
0227:                 if ($node != NULL) {
0228:                     $items[$cnt][$name] = (string)$node[0]->get_content();
0229:                 }
0230:             }
0231:             $items[$cnt]['id']        = $this->num2alpha($cnt);
0232:             $items[$cnt]['title']     = $items[$cnt]['name'];
0233:             $items[$cnt]['longitude'] = $items[$cnt]['x'];
0234:             $items[$cnt]['latitude']  = $items[$cnt]['y'];
0235: $items[$cnt]['description'] =<<< EOD
0236: {$items[$cnt]['name']}&nbsp;({$items[$cnt]['line']}){$items[$cnt]['distance']}
0237: EOD;
0238:             $cnt++;
0239:         }
0240: 
0241: //PHP5用; SimpleXML利用
0242:     } else {
0243:         $response = simplexml_load_file($url);
0244:         //レスポンス・チェック
0245:         if (isset($response->station) == FALSE) {
0246:             return array(FALSE, 'WebAPIのトラブルです.', FALSE);
0247:         }
0248:         //検索結果取りだし
0249:         foreach ($response->station as $element) {
0250:             foreach ($tbl as $name) {
0251:                 if (isset($element->$name)) {
0252:                     $items[$cnt][$name] = (string)$element->$name;
0253:                 }
0254:             }
0255:             $items[$cnt]['id']        = $this->num2alpha($cnt);
0256:             $items[$cnt]['title']     = $items[$cnt]['name'];
0257:             $items[$cnt]['longitude'] = $items[$cnt]['x'];
0258:             $items[$cnt]['latitude']  = $items[$cnt]['y'];
0259: $items[$cnt]['description'] =<<< EOD
0260: {$items[$cnt]['name']}&nbsp;({$items[$cnt]['line']}){$items[$cnt]['distance']}
0261: EOD;
0262:             $cnt++;
0263:         }
0264:     }
0265: 
0266:     return array($cnt - 1, '', $url);
0267: }

HeartRails Geo 最寄駅情報取得 APIの使い方は、前回と同じである。応答メッセージの処理は、PHP4 では DOM XML を、PHP5 以降では SimpleXML を使っている。

その他の WebAPI

pahooGeoCode::searchPoint2 が呼び出す WebAPI については、「PHP で Google等を利用して住所から緯度・経度を求める」を参照のこと。
pahooGeoCode::getAddress が呼び出す WebAPI については、「PHP で Google を利用して緯度・経度や住所を求める」を参照のこと。
pahooGeoCode::drawGMap が呼び出す WebAPI については、「PHP で Google を利用して緯度・経度や住所を求める」を参照のこと。

活用例

みんなの知識 ちょっと便利帳」では、「グーグルマップで見る京都の地下鉄路線図」からリンクする「地図・住所から「最寄り駅」をグーグルマップで探す - 初期設定:京都府庁周辺」や、「地図・住所から「最寄り駅」をグーグルマップで探す」で本プログラムを利用し、検索しやすいページを提供している。ありがとうございます。

参考サイト

(この項おわり)
header