
Oblicz lub zapytaj o odległość ortodromy między punktami szerokości i długości geograficznej za pomocą wzoru Haversine (przykłady PHP, JavaScript, Java, Python, MySQL, MSSQL)
W tym miesiącu sporo programowałem PHP i MySQL w odniesieniu do GIS. Szperając po sieci, naprawdę miałem trudności ze znalezieniem niektórych Obliczenia geograficzne aby znaleźć odległość między dwoma lokalizacjami, więc chciałem je tutaj udostępnić.

Prostym sposobem obliczenia odległości między dwoma punktami jest użycie wzoru Pitagorasa do obliczenia przeciwprostokątnej trójkąta (A² + B² = C²). Jest to znane jako Odległość euklidesowa.
To interesujący początek, ale nie dotyczy geografii, ponieważ odległość między liniami szerokości i długości geograficznej nie jest równa. Gdy zbliżasz się do równika, linie szerokości geograficznej oddalają się od siebie. Jeśli użyjesz prostego równania triangulacji, może ono zmierzyć odległość dokładnie w jednym miejscu, a źle w innym, ze względu na krzywiznę Ziemi.
Odległość ortodromy
Trasy pokonywane na długich dystansach wokół Ziemi są znane jako odległość Wielkiego Koła. Czyli… najkrótsza odległość między dwoma punktami na kuli różni się od punktów na płaskiej mapie. Połącz to z faktem, że linie szerokości i długości geograficznej nie są jednakowo oddalone… i masz trudne obliczenia.
Oto fantastyczny film wyjaśniający, jak działają wielkie kręgi.
Formuła Haversine
Odległość wykorzystująca krzywiznę Ziemi jest uwzględniona we wzorze Haversine'a, który wykorzystuje trygonometrię, aby uwzględnić krzywiznę Ziemi. Kiedy znajdujesz odległość między 2 miejscami na Ziemi (w linii prostej), linia prosta jest w rzeczywistości łukiem.
Ma to zastosowanie w locie lotniczym – czy kiedykolwiek spojrzałeś na rzeczywistą mapę lotów i zauważyłeś, że są one wygięte w łuk? Dzieje się tak dlatego, że lot łukiem między dwoma punktami jest krótszy niż lot bezpośrednio do lokacji.
PHP: Oblicz odległość między 2 punktami szerokości i długości geograficznej
Oto wzór PHP do obliczania odległości między dwoma punktami (wraz z konwersją mil na kilometry) zaokrąglonych do dwóch miejsc po przecinku.
function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'miles') {
$theta = $longitude1 - $longitude2;
$distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
$distance = acos($distance);
$distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
switch($unit) {
case 'miles':
break;
case 'kilometers' :
$distance = $distance * 1.609344;
}
return (round($distance,2));
}
Zmienne to:
- $Szerokość1 – zmienna określająca szerokość geograficzną pierwszej lokalizacji.
- $Długość1 – zmienna określająca długość geograficzną Twojej pierwszej lokalizacji
- $Szerokość2 – zmienna określająca szerokość geograficzną drugiej lokalizacji.
- $Długość2 – zmienna określająca długość geograficzną drugiej lokalizacji.
- $jednostka – domyślna istota mile. Można to zaktualizować lub przekazać jako kilometrów.
Java: Oblicz odległość między 2 punktami szerokości i długości geograficznej
public static double getDistanceBetweenPointsNew(double latitude1, double longitude1, double latitude2, double longitude2, String unit) {
double theta = longitude1 - longitude2;
double distance = 60 * 1.1515 * (180/Math.PI) * Math.acos(
Math.sin(latitude1 * (Math.PI/180)) * Math.sin(latitude2 * (Math.PI/180)) +
Math.cos(latitude1 * (Math.PI/180)) * Math.cos(latitude2 * (Math.PI/180)) * Math.cos(theta * (Math.PI/180))
);
if (unit.equals("miles")) {
return Math.round(distance, 2);
} else if (unit.equals("kilometers")) {
return Math.round(distance * 1.609344, 2);
} else {
return 0;
}
}
Zmienne to:
- szerokość geograficzna1 – zmienna określająca szerokość geograficzną pierwszej lokalizacji.
- długość geograficzna1 – zmienna określająca długość geograficzną Twojej pierwszej lokalizacji
- szerokość geograficzna2 – zmienna określająca szerokość geograficzną drugiej lokalizacji.
- długość geograficzna2 – zmienna określająca długość geograficzną drugiej lokalizacji.
- jednostka – domyślna istota mile. Można to zaktualizować lub przekazać jako kilometrów.
Javascript: Oblicz odległość między 2 punktami szerokości i długości geograficznej
function getDistanceBetweenPoints(latitude1, longitude1, latitude2, longitude2, unit = 'miles') {
let theta = longitude1 - longitude2;
let distance = 60 * 1.1515 * (180/Math.PI) * Math.acos(
Math.sin(latitude1 * (Math.PI/180)) * Math.sin(latitude2 * (Math.PI/180)) +
Math.cos(latitude1 * (Math.PI/180)) * Math.cos(latitude2 * (Math.PI/180)) * Math.cos(theta * (Math.PI/180))
);
if (unit == 'miles') {
return Math.round(distance, 2);
} else if (unit == 'kilometers') {
return Math.round(distance * 1.609344, 2);
}
}
Zmienne to:
- szerokość geograficzna1 – zmienna określająca szerokość geograficzną pierwszej lokalizacji.
- długość geograficzna1 – zmienna określająca długość geograficzną Twojej pierwszej lokalizacji
- szerokość geograficzna2 – zmienna określająca szerokość geograficzną drugiej lokalizacji.
- długość geograficzna2 – zmienna określająca długość geograficzną drugiej lokalizacji.
- jednostka – domyślna istota mile. Można to zaktualizować lub przekazać jako kilometrów.
Python: Oblicz odległość między dwoma punktami szerokości i długości geograficznej
W każdym razie, oto wzór Pythona do obliczania odległości między dwoma punktami (wraz z konwersją mil na kilometry) zaokrąglonych do dwóch miejsc po przecinku. Podziękowania dla mojego syna, Billa Karra, który jest analitykiem danych dla OtwórzWglądy, dla kodu.
from numpy import sin, cos, arccos, pi, round
def rad2deg(radians):
degrees = radians * 180 / pi
return degrees
def deg2rad(degrees):
radians = degrees * pi / 180
return radians
def getDistanceBetweenPointsNew(latitude1, longitude1, latitude2, longitude2, unit = 'miles'):
theta = longitude1 - longitude2
distance = 60 * 1.1515 * rad2deg(
arccos(
(sin(deg2rad(latitude1)) * sin(deg2rad(latitude2))) +
(cos(deg2rad(latitude1)) * cos(deg2rad(latitude2)) * cos(deg2rad(theta)))
)
)
if unit == 'miles':
return round(distance, 2)
if unit == 'kilometers':
return round(distance * 1.609344, 2)
Zmienne to:
- szerokość geograficzna1 – zmienna dla Twojej pierwszej lokalizacji szerokość.
- długość geograficzna1 – zmienna dla Twojej pierwszej lokalizacji długość geograficzna
- szerokość geograficzna2 – zmienna dla Twojej drugiej lokalizacji szerokość.
- długość geograficzna2 – zmienna dla Twojej drugiej lokalizacji długość geograficzna.
- jednostka – domyślna istota mile. Można to zaktualizować lub przekazać jako kilometrów.
MySQL: Pobieranie wszystkich rekordów z określonego zakresu poprzez obliczanie odległości w milach na podstawie szerokości i długości geograficznej
Możliwe jest również użycie języka SQL do obliczenia wszystkich rekordów w określonej odległości. W tym przykładzie zamierzam wysłać zapytanie do MyTable w MySQL, aby znaleźć wszystkie rekordy, które są mniejsze lub równe zmiennej $distance (w milach) do mojej lokalizacji w $szerokość i $długość geograficzna:
Zapytanie o pobranie wszystkich rekordów w ramach określonego dystans poprzez obliczenie odległości w milach między dwoma punktami szerokości i długości geograficznej są:
$query = "SELECT *, (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180)) + cos((".$latitude."*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`)*pi()/180)))) * 180/pi()) * 60 * 1.1515) as distance FROM `table` WHERE distance <= ".$distance."
Musisz to dostosować:
- $ longitude - to jest zmienna PHP, w której podaję długość geograficzną punktu.
- $ latitude - to jest zmienna PHP, w której podaję długość geograficzną punktu.
- $ odległość - jest to odległość, na jaką chciałbyś znaleźć wszystkie rekordy mniejsze lub równe.
- stół - to jest stół… będziesz chciał go zastąpić nazwą swojego stołu.
- szerokość - to jest pole twojej szerokości geograficznej.
- długość geograficzna - to jest pole twojej długości geograficznej.
MySQL: Pobieranie wszystkich rekordów z określonego zakresu poprzez obliczanie odległości w kilometrach przy użyciu szerokości i długości geograficznej
A oto zapytanie SQL używające kilometrów w MySQL:
$query = "SELECT *, (((acos(sin((".$latitude."*pi()/180)) * sin((`latitude`*pi()/180)) + cos((".$latitude."*pi()/180)) * cos((`latitude`*pi()/180)) * cos(((".$longitude."- `longitude`) * pi()/180)))) * 180/pi()) * 60 * 1.1515 * 1.609344) as distance FROM `table` WHERE distance <= ".$distance."
Musisz to dostosować:
- $ longitude - to jest zmienna PHP, w której podaję długość geograficzną punktu.
- $ latitude - to jest zmienna PHP, w której podaję długość geograficzną punktu.
- $ odległość - jest to odległość, na jaką chciałbyś znaleźć wszystkie rekordy mniejsze lub równe.
- stół - to jest stół… będziesz chciał go zastąpić nazwą swojego stołu.
- szerokość - to jest pole twojej szerokości geograficznej.
- długość geograficzna - to jest pole twojej długości geograficznej.
Użyłem tego kodu w korporacyjnej platformie mapowania, której używaliśmy w sklepie detalicznym z ponad 1,000 lokalizacji w Ameryce Północnej i działał pięknie.
Odległość geograficzna Microsoft SQL Server: STDistance
Jeśli korzystasz z Microsoft SQL Server, oferują one własną funkcję, STOdległość do obliczania odległości między dwoma punktami przy użyciu typu danych Geografia.
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326);
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
SELECT @g.STDistance(@h);
Cynk kapelusza dla Manash Sahoo, wiceprezesa i architekta Highbridge.
Bardzo dziękuję za udostępnienie. To było łatwe zadanie kopiowania i wklejania i działa świetnie. Zaoszczędziłeś mi dużo czasu.
FYI dla każdego, kto przenosi się na C:
double deg2rad (double deg) {return deg * (3.14159265358979323846 / 180.0); }
Bardzo fajny post - działał bardzo ładnie - musiałem tylko zmienić nazwę stołu, na którym znajduje się łata. Działa dość szybko, aby ... Mam dość małą liczbę łat (<400), ale myślę, że to by się dobrze skalowało. Ładna strona też - właśnie dodałem ją do mojego konta del.icio.us i będę regularnie sprawdzać.
Bardzo dziękuję Peterowi i Kerry! Jeśli lubisz pracować nad projektami GIS, polecam:
Bardzo dziękuję… 😀
Przez cały dzień szukałem obliczeń odległości i znalazłem algorytm harversine, dzięki za podanie przykładu, jak umieścić go w instrukcji sql. Dzięki i pozdrawiam, Daniel
Cieszę się, że mogłem pomóc, przyjacielu szyn!
Teraz szukam funkcji PHP „in Polygon”, która pobierze tablicę uporządkowanych współrzędnych szerokości i długości geograficznej i określi, czy inny punkt znajduje się w wielokącie, czy poza nim.
Znalazłem równanie, aby dowiedzieć się, czy punkt w wielokącie!
myślę, że twój SQL potrzebuje instrukcji posiadania.
zamiast WHERE odległość <= $ odległość, której możesz potrzebować
użyj HAVING odległość <= $ odległość
w przeciwnym razie dziękuję za zaoszczędzenie czasu i energii.
Cześć David,
Jeśli robisz jakikolwiek rodzaj oświadczenia GROUP BY, będziesz potrzebował MIEĆ. Nie robię tego w powyższym przykładzie.
Doug
Począwszy od MySQL 5.x nie można używać aliasu w klauzuli WHERE, patrz http://dev.mysql.com/doc/refman/5.0/en/problems-with-alias.html
Użyj HAVING zamiast WHERE w powyższych zapytaniach
Dziękuję Ci bardzo. Wykonałeś świetną robotę. Właśnie tego chcę. Wielkie dzięki.
Dziękuję bardzo za udostępnienie tego kodu. Zaoszczędziło mi to dużo czasu na rozwój. Podziękowania dla czytelników za wskazanie, że instrukcja HAVING jest niezbędna dla MySQL 5.x. Bardzo pomocny.
Mam szczęście, że czytelnicy są znacznie mądrzejsi niż ja!
🙂
Powyższy wzór oszczędza mi dużo czasu. Dziękuję Ci bardzo.
Muszę też przełączać się między formatem NMEA a stopniami. Znalazłem formułę pod tym adresem URL na dole strony. http://www.errorforum.com/knowledge-base/16273-converting-nmea-sentence-latitude-longitude-decimal-degrees.html
Czy ktoś wie jak to zweryfikować?
Dziękuję Ci!
Harry
Cześć,
Inne pytanie. Czy istnieje wzór na ciągi NMEA, taki jak ten poniżej?
1342.7500, N, 10052.2287, E
$GPRMC,032731.000,A,1342.7500,N,10052.2287,E,0.40,106.01,101106,,*0B
Dzięki,
Harry
Stwierdziłem też, że GDZIE nie działa dla mnie. Zmieniłem to na MIEĆ i wszystko działa idealnie. Na początku nie przeczytałem komentarzy i przepisałem je za pomocą zagnieżdżonego wyboru. Oba będą działać dobrze.
Bardzo dziękuję za skrypt napisany w mysql, po prostu musiałem dokonać kilku drobnych poprawek (MAJĄC) 🙂
Dobra robota
Niezwykle pomocny, bardzo dziękuję! Miałem trochę problemów z nowym „MAMY”, a nie „GDZIE”, ale kiedy przeczytałem tutaj komentarze (po około pół godzinie zgrzytania zębami z frustracji = P), udało mi się sprawnie działać. Dziękuję ^ _ ^
wielkie dzięki działa świetnie
Należy pamiętać, że takie polecenie typu select będzie bardzo intensywne obliczeniowo, a zatem powolne. Jeśli masz dużo takich zapytań, może to dość szybko przytłumić.
O wiele mniej intensywnym podejściem jest wykonanie pierwszego (surowego) wyboru przy użyciu obszaru KWADRAT zdefiniowanego przez obliczoną odległość, tj. „Wybierz * z nazwy tabeli, gdzie szerokość geograficzna między lat1 i lat2 oraz długość geograficzna między lon1 i lon2”. lat1 = targetlatitude – latdiff, lat2 = targetlatitude + latdiff, podobnie jak lon. latdiff ~= odległość / 111 (dla km) lub odległość/69 dla mil, ponieważ 1 stopień szerokości geograficznej wynosi ~ 111 km (niewielka zmiana, ponieważ ziemia jest lekko owalna, ale wystarcza do tego celu). londiff = odległość / (abs (cos (deg2rad (szerokość geograficzna)) * 111)) - lub 69 na mile (w rzeczywistości można wziąć nieco większy kwadrat, aby uwzględnić różnice). Następnie weź wynik tego i wprowadź go do radialnego wyboru. Tylko nie zapomnij uwzględnić współrzędnych poza granicami – tzn. zakres dopuszczalnej długości geograficznej to -180 do +180, a zakres dopuszczalnej szerokości geograficznej to -90 do +90 – na wypadek, gdyby twoja szerokość geograficzna lub londiff wykraczały poza ten zakres . Zauważ, że w większości przypadków może to nie mieć zastosowania, ponieważ wpływa tylko na obliczenia na linii przechodzącej przez ocean Pacyfiku od bieguna do bieguna, chociaż przecina część czukotki i część Alaski.
W ten sposób osiągamy znaczne zmniejszenie liczby punktów, na podstawie których dokonujesz tych obliczeń. Jeśli masz milion punktów globalnych w bazie danych rozmieszczonych z grubsza równomiernie i chcesz wyszukiwać w promieniu 100 km, to twoje pierwsze (szybkie) wyszukiwanie obejmuje obszar 10000 km20 i prawdopodobnie przyniesie około 500 wyników (przy równomiernym rozmieszczeniu na powierzchni około 20 mln kmXNUMX), co oznacza, że dla tego zapytania wykonujesz złożone obliczenia odległości XNUMX razy, a nie milion razy.
Drobny błąd w przykładzie… to byłby w promieniu 50 km (nie 100), ponieważ patrzymy na „promień” naszego… kwadratu.
Fantastyczna rada! Właściwie pracowałem z programistą, który napisał funkcję, która ciągnęła wewnętrzny kwadrat, a następnie funkcję rekurencyjną, która tworzyła „kwadraty” wokół obwodu, aby uwzględnić i wykluczyć pozostałe punkty. Rezultatem był niesamowicie szybki wynik - potrafił ocenić miliony punktów w mikrosekundach.
Moje podejście powyżej jest zdecydowanie „surowe”, ale możliwe. Dzięki jeszcze raz!
Doug,
Próbowałem użyć mysql i php do oceny, czy długi punkt znajduje się w wielokącie. Czy wiesz, czy Twój znajomy programista opublikował jakieś przykłady, jak wykonać to zadanie. Czy znasz jakieś dobre przykłady. Z góry dziękuję.
Cześć wszystkim, to jest moja testowa instrukcja SQL:
SELECT DISTINCT area_id, (
(
(
acos( sin( ( 13.65 * pi( ) /180 ) ) * sin( (
`lat_dec` * pi( ) /180 ) ) + cos( ( 13.65 * pi( ) /180 ) ) * cos( (
`lat_dec` * pi( ) /180 )
) * cos( (
( 51.02 - `lon_dec` ) * pi( ) /180 )
)
)
) *180 / pi( )
) *60 * 1.1515 * 1.609344
) AS distance
FROM `post_codes` WHERE distance <= 50
a MySQL mówi mi, że odległość, nie istnieje jako kolumna, mogę użyć kolejności według, mogę to zrobić bez GDZIE i to działa, ale nie z nim…
Zastąp „GDZIE odległość” na „MASZ odległość”.
Działa jak urok, dzięki, Douglas!
To jest świetne, ale tak jak ptaki latają. Byłoby wspaniale spróbować w jakiś sposób włączyć do tego Google Maps API (może przy użyciu dróg itp.) Tylko po to, aby dać pomysł za pomocą innej formy transportu. Nadal nie stworzyłem funkcji symulowanego wyżarzania w PHP, która byłaby w stanie zaoferować wydajne rozwiązanie problemu komiwojażera. Ale myślę, że być może uda mi się ponownie wykorzystać w tym celu część twojego kodu.
Cześć Douglas,
bardzo dziękuję za ten artykuł - właśnie zaoszczędziłeś mi dużo czasu.
dbać,
Nimrod @Israel
Dobry artykuł! Znalazłem wiele artykułów opisujących sposób obliczania odległości między dwoma punktami, ale naprawdę szukałem fragmentu kodu SQL.
Wielkie dzięki, działa dobrze
Bardzo dziękuję za tę formułę. Ogolił trochę czasu na projekcie lokalizacji sklepu, który mnie zżerał.
Dzięki pakietowi. Ta krótka linijka kodu pozwoliła mi zaoszczędzić sporo czasu w projekcie lokalizacji sklepu!
# 1054 - Nieznana kolumna „odległość” w „klauzuli gdzie”
Zatwierdzać
To samo tutaj! Jaki jest problem :-/? jak rozwiązać „odległość” - problem z kolumną? Pomóż nam proszę!! 🙂
Spróbuj użyć HAVING zamiast WHERE
2 dni poszukiwań, aby w końcu znaleźć tę stronę, która rozwiązuje mój problem. Wygląda na to, że lepiej wyskoczę z mojego WolframAlpha i poprawię matematykę. Zmiana z WHERE na HAVING sprawia, że mój skrypt działa. DZIĘKUJĘ CI
zamiast klauzuli WHERE użyj:
MAJĄC dystans <50
Dzięki Georgi. Ciągle otrzymuję kolumnę „odległość” nie znaleziono. Raz zmieniłem GDZIE na POSIADAŁO to zadziałało jak urok!
Chciałbym, żeby to była pierwsza strona, jaką znalazłem na tym. Po wypróbowaniu wielu różnych poleceń była to jedyna, która działała poprawnie i wymagała minimalnych zmian, aby dopasować moją własną bazę danych.
Wielkie dzięki!
Chciałbym, żeby to była pierwsza strona, jaką znalazłem na tym. Po wypróbowaniu wielu różnych poleceń była to jedyna, która działała poprawnie i wymagała minimalnych zmian, aby dopasować moją własną bazę danych.
Wielkie dzięki!
Wielkie dzięki!
Wielkie dzięki!
Nie sądzę, żeby kod się już pojawiał. Może to Firefox?
Właśnie przetestowałem zarówno przeglądarkę Firefox, jak i Chrome i to się pojawia. Spróbuj ponownie?
Cześć. Wielkie dzięki. To działa jak urok.
Wielkie dzięki, Douglas. To działa idealnie.
Wiem, że ten wzór działa, ale nie widzę, gdzie jest brany pod uwagę promień Ziemi. Czy ktoś może mnie oświecić, proszę?
Tim, pełne wyjaśnienie formuły Haversine (to nie jest kod), sprawdź artykuł w Wikipedii: http://en.wikipedia.org/wiki/Haversine_formula
Piękny! To bardzo mi pomogło!
Świetna rzecz, Douglas. Czy próbowałeś obliczyć punkt przecięcia, biorąc pod uwagę Długi / Szer / Namiar dwóch punktów?
Jeszcze tego nie zrobiłem, Khanh!
Dziękuję Douglas, zapytanie SQL jest dokładnie tym, czego potrzebowałem i pomyślałem, że będę musiał go napisać samodzielnie. Uratowałeś mnie od możliwych godzin krzywej uczenia się szerokości geograficznej!
Ciągle otrzymuję komunikat o błędzie: nieznana kolumna „Odległość” w „klauzuli gdzie” w zapytaniu MySQL.
Peter, przeczytaj proszę inne komentarze. Wygląda na to, że niektórzy ludzie musieli używać innej składni dla GDZIE / POSIADAJĄC.
Dziękuję za ten wspaniały artykuł! Właśnie przetestowałem kod w mojej bazie danych i działało świetnie!
Douglas, dziękuję za ten niesamowity kod. Łamałem głowę, jak to zrobić na moim portalu społecznościowym GPS. Zaoszczędziłeś mi wiele godzin.
Wspaniale to słyszeć, Ash!
dziękuję za opublikowanie tego pomocnego artykułu,
ale z jakiegoś powodu chciałbym zapytać
jak uzyskać odległość między współrzędnymi wewnątrz bazy mysql a współrzędnymi wstawionymi do php przez użytkownika?
aby dokładniej opisać:
1. użytkownik musi wstawić [id], aby wybrać określone dane z bazy danych i współrzędne samego użytkownika
2. plik php pobierz dane celu (współrzędne) za pomocą [id], a następnie oblicz odległość między użytkownikiem a punktem docelowym
czy może po prostu uzyskać odległość od poniższego kodu?
$ qry = „SELECT *, (((acos (sin ((„. $ latitude. ”) * pi () / 180)) * sin ((„ Latitude ”* pi () / 180)) + cos ((„. $ latitude. ”* pi () / 180)) * cos ((` Latitude` * pi () / 180)) * cos (((". $ longitude." - `Longitude`) * pi () / 180) ))) * 180 / pi ()) * 60 * 1.1515 * 1.609344) jako odległość OD `MyTable` WHERE distance> =". $ Distance. " >>>> czy mogę „usunąć” odległość stąd?
dzięki jeszcze raz,
Timmy S.
nieważne, dowiedziałem się, jak ta „funkcja” działa w php
$ dis = getDistanceBetweenPointsNew ($ userLati, $ userLongi, $ lati, $ longi, $ unit = 'Km')
wielkie dzięki!!
ok, wszystko czego próbowałem nie działa. To znaczy to, co mam, działa, ale odległości są dalekie.
Czy ktokolwiek mógłby zobaczyć, co jest nie tak z tym kodem?
if (isset ($ _ POST ['przesłane'])) {$ z = $ _POST ['kod pocztowy']; $ r = $ _POST ['promień']; echo “Wyniki dla”. $ z; $ sql = mysql_query („SELECT DISTINCT m.zipcode, m.MktName, m.LocAddSt, m.LocAddCity, m.LocAddState, m.x1, m.y1, m.verified, z1.lat, z2.lon, z1. city, z1.state OD mrk m, zip z1, zip z2 GDZIE m.zipcode = z1.zipcode AND z2.zipcode = $ z AND (3963 * acos (truncate (sin (z2.lat / 57.2958) * sin (m. y1 / 57.2958) + cos (z2.lat / 57.2958) * cos (m.y1 / 57.2958) * cos (m.x1 / 57.2958 - z2.lon / 57.2958), 8))) <= $ r ") lub umrzeć (mysql_error ()); while ($ row = mysql_fetch_array ($ sql)) {$ store1 = $ row ['MktName']. "”; $ store = $ row ['LocAddSt']. ””; $ store. = $ row ['LocAddCity']. ”,„. $ row ['LocAddState']. ” „. $ Row ['kod pocztowy']; $ latitude1 = $ row ['lat']; $ longitude1 = $ row ['lon']; $ latitude2 = $ row ['y1']; $ longitude2 = $ row ['x1']; $ city = $ row ['city']; $ stan = $ wiersz ['stan']; $ dis = getnew ($ latitude1, $ longitude1, $ latitude2, $ longitude2, $ unit = 'Mi'); // $ dis = odległość ($ lat1, $ lon1, $ lat2, $ lon2); $ zweryfikowane = $ wiersz ['zweryfikowane']; if ($ zweryfikowane == '1') {echo „”; echo „”. $ sklep. ””; echo $ dis. " mile stąd"; Echo ""; } else {echo „”. $ sklep. ””; echo $ dis. " mile stąd"; Echo ""; }}}
mój kod functions.php
funkcja getnew ($ latitude1, $ longitude1, $ latitude2, $ longitude2, $ unit = 'Mi') {$ theta = $ longitude1 - $ longitude2; $ odległość = (sin (deg2rad ($ latitude1)) * sin (deg2rad ($ latitude2))) + (cos (deg2rad ($ latitude1)) * cos (deg2rad ($ latitude2)) * cos (deg2rad ($ theta)) ); $ odległość = acos ($ odległość); $ odległość = rad2deg ($ odległość); $ odległość = $ odległość * 60 * 1.1515; switch ($ unit) {case 'Mi': break; przypadek „Km”: $ odległość = $ odległość * 1.609344; } return (round ($ distance, 2)); }
Z góry dziękuję
Dziękuję za ten artykuł. Działa dobrze z moim kodem. 🙂
Hej Douglas, świetny artykuł. Uważam, że twoje wyjaśnienie pojęć geograficznych i kodu jest naprawdę interesujące. Moją jedyną sugestią byłoby spacje i wcięcie kodu do wyświetlania (na przykład Stackoverflow). Rozumiem, że chcesz zaoszczędzić miejsce, ale konwencjonalne odstępy / wcięcia w kodzie znacznie ułatwiłyby mi jako programistowi czytanie i analizowanie. W każdym razie to drobiazg. Kontynuuj wspaniałą pracę.
Dzięki! Trochę zmodyfikowałem post… ale równania zajmują tak dużo miejsca i są tak długie, że nie jestem pewien, czy to za bardzo pomaga.
Dziękuję bardzo.
tutaj podczas korzystania z funkcji otrzymujemy jeden rodzaj odległości ... podczas gdy przy zapytaniu nadchodzi inny rodzaj odległości
Nie będę obliczał odległości między dwoma stanami
Muchas gracias por tan hermoso codigo…
To ma dobre funkcje cosinusa. Nie znam matematyki, ale dzięki!
Świetna robota… 🙂 (y)
wydaje się szybsze (mysql 5.9) dwukrotne użycie formuły w selekcji i gdzie:
$ formuła = „(((acos (sin ((„. $ latitude. ”) * pi () / 180)) * sin ((„ Latitude ”* pi () / 180)) + cos ((„. $ latitude. ”* Pi () / 180)) * cos ((` Latitude` * pi () / 180)) * cos (((". $ Longitude." - `Longitude`) * pi () / 180)))) * 180 / pi ()) * 60 * 1.1515 * 1.609344) ”;
$ sql = 'SELECT *,'. $ formula. ' jako odległość OD tabeli GDZIE '.. $ wzór.' <= '. $ odległość;
dzięki…
nie działa, jeśli
„GDZIE odległość”
działa, jeśli
„MAJĄC dystans”
Wielkie dzięki za przeczytanie tego artykułu. Jest bardzo pomocny.
Początkowo PHP zostało stworzone jako prosta platforma skryptowa o nazwie „Osobista strona główna”. Obecnie PHP (skrót od Hypertext Preprocessor) jest alternatywą technologii Microsoft Active Server Pages (ASP).
PHP jest językiem serwerowym typu open source, używanym do tworzenia dynamicznych stron internetowych. Może być osadzony w HTML. PHP jest zwykle używane w połączeniu z bazą danych MySQL na serwerach WWW Linux / UNIX. Jest to prawdopodobnie najpopularniejszy język skryptowy.
Powyższe rozwiązanie nie działa poprawnie.
Muszę zmienić na:
$ qqq = "SELECT *, (((acos (sin ((". $ latitude. "* pi () / 180)) * sin ((` latt` * pi () / 180)) + cos ((". $ latitude. “* pi () / 180)) * cos ((` latt` * pi () / 180)) * cos (((". $ longitude." - `longt`) * pi () / 180) ))) * 180 / pi ()) * 60 * 1.1515) jako odległość OD „rejestru”;
Dzięki Kupendra!
dziękuję sir wroking doskonale .. ale mam jedno pytanie, jeśli chcę wyjść bez przecinka, to co mogę zrobić ..?
Z góry dziękuję.
Witam, naprawdę będę potrzebować twojej pomocy w tej sprawie.
Wysłałem żądanie pobierania do mojego serwera internetowego
53.47792 = szerokość geograficzna $
-2.23389 = długość geograficzna $
a 20 = odległość, którą chcę odzyskać
Jednak przy użyciu formuły pobiera wszystkie wiersze w mojej bazie danych
$results = DB::select( DB::raw("WYBIERZ *, (((acos(sin(("$szerokość geograficzna."pi()/180)) * grzech((łacpi()/180))+cos((„.$szerokość geograficzna.”pi()/180)) * cos((łacpi()/180)) * cos(((„.$długość geograficzna.”- lng)pi()/180))))180/pi())601.1515*1.609344) jako odległość OD znaczników MAJĄCY odległość >= „.$odległość ));
[{„Id”: 1, ”name”: ”Frankie Johnnie & Luigo Too”, ”address”: ”939 W El Camino Real, Mountain View, CA”, „lat”: 37.386337280273, „lng”: - 122.08582305908, „Distance”: 16079.294719663}, {„id”: 2, ”name”: ”Amici's East Coast Pizzeria”, „address”: ”790 Castro St, Mountain View, CA”, „lat”: 37.387138366699, „lng”: -122.08323669434, „distance”: 16079.175940152}, {„id”: 3, ”name”: ”Kapp's Pizza Bar & Grill”, „address”: ”191 Castro St, Mountain View, CA”, „lat”: 37.393886566162, ”Lng”: - 122.07891845703, ”distance”: 16078.381373826}, {„id”: 4, ”name”: ”Round Table Pizza: Mountain View”, „address”: ”570 N Shoreline Blvd, Mountain View, CA”, ”Lat”: 37.402652740479, ”lng”: - 122.07935333252, ”distance”: 16077.420540582}, {„id”: 5, ”name”: ”Tony & Alba's Pizza & Pasta”, „address”: ”619 Escuela Ave, Mountain View, CA ”,„ lat ”: 37.394012451172,„ lng ”: - 122.09552764893,„ distance ”: 16078.563225154}, {„ id ”: 6,„ name ”:” Oregano's Wood-Pizza ”,„ address ”:” 4546 El Camino Real, Los Altos, CA ”,„ lat ”: 37.401725769043,„ lng ”: - 122.11464691162,„ distance ”: 16077.937560795}, {„ id ”: 7,„ name ”:„ Bary i grille ”,„ address ”:„ 24 Whiteley Street, Manchester ”,„ lat ”: 53.485118865967,„ lng ”: - 2.1828699111938,„ distance ”: 8038.7620112314}]
Chcę pobrać tylko rzędy z 20 milami, ale to pokazuje wszystkie rzędy. Proszę, co robię źle
Szukam podobnego zapytania, ale nieco przyspieszonego – w skrócie oznacza to zgrupowanie wszystkich współrzędnych w promieniu 2 mil od każdej współrzędnej, a następnie policzenie, ile współrzędnych w każdej grupie i wyprowadzenie tylko jednej grupy, która ma najwięcej współrzędnych – nawet jeśli masz więcej niż jedną grupę wśród grup o największej liczbie współrzędnych – po prostu wypisz losową grupę z grup o tej samej największej liczbie –
Dziękuję bardzo za udostępnienie.