2011-11-15 69 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

真棒回答,非常感謝 –

相關問題