PHPで住所・ランドマークから緯度・経度を求める

(1/1)
GoogleYahoo!JAPANHeartRailsOSM Nominatim のいずれかのジオコーディングサービスを利用し、住所や駅名などのランドマークから緯度・経度を求める PHP プログラムをつくり、流用できるようにクラス化する。
これらサービスのうち Google は全世界を対象として最も精度の高い検索が可能だが、有料サービスに移行したため(無料枠あり)、その他の無料利用できるサービスを選択できるようにしている。
ぱふぅ家のホームページで紹介するプログラムの住所検索機能は、すべてこのクラス pahooGeoCode を流用している。

(2020 年 3 月 21 日)OSM Nominatim Search API を利用できるようにした。
(2019 年 5 月 8 日)HeartRails Geo API を利用できるようにした。

目次

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

PHPで住所・ランドマークから緯度・経度を求める

サンプル・プログラム

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

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

PHPで住所・ランドマークから緯度・経度を求める

準備:pahooGeoCode クラス

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

準備:住所検索サービスの選択

0031: //住所検索サービスの選択
0032: //    0:Google
0033: //    1:Yahoo!JAPAN
0034: //   11:HeartRails Geo API
0035: //   12:OSM Nominatim Search API
0036: define('GEOSERVICE', 0);

住所検索に使う WebAPI は、GoogleYahoo!JAPANHeartRails Geo APIOSM Nominatim Search APIから選べる。あらかじめ、定数 GEOSERVICE に値を設定すること。
住所検索サービスの制約
サービス名 制 約
0 Google 有料(決められた無料枠あり)。全世界の住所、ランドマークの検索可能。
1 Yahoo!JAPAN 無料(?)。住所、ランドマーク、海外のどれを検索するか指定。ランドマークや海外地名検索はGoogleに劣る。
11 HeartRails Geo API 無料。住所、または住所の一部のみ検索可能。
12 OSM Nominatim Search API 無料。全世界の住所、ランドマークの検索可能。精度はGoogleに劣る。

「Google Geocoding API」による緯度・経度変換

Google Geocoding API」は、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は XML などで戻すという形である。今回使う入力パラメータと出力結果のデータ構造を以下に示す。
得られる緯度・経度は世界測地系(wgs84)であることに留意されたい。
WebAPIのURL
URL
https://maps.googleapis.com/maps/api/geocode/xml

入力パラメータ
フィールド名 要否 内  容
key 必須 APIキー
address 必須 住所やランドマーク(UTF-8)
language 任意 使用言語。ja など
sensor 任意 true または false
2007 年(平成 19 年)10 月現在、検索キーワードには住所や駅名だけでなく、「東京ディスニーランド」「出雲大社」といったランドマークの指定もできるようになっている。
応答データ構造(xml) GeocodeResponse status ステータス result type 検索結果のタイプ formatted_address 人間が読むことができる住所 address_component long_name 正式名称 short_name 略称 type 検索結果のタイプ geometry location lat 緯度 lng 経度

解説:GoogleMaps API Geocoding

0178: /**
0179:  * GoogleMaps API Geocoding(V3) のURLを取得する
0180:  * @param string $query 検索キーワード(UTF-8)
0181:  * @return string URL URL
0182: */
0183: function getURL_GeoCodeAPI_V3($query) {
0184:     $key = $this->GOOGLE_API_KEY_2;
0185:     return "https://maps.googleapis.com/maps/api/geocode/xml?key={$key}&language=ja&region=JP&address=" . urlencode($query);
0186: }

