在php

时间:2016-06-26 01:16:53

标签: php google-maps maps

我有一个包含超过13000个元组数据/地址的数据库表,我想使用php和geocoder来添加所有地址的纬度和经度。我已经这样做了,但它不断返回 over_query_limit 状态错误。我试图搜索,大多数人建议在我已经完成的地理编码器调用之间添加sleep(1),但无济于事。我想问一下,我是否有办法绕过这个状态,并为我的所有地址添加纬度和经度?我的代码如下:

    <?php
error_reporting(E_ALL);

set_time_limit(0);

class google_geocode
{
    public $geocodeOverQueryLimit=false;

    protected $PDO=false;

    public function __construct ()
    {
        $host='127.0.0.1';
        $database='forge';
        $charset='utf8';
        $username='root';
        $password='';

        $this->PDO = new PDO('mysql:host=' . $host . ';dbname=' . $database . ';charset=' . $charset, $username, $password);
    }

    public function dbQuote($text) 
    {
        return $this->PDO->quote($text);
    }

    public function dbName($value) 
    {
        return '`'. $value . '`';
    }

    public function dbQuery($cmd) 
    {
        return $this->PDO->query($cmd);
    }

    public function dbExec($cmd) 
    {
        return $this->PDO->exec($cmd);
    }

    public function dbFetch($res) 
    {
        return $res->fetch(PDO::FETCH_ASSOC);
    }

    public function getGoogleGeocode($address,$language='',$region='' )
    {
        $url = 'http://maps.googleapis.com/maps/api/geocode/json?address=' . urlencode($address) . '&sensor=false&output=json';
        if ($region!='') $url .= '&region=' . $region;
        if ($language!='') $url .= '&language=' .$language;

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER,0);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.0; rv:41.0) Gecko/20100101 Firefox/41.0');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $data = curl_exec($ch);

        curl_close($ch);

        return $data;
    }

    protected function getGoogleGeocodeData ($address,$region='',$language='') {
        $expired = 365; // in days

        $query=$this->dbQuery("SELECT `id`,`lng`, `lat`, `data`, `parsed`, TIMESTAMPDIFF(SECOND,`timestamp`,CURRENT_TIMESTAMP()) as `diff` FROM google_geocode_data WHERE address=" . $this->dbQuote($address) . " AND region=" . $this->dbQuote($region) . " AND language=" . $this->dbQuote($language) );

        if ($query&&($row=$this->dbFetch($query))) 
        {
            $return = new stdClass;
            $return->address = $address;
            $return->lng = $row['lng'];
            $return->lat = $row['lat'];
            $return->data = json_decode($row['data']);

            $return->expired = ($row['diff']>$expired*24*60*60);

            return $return;
        }

        return false;
    }

    protected function setGoogleGeocodeData ($address,$region,$data='',$lng='',$lat='',$language='') {
        if (!($_data=json_decode($data)) || $_data->status!=='OK') return false;

        if (!is_numeric($lng) || !is_numeric($lat)) 
        {
            $lng=$_data->results[0]->geometry->location->lng;
            $lat=$_data->results[0]->geometry->location->lat;
        }

        $query=$this->dbQuery("SELECT `id` FROM google_geocode_data WHERE address=" . $this->dbQuote($address) . " AND region=" . $this->dbQuote($region) . " AND language=" . $this->dbQuote($language) );

        if ($query&&($row=$this->dbFetch($query))) 
        {
            $id=$row['id'];

            return !!$this->dbQuery("UPDATE `google_geocode_data` SET `lng`=" . $this->dbQuote($lng) 
                . ",`lat`=" . $this->dbQuote($lat) 
                . ",`data`=" . $this->dbQuote($data) 
                . ",`timestamp`=now() where `id`=" . $id);
        }
        else
            return !!$this->dbQuery("INSERT INTO `google_geocode_data` (`address`,`region`,`language`,`lng`,`lat`,`data`) VALUES (" 
                . $this->dbQuote($address) . "," 
                . $this->dbQuote($region) . "," 
                . $this->dbQuote($language) . "," 
                . $this->dbQuote($lng) . "," 
                . $this->dbQuote($lat) . "," 
                . $this->dbQuote($data) . ")");
    }

    public function getGeocode($address,$region='',$language='') {
        if (false===($data=$this->getGoogleGeocodeData($address,$region,$language)) || $data->expired) 
        {
            if (($data=$this->getGoogleGeocode($address,$language,$region))
                && ($geodata=json_decode($data)) && $geodata->status=='OK') 
                {

                if ($this->setGoogleGeocodeData($address,$region,$data,false,false,$language))
                    $data=$this->getGoogleGeocodeData($address,$region,$language);
                else 
                {
                    $data=new stdClass();
                    $data->address=$address;
                    $data->lat=$geodata->results[0]->geometry->location->lat;
                    $data->lng=$geodata->results[0]->geometry->location->lng;
                    $data->data=json_decode($data);
                    $data->expired=false; 

                }
            } 
            else $data=false;

            if (isset($geodata)&&$geodata&&$geodata->status=='OVER_QUERY_LIMIT')
            {
                $this->geocodeOverQueryLimit=true;
            }
        }

        return $data;
    }

}

