Най-бързият начин да направите това е да използвате геопространствените разширения за MySQL, което трябва да е достатъчно лесно, тъй като вече използвате MyISAM таблица. Документацията за тези разширения може да бъде намерена тук:http:/ /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html
Добавете нова колона с тип данни POINT:
ALTER TABLE `adverts`
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)
След това можете да попълните тази колона от съществуващите си полета за географска ширина и дължина:
UPDATE `adverts`
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));
Следващата стъпка е да създадете ограничаваща кутия въз основа на въведените ширина и дължина, които ще бъдат използвани във вашия WHERE
клауза като CONTAINS
ограничение. Ще трябва да определите набор от X,Y POINT
координати, които работят за вашите изисквания въз основа на желаната област за търсене и дадена начална точка.
Вашата последна заявка ще търси всички POINT
данни, които са във вашето търсене POLYGON
, и след това можете да използвате изчисление на разстоянието, за да прецизирате и сортирате данните си:
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
Обърнете внимание, че GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))')
в горното няма дасработи , ще трябва да замените координатите с валидни точки около началото на вашето търсене. Ако очаквате lat/long да се промени, трябва да помислите за използването на тригер, за да запазите POINT
данни и свързания SPATIAL KEY
актуална. С големи набори от данни трябва да видите значително подобрена производителност спрямо изчисляване на разстояние за всеки запис и филтриране с помощта на HAVING
клауза. Аз лично дефинирах функции за използване при определяне на разстоянието и създаване на ограничаващ POLYGON
.