0188: /**
0189:  * Google Geocoding API(V3) を用いて住所・駅名の緯度・経度を求める
0190:  * @param string $query 検索キーワード
0191:  * @param array  $items 情報を格納する配列
0192:  * @return int ヒットした施設数/(-1):API呼び出し失敗
0193: */
0194: function getPointsV3_all($query, &$items) {
0195:     $url = $this->getURL_GeoCodeAPI_V3($query);   //リクエストURL
0196:     $this->webapi = $url;
0197:     $n = 1;
0198: 
0199: //PEAR::XML_Unserializer
0200:     if (class_exists('XML_Unserializer')) {
0201:         $xml = new XML_Unserializer();
0202:         $xml_data = file_get_contents($url);
0203:         $xml->unserialize($xml_data);
0204:         $arr = $xml->getUnserializedData();
0205:         //レスポンス・チェック
0206:         if (preg_match('/ok/i', $arr['status']) == 0)   return (-1);
0207:         //位置情報
0208:         if (isset($arr['result']['geometry'])) {
0209:             $items[$n]['latitude']  = $arr['result']['geometry']['location']['lat'];
0210:             $items[$n]['longitude'] = $arr['result']['geometry']['location']['lng'];
0211:             $items[$n]['address']   = $this->trimAddress($arr['result']['formatted_address']);
0212:             $n++;
0213:         } else {
0214:             foreach ($arr['result'] as $val) {
0215:                 $items[$n]['latitude']  = $val['geometry']['location']['lat'];
0216:                 $items[$n]['longitude'] = $val['geometry']['location']['lng'];
0217:                 $items[$n]['address']   = $this->trimAddress($val['formatted_address']);
0218:                 $n++;
0219:             }
0220:         }
0221:         $xml = NULL;
0222: 
0223: //PHP4用; DOM XML利用
0224:     } else if ($this->isphp5over() == FALSE) {
0225:         if (($dom = $this->read_xml($url)) == NULL)  return FALSE;
0226:         $gr = $dom->get_elements_by_tagname('GeocodeResponse');
0227:         //レスポンス・チェック
0228:         $res  = $gr[0]->get_elements_by_tagname('status');
0229:         if (preg_match("/ok/i", $res[0]->get_content()) == 0)  return 0;
0230:         //位置情報
0231:         $res = $gr[0]->get_elements_by_tagname('result');
0232:         foreach ($res as $val) {
0233:             $geo = $val->get_elements_by_tagname('geometry');
0234:             $loc = $geo[0]->get_elements_by_tagname('location');
0235:             $lat = $loc[0]->get_elements_by_tagname('lat');
0236:             $items[$n]['latitude'] = (double)$lat[0]->get_content();
0237:             $lng = $loc[0]->get_elements_by_tagname('lng');
0238:             $items[$n]['longitude'] = (double)$lng[0]->get_content();
0239:             $addr = $val->get_elements_by_tagname('formatted_address');
0240:             $items[$n]['address'] = $this->trimAddress((string)$addr[0]->get_content());
0241:             $n++;
0242:         }
0243: //PHP5用; SimpleXML利用
0244:     } else {
0245:         $this->unknown_certificate();
0246:         $res = simplexml_load_file($url);
0247:         //レスポンス・チェック
0248:         if (preg_match("/ok/i", $res->status) == 0)        return 0;
0249:         foreach ($res->result as $element) {
0250:             $items[$n]['latitude']  = (double)$element->geometry->location->lat;
0251:             $items[$n]['longitude'] = (double)$element->geometry->location->lng;
0252:             $items[$n]['address']   = $this->trimAddress((string)$element->formatted_address);
0253:             $n++;
0254:         }
0255:     }
0256:     return ($n - 1);
0257: }

WebAPI の呼び出しと、応答(XML データ)の処理は、これまでと同様である。
検索結果が複数ある場合に備え、緯度・経度・人間が読める住所のセットを、連想配列のプロパティ $items に格納しておく。

「YOLPコンテンツジオコーダAPI」による緯度・経度変換

YOLP コンテンツジオコーダ API」は、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は XML などで戻すという形である。今回使う入力パラメータと出力結果のデータ構造を以下に示す。
得られる緯度・経度は世界測地系(wgs84)であることに留意されたい。
WebAPIのURL
URL
https://map.yahooapis.jp/geocode/cont/V1/contentsGeoCoder

入力パラメータ
フィールド名 要否 内  容
appid 必須 アプリケーションID
query 必須 住所やランドマーク
ei 任意 文字エンコード:UTF-8(デフォルト)/EUC-JP/SJISなど
category 任意 検索対象カテゴリ:address(デフォルト)/landmark/world
results 任意 表示件数:最大10(デフォルト)
output 任意 出力形式:xml(デフォルト)/json
callback 任意 JSONPとして出力する際のコールバック関数名を入力するためのパラメータ。UTF-8でエンコードした文字列を入力する。
応答データ構造(xml) YDF ResultInfo Count データ件数 Total 全データ件数 Start 取得開始位置 Latency 応答時間 Status 処理結果(正常時200) Description 文字列解析結果 Copyright CompressType Feature Id ID Name 部分住所 Description 記載 Geometry Type 図形種別 Coordinates 経度,緯度 Property Genre ジャンルコード Query 検索クエリ Address 住所 AddressKana 住所読み AddressElement Name 部分住所

解説:YOLPコンテンツジオコーダAPI

