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

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

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

目次

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

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

サンプル・プログラム

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

準備:pahooGeoCode クラス

  37: class pahooGeoCode {
  38:     var $items;     //検索結果格納用
  39:     var $error;     //エラー・フラグ
  40:     var $errmsg;    //エラー・メッセージ
  41:     var $hits;      //検索ヒット件数
  42:     var $webapi;    //直前に呼び出したWebAPI URL
  43: 
  44:     //Google Cloud Platform APIキー
  45:     //https://cloud.google.com/maps-platform/
  46:     //※Google Maps APIを利用しないのなら登録不要
  47:     var $GOOGLE_API_KEY_1 = '**************************';   //HTTPリファラ用
  48:     var $GOOGLE_API_KEY_2 = '**************************';   //IP制限用
  49: 
  50:     //Yahoo! JAPAN Webサービス アプリケーションID
  51:     //https://e.developer.yahoo.co.jp/register
  52:     //※Yahoo! JAPAN Webサービスを利用しないのなら登録不要
  53:     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)の選択

  38: //地図描画サービスの選択
  39: //    0:Google
  40: //    2:地理院地図・OSM
  41: define('MAPSERVICE', 2);
  42: 
  43: //住所検索サービスの選択
  44: //    0:Google
  45: //    1:Yahoo!JAPAN
  46: //   11:HeartRails Geo API
  47: //   12:OSM Nominatim Search API
  48: define('GEOSERVICE', 1);
  49: 
  50: //逆ジオコーディングサービスの選択
  51: //    0:Google
  52: //    1:Yahoo!JAPAN
  53: //   11:HeartRails Geo API
  54: //   21:簡易ジオコーディングサービス
  55: 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
https://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有無

解説:喫茶店を検索

 245: /**
 246:  * グルメサーチAPIのURLを取得する
 247:  * @param   double $latitude  緯度(世界測地系)
 248:  * @param   double $longitude 経度(世界測地系)
 249:  * @param   double $distance  範囲(メートル)
 250:  * @param   string $genre     ジャンルID
 251:  * @return  string URL グルメサーチAPIのURL
 252: */
 253: function getURL_GourmetSearchAPI($latitude, $longitude, $distance, $genre) {
 254:     $range_tbl = array(1=>300, 2=>500, 3=>1000, 4=>2000, 5=>3000);
 255: 
 256:     $apikey = HOTPEPPER_ACCESSKEY;
 257:     $counts = HOTPEPPER_COUNTS;
 258:     $range = count($range_tbl);
 259:     foreach ($range_tbl as $key=>$val) {
 260:         if ($distance <$val) {
 261:             $range = $key;
 262:             break;
 263:         }
 264:     }
 265: 
 266:     $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";
 267: 
 268:     return $url;
 269: }

 271: /**
 272:  * グルメサーチAPIを利用して指定座標の近くにある喫茶店を検索
 273:  * @param   double $latitude  緯度(世界測地系)
 274:  * @param   double $longitude 経度(世界測地系)
 275:  * @param   double $distance  範囲(メートル)
 276:  * @param   array $items 情報を格納する配列
 277:  * @return  array(ヒットした施設数, メッセージ, APIのURL)
 278: */
 279: function searchCafe($latitude, $longitude, $distance, &$items) {
 280:     $msg = '';
 281:     $url = getURL_GourmetSearchAPI($latitude, $longitude, $distance, HOTPEPPER_GENRE);
 282:     $data = @file_get_contents($url);
 283:     $json = json_decode($data);
 284: 
 285:     //レスポンス・チェック
 286:     if (($data == FALSE|| ($json == NULL)) {
 287:         if (isset($json->results->results_available&& ((int)($json->results->results_available<0)) {
 288:             $msg = '検索範囲に店舗が無いか,ホットペッパーAPIのエラーです';
 289:         }
 290:         return array(FALSE, $msg, $url);
 291:     }
 292: 
 293:     //応答解釈
 294:     $n = 1;
 295:     foreach ($json->results->shop as $element) {
 296:         $items[$n]['id']        = num2alpha($n);
 297:         $items[$n]['title']     = (string)$element->name;
 298:         $items[$n]['url']       = (string)$element->urls->pc;
 299:         $items[$n]['category']  = (string)$element->genre->catch;
 300:         $items[$n]['open']      = (string)$element->open;
 301:         $items[$n]['close']     = (string)$element->close;
 302:         $items[$n]['address']   = (string)$element->address;
 303:         $items[$n]['image']     = (string)$element->photo->pc->l;
 304:         $items[$n]['latitude']  = (double)$element->lat;
 305:         $items[$n]['longitude'] = (double)$element->lng;
 306:         $items[$n]['description'] =<<< EOT
 307: <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>
 308: EOT;
 309:         $n++;
 310:     }
 311: 
 312:     return array($n, '', $url);
 313: }

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

参考サイト

(この項おわり)
header