Wyszukiwanie rekordów w obrębie x km

0

Cześć.

Jak zrobić (albo co wpisać w google :D) wyszukiwanie rekordów w obrębie x km od danego miejsca.

Mam tabelę gdzie lokalizacja wybierana jest poprzez integrację z google, w bazie zapisywane są współrzędne. Następnie osoba która korzysta z wyszukiwarki też wybiera lokalizację z google i teraz chcę wyświetlić rekordy które są powiedzmy w promieniu 10km od szukanej lokalizacji. Jak to obliczyć? Czego szukać? Gotowa biblioteka?

Dzięki

1

Google Maps udostępnia API do mierzenia odległości między punktami.

https://developers.google.com/maps/documentation/distance-matrix/overview

Możesz wybrać odległość w kilometrach/metrach, a także w minutach samochodem, pociągiem lub z buta.

0

Nie jestem pewien czy o to chodzi.
Najlepszym przykładem tego co mam na myśli są portale ogłoszeniowe, np olx

0
michalos25 napisał(a):

Nie jestem pewien czy o to chodzi.
Najlepszym przykładem tego co mam na myśli są portale ogłoszeniowe, np olx

Czyli po prostu chcesz mieć funkcję do której przekażesz długość i szerokość geograficzną dwóch punktów, i dostaniesz odległość między nimi w linii prostej (nie patrząć na rzeki, drogi, budynki) etc.?

Jeśli tak, to tutaj jest example: https://stackoverflow.com/questions/10053358/measuring-the-distance-between-two-coordinates-in-php

function haversineGreatCircleDistance(
  $latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000)
{
  // convert from degrees to radians
  $latFrom = deg2rad($latitudeFrom);
  $lonFrom = deg2rad($longitudeFrom);
  $latTo = deg2rad($latitudeTo);
  $lonTo = deg2rad($longitudeTo);

  $latDelta = $latTo - $latFrom;
  $lonDelta = $lonTo - $lonFrom;

  $angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
    cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
  return $angle * $earthRadius;
}

Działa dobrze, jeśli tylko któryś z punktów nie jest blisko bieguna (przez problem z precyzją).

0

Tylko tutaj trzeba znać punkty docelowe a podczas wyszukiwania są tylko wejściowe. Czyli pobieram rekordy, później obliczam odległość i odrzucam te rekordy gdzie odległość przekracza założony promień?

0
michalos25 napisał(a):

Tylko tutaj trzeba znać punkty docelowe a podczas wyszukiwania są tylko wejściowe. Czyli pobieram rekordy, później obliczam odległość i odrzucam te rekordy gdzie odległość przekracza założony promień?

Czyli chcesz wziąć punkt początkowy, listę punktów końcowych, i wyfiltrować z tej listy punktów końcowych tylko te mniejsze niż zadany dystans?

3

Jaką masz bazę danych? Przykładowo w postgres jest dodatek postgis i funkcja ST_Distance https://postgis.net/docs/ST_Distance.html
Lub ST_DWithin https://postgis.net/docs/ST_DWithin.html
W SQL server jest podobnie. https://docs.microsoft.com/en-us/sql/t-sql/spatial-geography/stdistance-geography-data-type?view=sql-server-ver15
Jeśli masz koordynaty w odpowiednim formacie to troszkę bardziej rozbudowane zapytanie SQL powinno zwrócić odpowiednie obiekty.
Żeby nie było danymi geograficznymi w SQL się tylko bawiłem i ekspertem NIE jestem, ale wygląda na to, że tego szukasz.
Może są do tego jakieś paczki, ale raw query byłoby chyba najprostsze.
Inna alternatywa to jak pisze @TomRiddle szukanie API które to za Ciebie policzy, ale ilość strzałów do API może być Wtedy bardzo duża.

0

@TomRiddle: mniej więcej o to mi chodziło tylko tutaj mam wątpliwości co do wydajności.
Ciekawą opcją wydaje się być to co napisał @jurek1980 odnośnie zapytania.

0
michalos25 napisał(a):

@TomRiddle: mniej więcej o to mi chodziło tylko tutaj mam wątpliwości co do wydajności.
Ciekawą opcją wydaje się być to co napisał @jurek1980 odnośnie zapytania.

Nie rób premature optimization: https://stackify.com/premature-optimization-evil/

Takie funkcje matematyczne jak asin(), deg2rad() etc. są w miare szybkie.

1

Hmm. @TomRiddle może źle rozumiem, ale jeśli w bazie jest 5000 wierszy z punktami, to sugerujesz pobrać wszystkie, przeliczyć odległość po stronie PHPa i odrzucić niewłaściwe? No to straszny narzut na zapytaniu, a co jeszcze jak tych wierszy jest miliony. Nie wiem. Opcja odpowedniego zapytania do bazy, jeśli ma ona taką opcję wydaje się najprostsza i najmniej kosztująca zasoby.

Zresztą od czego jest StackOverflow.
https://gis.stackexchange.com/questions/353946/return-rows-where-distance-is-within-x-meters
Jedno prościutkie query i są rekordy w konkretnej odległości. Nie trzeba pobierać wszystkich przy każdym wykonaniu.

0
jurek1980 napisał(a):

Hmm. @TomRiddle może źle rozumiem, ale jeśli w bazie jest 5000 wierszy z punktami, to sugerujesz pobrać wszystkie, przeliczyć odległość po stronie PHPa i odrzucić niewłaściwe? No to straszny narzut na zapytaniu, a co jeszcze jak tych wierszy jest miliony. Nie wiem. Opcja odpowedniego zapytania do bazy, jeśli ma ona taką opcję wydaje się najprostsza i najmniej kosztująca zasoby.

Zresztą od czego jest Stacja.
https://gis.stackexchange.com/questions/353946/return-rows-where-distance-is-within-x-meters
Jedno prościutkie query i są rekordy w kontentej odległości. Nie trzeba pobierać wszystkich przy każdym wykonaniu.

Zależy po której stronie chcesz mieć kontrolę takiego czegoś.

Jeśli w persystencji (czyli w bazie) to spoko, możesz zrobić ST_DWithin(). Dla zwykłego filtrowania recordów które są dalej/bliżej niż, to to jest spoko.

Natomiast jeśli chcesz mieć taką kontrolę po stronie Twojej aplikacji, i nie możesz tego zrobić na 5000 recordów, dlatego że połączenie z persystencją (czyli z bazą) Cię spowalnia, to coś jest grubo nie tak.

1 użytkowników online, w tym zalogowanych: 0, gości: 1