2011-11-15 31 views
12

我最近开始着眼于谷歌地图API来尝试在我的网站中发现新的东西。我目前使用此代码:查找邮编10英里范围内的城镇。谷歌地图API

<?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); 


?> 

简单的使用,我定义了一个邮政编码和搜索谷歌数据库,然后返回镇,县等

如果可能的话,我想不仅展示最近的城镇,但也有5-10英里范围内的任何一个。有人能告诉我怎么去做这件事吗?

感谢所有帮助

+0

有几个有前途的问答:http://stackoverflow.com/search?q=radius+search+google+maps+php - 你检查过哪些人,为什么他们不帮你解决问题? – Gordon

+0

我会看看那些,我没有看到很多有用的东西,而是在输入我的问题时查看了建议的帖子。你知道在哪里可以买到英国的邮政编码数据库,而不用为皇家邮政付钱吗?我看到一篇文章说wikileaks发布了它,但这是在2009年,所以即时猜测它不完全是最新的 –

+0

不知道,对不起。一个快速谷歌带来了https://www.ordnancesurvey.co.uk/opendatadownload/products.html但我不知道这些是免费使用或有帮助。 – Gordon

回答

51

更新:我写了一个更详细的博文关于这个具体问题上http://www.mullie.eu/geographic-searches/

-

遍历所有可用的城镇使用谷歌地图API获取它们的纬度&经度。将这些保存到某个地方(数据库)。 - 请注意,谷歌不会接受大量的电话,所以请加油。

然后,取出一个小镇的时候,你可以用类似的代码下面的代码获取城市withing一定的范围内:

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,...
  • 这将不准确。我们无法在数据库中进行精确的球面计算,因此我们采用了较低纬度的&经度极限。这基本上意味着一个比你的距离稍远的位置(例如,在最远的东北部,实际半径之外(实际上几乎是一个圆圈)),但仍然在经度的最大纬度&(因为我们比较它广场数据库极限)这将只给一个粗略的,但城市withing您的半径螺母100%准确选择

我会尽力说明这一点:。

_________________ 
| /\  | 
| Y/ \ | 
|/  \ | 
|(  X  )| 
| \  /| 
| \ / | 
|______\_/______| 

以上圆(有点)是你想要根据位置X查找位置的实际半径。这太难以直接从数据库中完成,所以我们实际从数据库中获取的是周围的广场。正如你所看到的,有可能位置(如Y)落在这些最小边界内,尽管它们实际上没有处理所请求的半径。这些可以稍后通过PHP过滤掉。

要解决这最后一个问题,您可以循环所有结果并计算您的根位置和找到的近似匹配之间的确切距离,以计算它们是否确实在您的半径内。对于这一点,你可以使用此代码:

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之间,然后你就可以过滤掉正是是足够接近这些城市通过粗糙分贝取而代之,但并不仅仅足够接近实际的范围。

+4

我不知道你为什么只有6 ups =) – 2012-03-12 09:57:01

+0

真棒回答,非常感谢 –

相关问题