Yahoo!ジオコーダAPI | アプリケーションIDの登録~住所から緯度経度取得

公式: Yahoo!ジオコーダAPI

  1. まずはアプリケーションIDが必要なので、手続きを行う。
    Yahoo!デベロッパーネットワークのサイトにアクセス、「アプリケーション登録ページ」を開く。
  2. PHPファイルにアプリケーションIDを埋め込むので「サーバーサイド」を選択。
    他は適当に入力する。
  3. 登録が完了するとアプリケーションIDが発行されるので、控えを取得しておく。
  4. PHP側のコーディング。住所から緯度経度を取得する。
    PHP
    
    			<?php 
    			$app_id = "先ほど取得したアプリケーションID";
    			$place = "沖縄県国頭郡本部町石川424";// 住所
    			$place = urlencode($place);// URLエンコード
    			$url = "https://map.yahooapis.jp/geocode/V1/geoCoder?appid={$app_id}&query={$place}&results=1"; // XML系s機
    			//$url = "https://map.yahooapis.jp/geocode/V1/geoCoder?appid={$app_id}&query={$place}&results=1&output=json"; // JSON形式
    			$text = file_get_contents ($url);
    			var_dump($text);
    			?>
    			
    出力(緯度経度も取得できていることが分かる)
    <YDF xmlns="http://olp.yahooapis.jp/ydf/1.0" totalResultsReturned="1" totalResultsAvailable="1" firstResultPosition="1"><ResultInfo><Count>1</Count><Total>1</Total><Start>1</Start><Status>200</Status><Description></Description><Copyright></Copyright><Latency>0.014</Latency></ResultInfo><Feature><Id>47308.1.424</Id><Gid></Gid><Name>沖縄県国頭郡本部町石川(字)424</Name><Geometry><Type>point</Type><Coordinates>127.87798745,26.69430191</Coordinates><BoundingBox>127.87238745,26.68870191 127.88358745,26.69990191</BoundingBox></Geometry><Category/><Description></Description><Style/><Property><Uid>8408cdf99bc13cfe5f7451f14e00734ed5928a78</Uid><CassetteId>b22fee69b0dcaf2c2fe2d6a27906dafc</CassetteId><Yomi>オキナワケンクニガミグンモトブチョウイシカワ(アザ)</Yomi><Country><Code>JP</Code><Name>日本</Name></Country><Address>沖縄県国頭郡本部町石川(字)424</Address><GovernmentCode>47308</GovernmentCode><AddressMatchingLevel>6</AddressMatchingLevel><AddressType>地番・戸番</AddressType></Property></Feature></YDF>

Yahoo!ジオコーダAPI | CURL版により緯度経度取得率を高める

※2023年6月の時点において、CURLの方法は失敗するようだ。

file_get_contentsでは緯度経度取得に失敗することが多々ある。
CURLを用いると成功率はかなり高まるようだ。

PHP(CakePHP2)

	/**
	 * 一括緯度経度取得・バッチ処理 | Ajax 非同期通信
	 * @return string json
	 */
	public function bulk_latlng_bat(){
		$this->autoRender = false;//ビュー(ctp)を使わない。
		
		// 通信元から送信されてきたパラメータを取得する。
		$param_json = $_POST['key1'];
		$ent = json_decode($param_json,true);//JSON文字を配列に戻す
		
		$place = "東京都墨田区押上1丁目1-2";
		$place  = preg_replace("/( | )/", "", $place); // 住所中の空白を除去すると緯度経度取得の成功率が高まる。
		
		// $app_id = Configure::read('yahoo_api_key'); // Yahoo APIキー
		$app_id = 【あなたのAPIキー】
		

		// Yahoo!ジオコーダAPIを利用して住所から緯度経度を取得する  (住所によっては緯度経度が取得できないケースもあり)
		$base_url = "https://map.yahooapis.jp/geocode/V1/geoCoder?output=xml&appid={$app_id}";
		$param = '&query=' . $place;
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $base_url. $param);
		curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		$xml_str = curl_exec($curl);
		
		// XMLをパースして配列データに変化する
		$geoData =$this->xml2arr($xml_str);
		
		$find_flg = false; // true:緯度経度が見つかる, false:緯度経度が見つからない
		$lat = 0; // 緯度
		$lng = 0; // 経度
		if(!empty($geoData['Feature'])){
			if(!empty($geoData['Feature']['Geometry'])){
				if(!empty($geoData['Feature']['Geometry']['Coordinates'])){
					$find_flg = true;
					$coordinates = $geoData['Feature']['Geometry']['Coordinates'];
					$ary=explode(",", $coordinates);
					$lat = trim($ary[1]);
					$lng = trim($ary[0]);
				}
			}
		}
		
		・・・省略・・・

	}
	
	/**
	 * XMLテキストからデータ配列に変換する
	 *
	 * @note
	 * 多層構造であるとき、階層化の配列が0件でであるなら0件配列でなく空文字がセットされる。
	 * JSONとは完全な互換性はないので注意すること。
	 *
	 * @param string $xml_text XMLテキスト
	 * @return データ配列
	 */
	public function xml2arr($xml_text){
		// XML解析
		$data= new SimpleXMLElement($xml_text,
				LIBXML_COMPACT | LIBXML_NOERROR,
				false);
		
		// SimpleXMLElementオブジェクト型から配列データに変換する
		$this->obj2arr($data);
		
		return $data;
	}
	
	/**
	 * SimpleXMLElementのレスポンスのオブジェクトをデータ配列に変換する。
	 *
	 * @note
	 * 階層化の配列が0件である場合、0件配列でなく、空文字がセットされる。
	 * 高速化のため引数を参照型しており、レスポンスも兼ねている。
	 *
	 * @param array $data SimpleXMLElementオブジェクト → 配列データ
	 */
	private function obj2arr(&$data){
		
		if(is_array($data)){
			foreach($data as $i => &$chiled){
				$this->obj2arr($chiled);
			}
			unset($chiled);
		}elseif(is_object($data)){
			$count = $data->count();
			if(empty($count)){
				$data = '';
			}else{
				$data = get_object_vars($data);
				foreach($data as $i => &$chiled){
					$this->obj2arr($chiled);
				}
				unset($chiled);
			}
		}
	}