1086: /**
1087:  * YOLPコンテンツジオコーダAPI のリクエストURLを取得する
1088:  * @param string $query 検索キーワード(UTF-8)
1089:  * @param string $category 検索対象カテゴリ
1090:  *                           address  = 住所(省略時)
1091:  *                           landmark = ランドマーク
1092:  *                           world    = 世界
1093:  * @return string URL リクエストURL
1094: */
1095: function getURL_YOLP_GeoCoder($query$category='address') {
1096:     $appid = $this->YAHOO_APPLICATION_ID;
1097:     return "https://map.yahooapis.jp/geocode/cont/V1/contentsGeoCoder?appid={$appid}&el=UTF-8&output=xml&category={$category}&query=" . urlencode($query);
1098: }

1100: /**
1101:  * YOLPコンテンツジオコーダAPI を用いて住所・駅名の緯度・経度を求める
1102:  * @param string $query 検索キーワード
1103:  * @param array  $items 情報を格納する配列
1104:  * @param string $category 検索対象カテゴリ
1105:  *                           address  = 住所(省略時)
1106:  *                           landmark = ランドマーク
1107:  *                           world    = 世界
1108:  * @return int ヒットした施設数/(-1):API呼び出し失敗
1109: */
1110: function getPointsYOLP_all($query, &$items$category='address') {
1111:     $url = $this->getURL_YOLP_GeoCoder($query$category);    //リクエストURL
1112:     $this->webapi = $url;
1113:     $n = 1;
1114: 
1115:     $this->unknown_certificate();
1116:     $res = simplexml_load_file($url);
1117:     //レスポンス・チェック
1118:     if (!isset($res->ResultInfo)) return (-1);
1119:     if (isset($res->ResultInfo->Total) && ((int)$res->ResultInfo->Total <= 0))  return 0;        //v.5.73追加
1120: 
1121:     foreach ($res->Feature as $element) {
1122:         if (preg_match('/([\-0-9\.]+)\,([\-0-9\.]+)/i', $element->Geometry->Coordinates$arr) > 0) {
1123:             if (isset($arr[1]) && isset($arr[2])) {
1124:                 $items[$n]['latitude']  = (double)$arr[2];
1125:                 $items[$n]['longitude'] = (double)$arr[1];
1126:                 $items[$n]['address']   = (string)$element->Property->Address;
1127:                 $n++;
1128:             }
1129:         }
1130:     }
1131: 
1132:     return ($n - 1);
1133: }

WebAPI の呼び出しと、応答(XML データ)の処理は、これまでと同様である。
検索結果が複数ある場合に備え、緯度・経度・住所のセットを、連想配列のプロパティ $items に格納しておく。

1135: /**
1136:  * YOLPコンテンツジオコーダAPI のカテゴリ選択ラジオボタンの生成
1137:  * @param string $name    HTML name
1138:  * @param string $default デフォルト値(省略可能)
1139:  * @return string HTML
1140: */
1141: function makeYOLP_GeoSelectCategory($name$default='') {
1142:     //デフォルト値設定
1143:     if (isset($this->YOLP_GeoCategory[$default])) {
1144:         foreach ($this->YOLP_GeoCategory as $key=>$item) {
1145:             $item[$key]['checked'] = '';
1146:         }
1147:         $this->YOLP_GeoCategory[$default]['checked'] = 'checked';
1148:     }
1149:     //選択ラジオボタンの生成
1150:     $html = '';
1151:     $i = 1;
1152:     foreach ($this->YOLP_GeoCategory as $key=>$val) {
1153:         $html .= "<input type=\"radio\" name=\"{$name}\" value=\"{$key}\" {$val['checked']} />{$val['title']} ";
1154:         $i++;
1155:     }
1156:     return $html;
1157: }

1167: /**
1168:  * checkedされているカテゴリを検索する
1169:  * @return string 選択された関数名/FALSE=checkedされている処理がない
1170: */
1171: function getYOLP_GeoSelectCategory() {
1172:     foreach ($this->YOLP_GeoCategory as $key=>$val) {
1173:         if ($val['checked'] == 'checked')    return $key;
1174:     }
1175: 
1176:     return FALSE;
1177: }

1179: /**
1180:  * カテゴリをchekedする
1181:  * @param string $val カテゴリ値
1182:  * @return bool TRUE/FALSE
1183: */
1184: function setYOLP_GeoSelectCategory($val) {
1185:     $old = $this->getYOLP_GeoSelectCategory();
1186:     if ($val != FALSE)   $this->YOLP_GeoCategory[$old]['checked'] = '';
1187:     $this->YOLP_GeoCategory[$val]['checked'] = 'checked';
1188: 
1189:     return TRUE;
1190: }

