エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


路線・駅検索をPHPで実装する方法解説。GoogleMapsの緯度経度から計算し検索

      2018/09/04

路線・駅検索をPHPで実装する方法を解説

 
路線・駅検索を利用するシステムはいっぱいあります。
 
例えば Webサイトでは、求人検索サイトや、不動産の物件検索サイト、飲食店検索サイトなどです。
路線、駅を選択し、駅から 5分、10分の距離にある企業や物件、店舗などを検索するシステムです。
 
その路線・駅検索のシステムをより簡単に実装できないか、ということを考えました。
 
 

一般的な路線・駅検索の仕組み

 
一般的な路線・駅検索の仕組みは、検索対象となるスポット(求人企業の事務所の位置、不動産物件の位置など)の「最寄りとなる駅」と「駅からの距離(もしくは、徒歩でかかる時間)」を登録しておきます。
最寄りの駅が複数ある場合は、複数の駅を登録しておきます。
 
そして、検索をする際には、その登録している駅と駅からの距離の情報を対象に検索を実行し、結果を処理します。
 
 

一般的な路線・駅検索の問題点

 
ですが、路線・駅検索は結構ハードルが高いのです。
かかるコストも高いのです。
 
なぜなら、そもそも、路線、駅のデータが公的な情報としてまとまって提供されているわけではないためです。
また、路線、駅のデータは相応に膨大な量になり、かつ、駅や路線は増えたり減ったりすることがあるからです。
 
そして、もう一つの根本的な問題点として、鉄道には駅で電車を乗り換える、ということがある点です。
 
 
例えば、日本一の乗降客がある新宿駅。
新宿駅には多くの路線が乗り入れています。
JR、京王線、小田急線、東京メトロ丸の内線、都営地下鉄大江戸線などです。
また、最初に JRと書きましたが、JRの中にも山手線、中央線、総武線各駅などなど複数路線があります。
 
また、「新宿駅」という名前ではないものの、実際には乗換駅である場合もあります。
東京メトロ丸の内線、副都心線の新宿三丁目駅、都営大江戸線の新宿西口駅などです。
 
さらに、西武新宿線の「新宿駅」は、「新宿駅」という名前が付いていますが、都営大江戸線の新宿西口駅よりも遠くにあります。
乗り換えには、屋根がない地上を数百メートルほど歩く必要があり(横断歩道などで大通りを通る必要などもあります)、同じ新宿駅としていいのか、という疑問がわきます。
 
同じように、同じ駅名なのに離れた場所にある駅や、違う駅名なのにすぐ近くの駅であったり、ということが全国にあるのです。
 
どの駅を乗換駅とするか、しないか、それをどう判断するのかは非常に煩雑なのです。
 
 

駅・路線検索の問題点の一つの解決策

 
そのため、一般的な最寄りの駅を登録する方法を止め、指定された駅と、検索対象となるスポットの緯度経度を取得し、そこから 2点間の距離を計算し、それに基づいて条件抽出したらいいんじゃないか、という発想をしたわけです。
(まぁ、この発想に基づいて処理をする APIがすでにあるようなので、特段新しい発想ではありませんが...)
 
 
ただし、この方法の問題点は、駅からの距離は分かるものの、駅から徒歩で何分かかるのかが分からない、ということです。
駅から 500mであったとしても、直線で行ける場合と、遠回りしないとたどり着けない場合とあり、どれだけかかるかが分からないという点です。
 
また、駅の場所として処理される緯度経度は、駅の中の特定の場所で、駅の出口からの距離ではないところも問題点となりえます。
 
 
もっとも、一般的な表示である「駅から徒歩 5分」と書かれていても、坂道や信号待ちの時間などは考慮されていませんし、そもそも地下鉄や大きな駅など、ホームから駅の出口までに 10分ほどかかるような駅もありますので、「駅から徒歩 5分」と書かれていても、電車を降りてからどれくらい時間がかかるのかを正確に示したものではない、ということになります。
 
それを考えると、「どういう計算で算出している情報なのか」さえ明記しておけばいいんじゃないか、と考えました。
(一般的には道のりで時間を出していますので、誤解は発生しやすいかとは思いますが。)
 
 

路線・駅の情報は「駅データ.jp」を利用

