PHPでキーワード・郵便番号から住所を検索

(1/1)
PHPで住所・ランドマークから緯度・経度を求める」を拡張し、都道府県一覧、キーワード、緯度・経度、郵便番号から住所を検索するプログラムをつくる。また、検索した住所に対応する地図を表示する。WebAPIとしては、HeartRails Geo API を中心にクラウド連携する。

(2022年2月12日)PHP8対応,リファラ・チェック改良

実行例

PHPでキーワード・郵便番号から住所を検索
Googleマップ表示

サンプル・プログラム

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

プログラムの流れ

初期状態では、都道府県情報取得APIを呼び出し、都道府県を一覧表示する。
PHPでキーワード・郵便番号から住所を検索
都道府県を選択すると、市区町村情報取得APIを呼び出し、市区町村を一覧表示する。
PHPでキーワード・郵便番号から住所を検索
市区町村を選択すると、町域情報取得情報取得APIを呼び出し、町域を一覧表示する。
PHPでキーワード・郵便番号から住所を検索
町域を選択すると、キーワードによる住所検索APIを呼び出し、住所を表示する。
なお、HeartRails Geo APIの仕様上、字名 (あざめい) の読み仮名は取得できない。定数 GETRUBYTRUE にすることで、gooラボ ひらがな化API を使って読み仮名を取得できるが、必ずしも正しい読み仮名という保証はできない。
PHPでキーワード・郵便番号から住所を検索
[地図]リンクをクリックすると、当該住所の地図を表示する。
PHPでキーワード・郵便番号から住所を検索
キーワード検索では、ダイレクトに住所を検索・表示する。
キーワードは、住所の一部や、平仮名による検索もできる。
PHPでキーワード・郵便番号から住所を検索
郵便番号は、半角・全角ともに指定可能で、ハイフンの有無は問わない。
郵便番号が入力されると、郵便番号による住所検索APIを呼び出し、住所を表示する。
PHPでキーワード・郵便番号から住所を検索

準備: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の登録方法」を、Yahoo!JAPAN を利用するのであれば、Yahoo! JAPAN Webサービス アプリケーションIDが必要で、その入手方法は「Google Cloud Platform - WebAPIの登録方法」を、それぞれ参照されたい。