YOLP コンテンツジオコーダ API では、住所、ランドマーク、海外を指定する必要があり、これらを指定しやすくするためのユーザー関数を用意した。

「HeartRails Geo API」による緯度・経度変換

HeartRails Geo API - キーワードによる住所検索 API」は、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は XML などで戻すという形である。今回使う入力パラメータと出力結果のデータ構造を以下に示す。
得られる緯度・経度は世界測地系(wgs84)であることに留意されたい。
WebAPIのURL
URL
http://geoapi.heartrails.com/api/xml?method=suggest

入力パラメータ
フィールド名 要否 内  容
method 必須 メソッド名:suggest(固定)
keyword 必須 検索キーワード(UTF-8でURLエンコード)
matching 必須 prefix(前方一致)、like(部分一致)、suffix(後方一致)のいずれか
応答データ構造(xml) response location city 市区町村名 city-kana 市区町村名よみ(平仮名) town 町域名 town-kana 町域名よみ(平仮名) x 経度(世界測値系) y 緯度(世界測値系) prefecture 都道府県名 postal 郵便番号(ハイフンなし)

解説:HeartRails Geo API

1325: /**
1326:  * HeartRails Geo API - 住所検索APIを用いて住所の緯度・経度を求める
1327:  * @param string $query 検索キーワード:住所のみ(UTF-8)
1328:  * @param array  $items 情報を格納する配列
1329:  * @param string $matching 検索方式
1330:  *                             prefix = 前方一致
1331:  *                             like   = 部分一致(省略時)
1332:  *                             suffix = 後方一致
1333:  * @return int ヒットした地点数/(-1):API呼び出し失敗
1334: */
1335: function getPointsHeartRailsGeo_all($query, &$items$matching='like') {
1336:     //リクエストURL
1337:     $url = "http://geoapi.heartrails.com/api/xml?method=suggest&matching={$matching}&keyword=" . urlencode($query);
1338:     $this->webapi = $url;
1339:     $n = 1;
1340: 
1341:     $this->unknown_certificate();
1342:     $res = simplexml_load_file($url);
1343:     //レスポンス・チェック
1344:     if (isset($res->error)) {
1345:         $this->error = TRUE;
1346:         $this->errmsg = (string)$res->error;
1347:         $n = 0;
1348:     } else if (! isset($res->location)) {
1349:         $this->error = TRUE;
1350:         $this->errmsg = 'Not found';
1351:         $n = 1;
1352:     } else {
1353:         foreach ($res->location as $element) {
1354:             $items[$n]['latitude']   = (double)$element->y;
1355:             $items[$n]['longitude']  = (double)$element->x;
1356:             $items[$n]['prefecture'] = (string)$element->prefecture;
1357:             $items[$n]['city']       = (string)$element->city;
1358:             $items[$n]['city_kana']  = (string)$element->{'city-kana'};
1359:             $items[$n]['town']       = (string)$element->town;
1360:             $items[$n]['town_kana']  = (string)$element->{'town-kana'};
1361:             $items[$n]['postal']     = (string)$element->postal;
1362:             $items[$n]['address']    = (string)$element->prefecture . (string)$element->city . (string)$element->town;
1363:             $n++;
1364:         }
1365:     }
1366: 
1367:     return ($n - 1);
1368: }

WebAPI の呼び出しと、応答(XML データ)の処理は、これまでと同様である。
検索結果が複数ある場合に備え、緯度・経度・住所のセットを、連想配列のプロパティ $items に格納しておく。

「OSM Nominatim Search API」による緯度・経度変換

OSM Nominatim Search API」は、誰でも自由に地図を使えるよう、みんなでオープンデータの地理情報を作る「OpenStreetMap」(OSM)プロジェクトに含まれる WebAPI で、入力パラメータ(IN)は GET 渡しで、出力結果(OUT)は XML などで戻すという形である。今回使う入力パラメータと出力結果のデータ構造を以下に示す。得られる緯度・経度は世界測地系(wgs84)であることに留意されたい。
WebAPIのURL
URL
https://nominatim.openstreetmap.org/search

