使用 PHP/MySQL 在google map中解析地址为经纬度
为了存储与地址相关联的地址解析信息,我们需要设计合适的数据架构。在本文的示例中,我们希望在地图混搭程序上显示餐馆或酒吧。对于这类场所,典型的数据库表中应包含以下必要字段:
- 地址的唯一 id
- 文本字符串形式的场所地址
- 经过地址解析的位置的 lat 值和 lng 值
另外,我们希望所提供的地址数据库可以被实际用户使用,因此,需要为场所添加人类可读的名称以进行唯一标识,并添加 type 属性以区分餐馆和酒吧(仅出于增添乐趣的目的)。
- 文本字符串形式的场所名称
- 场所的 type(本示例中为酒吧或者餐馆)
在创建地址表时,请注意,Google Maps API 中的 lat 值和 lng 值只需精确到 6 位数即可唯一标识某个场所。为了少占用存储空间,我们将 lat 字段和 lng 字段指定为 FLOAT(10,6) 大小的数字。这种大小的浮点数的存储精确度为小数点后 6 位数以及小数点前最多 4 位数,例如 -123.456789 度。
可以使用下面显示的 SQL 语句创建地址表:
CREATE TABLE `markers` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 60 ) NOT NULL ,
`address` VARCHAR( 80 ) NOT NULL ,
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL ,
`type` VARCHAR( 30 ) NOT NULL
) ENGINE = MYISAM ;
请注意,以下示例代码中使用了一个虚拟 KEY 常数,您需要将该键替换为自己的键,否则您的所有请求都会返回一个610状态代码。
使用 PHP 5 和 XML 输出进行地址解析的示例代码如下所示 :
<?php
require("phpsqlgeocode_dbinfo.php");
define("MAPS_HOST", "maps.google.com");
define("KEY", "abcdefg");
// Opens a connection to a MySQL server
$connection = mysql_connect("localhost", $username, $password);
if (!$connection) {
die("Not connected : " . mysql_error());
}
// Set the active MySQL database
$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
die("Can\'t use db : " . mysql_error());
}
// Select all the rows in the markers table
$query = "SELECT * FROM markers WHERE 1";
$result = mysql_query($query);
if (!$result) {
die("Invalid query: " . mysql_error());
}
// Initialize delay in geocode speed
$delay = 0;
$base_url = "http://" . MAPS_HOST . "/maps/geo?output=xml" . "&key=" . KEY;
// Iterate through the rows, geocoding each address
while ($row = @mysql_fetch_assoc($result)) {
$geocode_pending = true;
while ($geocode_pending) {
$address = $row["address"];
$id = $row["id"];
$request_url = $base_url . "&q=" . urlencode($address);
$xml = simplexml_load_file($request_url) or die("url not loading");
$status = $xml->Response->Status->code;
if (strcmp($status, "200") == 0) {
// Successful geocode
$geocode_pending = false;
$coordinates = $xml->Response->Placemark->Point->coordinates;
$coordinatesSplit = split(",", $coordinates);
// Format: Longitude, Latitude, Altitude
$lat = $coordinatesSplit[1];
$lng = $coordinatesSplit[0];
$query = sprintf("UPDATE markers " .
" SET lat = '%s', lng = '%s' " .
" WHERE id = '%s' LIMIT 1;",
mysql_real_escape_string($lat),
mysql_real_escape_string($lng),
mysql_real_escape_string($id));
$update_result = mysql_query($query);
if (!$update_result) {
die("Invalid query: " . mysql_error());
}
} else if (strcmp($status, "620") == 0) {
// sent geocodes too fast
$delay += 100000;
} else {
// failure to geocode
$geocode_pending = false;
echo "Address " . $address . " failed to geocoded. ";
echo "Received status " . $status . "\n";
}
usleep($delay);
}
}
?>