Location: PHPKode > scripts > Geocoder > geocoder/Geocoder.inc
<?php
/**
 * Abstract superclass for Geocoder classes
 *
 * @author Jan Bruyndonckx
 * @copyright Copyright (c) 2008 Banzora   http://software.banzora.com
 * @package main
 * @subpackage lib
 *
*/

require_once "lib/HTTP/Request.php";
require_once "lib/HTTP/Header.php";
require_once "StringUtils.inc" ;
require_once "WorldGeocoder.inc" ;
require_once "GoogleGeocoder.inc" ;

/**
  Abstract class to geocode a location.
*/

define ('GEO_STRICT', true) ;

abstract class Geocoder
{
    protected $zipcode ;
    protected $city ;
    protected $state ;
    protected $country ;

    /**--------------------------------------------------------------------
    Constructor, takes zipcode, city and state as arguments.
    city & state are optional.
    */
    public function __construct ($country, $zipcode, $city=NULL, $state=NULL)
    {
        // maybe state is part of the city for the US
        if (($country == 'US') && ($state == NULL)) {
            $t = explode (',', $city) ;
            array_trim($t) ;
            $city = $t[0] ;
            if (isset ($t[1]) && (strlen ($t[1]) == 2)) {
                $state = $t[1] ;
            }
        }

        $this->country = $country ;
        $this->zipcode = $zipcode ;
        $this->city = $city ;
        $this->state = $state ;

        if ($this->zipcode != NULL)
        $this->zipcode = urlencode($this->zipcode) ;
        if ($this->city != NULL) {
            $this->city = urlencode(remove_accents($this->city)) ;
        }
    }

    /**--------------------------------------------------------------------
    Submit a geocoding query.
    Return NULL if query failed, or: array ("longitude"=>float, "latitude"=>float)
    */
    public function submit ()
    {
        $result = $this->submitQuery() ;
        if (($result == NULL) ||
        (is_array($result)))
        {
            return $this->createResult(NULL, NULL, "Could not geocode $this->city,$this->country") ;
        }
        return $this->parseResult ($result) ;
    }

    /**
		@return string the full url with parameters encoded
	*/
    abstract protected function createRequest () ;

    /**
		@param string the XML body as replied by the service
		@return array the result as made by createResult() or NULL
	*/
    abstract public function parseResult ($serviceURL) ;

    /**--------------------------------------------------------------------
    Perform the query to the internet service provider.
    Return NULL in case of error, or an xml text
    */
    private function submitQuery ()
    {
        $url=$this->createRequest() ;
        if ($url == NULL) {
            return NULL ;
        }
        $req = new HTTP_Request($url);
        $req->sendRequest() ;
        $header = new HTTP_Header () ;
        $code = $req->getResponseCode() ;
        //var_dump($code) ;
        if ($code == 400)
        {
            // bad request, probably zip code wrong?
            return $this->createResult (NULL, NULL, "bad_request") ;
        }
        if (!$header->isSuccessful($code))
        {
            return NULL;
        }

        return ($req->getResponseBody());
    }

    /**
	@return array the longitude and latitude as an array with the data as a key
	*/
    protected function createResult ($longitude, $latitude, $error=NULL)
    {
        return array (
        "latitude" => $latitude,
        "longitude" => $longitude,
        "error" => $error) ;
    }

    //---------------------------------------------------------------------
    /**
     * Geocode the address. If not found on the world geocoder, fall back on Google
     *
     * @param string $country
     * @param string $zipcode
     * @param string $city, optional
     * @param string $state, optional
     * @param boolean $strict, optional; use only world geocoder
     * @return array
     */
    static public function geoCode ($country, $zipcode, $city=NULL, $state=NULL, $strict=false) {

        //Logger::log ("geocode: $city, $country") ;

        // If we have a zipcode, then give precedence to Google
        if (($zipcode != NULL)) {
            $geo = new GoogleGeocoder ($country, $zipcode, $city, $state) ;
            $result = $geo->submit () ;
            if (!isset ($result['error'])) {
                return $result ;
            }
        }

        // not found, try world geocoder
        $geo = new WorldGeocoder($country, $zipcode, $city, $state) ;
        $result = $geo->submit () ;

        // not found, try google again (but now implicitly without zip)
        if (($strict == false) && isset($result['error'])) {

            $geo = new GoogleGeocoder ($country, $zipcode, $city, $state) ;
            $result = $geo->submit () ;
        }
        return $result ;
    }

    /**
     * Check if the city/country combination is correct by gettings its geocode
     *
     * @param string $city
     * @param string $country
     * @param boolean $strict
     * @return boolean
     */
    public static function checkValidPlace ($city, $country, $strict = false) {

        $geo = new WorldGeocoder($country, NULL, $city, NULL) ;
        $result = $geo->submit () ;
        $result = !(isset($result['error'])) ;

        if (($result == false) && ($strict === false)) {
            $geo = new GoogleGeocoder ($country, NULL, $city, NULL) ;
            $result = $geo->submit () ;
            $result = !(isset($result['error'])) ;
        }

        return $result ;
    }

}
// end class Geocoder

?>
Return current item: Geocoder