今回紹介している路線・駅のデータは、下記の「駅データ.jp」さんのデータを利用しています。
「駅データ.jp」さんが路線、駅のデータ、および、検索の APIを提供してくださっていますので、このサービスが提供されている間は駅、路線のデータは容易に取得することができるでしょう。
システムをより簡易に作成したい場合は、APIを利用すると便利でしょう。
 https://www.ekidata.jp/
 
 

路線・駅検索のサンプルプログラム

 

路線・駅検索のサンプルプログラムの使い方

 
路線・駅検索のサンプルプログラムを下記にアップしました。
 https://s-giken.info/station_search/station_search.php
 
路線・駅検索をPHPで実装する方法解説。GoogleMapsの緯度経度から計算し検索
 
上記のような入力画面があり、都道府県、路線、駅を選択し、そこからの距離を数値で入力すると、指定の距離以内にある駅の一覧が表示されます。
 
普通は、不動産の物件や、求人企業の事務所、飲食店などの場所を検索するものだと思いますが、サンプル用にそれらの物件の位置情報のデータベースを構築することが現実的ではなかったため、物件情報の代わりに「駅データ.jp」から取得した駅の情報を検索対象の物件としても利用しています。
 
そのため、駅から駅を検索するという一般的には見ない路線・駅検索システムが出来上がっています(笑)。
 
 

路線・駅検索のサンプルプログラムのテーブルの構成

 
テーブルは、Company(事業者データ)、Line(路線データ)、Station(駅データ)の 3つで構成されていまして、それぞれ以下の構成をしています。
 
「駅データ.jp」の csvファイルをそのまま使うことを目的としましたので、「駅データ.jp」の構成と同じです。
 
【Company(事業者データ)】

 
【Line(路線データ)】

 
【Station(駅データ)】

 
 

路線・駅検索のサンプルプログラムの駅を検索する SQL文

 
そして、一番重要な検索する際の SQLは以下のようになります。
 

 
「【入力の距離】」は、入力された値です。
「【駅の緯度】」「【駅の経度】」は、選択された「駅」の情報から「駅データ.jp」の APIを利用して、算出した値を編集します。
 
計算式を含む SQL文ですのでちょっと長いですが、SQL文としては非常にシンプルな形式です。
 
 
また、「【緯度1°の距離】」「【経度1°の距離】」は、あらかじめ計算をして算出をしておきます。
 
詳細な解説は、2点間の緯度経度から距離を計算する記事「路線・駅検索のために緯度経度からPHPで2点間の距離を計算する処理解説」を読んでいただければ、と思いますが、計算式は以下のようになります。
単位は「m」です。
 

 
 

路線・駅検索についてのまとめ

 
路線・駅検索は、作ってみると意外に簡単でしたね。
考え方もそれほど難しいものではないですので、路線・駅検索を必要としている方は、あなたのシステムにも組み込んでいけるんじゃないでしょうか。
 
ただ、緯度と経度がごっちゃになったり、すっかり忘れてしまっていた三角関数など、違うところで苦戦しました...
 
 
また、この記事は 3本で 1セットの内容です。
まず「2地点の緯度経度から距離を計算する方法を考察」し、2つ目のこの記事で、その 2点間の距離を計算する方法を基にして、「路線・駅検索の仕組みを考察」しました。
そして、3本目の記事で、その「路線・駅検索の仕組みを WordPressに実装する方法を考察」する、という流れです。
 
これだけのステップを踏まないとたどり着けない、ということではありますが、ブログの記事としては 3本の記事を作ることができました(笑)。
 路線・駅検索のために緯度経度からPHPで2点間の距離を計算する処理解説
 路線・駅検索をPHPで実装する方法解説。GoogleMapsの緯度経度から計算し検索
 「WordPressで駅検索を実装」(鋭意執筆中)
 
 
3本目の記事は、現在鋭意作成中です。
なぜ、WordPressに組み込むことを目指すのか、と言いますと、「月極駐車場検索エース」というサイトを作りましたが、ここには都道府県検索はありますが、路線・駅検索がありません。
そのため、「月極駐車場検索エース」に路線・駅検索を組み込むことを目指して思考を始めましたので、最終目標は WordPressへの組み込みなわけです。
 
