Zend Frameworkでgoogle geocoding

| | コメント(0) | トラックバック(0)
WEBサービスの地図なんかを使うときには、住所の緯度経度が必要なことが多い。住所から緯度経度を求めることをジオコーディングという。

といっても、これも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とかもここに入るかも入らないかも。

後一番重要なことですが、まだそんなに使い込んでないので想定外ケースとかいらんコードとかあるかも。

ご利用は利用規約を確認のうえで。





トラックバック(0)

このブログ記事を参照しているブログ一覧: Zend Frameworkでgoogle geocoding

このブログ記事に対するトラックバックURL: http://hirop0164.s326.xrea.com/mt/mt-tb.cgi/261

コメントする


画像の中に見える文字を入力してください。

ブックマーク

はてなブックマークに追加 Yahoo!ブックマークに登録 del.icio.us に登録 ライブドアクリップに追加 Google Bookmarks に追加

Ajax: 2009年5月: 月別アーカイブ

このブログ記事について

このページは、ぴろしが2009年2月15日 02:49に書いたブログ記事です。

ひとつ前のブログ記事は「Smartyで日付のselectボックスをあつかう」です。

次のブログ記事は「smartyでよく使いそうな自作プラグイン3-新着にNew!をつける」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。