入力パラメータ
フィールド名 要否 内  容
format 任意 出力形式。html|xml|json|jsonv2。省略時はhtml
q 必須 住所やランドマーク(UTF-8)
json_callback 任意 json の出力をラップするコールバック関数(JSONP)
addressdetails 任意 住所の要素への細分化を含むかどうか。0|1。省略時は0
2020 年(令和 2 年)3 月現在、API コール時に User-Agent を含める必要がある。
応答データ構造(json) place_id ID lon 経度(世界測値系) lat 緯度(世界測値系) display_name 住所,郵便番号など license ライセンス

解説:OSM Nominatim Search API

1561: /**
1562:  * OSM Nominatim Search API - 住所検索APIを用いて住所の緯度・経度を求める
1563:  * @param string $query 検索キーワード:住所のみ(UTF-8)
1564:  * @param array  $items 情報を格納する配列
1565:  * @return int ヒットした地点数/(-1):API呼び出し失敗
1566: */
1567: function getPointsNominatim_all($query, &$items) {
1568:     //リクエストURL
1569:     $url = 'https://nominatim.openstreetmap.org/search?format=json&q=' . urlencode($query);
1570:     $this->webapi = $url;
1571:     $n = 1;
1572: 
1573:     //User-Agent偽装
1574:     $header = array(
1575:         'Content-Type: application/x-www-form-urlencoded',
1576:         'User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:13.0) Gecko/20100101 Firefox/13.0.1'
1577:     );
1578:     $stream = stream_context_create(array(
1579:         'http' => array(
1580:             'method' => 'GET',
1581:             'header' => implode("\r\n", $header),
1582:             'ignore_errors'=>TRUE
1583:         )
1584:     ));
1585:     $json = file_get_contents($urlFALSE$stream);
1586: 
1587:     //レスポンス・チェック
1588:     if ($json == FALSE) {
1589:         $this->error = TRUE;
1590:         $this->errmsg = '';
1591:         $n = 0;
1592:     } else {
1593:         if ($this->isphp7over()) {
1594:             $res = @json_decode($jsonFALSE, 512, JSON_BIGINT_AS_STRING);
1595:         } else {
1596:             $res = @json_decode($jsonFALSE, 512);
1597:         }
1598:         foreach ($res as $element) {
1599:             $items[$n]['latitude']   = (double)$element->lat;
1600:             $items[$n]['longitude']  = (double)$element->lon;
1601:             $items[$n]['address']    = (string)$element->display_name;
1602:             $n++;
1603:         }
1604:     }
1605:     if ($n == 1) {
1606:         $this->error = TRUE;
1607:         $this->errmsg = 'Not found';
1608:     }
1609: 
1610:     return ($n - 1);
1611: }

出力形式は JSON を選択した。
WebAPI の呼び出し時、User-Agent を設定する目的で、 stream_context_create  関数を利用し、 file_get_contents  関数を呼び出している。
 json_decode  関数の呼び出しは、BIGINT の扱いが異なる PHP 7 以上と未満で場合分けしている。
検索結果が複数ある場合に備え、緯度・経度・人間が読める住所のセットを、連想配列のプロパティ $items に格納しておく。

解説:検索と結果取得

