查找邮政编码 10 英里范围内的城镇.谷歌地图API
我最近开始研究 Google Maps API 以在我的网站中尝试一些新的东西.我目前正在使用此代码:
I've recently started looking at the Google Maps API to try out something new in my websites. I am currently using this code:
<?php
$postcode = $_REQUEST['postcode'];
$url = 'http://maps.googleapis.com/maps/api/geocode/xml?address='.$postcode.'&sensor=false';
$parsedXML = simplexml_load_file($url);
if($parsedXML->status != "OK") {
echo "There has been a problem: " . $parsedXML->status;
}
$myAddress = array();
foreach($parsedXML->result->address_component as $component) {
if(is_array($component->type)) $type = (string)$component->type[0];
else $type = (string)$component->type;
$myAddress[$type] = (string)$component->long_name;
}
header('Content-Type: application/json');
echo json_encode($myAddress);
?>
它只使用我定义的邮政编码并搜索 Google 数据库,然后返回城镇、县等.
which simply uses a postcode that I define and searches the Google database and then returns the town, county etc.
如果可能,我不仅想显示最近的城镇,还想显示 5-10 英里范围内的任何城镇.有人能告诉我我会怎么做吗?
If possible, I would like to not only show the nearest town but also any within a 5-10 mile radius. Could someone tell me how I would go about doing this please?
感谢您的帮助
推荐答案
更新:我在 http://www.mullie.eu/geographic-searches/
--
使用 Google Maps API 遍历所有可用城镇以获取其纬度和经度.将这些保存在某处(数据库).- 请注意,Google 不会接听大量电话,因此请限制您的电话.
Loop through all available towns using the Google Maps API to fetch their latitude & longitude. Save these somewhere (database). - Beware, Google will not accept an enormous amount of calls, so throttle your calls.
然后,在抓取城镇时,可以使用类似于下面代码的代码抓取一定范围内的城市:
Then, when fetching a town, you can use code similar to the code below to grab the cities withing a certain range:
public static function getNearby($lat, $lng, $type = 'cities', $limit = 50, $distance = 50, $unit = 'km')
{
// radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius'
if ($unit == 'km') $radius = 6371.009; // in kilometers
elseif ($unit == 'mi') $radius = 3958.761; // in miles
// latitude boundaries
$maxLat = (float) $lat + rad2deg($distance / $radius);
$minLat = (float) $lat - rad2deg($distance / $radius);
// longitude boundaries (longitude gets smaller when latitude increases)
$maxLng = (float) $lng + rad2deg($distance / $radius / cos(deg2rad((float) $lat)));
$minLng = (float) $lng - rad2deg($distance / $radius / cos(deg2rad((float) $lat)));
// get results ordered by distance (approx)
$nearby = (array) FrontendDB::getDB()->retrieve('SELECT *
FROM table
WHERE lat > ? AND lat < ? AND lng > ? AND lng < ?
ORDER BY ABS(lat - ?) + ABS(lng - ?) ASC
LIMIT ?;',
array($minLat, $maxLat, $minLng, $maxLng, (float) $lat, (float) $lng, (int) $limit));
return $nearby;
}
上述代码注意事项:
- 使用自己的数据库包装器,因此转换为 mysql_query、PDO、...
- 这不会是准确的.我们无法在 DB 中进行精确的球面计算,因此我们采用了上面的 &低纬度经度限制.这基本上意味着一个位置比您的距离稍远(例如在远东北,就在实际半径之外(实际上几乎是一个圆),但仍在最大纬度和经度内(因为我们将其与数据库中的平方限制进行比较).这将只是粗略但 100% 准确地选择您半径范围内的城市.
我将尝试说明这一点:
_________________
| / |
| Y / |
| / |
|( X )|
| / |
| / |
|______\_/______|
上面的圆(有点)是你想要在其中找到位置的实际半径,基于位置 X.这很难直接从你的数据库中完成,所以我们实际上从数据库中获取的是周围的正方形.如您所见,位置(如 Y)有可能落在这些 max & 范围内.最小边界,尽管它们实际上并不在请求的半径范围内.不过这些可以稍后通过 PHP 过滤掉.
The above circle (somewhat) is the actual radius where you want to find locations within, based upon location X. This is too hard to accomplish straight out of your DB, so what we actually fetch from the DB is the surrounding square. As you can see, it's possible that locations (like Y) fall within these max & min boundaries, though they aren't actually withing the requested radius. These can later be filtered out through PHP though.
为了解决最后一个问题,您可以循环所有结果并计算您的根位置和找到的接近匹配之间的确切距离,以计算它们是否实际上在您的半径内.为此,您可以使用以下代码:
To tackle this last issue, you could loop all results and calculate the exact distance between both your root location, and the close matches found, to calculate if they're actually within your radius. For that, you could use this code:
public static function getDistance($lat1, $lng1, $lat2, $lng2, $unit = 'km')
{
// radius of earth; @note: the earth is not perfectly spherical, but this is considered the 'mean radius'
if ($unit == 'km') $radius = 6371.009; // in kilometers
elseif ($unit == 'mi') $radius = 3958.761; // in miles
// convert degrees to radians
$lat1 = deg2rad((float) $lat1);
$lng1 = deg2rad((float) $lng1);
$lat2 = deg2rad((float) $lat2);
$lng2 = deg2rad((float) $lng2);
// great circle distance formula
return $radius * acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($lng1 - $lng2));
}
这将计算位置 X 和位置 Y 之间的(准)精确距离,然后您可以准确地过滤掉那些足够近以通过粗略数据库提取的城市,但又不只是足够近以实际在您的范围内边界.
This will calculate the (quasi) exact distance between location X and location Y, and then you can filter out exactly those cities that were near enough to pass the rough db-fetch, but not just near enough to actually be within your bounds.
相关文章