Mam działający skrypt PHP, który pobiera wartości długości i szerokości geograficznej, a następnie wprowadza je do zapytania MySQL. Chciałbym, aby był to wyłącznie MySQL. Oto mój obecny kod PHP:
if ($distance != "Any" && $customer_zip != "") { //get the great circle distance
//get the origin zip code info
$zip_sql = "SELECT * FROM zip_code WHERE zip_code = '$customer_zip'";
$result = mysql_query($zip_sql);
$row = mysql_fetch_array($result);
$origin_lat = $row['lat'];
$origin_lon = $row['lon'];
//get the range
$lat_range = $distance/69.172;
$lon_range = abs($distance/(cos($details[0]) * 69.172));
$min_lat = number_format($origin_lat - $lat_range, "4", ".", "");
$max_lat = number_format($origin_lat + $lat_range, "4", ".", "");
$min_lon = number_format($origin_lon - $lon_range, "4", ".", "");
$max_lon = number_format($origin_lon + $lon_range, "4", ".", "");
$sql .= "lat BETWEEN '$min_lat' AND '$max_lat' AND lon BETWEEN '$min_lon' AND '$max_lon' AND ";
}
Czy ktoś wie, jak zrobić to całkowicie MySQL? Przeglądałem trochę Internet, ale większość literatury na ten temat jest dość myląca.
php
mysql
great-circle
Nick Woodhams
źródło
źródło
Odpowiedzi:
Z Google Code FAQ - Tworzenie lokalizatora sklepów za pomocą PHP, MySQL i Google Maps :
źródło
markers
tabelę z polami id, lan i lng.$greatCircleDistance = acos( cos($latitude0) * cos($latitude1) * cos($longitude0 - $longitude1) + sin($latitude0) * sin($latitude1));
o szerokości i długości geograficznej w radianach.
więc
jest twoje zapytanie SQL
aby uzyskać wyniki w kilometrach lub milach, należy pomnożyć wynik przez średni promień Ziemi (
3959
mile, kilometry6371
lub3440
mile morskie)To, co obliczasz w swoim przykładzie, to obwiednia. Jeśli umieścisz swoje dane współrzędnych w przestrzennym włączona kolumny MySQL , można użyć kompilacji MySQL funkcjonalności do kwerendy danych.
źródło
Jeśli dodasz pola pomocnicze do tabeli współrzędnych, możesz poprawić czas odpowiedzi na zapytanie.
Lubię to:
Jeśli używasz TokuDB, uzyskasz jeszcze lepszą wydajność, jeśli dodasz indeksy klastrowe w jednym z predykatów, na przykład w następujący sposób:
Będziesz potrzebował podstawowych lat i lon w stopniach, a także sin (lat) w radianach, cos (lat) * cos (lon) w radianach i cos (lat) * sin (lon) w radianach dla każdego punktu. Następnie tworzysz funkcję mysql, coś takiego:
To daje odległość.
Nie zapomnij dodać indeksu do lat / lon, aby obwiednia mogła pomóc w wyszukiwaniu zamiast spowalniać (indeks jest już dodany w zapytaniu CREATE TABLE powyżej).
Biorąc pod uwagę starą tabelę z tylko współrzędnymi lat / lon, możesz skonfigurować skrypt, aby aktualizować go w następujący sposób: (php za pomocą meekrodb)
Następnie optymalizujesz rzeczywiste zapytanie, aby wykonać obliczenie odległości tylko wtedy, gdy jest to naprawdę potrzebne, na przykład ograniczając okrąg (dobrze, owalny) od wewnątrz i na zewnątrz. W tym celu musisz wstępnie obliczyć kilka metryk dla samego zapytania:
Biorąc pod uwagę te przygotowania, zapytanie przebiega mniej więcej tak (php):
WYJAŚNIJ na powyższe zapytanie może powiedzieć, że nie używa indeksu, chyba że istnieje wystarczająca liczba wyników, aby je wywołać. Indeks zostanie wykorzystany, gdy w tabeli współrzędnych będzie wystarczająca ilość danych. Możesz dodać FORCE INDEX (lat_lon_idx) do SELECT, aby używał indeksu bez względu na rozmiar tabeli, dzięki czemu możesz sprawdzić przy pomocy EXPLAIN, że działa poprawnie.
Z powyższymi przykładami kodu powinieneś mieć działającą i skalowalną implementację wyszukiwania obiektów według odległości z minimalnym błędem.
źródło
Musiałem to szczegółowo opracować, więc podzielę się swoim wynikiem. Ten wykorzystuje
zip
stółlatitude
ilongitude
stoły. To nie zależy od Google Maps; raczej możesz dostosować go do dowolnej tabeli zawierającej długość / szerokość.Spójrz na ten wiersz w środku tego zapytania:
Wyszukuje 30 najbliższych pozycji w
zip
tabeli w odległości 50,0 mil od punktu szerokości / długości 42,81 / -70,81. Gdy wbudujesz to w aplikację, umieścisz własny punkt i promień wyszukiwania.Jeśli chcesz pracować w kilometrach, a nie zmiana mil,
69
aby111.045
i zmiany3963.17
do6378.10
w zapytaniu.Oto szczegółowy opis. Mam nadzieję, że to komuś pomoże. http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/
źródło
Napisałem procedurę, która może obliczyć to samo, ale musisz wprowadzić szerokość i długość geograficzną w odpowiedniej tabeli.
źródło
Nie mogę skomentować powyższej odpowiedzi, ale bądź ostrożny z odpowiedzią @Pavel Chuchuva. Ta formuła nie zwróci wyniku, jeśli obie współrzędne są takie same. W takim przypadku odległość wynosi zero, więc wiersz nie zostanie zwrócony z tą formułą w takiej postaci, w jakiej jest.
Nie jestem ekspertem od MySQL, ale wydaje mi się, że to działa dla mnie:
źródło
ACOS(1)
0). Państwo może zobaczyć zaokrąglania problemy z Xaxis * Xaxis + yAxis * yAxis + zaxis * zaxis dzieje się poza zasięgiem dla ACO, ale nie wydaje się być ochronę przed tym?na odległość 25 km
źródło
Myślałem, że moja implementacja javascript będzie dobrym odniesieniem do:
źródło
obliczyć odległość w Mysql
w ten sposób zostanie obliczona wartość odległości i każdy może złożyć wniosek zgodnie z wymaganiami.
źródło