WEBサービスの地図なんかを使うときには、住所の緯度経度が必要なことが多い。住所から緯度経度を求めることをジオコーディングという。
といっても、これもWEBサービスで解決する。google geocodingだ。
といっても、これもWEBサービスで解決する。google geocodingだ。
基本的にZFに初めからあったAmazonクラスを元に作った。
My/Service/Google/Map.php
<?php
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
class My_Service_Google_Map {
private $_url = 'http://maps.google.com';
private $_apiKey;
private $_rest;
public function __construct($apiKey){
$this->_apiKey = $apiKey;
$this->_rest = new Zend_Rest_Client($this->_url);
}
public function geocode(array $options){
$options = array_merge(array('key' => $this->_apiKey), $options);
$this->_rest->getHttpClient()->resetParameters();
$response = $this->_rest->restGet('/maps/geo', $options);
if ($response->isError()) {
/**
* @see Zend_Service_Exception
*/
throw new Zend_Service_Exception('An error occurred sending request. Status code: '
. $response->getStatus());
}
$dom = new DOMDocument();
$dom->loadXML($response->getBody(), LIBXML_NOBLANKS);
self::_checkErrors($dom);
return new My_Service_Google_Geocode_Item($dom);
}
/**
* Check result for errors
*
* @param DOMDocument $dom
* @throws Zend_Service_Exception
* @return void
*/
private static function _checkErrors(DOMDocument $dom){
if ($dom->getElementsByTagName('code')->item(0)->nodeValue != '200') {
$message = 'google geoからレスポンスは帰って来たがエラー';
$code = $dom->getElementsByTagName('code')->item(0)->nodeValue;
/**
* @see Zend_Service_Exception
*/
throw new Zend_Service_Exception("$message ($code)");
}
}
}
My/Service/Google/Geocode/Item.php
<?php
class My_Service_Google_Geocode_Item
{
private $_dom;
/**
* Parse the given <Item> element
*
* @param DOMElement $dom
* @return void
*/
public function __construct($dom){
$this->_dom = $dom;
}
public function getCoordinates(){
return $this->_dom->getElementsByTagName('coordinates')->item(0)->nodeValue;
}
public function getLatitude(){
$coordinates = $this->getCoordinates();
$array = explode(',', $coordinates);
return $array[0];
}
public function getLongitude(){
$coordinates = $this->getCoordinates();
$array = explode(',', $coordinates);
return $array[1];
}
}
Amazonのクラスは基本的にXPathを使ってるんだけど、なぜかXPathでうまくいかなかったのと、XMLの規模自体がたいしたことないのでDomで完結させることにした。
getCoordinates()で、緯度・経度・高さのカンマ区切りデータが取れる。
で、高さが要らないのとなぜかGooglemapとかで要求される緯度・経度と順番が逆なのでgetLatitude()とgetLongitude()で、それぞれを取れるようにした。どっちがどっちだかいつもわからなくなるけど、とにかく逆だった。これで10分くらいはまった。
あと、基本的にgeocodingもGoogleMapの1機能のようなので、クラスとしてはGoogleMapサービスを請負う上記のクラスに組み込んだ。と言っても今はgeoしかないけど。そのうちGoogleMapとかもここに入るかも入らないかも。
後一番重要なことですが、まだそんなに使い込んでないので想定外ケースとかいらんコードとかあるかも。
ご利用は利用規約を確認のうえで。
コメントする