2011-11-15 63 views
12

Gần đây, tôi đã bắt đầu xem API Google Maps để thử một điều gì đó mới mẻ trong các trang web của mình. Tôi hiện đang sử dụng mã này:Tìm thị trấn trong bán kính 10 dặm mã bưu điện. Google maps 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); 


?> 

mà chỉ đơn giản sử dụng một mã bưu điện mà tôi xác định và tìm kiếm cơ sở dữ liệu của Google và sau đó trả về thị trấn, quận, vv

Nếu có thể, tôi muốn không chỉ hiển thị thị trấn gần nhất nhưng cũng nằm trong bán kính 5-10 dặm. Ai đó có thể cho tôi biết làm thế nào tôi sẽ đi về làm điều này xin vui lòng?

Nhờ sự giúp đỡ

+0

có một số câu hỏi và đáp ứng đầy hứa hẹn tại: http://stackoverflow.com/search?q=radius+search+google+maps+php - bạn đã kiểm tra điều gì và tại sao chúng không giúp bạn giải quyết vấn đề của mình? – Gordon

+0

Tôi sẽ có một cái nhìn thông qua những người, tôi đã xem xét các bài viết được đề xuất trong khi gõ câu hỏi của tôi nhưng không thấy nhiều thứ hữu ích. Bạn có biết nơi tôi có thể có được một cơ sở dữ liệu mã bưu chính Anh mà không trả tiền cho Royal Mail ngớ ngẩn không? Tôi thấy một bài báo cho biết wikileaks phát hành nó nhưng đây là trong năm 2009 vì vậy tôi đoán nó không được cập nhật đầy đủ –

+0

không có ý tưởng, xin lỗi. một google nhanh chóng đưa lên https://www.ordnancesurvey.co.uk/opendatadownload/products.html nhưng tôi không chắc chắn liệu chúng có miễn phí để sử dụng hay hữu ích hay không. – Gordon

Trả lời

51

Cập nhật: Tôi đã viết lên một bài đăng trên blog chi tiết hơn về chủ đề cụ thể này trên http://www.mullie.eu/geographic-searches/

-

Vòng qua tất cả các thị trấn có sẵn bằng cách sử dụng API của Google Maps để tìm kinh độ của họ theo độ dài &. Lưu những nơi này (cơ sở dữ liệu). - Hãy coi chừng, Google sẽ không chấp nhận một số lượng lớn các cuộc gọi, vì vậy hãy tăng tốc các cuộc gọi của bạn.

Sau đó, khi lấy một thị trấn, bạn có thể sử dụng mã tương tự như mã dưới đây để lấy những thành phố withing một phạm vi nhất định:

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; 
} 

Thuyết minh về đoạn code trên:

  • cơ sở dữ liệu riêng trình bao bọc được sử dụng, vì vậy hãy chuyển sang mysql_query, PDO, ...
  • Điều này sẽ không chính xác. Chúng tôi không thể thực hiện các phép tính hình cầu chính xác trong DB, vì vậy, chúng tôi đã thực hiện các giới hạn kinh độ trên & trên vĩ độ & kinh độ thấp hơn. Điều này về cơ bản có nghĩa là một vị trí hơi xa hơn khoảng cách của bạn (ví dụ ở phía đông bắc, ngay bên ngoài bán kính thực tế (thực sự là một vòng tròn), nhưng vẫn nằm trong vĩ độ tối đa & kinh độ (vì chúng ta so sánh nó vuông giới hạn trong cơ sở dữ liệu) này sẽ chỉ cung cấp cho một thô nhưng hạt 100% lựa chọn chính xác của thành phố withing bán kính của bạn

tôi sẽ cố gắng để minh họa điều này:..

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

trên đây vòng tròn (phần nào) là bán kính thực tế nơi bạn muốn tìm vị trí bên trong, dựa trên vị trí X. Đây là quá khó để hoàn thành ngay lập tức DB của bạn, vì vậy những gì chúng tôi thực sự lấy từ DB là quảng trường xung quanh. Như bạn có thể thấy, có thể các vị trí (như Y) nằm trong các ranh giới tối thiểu & tối thiểu này, mặc dù chúng không thực sự có bán kính được yêu cầu. Sau này, chúng có thể được lọc qua PHP.

Để giải quyết vấn đề cuối cùng này, bạn có thể lặp lại tất cả kết quả và tính toán khoảng cách chính xác giữa vị trí gốc và kết quả phù hợp để tính toán nếu chúng thực sự nằm trong bán kính của bạn. Đối với điều đó, bạn có thể sử dụng mã này:

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

Điều này sẽ tính chính xác khoảng cách chính xác giữa vị trí X và vị trí Y, sau đó bạn có thể lọc chính xác những thành phố đủ gần -fetch, nhưng không chỉ đủ gần để thực sự nằm trong giới hạn của bạn.

+4

Tôi không biết tại sao bạn chỉ có 6 ups =) –

+0

câu trả lời tuyệt vời, cảm ơn rất nhiều –

Các vấn đề liên quan