Здесь хранится функция для MySQL, которую я создал некоторое время назад - она возвращает (приблизительное) расстояние между двумя парами широты и долготы в метрах .
DELIMITER $$
CREATE FUNCTION LAT_LNG_DISTANCE(lat1 FLOAT, lng1 FLOAT, lat2 FLOAT, lng2 FLOAT) RETURNS int(11)
BEGIN
DECLARE latD FLOAT;
DECLARE lngD FLOAT;
DECLARE latS FLOAT;
DECLARE lngS FLOAT;
DECLARE a FLOAT;
DECLARE c FLOAT;
SET lat1 = RADIANS(lat1);
SET lng1 = RADIANS(lng1);
SET lat2 = RADIANS(lat2);
SET lng2 = RADIANS(lng2);
SET latD = lat2 - lat1;
SET lngD = lng2 - lng1;
SET latS = SIN(latD / 2);
SET lngS = SIN(lngD / 2);
SET a = POW(latS, 2) + COS(lat1) * COS(lat2) * POW(lngS, 2);
SET c = 2 * ASIN(LEAST(1, SQRT(a)));
RETURN ROUND(c * 6378137);
END;
$$
DELIMITER ;
Теперь мы определили, что нам нужно получить источник поиска на основе почтового индекса, который нам дал пользователь. Поскольку я не знаю точную структуру вашей базы данных, я буду использовать общие объединения и условия, которые, я надеюсь, будут достаточно похожи на реальные, чтобы вы могли легко адаптироваться. Я собираюсь использовать $var
, чтобы подразумевать передачу значения из PHP; само собой разумеется, ему нужно будет уйти соответствующим образом.
SELECT l.lat, l.lng
FROM city_locations l
INNER JOIN city_postcodes c
ON l.city_id = c.city_id
WHERE c.postcode = $postcode;
Теперь мы можем передать результаты этого запроса следующему запросу, который будет использовать функцию LAT_LNG_DISTANCE
, которую мы определили ранее.
SELECT *
FROM people p
INNER JOIN city_locations l
ON p.city_id = l.city_id
WHERE LAT_LNG_DISTANCE(l.lat, l.lng, $search_lat, $search_lng) < p.range * 1609;
Кстати,
1609 - это количество метров в миле. Надеюсь, я правильно понял вопрос!