ただ、WordPressに組み込むには、カスタムフィールドだけで処理するのは難しく、オリジナルのテーブルを構築する必要がありそうで、オリジナルテーブルにアクセスする方法と、オリジナルテーブルにデータを保存する方法、さらに、それらとカテゴリ検索や各フィールドの条件検索と組み合わせる方法などを理解する必要がありそうで、少し時間がかかりそうです。

 - PHP・Smarty・ECCUBE

GoogleAdwords

GoogleAdwords

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Comment

  1. やまちゃん より:

    掲載されてる以下のSQLに緯度1°の距離が一度も出てきていないので間違いだと思うのですが、どうでしょうか。

    select
    a.company_name,
    b.line_name,
    c.station_name,
    c.pref_cd,
    c.address,
    c.lon,
    c.lat,
    sqrt ( pow ( ( c.lat – 【駅の緯度】 ) * 【経度1°の距離】, 2 ) + pow ( ( c.lon – 【駅の経度】 ) * 【経度1°の距離】, 2 ) ) as d
    from
    company as a,
    line as b,
    station as c
    where
    c.line_cd = b.line_cd and
    b.company_cd = a.company_cd and
    ( 【入力の距離】 > sqrt ( pow ( ( c.lat – 【駅の緯度】 ) * 【経度1°の距離】, 2 ) + pow ( ( c.lon – 【駅の経度】 ) * 【経度1°の距離】, 2 ) ) )
    order by d

    • エス技研 より:

      やまちゃんさん、コメントありがとうございます。
      ご指摘の通り、間違いがありましたので修正をさせていただきました。
      記事を書くときに文字列をコピペして、必要な変更を仕切れていなかったんだろうな、と思います。
      ご連絡ありがとうございました。

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

ECCUBE mtb_constants initパラメータ設定の項目を追加する方法

ECCUBEのパラメータ設定で設定できる項目を追加する方法を説明します。

Smartyの修飾子regex_replaceで正規表現の後方参照・PHPではpreg_replace

ECCUBEで使われているSmartyで文字列を正規表現で置換し後方参照で値を利用する装飾子regex_replaceの解説です。細かな条件がありますので注意が必要です。

リダイレクトループが原因で「ERR_TOO_MANY_REDIRECTS」「このページを表示できません」が出たときの対策12事例+α

リダイレクトループ、自動転送設定ループの原因の解説とその対応方法を含め事例 12例を挙げて説明。

PHP画面が真っ白 header(“Location: $url”);

PHPの開発で header(“Location: $url”);を使うと画面が真っ白になる不具合が出る場合もあります。

乱数発生器(パスワード生成サービス)がバージョンアップで高速化!
乱数発生器(パスワード生成サービス)がバージョンアップで高速化!

乱数やパスワードを生成する乱数発生器を高速化!重複しない10桁、20桁の文字列を10万件、20万件と生成することも可能!イベントのキャンペーンのシリアルコードなどにも利用可能!

SEO対策用タイトル、ディスクリプションの文字数カウントツール

SEO対策に使える文字数カウントツールで文字数の条件の説明も行っています。

PHPで配列の値をダブルクオーテーションで囲んでimplodeでカンマ区切りにする方法
PHPで配列の値をダブルクオーテーションで囲んでimplodeでカンマ区切りにする方法

PHPで配列の値を、preg_replace関数でクォーテーションで囲み、implode関数で「,(カンマ)」で区切ってテキスト化する方法。この方法であれば配列が空でも分岐の処理は必要なし!

QRコード作成ライブラリ「cakePHP-QR-Code-Helper」をPHPで使うカスタマイズ
QRコード作成ライブラリ「cakePHP-QR-Code-Helper」をPHPで使うカスタマイズ

CakePHP2用のQRコード作成ライブラリ「cakePHP-QR-Code-Helper」をプレーンのPHPでも使うためのカスタマイズ方法を解説。1ファイルを設置するだけでQRコードが作れるため使い勝手がいい。

PHPのソースで見慣れない記号が出てきた・アロー演算子(->)、ダブルアロー演算子(=>)

PHPのプログラムソースには見慣れない記号が出てきます。その意味や調べ方です。

PHPのスクレイピングライブラリ「PHP Simple HTML DOM Parser」の使い方
PHPのスクレイピングライブラリ「PHP Simple HTML DOM Parser」の使い方

PHPのスクレイピングライブラリ「PHP Simple HTML DOM Parser」の使い方を解説。要素を取得する方法、そこから属性を取得する方法を解説。また、マニュアルにはない注意点なども解説。