PHPでホットペッパーを利用して喫茶店を検索する

(1/1)
ホットペッパーの「グルメサーチAPI」は、指定した緯度・経度の近くにある飲食店を検索できる無料WebAPIサービスだ。ぐるなびAPIの無料サービスが終了してしまったため、代わりにこのサービスを見つけた。地図サービスをクラウド連携することで、住所やランドマークから周辺にある喫茶店を探すPHPプログラムを作ってみる。

(2022年3月19日)Leafletでマップ移動時に緯度・経度を拾わない不具合を修正した。

目次

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

PHPでホットペッパーを利用して喫茶店を検索する
Googleマップ表示
「住所」に、住所やランドマーク、緯度経度を入力して「検索」ボタンをクリックすると、近くにある喫茶店がマップ上に表示されるとともに、一覧表示される。

サンプル・プログラム

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

準備:pahooGeoCode クラス

0037: class pahooGeoCode {
0038:     var $items;      //検索結果格納用
0039:     var $error;      //エラーフラグ
0040:     var $hits;       //検索ヒット件数
0041:     var $webapi; //直前に呼び出したWebAPI URL
0042: 
0043:     //Google Cloud Platform APIキー
0044:     //https://cloud.google.com/maps-platform/
0045:     //※Google Maps APIを利用しないのなら登録不要
0046:     var $GOOGLE_API_KEY_1 = '**************************';   //HTTPリファラ用
0047:     var $GOOGLE_API_KEY_2 = '**************************';   //IP制限用
0048: 
0049:     //Yahoo! JAPAN Webサービス アプリケーションID
0050:     //https://e.developer.yahoo.co.jp/register
0051:     //※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
0052:     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が必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPIの登録方法」を、それぞれ参照されたい。

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

0038: //地図描画サービスの選択
0039: //    0:Google
0040: //    2:地理院地図・OSM
0041: define('MAPSERVICE', 2);
0042: 
0043: //住所検索サービスの選択
0044: //    0:Google
0045: //    1:Yahoo!JAPAN
0046: //   11:HeartRails Geo API
0047: //   12:OSM Nominatim Search API
0048: define('GEOSERVICE', 1);
0049: 
0050: //逆ジオコーディングサービスの選択
0051: //    0:Google
0052: //    1:Yahoo!JAPAN
0053: //   11:HeartRails Geo API
0054: //   21:簡易ジオコーディングサービス
0055: define('REVGEOSERVICE', 21);

表示する地図は、Googleマップ地理院地図・オープンストリートマップ(OSM)から選べる。あらかじめ、定数 MAPSERVIC に値を設定すること。
住所検索サービスは、GoogleYahoo!JAPANHeartRails Geo APIOSM Nominatim Search API から選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
逆ジオコーディングサービスは、GoogleYahoo!JAPANHeartRails Geo API簡易ジオコーディングサービスから選べる。あらかじめ、定数 REVGEOSERVICE に値を設定すること。
PHPでホットペッパーを利用して喫茶店を検索する
Open Streetマップ表示

ホットペッパー グルメサーチAPI

ホットペッパー グルメサーチAPIは、入力パラメータ(IN)として GET方式を、出力結果(OUT)がXMLまたはJSONで戻るというAPIである。
WebAPIのURL
URL
http://webservice.recruit.co.jp/hotpepper/gourmet/v1/

入力パラメータ
フィールド名 要否 内  容
key 必須 APIキー
lat 必須 緯度
lng 必須 経度
range 必須 検索範囲
1: 300m
2: 500m
3: 1000m (初期値)
4: 2000m
5: 3000m
datum 任意 world: 世界測地系、tokyo: 旧日本測地系。初期値は world。
genre 任意 お店ジャンルコード。本プログラムでは定数HOTPEPPER_GENREで指定。
count 任意 検索結果の最大出力データ数を指定します。初期値:10、宰相:1、最大100。
format 任意 レスポンス形式。初期値:xml。xml または json または jsonp。
応答データ構造(json) results shop id お店ID name 掲載店名 address 住所 lat 緯度(世界測地系) lng 経度(世界測地系) open 営業時間 close 定休日 genre catch お店ジャンルキャッチ urls pc PC向けURL photo pc l PC用店舗トップ写真(大)画像URL m PC用店舗トップ写真(中)画像URL s PC用店舗トップ写真(小)画像URL wifi Wi-Fi有無 shop id お店ID name 掲載店名 address 住所 lat 緯度(世界測地系) lng 経度(世界測地系) open 営業時間 close 定休日 genre catch お店ジャンルキャッチ urls pc PC向けURL photo pc l PC用店舗トップ写真(大)画像URL m PC用店舗トップ写真(中)画像URL s PC用店舗トップ写真(小)画像URL wifi Wi-Fi有無

解説:喫茶店を検索

0245: /**
0246:  * グルメサーチAPIのURLを取得する
0247:  * @param   double $latitude  緯度(世界測地系)
0248:  * @param   double $longitude 経度(世界測地系)
0249:  * @param   double $distance  範囲(メートル)
0250:  * @param   string $genre     ジャンルID
0251:  * @return  string URL グルメサーチAPIのURL
0252: */
0253: function getURL_GourmetSearchAPI($latitude$longitude$distance$genre) {
0254:     $range_tbl = array(1=>300, 2=>500, 3=>1000, 4=>2000, 5=>3000);
0255: 
0256:     $apikey = HOTPEPPER_ACCESSKEY;
0257:     $counts = HOTPEPPER_COUNTS;
0258:     $range = count($range_tbl);
0259:     foreach ($range_tbl as $key=>$val) {
0260:         if ($distance <= $val) {
0261:             $range = $key;
0262:             break;
0263:         }
0264:     }
0265: 
0266:     $url = "http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key={$apikey}&&lat={$latitude}&lng={$longitude}&range={$range}&genre={$genre}&datum=world&count={$counts}&format=json";
0267: 
0268:     return $url;
0269: }

0271: /**
0272:  * グルメサーチAPIを利用して指定座標の近くにある喫茶店を検索
0273:  * @param   double $latitude  緯度(世界測地系)
0274:  * @param   double $longitude 経度(世界測地系)
0275:  * @param   double $distance  範囲(メートル)
0276:  * @param   array $items 情報を格納する配列
0277:  * @return  array(ヒットした施設数, メッセージ, APIのURL)
0278: */
0279: function searchCafe($latitude$longitude$distance, &$items) {
0280:     $msg = '';
0281:     $url = getURL_GourmetSearchAPI($latitude$longitude$distanceHOTPEPPER_GENRE);
0282:     $data = @file_get_contents($url);
0283:     $json = json_decode($data);
0284: 
0285:     //レスポンス・チェック
0286:     if (($data == FALSE|| ($json == NULL)) {
0287:         if (isset($json->results->results_available) && ((int)($json->results->results_available) <= 0)) {
0288:             $msg = '検索範囲に店舗が無いか,ホットペッパーAPIのエラーです';
0289:         }
0290:         return array(FALSE$msg$url);
0291:     }
0292: 
0293:     //応答解釈
0294:     $n = 1;
0295:     foreach ($json->results->shop as $element) {
0296:         $items[$n]['id']        = num2alpha($n);
0297:         $items[$n]['title']     = (string)$element->name;
0298:         $items[$n]['url']       = (string)$element->urls->pc;
0299:         $items[$n]['category']  = (string)$element->genre->catch;
0300:         $items[$n]['open']      = (string)$element->open;
0301:         $items[$n]['close']     = (string)$element->close;
0302:         $items[$n]['address']   = (string)$element->address;
0303:         $items[$n]['image']     = (string)$element->photo->pc->l;
0304:         $items[$n]['latitude']  = (double)$element->lat;
0305:         $items[$n]['longitude'] = (double)$element->lng;
0306: $items[$n]['description'] =<<< EOT
0307: <span class="small"><a href="{$items[$n]['url']}" target="_blank">{$items[$n]['title']}</a><br />{$items[$n]['address']}<br />営業時間:{$items[$n]['open']}/定休日:{$items[$n]['close']}<br /><img src="{$items[$n]['image']}" /></span>
0308: EOT;
0309:         $n++;
0310:     }
0311: 
0312:     return array($n, '', $url);
0313: }

WebAPIを呼び出して結果を受け取るのはユーザー関数 searchCafe である。結果は配列変数 $items に格納する。
その他のプログラムの流れは、「PHPで電源・WiFi利用可能店舗を検索する」とほぼ同じである。

参考サイト

(この項おわり)
header