class listings
{
    static $PDO;

    static function dbQuote($text) 
    {
        return static::$PDO->quote($text);
    }

    static function dbName($value) 
    {
        return '`'. $value . '`';
    }

    static function dbQuery($cmd) 
    {
        return static::$PDO->query($cmd);
    }

    static function dbExec($cmd) 
    {
        return static::$PDO->exec($cmd);
    }

    static function dbFetch($res) 
    {
        return $res->fetch(PDO::FETCH_ASSOC);
    }

    static function dbQuery1Row($cmd) 
    {
        if (($query=static::$PDO->query($cmd)))
            return $query->fetch(PDO::FETCH_ASSOC);

        return false;
    }

    static function initialize ()
    {



        $host='127.0.0.1';
        $database='forge';
        $charset='utf8';
        $username='root';
        $password='';       

        static::$PDO = new PDO('mysql:host=' . $host . ';dbname=' . $database . ';charset=' . $charset, $username, $password);

        $geocode=new google_geocode();


        $mlsid=0;
        $sql="SELECT mlsid,apt_num,addr FROM commercials1 WHERE (`lat`='0' OR `lat` IS NULL OR `lng`='0' OR `lng` IS NULL) AND mlsid>'{$mlsid}' LIMIT 0,1";
        while (($row=static::dbQuery1Row($sql)))
        {
            echo ($mlsid=$row['mlsid']) ."\n";

            $address=trim($row['apt_num']);

            if (($value=trim($row['addr']))!='')
            {
                if ($address!='') $address.=' ';
                $address.=$value;
            }

            if ($address=='') continue;
            if (($data=$geocode->getGeocode($address,'ca','en')))
            {
                echo $data->lat."-".$data->lng;
                static::dbQuery("UPDATE commercials1 SET `lat`=" . static::dbQuote($data->lat) . ",`lng`=" . static::dbQuote($data->lng) . " WHERE mlsid='{$mlsid}'");
            }
            sleep(3);
            if ($geocode->geocodeOverQueryLimit)
            {
                echo "OverQueryLimit\n";
                break;
            }

            //usleep (100);
        }

    }
}

listings::initialize ();

echo 'Done';

?>

1 个答案:

答案 0 :(得分:0)

"over_query_limit status error"表示您已达到地理编码的配额。您已超过2,500免费请求限制。

  

Google Maps Geocoding API具有以下限制:

     

-Standard Usage限制标准API的用户:

     

每天-2,500个免费请求,以客户端和客户端的总和计算   服务器端查询。每秒50个请求,以总和计算   客户端和服务器端查询。

     

- 如果您想超过2,500个配额,您必须获得许可   Premium Plan customer