PHPで「ぐるなび」を使って喫茶店を探す

(1/1)
ぐるなび Web サービス:レストラン検索API」は、ぐるなびに掲載されている飲食店の基本情報(住所など)や緯度経度、設備情報、クーポン URL、画像 URL などを取得することができる WebAPI サービスだ。
Google や Yahoo!JAPAN の地図サービスをマッシュアップすることで、住所やランドマークから最寄りの喫茶店を求める PHP プログラムを作ってみることにする。

※2019 年(平成 31 年)3 月 16 日、Yahoo! JavaScript マップも利用できるようにした。

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

PHPで「ぐるなび」を使って喫茶店を探す
Google マップ表示

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

圧縮ファイルの内容
searchCafe.phpサンプル・プログラム本体
pahooGeoCode.php住所・緯度・経度に関わるクラス pahooGeoCode。
使い方は「PHPで住所・ランドマークから最寄り駅を求める」などを参照。include_path が通ったディレクトリに配置すること。

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

PHPで「ぐるなび」を使って喫茶店を探す
プログラムの流れは「PHP で最寄り駅を求める」の時と同じで、緯度・経度から施設情報を求める部分を、「ぐるなび Web サービス:レストラン検索API」に差し替えただけである。

準備:pahooGeoCode クラス

0026: class pahooGeoCode {
0027:     var $items;      //検索結果格納用
0028:     var $error;      //エラーフラグ
0029:     var $hits;       //検索ヒット件数
0030:     var $webapi; //直前に呼び出したWebAPI URL
0031: 
0032:     //Google Cloud Platform APIキー
0033:     //https://cloud.google.com/maps-platform/
0034:     //※Google Maps APIを利用しないのなら登録不要
0035:     var $GOOGLE_API_KEY_1 = '**************************';   //HTTPリファラ用
0036:     var $GOOGLE_API_KEY_2 = '**************************';   //IP制限用
0037: 
0038:     //Yahoo! JAPAN Webサービス アプリケーションID
0039:     //https://e.developer.yahoo.co.jp/register
0040:     //※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
0041:     var $YAHOO_APPLICATION_ID = '*****************************';

地図サービスを利用するために、クラスファイル "pahooGeoCode.php" を使用する。組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。
クラスについては「PHP でクラスを使ってテキストの読みやすさを調べる」を参照されたい。

地図として Google マップを利用するのであれば、Google Cloud Platform API キー が必要で、その入手方法は「Google Cloud Platform - WebAPI の登録方法」を、YOLP マップを利用するのであれば、Yahoo! JAPAN Web サービス アプリケーション IDが必要で、その入手方法は「Google Cloud Platform - WebAPI の登録方法」を、それぞれ参照されたい。

準備:地図サービス(WebAPI)の選択

0027: //地図サービス(WebAPI)の選択
0028: //    0:Google
0029: //    1:Yahoo!JAPAN
0030: define('GEOSERVICE', 1);

表示する地図は、Google マップと Yahoo!マップ(YOLP 地図)から選べる。
あらかじめ、定数 GEOSERVICE に値を設定すること。
PHPで住所・ランドマークから最寄り駅を求める
Yahoo!マップ表示

準備:ぐるなびWebサービス

0037: //ぐるなびWebサービス アクセスキー:https://api.gnavi.co.jp/api/ で発行
0038: define('GNAVI_ACCESSKEY', '*******************************');

ぐるなび Web サービス」を利用するために、アクセスキーが必要で、入手方法は「ぐるなび Web サービス - WebAPI の登録方法」を参照されたい。

「ぐるなびWebサービス:レストラン検索API」による店舗探索

ぐるなび Web サービス:レストラン検索API」は、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は JSON で戻すという形である。今回使う入力パラメータと出力結果のデータ構造の一部を以下に記す。
WebAPI
URL
https://api.gnavi.co.jp/RestSearchAPI/v3/

入力パラメータ
フィールド名 要否 内  容
keyid 必須 ぐるなびより提供されたアクセスキー
input_coordinates_mode 任意 入力パラメータに含まれる緯度/経度の測地系を指定
1:日本測地系
2:世界測地系(デフォルト)
latitude 任意 検索地点の緯度(小数表記)
longitude 任意 検索地点の経度(小数表記)
coordinates_mode 任意 レスポンスに含まれる緯度/経度の測地系を指定
1:日本測地系
2:世界測地系(デフォルト)
range 任意 緯度/経度からの検索範囲(半径)
1:300m、2:500m(デフォルト)、3:1000m、4:2000m、5:3000m
freeword 任意 検索ワードをUTF-8でURLエンコードすること「,」区切りで複数ワードが検索可能(10個まで)
出力パラメータ (JSON)
フィールド名 内  容
@attributes api_versionAPIのバージョン
total_hit_count該当件数
hit_per_page表示件数
page_offset表示ページ
total_hit_count表示ページ
rest[] id店舗ID
update_date情報更新日時
name店舗名
name_kana店舗名称(カタカナ)
latitude緯度(小数表記)
longitude経度(小数表記)
categoryフリーワードカテゴリー
urlPCサイトURL
url_mobile携帯サイトURL
address住所
tel電話番号
opentime営業時間
holiday休業日

解説:ぐるなびWebサービス

0212:     return chr(64 + $i);
0213: }
0214: 
0215: /**
0216:  * ぐるなびWebサービスのURLを取得する
0217:  * @param double $latitude  緯度(世界測地系)
0218:  * @param double $longitude 経度(世界測地系)
0219:  * @param double $distance  範囲(メートル)
0220:  * @param string $freeword  フリーワード検索(カンマ区切り)
0221:  * @return string URL レストラン検索APIのURL
0222: */
0223: function getURL_RestSearchAPI($latitude$longitude$distance$freeword) {
0224:     $range_tbl = array(1=>300, 2=>500, 3=>1000, 4=>2000, 5=>3000);
0225: 
0226:     $keyid = GNAVI_ACCESSKEY;
0227:     $range = count($range_tbl);
0228:     foreach ($range_tbl as $key=>$val) {
0229:         if ($distance <= $val) {
0230:             $range = $key;
0231:             break;
0232:         }
0233:     }
0234:     $freeword = urlencode($freeword);
0235: 
0236:     $url = "https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid={$keyid}&input_coordinates_mode=2&coordinates_mode=2&latitude={$latitude}&longitude={$longitude}&range={$range}&freeword={$freeword}";
0237: 
0238:     return $url;
0239: }
0240: 
0241: /**
0242:  * レストラン検索APIを利用して指定座標の近くにある喫茶店を検索
0243:  * @param double $latitude  緯度(世界測地系)
0244:  * @param double $longitude 経度(世界測地系)
0245:  * @param double $distance  範囲(メートル)
0246:  * @param array $items 情報を格納する配列
0247:  * @return array(ヒットした施設数, メッセージ, APIのURL)
0248: */
0249: function searchCafe($latitude$longitude$distance, &$items) {
0250:     $url = getURL_RestSearchAPI($latitude$longitude$distance, '喫茶店');
0251:     $data = @file_get_contents($url);
0252:     $json = json_decode($data);
0253: 
0254:     //レスポンス・チェック
0255:     if (($data == FALSE|| ($json == NULL)) {
0256:         if (isset($json->error->message)) {
0257:             $msg = (string)$json->error->message;
0258:         } else {
0259:             $msg = '検索範囲に店舗が無いか,ぐるなびWebサービスのエラーです';
0260:         }
0261:         return array(FALSE$msg$url);
0262:     }
0263: 
0264:     //応答解釈
0265:     $n = 1;
0266:     foreach ($json->rest as $element) {
0267:         $items[$n]['id']        = num2alpha($n);
0268:         $items[$n]['title']     = (string)$element->name;
0269:         $items[$n]['url']       = (string)$element->url;
0270:         $items[$n]['category']  = (string)$element->category;
0271:         $items[$n]['phone']     = (string)$element->tel;
0272:         $items[$n]['opentime']  = preg_replace("/\n/ui", '<br />', (string)$element->opentime);
0273:         $items[$n]['holiday']   = preg_replace("/\n/ui", '<br />', (string)$element->holiday);
0274:         $items[$n]['latitude']  = (double)$element->latitude;
0275:         $items[$n]['longitude'] = (double)$element->longitude;
0276:         $address = (string)$element->address;
0277:         $address = preg_replace('/〒[0-9\-]+ /ui', '', $address);
0278:         $address = preg_replace("/\n/ui", '<br />', $address);
0279:         $items[$n]['address'] = $address;
0280: $items[$n]['description'] =<<< EOT
0281: <span class="small"><a href="{$items[$n]['url']}" target="_blank">{$items[$n]['title']}</a><br />電話:{$items[$n]['phone']}<br />住所:{$items[$n]['address']}<br />営業時間:{$items[$n]['opentime']}<br />定休日:{$items[$n]['holiday']}</span>
0282: EOT;
0283:         $n++;
0284:     }

ぐるなび Web サービス:レストラン検索API」を呼び出し、店舗情報を配列 $items に格納するのが、ユーザー関数 searchCafe である。WebAPI の応答を  json_decode  を使って解釈し、配列 $items に格納する。

マップに描画する際に必要になるので、要素 description には、店舗名、電話番号、住所、営業時間、定休日とリンク先 URL をハイパーリンクする。

参考サイト

(この項おわり)
header