我有一个包含超过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 .= '®ion=' . $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';
?>
答案 0 :(得分:0)
"over_query_limit status error"表示您已达到地理编码的配额。您已超过2,500免费请求限制。
Google Maps Geocoding API具有以下限制:
-Standard Usage限制标准API的用户:
每天-2,500个免费请求,以客户端和客户端的总和计算 服务器端查询。每秒50个请求,以总和计算 客户端和服务器端查询。
- 如果您想超过2,500个配额,您必须获得许可 Premium Plan customer