Najszybszym sposobem, aby to zrobić, jest użycie rozszerzeń geoprzestrzennych dla MySQL, co powinno być wystarczająco łatwe, ponieważ używasz już tabeli MyISAM. Dokumentację tych rozszerzeń można znaleźć tutaj:http:// /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html
Dodaj nową kolumnę z typem danych POINT:
ALTER TABLE `adverts`
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)
Następnie możesz wypełnić tę kolumnę z istniejących pól szerokości i długości geograficznej:
UPDATE `adverts`
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));
Następnym krokiem jest utworzenie ramki ograniczającej na podstawie wejściowej szerokości i długości geograficznej, które będą używane w WHERE
klauzula jako CONTAINS
ograniczenie. Będziesz musiał określić zestaw X,Y POINT
współrzędne, które działają zgodnie z Twoimi wymaganiami w oparciu o żądany obszar wyszukiwania i podany punkt początkowy.
Twoje ostatnie zapytanie wyszuka wszystkie POINT
dane znajdujące się w wyszukiwaniu POLYGON
, a następnie możesz użyć obliczenia odległości w celu dalszego doprecyzowania i posortowania danych:
SELECT a.*,
ROUND( SQRT( ( ( (adverts.latitude - '53.410778') * (adverts.latitude - '53.410778') ) * 69.1 * 69.1 ) + ( (adverts.longitude - '-2.97784') * (adverts.longitude - '-2.97784') * 53 * 53 ) ), 1 ) AS distance
FROM adverts a
WHERE a.type_id = 3
AND CONTAINS(a.geopoint, GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'))
HAVING distance < 25
ORDER BY distance DESC
LIMIT 0, 30
Zauważ, że GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))')
w powyższym nie będzie działać , musisz zastąpić współrzędne prawidłowymi punktami wokół początku wyszukiwania. Jeśli spodziewasz się zmiany szerokości/długości, powinieneś rozważyć użycie wyzwalacza, aby zachować POINT
dane i powiązany SPATIAL KEY
aktualny. W przypadku dużych zestawów danych powinieneś zauważyć znacznie lepszą wydajność w porównaniu z obliczaniem odległości dla każdego rekordu i filtrowaniem za pomocą HAVING
klauzula. Osobiście zdefiniowałem funkcje do użycia przy określaniu odległości i tworzeniu obwiedni POLYGON
.