準備:pahooNormalizeText クラス

  12: class pahooNormalizeText {
  13:     var $items;     //検索結果格納用
  14:     var $error;     //エラーフラグ
  15:     var $errmsg;    //エラーメッセージ
  16:     var $hits;      //検索ヒット件数
  17:     var $webapi;    //直前に呼び出したWebAPI URL
  18: 
  19:     //Yahoo! JAPAN Webサービス アプリケーションID
  20:     //https://developers.google.com/maps/documentation/javascript/get-api-key
  21:     var $YAHOO_APPLICATION_ID = '**********************************';
  22: 
  23:     //gooラボ アプリケーションID
  24:     //https://labs.goo.ne.jp/apiregister/
  25:     var $GOOLABS_APPLICATION_ID = '***********************************';
  26: 
  27:     //MeCabの実行プログラム;各自の環境に合わせて変更のこと
  28:     var $MECAB = 'C:\Program Files\MeCab\bin\mecab.exe';
  29:     //ユーザー辞書
  30:     var $FILE_UDIC_MECAB =  'C:\Program Files\MeCab\dic\user_wiki.dic';
  31:     //特殊変換ファイル名
  32:     var $FILE_SPECIAL = 'special_table.txt';
  33: 
  34:     //正規化モード
  35:     var $OPTION_SPC_TRIM1 = 't';        //行頭・行末の空白文字を除く
  36:     var $OPTION_SPC_TRIM2 = 'T';        //全角文字と隣り合う空白文字を除く
  37:     var $OPTION_NUM_HAN   = 'n';        //数字を半角に統一
  38:     var $OPTION_NUM_ZEN   = 'N';        //数字を全角に統一
  39:     var $OPTION_NUM_KAN   = 'K';        //数字を漢字に統一
  40:     var $OPTION_ALP_HAN   = 'a';        //英字を半角に統一
  41:     var $OPTION_ALP_ZEN   = 'A';        //英字を全角に統一
  42:     var $OPTION_YAK_HAN   = 'y';        //記号を半角に統一
  43:     var $OPTION_YAK_ZEN   = 'Y';        //記号を全角に統一
  44:     var $OPTION_KATA_HAN  = 'h';        //カタカナを半角に統一
  45:     var $OPTION_KATA_ZEN  = 'H';        //カタカナを全角に統一
  46:     var $OPTION_SPEC_HAN  = 's';        //特殊文字を半角に統一
  47:     var $OPTION_SPEC_ZEN  = 'S';        //特殊文字を全角に統一
  48: 
  49:     //年号エスケープ記号(元号・西暦変換させない)
  50:     var $ESCYEAR = '\\';

テキストの全角・半角変換、西暦・和暦の変換、読み仮名の取得などを行うために、クラスファイル "pahooNormalizeText.php" を使用する。組み込み関数  require_once  を使って読めるディレクトリに配置する。ディレクトリは、設定ファイル php.ini に記述されているオプション設定 include_path に設定しておく。
クラスについては「PHPでクラスを使ってテキストの読みやすさを調べる」を参照されたい。

読み仮名の取得などに Yahoo!JAPAN を利用するのであれば、Yahoo! JAPAN Webサービス アプリケーションIDが必要で、その入手方法は「Yahoo!JAPAN デベロッパーネットワーク - WebAPIの登録方法」を、gooラボ を利用するのであれば、アプリケーションID が必要で、その入手方法は「gooラボ - WebAPIの登録方法」を、それぞれ参照されたい。

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

  37: //地図描画サービスの選択
  38: //    0:Google
  39: //    2:地理院地図・OSM
  40: define('MAPSERVICE', 0);

表示する地図は、Googleマップ地理院地図・オープンストリートマップ(OSM)から選べる。あらかじめ、定数 MAPSERVIC に値を設定すること。

解説:初期値

  46: //マップの表示サイズ(単位:ピクセル)
  47: define('MAP_WIDTH',  600);
  48: define('MAP_HEIGHT', 400);
  49: //マップID
  50: define('MAPID', 'map_id');
  51: //初期値
  52: define('DEF_TYPE',  'roadmap');     //マップタイプ
  53: define('DEF_ZOOM',  13);            //ズーム
  54: 
  55: //都道府県・市区町村一覧の表示列数
  56: define('COLUMNS', 3);

各種のデフォルト・パラメータは、これらの定数によって設定されている。自由に変更できる。

解説:検索実行

 491: //検索実行
 492: if ($query !'') {
 493:     $query = trim($query);
 494:     //郵便番号
 495:     if (preg_match('/^[\-0123456789-0123456789]+$/i', $query> 0) {
 496:         $q2 = mb_convert_kana($query, 'n');
 497:         $q2 = preg_replace('/[\-|-]/i', '', $q2);
 498:         $n = $pgc->searchByPostal_HeartRailsGeo($q2, $items);
 499:         if (GETRUBY)    getTownsKana($items);
 500:     //緯度・経度
 501:     } else if (preg_match('/E(\d+)\.(\d+)\.(\d+)\.(\d+)N(\d+)\.(\d+)\.(\d+)\.(\d+)/i', $query> 0) {
 502:         list($latitude, $longitude) = $pgc->parse_geo($query);
 503:         $res = $pgc->getHeartRailsGeo_Address($latitude, $longitude);
 504:         foreach ($res as $key=>$val)    $items[1][$key] = $val;
 505:         $items[1]['latitude'] = $latitude;
 506:         $items[1]['longitude'] = $longitude;
 507:     //キーワード
 508:     } else {
 509:         $n = $pgc->getPointsHeartRailsGeo_all($query, $items);
 510:         if (GETRUBY)    getTownsKana($items);
 511:     }
 512: else if ($city !'') {
 513:     $n = $pgc->getTowns_HeartRailsGeo($prefecture, $city, $items);
 514:     if (GETRUBY)    getTownsKana($items);
 515: else if ($prefecture !'') {
 516:     $n = $pgc->getCities_HeartRailsGeo($prefecture, $items);
 517: else {
 518:     $n = $pgc->getPrefectures_HeartRailsGeo($items);
 519: }
 520: 
 521: //地図作成
 522: if ($map) {
 523:     $jsmap = $pgc->drawJSMap(MAPID, $latitude, $longitude, DEF_TYPE, DEF_ZOOM, NULL, NULL, MAPSERVICE);
 524: else {
 525:     $jsmap = '';
 526: }
 527: 
 528: //表示HTML作成
 529: $HtmlBody = makeCommonBody($mode, $prefecture, $city, $query, $items, $jsmap, $pgc);

住所検索は、URLパラメータによって呼び出すWebAPIを切り替える。
キーワード $query がある場合は、その内容(パターン)によって、郵便番号、緯度・経度、キーワード検索のいずれかに仕分ける。

解説:字名の読み仮名取得

 188: /**
 189:  * 「gooラボ ひらがな化API」を用いて読み仮名を取得
 190:  * @param   string $sentence 解析するテキスト
 191:  * @return  string 読み仮名/FALSE:エラー
 192: */
 193: function getRuby_goo($sentence) {
 194:     //WebAPIにパラメータをPOST渡しする
 195:     $url = 'https://labs.goo.ne.jp/api/hiragana';
 196:     $post = array(
 197:         'app_id'       => $this->GOOLABS_APPLICATION_ID,
 198:         'sentence'     => $sentence,
 199:         'output_type'  => 'hiragana'
 200:     );
 201:     $cnt = 0;
 202:     $message = '';
 203: 
 204:     //API呼び出し
 205:     $this->webapi = $url;
 206:     $json = $this->post($url, $post);
 207:     if ($json == FALSE) {
 208:         $this->error  = TRUE;
 209:         $this->errmsg = 'WebAPI error: ' . $url;
 210:         return FALSE;
 211:     } else {
 212:         $obj = json_decode($json);
 213:         if (isset($obj->converted)) {
 214:             $res = (string)$obj->converted;
 215:         } else {
 216:             $this->error  = TRUE;
 217:             $this->errmsg = 'WebAPI error: ' . $url;
 218:             $res = FALSE;
 219:         }
 220:     }
 221: 
 222:     return $res;
 223: }

HeartRails Geo APIの仕様上、字名 (あざめい) の読み仮名は取得できない。そこで、定数 GETRUBYTRUE にすることで、gooラボ ひらがな化API を使って読み仮名を取得できるようにした。コールするメソッドは getRuby_goo である。

活用例

全国市区町村名・町域読み方調べ」(みんなの知識 ちょっと便利帳)では、このサンプル・プログラムを利用しやすいようにアレンジして掲載している。ありがとうございます。

参考サイト

(この項おわり)
header