1804: /**
1805:  * ジオコーダAPI を用いて住所・ランドマークの緯度・経度を検索
1806:  *
1807:  * @param string $query 検索キーワード(UTF-8)
1808:  * @param int    $api    0:Google Geocoding API(省略時)
1809:  *                         1:Yahoo!ジオコーダAPI
1810:  *                        11:HeartRails Geo API
1811:  *                        12:OSM Nominatim Search API
1812:  * @param string $category 検索対象カテゴリ(YOLPのみ必要)
1813:  *                           address  = 住所(省略時)
1814:  *                           landmark = ランドマーク
1815:  *                           world    = 世界
1816:  * @return array(int ヒットした地点数,string WebAPI)
1817: */
1818: function searchPoint3($query$api=0, $category='address') {
1819:     static $pat1 = '/E(\d+\.?\d*)N(\d+\.?\d*)/i';
1820:     static $pat2 = '/E(\d+)\.(\d+)\.(\d+)\.(\d+)N(\d+)\.(\d+)\.(\d+)\.(\d+)/i';
1821: 
1822:     unset($this->items);
1823:     $this->items = array();
1824:     $this->hits = 0;
1825: 
1826:     //緯度・経度表記(1)
1827:     if (preg_match($pat1$query) > 0) {
1828:         list($this->items[1]['latitude'], $this->items[1]['longitude']) =
1829:             $this->parse_geo($query);
1830:         $this->items[1]['address'] = '';
1831:         $this->hits = 1;
1832: 
1833:     //緯度・経度表記(2)
1834:     } else if (preg_match($pat2$query) > 0) {
1835:         list($this->items[1]['latitude'], $this->items[1]['longitude']) =
1836:             $this->parse_geo($query);
1837:         $this->items[1]['address'] = '';
1838:         $this->hits = 1;
1839: 
1840:     //Google Geocoding API使用
1841:     } else if ($api == 0) {
1842:         $n = $this->getPointsV3_all($query$this->items);
1843:         if ($n == (-1)) { //v.5.73修正
1844:             $this->error  = TRUE;
1845:             $this->errmsg = 'Google Geocoding APIにトラブル発生';
1846:             $this->hits = 0;
1847:         } else if ($n == 0) {
1848:             $this->error  = TRUE;
1849:             $this->errmsg = '指定キーワードでは検索できない';
1850:             $this->hits = 0;
1851:         } else {
1852:             $this->hits = $n;
1853:         }
1854: 
1855:     //Yahoo!ジオコーダAPI使用
1856:     } else if ($api == 1) {
1857:         $n = $this->getPointsYOLP_all($query$this->items$category);
1858:         if ($n == (-1)) { //v.5.73修正
1859:             $this->error  = TRUE;
1860:             $this->errmsg = 'Yahoo!ジオコーダAPIにトラブル発生';
1861:             $this->hits = 0;
1862:         } else if ($n == 0) {
1863:             $this->error  = TRUE;
1864:             $this->errmsg = '指定キーワードでは検索できない';
1865:             $this->hits = 0;
1866:         } else {
1867:             $this->hits = $n;
1868:         }
1869: 
1870:     //HeartRails Geo API使用
1871:     } else if ($api == 11) {
1872:         $n = $this->getPointsHeartRailsGeo_all($query$this->items, 'like');
1873:         if ($n == (-1)) { //v.5.73修正
1874:             $this->hits = 0;
1875:         } else if ($n == 0) {
1876:             $this->errmsg = '指定キーワードでは検索できない';
1877:             $this->hits = 0;
1878:         } else {
1879:             $this->hits = $n;
1880:         }
1881: 
1882:     //OSM Nominatim Search API使用
1883:     } else if ($api == 12) {
1884:         $n = $this->getPointsNominatim_all($query$this->items);
1885:         if ($n == (-1)) {
1886:             $this->errmsg = 'OSM Nominatim Search APIにトラブル発生';
1887:             $this->hits = 0;
1888:         } else if ($n == 0) {
1889:             $this->errmsg = '指定キーワードでは検索できない';
1890:             $this->hits = 0;
1891:         } else {
1892:             $this->hits = $n;
1893:         }
1894: 
1895:     //エラー
1896:     } else {
1897:         $this->error  = TRUE;
1898:         $this->errmsg = 'ジオコーダーAPIの指定間違い';
1899:         $this->hits = 0;
1900:     }
1901: 
1902:     return array($this->hits$this->webapi);
1903: }

メソッド searchPoint3 は、引数の形式に応じて、緯度・経度表記なら値を分離し、それ以外なら引数 $api の値によって、Google用メソッド getPointsV3_all、Yahoo!用メソッド getPointsYOLP_all、HeartRails Geo API用メソッド getPointsHeartRailsGeo_all、OSM Nominatim Search API用メソッド getPointsNominatim_all を呼び出す。
結果はプロパティ $items に格納する。戻り値としてヒットした件数を返す。

0324: /**
0325:  * 検索結果(緯度・経度)を取得
0326:  * @param int $id 取得したい地点番号
0327:  * @return array(緯度,経度,住所):世界測地系
0328: */
0329: function getPoint($id) {
0330:     if ($id <= 0 || $id > $this->hits) {
0331:         $this->error  = TRUE;
0332:         $this->errmsg = '不正な地点番号';
0333:         $latitude  = FALSE;
0334:         $longitude = FALSE;
0335:         $address   = FALSE;
0336:     } else {
0337:         $this->error  = FALSE;
0338:         $this->errmsg = '';
0339:         $latitude  = $this->items[$id]['latitude'];
0340:         $longitude = $this->items[$id]['longitude'];
0341:         $address   = $this->items[$id]['address'];
0342:     }
0343: 
0344:     return array($latitude$longitude$address);
0345: }

プロパティ $items に格納された情報を取り出すには、メソッド getPoint を使う。
引数の地点番号は、1 から順に増える正の整数である。最大値は searchPoint3 の戻り値である。

参考サイト

(この項おわり)
header