2011-11-15 14 views
12

Niedawno zacząłem przeglądać interfejs API Map Google, aby wypróbować coś nowego w moich witrynach. Obecnie używam tego kodu:Wyszukiwanie miast w promieniu 10 mil od kodu pocztowego. 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); 


?> 

który po prostu używa kodu pocztowego, że określenia i przeszukuje bazę danych Google, a następnie zwraca ulica, kod pocztowy

Jeśli to możliwe, chciałbym nie tylko pokaz najbliższe miasto, ale także wszelkie w promieniu 5-10 mil. Czy ktoś może mi powiedzieć, jak bym to zrobił?

Dzięki za wszelką pomoc

+0

Jest kilka obiecujących pytań i odpowiedzi: http://stackoverflow.com/search?q=radius+search+google+maps+php - które z nich sprawdziłeś i dlaczego nie pomogły Ci rozwiązać Twojego problemu? – Gordon

+0

Muszę przejrzeć te, spojrzałem na sugerowane posty podczas pisania mojego pytania, ale nie widziałem wiele przydatnych rzeczy. Czy wiesz, gdzie mogłem zdobyć bazę danych kodów pocztowych w Wielkiej Brytanii, nie płacąc za to głupich pieniędzy Royal Mail? Widziałem artykuł, który powiedział, że wikileaks go wypuścił, ale to było w 2009 roku, więc domyślam się, że nie jest w pełni aktualny. –

+0

Nie mam pojęcia, przepraszam. szybki google wychował https://www.ordnancesurvey.co.uk/opendatadownload/products.html, ale nie jestem pewien, czy są one darmowe lub pomocne. – Gordon

Odpowiedz

51

aktualizacji: Napisałem nawet dokładniejszy blogpost temat tego konkretnego tematu na http://www.mullie.eu/geographic-searches/

-

pętli wszystkich dostępnych miast za pomocą interfejsu API do Google Maps pobrać ich szerokość geograficzną & długości geograficznej. Zapisz je gdzieś (baza danych). - Uważaj, Google nie akceptuje ogromnej liczby połączeń, więc ograniczaj swoje połączenia.

Potem, gdy ściągam miasto, można użyć kodu podobnego do poniższego kodu, aby chwycić miast withing pewien zakres:

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

Uwagi o powyższym kodzie:

  • własnej bazy danych Opakowanie jest używane, więc zamień na mysql_query, PDO, ...
  • To nie będzie dokładne. Nie możemy wykonać dokładnych obliczeń sferycznych w DB, więc przyjęliśmy górną granicę długości & o niższej szerokości geograficznej &. Zasadniczo oznacza to lokalizację, która jest nieco dalej niż odległość (np. Na dalekim północnym-wschodzie, tuż poza faktycznym promieniem (który właściwie jest raczej okręgiem), ale nadal w obrębie maksymalnej szerokości geograficznej & długości geograficznej (ponieważ porównujemy to do kwadratu limity w bazie danych), to będzie po prostu dać szorstka ale nakrętka 100% dokładny wybór miast withing swój promień

postaram się zilustrować to:..

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

powyższy krąg (w pewnym stopniu) jest rzeczywistym promieniem, w którym chcesz znaleźć lokalizacje w oparciu o lokalizację X. Jest to zbyt trudne do osiągnięcia bezpośrednio z twojego DB, więc to, co faktycznie pobieramy z DB, to otaczający kwadrat. Jak widać, możliwe jest, że lokalizacje (takie jak Y) mieszczą się w granicach max. & min, chociaż w rzeczywistości nie mają żądanego promienia. Można je później odfiltrować przez PHP.

Aby rozwiązać ten ostatni problem, można zapętlić wszystkie wyniki i obliczyć dokładną odległość między lokalizacją źródłową a znalezionymi bliskimi, aby obliczyć, czy rzeczywiście znajdują się one w promieniu. W tym celu można użyć tego kodu:

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

Będzie to obliczyć (quasi) dokładną odległość między lokalizacji X i miejscu Y, a następnie można odfiltrować dokładnie te miasta, które były na tyle blisko, aby przejść szorstki db -Pobierz, ale nie tylko na tyle blisko, aby faktycznie znaleźć się w zasięgu.

+4

Nie wiem, dlaczego masz tylko 6 ups =) –

+0

wspaniała odpowiedź, bardzo dziękuję –

Powiązane problemy