我目前正在从事一个项目,该项目需要对存储在mySQL数据库中的位置进行地理编码。
我编写了一个小脚本,该脚本将CSV导入mySQL数据库,并自动在每行中用“ 0.000000”填充经度和纬度字段。
现在,我找到了一个脚本,该脚本检查数据库中是否缺少地理编码并进行更新。由于this script已有几年历史,并且刚与Google合作,所以我满足了我的需求(应该与Wordpress和Nominatim一起使用,而不是与Google Maps一起使用)。
导入CSV效果很好,但是运行此脚本更新约5200个位置时,我超时了。不幸的是,我无法增加任何超时设置,因此需要将任务分成多个步骤。
我该怎么做?
在使用PHP时,我还是有点耳熟能详,因此可以提供任何帮助。我已经尝试通过增加一个计数器变量来分割循环,该变量与我需要更新的mySQL行数成平方。现在应该每100行刷新一次页面,但是不幸的是,它实际上并没有工作。它适用于大约500个位置,但之后-超时。
有人知道解决方案吗?
// Opens a connection to a MySQL server
$connection = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
if (!$connection) {
die("Not connected : " . mysql_error());
}
// Set the active MySQL database
$db_selected = mysql_select_db(DB_NAME, $connection);
if (!$db_selected) {
die("Can\'t use db : " . mysql_error());
}
// Select all the rows in the markers table
$query = "SELECT * FROM locations WHERE 1";
$result = mysql_query($query);
if (!$result) {
die("Invalid query: " . mysql_error());
}
// Initialize delay in geocode speed
$delay = 0;
function getLnt($address){
$request_url = "http://nominatim.openstreetmap.org/search?q=".urlencode($address)."&format=json&addressdetails=1";
$result_string = file_get_contents($request_url);
$result_json = json_decode($result_string, true);
return $result_json[0];
}
// Iterate through the rows, geocoding each address
while ($row = @mysql_fetch_assoc($result)) {
$geocode_pending = true;
while ($geocode_pending) {
$street = $row["address"];
$zip = $row["zip"];
$city = $row["city"];
$id = $row["id"];
$address = $street.', '.$zip.' '.$city;
$details = getLnt($address);
$lat = $details[lat];
$lng = $details[lon];
$state = $details[address][state];
$country_iso = $details[address][country_code];
if (http_response_code() == 200) {
// successful geocode
$geocode_pending = false;
$query = sprintf("
UPDATE locations SET lat = '%s', lng = '%s', state = '%s', country_iso = '%s' WHERE lat = '0.000000' AND lng = '0.000000' AND id = '%s' LIMIT 1;",
mysql_real_escape_string($lat), mysql_real_escape_string($lng), mysql_real_escape_string(utf8_decode($state)),mysql_real_escape_string($country_iso),mysql_real_escape_string($id)
);
$update_result = mysql_query($query);
if (!$update_result) {
die("Invalid query: " . mysql_error());
}
} else if(http_response_code() == 620) {
// sent geocodes too fast
$delay += 100000;
} else if($details == NULL) {
// failure to geocode
$geocode_pending = false;
echo "Address " . $address . " failed to geocoded. ";
echo "Received status " . $status . "
\n";
}
usleep($delay);
}
}
最佳答案
您必须在您的位置查询中添加分页:
// Select all the rows in the markers table
$offset = intval($_GET['offset'];
$query = "SELECT * FROM locations WHERE 1 LIMIT $offset, 100";
然后在浏览器中浏览页面。您可以手动执行此操作,也可以在另一页上使用javascript / jquery来查询目标位置:
var locations_count = 1000000;
var offset = 0;
var func = function(){
$.get('update-location.php', {offset: offset}, function(){
document.write('<br/>Processed ' + offset + ' records');
offset += 100;
if( offset < locations_count )
setTimeout(func, 100);
else
document.write('<br/>Update finished');
});
};
func();
(不要忘记将
locations_count
更新为您的实际位置数量)。等解决方案:
将表转储到本地计算机,然后在本地更新它,然后在服务器上更新结果表。