2012-06-26 12 views
5

Mam problemy podczas próby zwrócenia najbliższej lokalizacji użytkownikowi za pomocą instrukcji SQL. Aby przetestować używam te same współrzędne, oto co mam:Pomiar odległości między dwoma punktami Lat/Lng

SQL:

SELECT `companies`.`customerName` , 
    (3959 * 
     ACOS(
      COS(
       RADIANS(37.367485) * COS(RADIANS(`locations`.`gps_lat`)) * 
       COS(
        RADIANS(`locations`.`gps_lng`) - RADIANS(-77.399994) + 
        SIN(RADIANS(37.367485)) * SIN(RADIANS(`locations`.`gps_lat`)) 
       ) 
      ) 
     ) 
    ) 
AS `distance` 
FROM `locations` 
JOIN `companies` ON `locations`.`co_id` 
HAVING `distance` > 25 
ORDER BY distance 
LIMIT 0 , 10 

Wyniki:

| customerName | distance   | 
| SOME COMPANY | 1914.41747964854 | 


locationswartości z tabeli :

gps_lat | gps_lng 
37.367485 | -77.399994 


użyłem przykład z Google, sprawdziłem wzór A kilka razy, a ja nie potrafię wymyślić, gdzie poszło źle. Każda pomoc jest doceniana.


EDIT:
Ponieważ nie wydaje się być trochę zamieszania na mnie wiedząc, co robię:

> zastapiony uzyskując wynik, 1914 jest oczywiście większy niż 25.

Stosowanie tego polega na przekazywaniu współrzędnych użytkownika z aplikacji na Androida na nasz serwer sieciowy. Szerokość i długość geograficzna zostaną pobrane z wartości $_GET i przekierowane przez firmy znajdujące się w bazie danych MySQL serwera WWW.

Powyższa składnia to po prostu sprawdzanie mojej instrukcji SQL w Mysql Workbench. Oczywiście szukam wyniku zerowego.

+3

Jeśli chcesz się najbliżej, dlaczego go, aby ograniczyć „odległość > 25 "? –

+0

Zrobiłem, zwróciłem zero wyników. Zwróć uwagę na odległość, którą otrzymałem powyżej – jnthnjns

+2

W zależności od używanego systemu RDBMS, może to być znacznie prostsze (i szybsze). Przykład: [MySQL] (http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html), [SQL Server] (http://msdn.microsoft.com/en-us/ library/bb933876% 28v = sql.105% 29.aspx), [PostgreSQL] (http://postgis.refractions.net/). –

Odpowiedz

5

Myślę, że rozwiązałem ten problem, zmieniając z przykładu Googlesa na formułę dostarczoną przez "Adventures of an adoptated yooper". Korzystając z jego/jej wersji Haversine Formula.
Uwaga: Powyższy przykład Google również używa Haversine.

SQL:

SELECT `companies`.`customerName` , 
(2 * (3959 * ATAN2(
      SQRT(
      POWER(SIN((RADIANS(37.367485 - `locations`.`gps_lat`))/2), 2) + 
      COS(RADIANS(`locations`.`gps_lat`)) * 
      COS(RADIANS(37.367485)) * 
      POWER(SIN((RADIANS(-77.399994 - `locations`.`gps_lng`))/2), 2) 
     ), 
      SQRT(1-(
      POWER(SIN((RADIANS(37.367485 - `locations`.`gps_lat`))/2), 2) + 
      COS(RADIANS(`locations`.`gps_lat`)) * 
      COS(RADIANS(37.367485)) * 
      POWER(SIN((RADIANS(-77.399994 - `locations`.`gps_lng`))/2), 2) 
     )) 
     ) 
    )) 
AS 'distance' 
FROM `locations` 
JOIN `companies` ON `locations`.`co_id` 
HAVING distance < 25 
ORDER BY distance 
LIMIT 0 , 10 



Dla tych ciekawy sprawie mojego wniosku, Final PHP:

uzyskać wartość: ?lat=37.367485&lng=-77.399994

$earth_radius_miles = 3959; // Earth radius in miles 
$earth_radius_kilometers = 6371; // Earth radius in kilometers 
$result_radius = 10000; // Maximum distance in either miles or kilometers 

$get_lat = $_GET["lat"]; 
$get_lng = $_GET["lng"]; 

$dbSelect = mysql_query("SELECT `companies`.`customerName`, 
(2 * (".$earth_radius_miles." * ATAN2(
      SQRT(
      POWER(SIN((RADIANS(".$get_lat." - `locations`.`gps_lat`))/2), 2) + 
      COS(RADIANS(`locations`.`gps_lat`)) * 
      COS(RADIANS(".$get_lat.")) * 
      POWER(SIN((RADIANS(".$get_lng." - `locations`.`gps_lng`))/2), 2) 
     ), 
      SQRT(1-(
      POWER(SIN((RADIANS(".$get_lat." - `locations`.`gps_lat`))/2), 2) + 
      COS(RADIANS(`locations`.`gps_lat`)) * 
      COS(RADIANS(".$get_lat.")) * 
      POWER(SIN((RADIANS(".$get_lng." - `locations`.`gps_lng`))/2), 2) 
     )) 
     ) 
    )) 
AS 'distance' 
FROM `locations` 
JOIN `companies` ON `locations`.`co_id` 
HAVING distance < ".$result_radius." 
ORDER BY distance 
LIMIT 0 , 10") 
or die(mysql_error()); 

Wyniki:

[{"customerName":"SOME COMPANY","distance":"0"}] 

ja testowałem te wyniki z innych współrzędnych i wydaje się być doskonale działa.Nie testowałem niczego z dużą odległością między dwoma punktami, ale moja aplikacja nie wymaga tego.

+1

Nie można potwierdzić, ale +1 dla prezentacji – Smandoli

1

Ashok, można obliczyć odległość między dwoma cordinates za pomocą wzoru:

enter image description here

gdzie

R = radius of the earth (6,371 km) 
Δlat = |lat2- lat1| 
Δlong = |long2- long1| 
Powiązane problemy