Функция MySQL для определения близости/диапазона Zip-кода

Мне удалось создать функцию php для определения списка почтовых индексов в определенном диапазоне заданного почтового индекса. Однако моя следующая задача немного сложнее.

Предположим, что таблица имеет следующие столбцы:

id,
username
info
latitude
longitude
range

Каждая запись имеет уникальный идентификатор строки, некоторую информацию, широту, долготу и максимальный диапазон от тех координат, которые человек хочет, чтобы эта запись была найдена. Итак, если я создаю запись с координатами -20, 50 с диапазоном 15, это означает, что я хочу, чтобы люди в пределах 15 миль от координат -20, 50 могли видеть мою запись. Выяснение широты и долготы пользователя, выполняющего поиск, является тривиальным вопросом.

Когда пользователь выполняет поиск по базе данных, все записи должны быть получены для координат широты и долготы в пределах значения диапазона от пользователей lat/long.

Таким образом, нефункциональный пример кода с использованием формулы расстояния для иллюстрации будет

$userLat= Широта пользователя, выполняющего поиск

$userLong= Долгота пользователя, выполняющего поиск

SELECT info FROM table 
WHERE sqrt(($userLat - lat)^2 - ($userLong - long)^2) <= range 
ORDER BY username ASC

Это было бы идеально, но это неверно с точки зрения кодирования. Есть ли способ выполнить приведенные выше сравнения с использованием PHP и MySQL в одном запросе? Это предполагает возможность запуска операций с использованием нескольких значений столбцов из заданной строки.

ОБНОВЛЕНИЕ + РЕШЕНИЕ

Я создал еще один вопрос, который решает эту проблему и имеет очень компактную функцию для выполнения этого вопроса. Это послужило для него функцией, предоставляемой coderpros (его функция намного лучше справляется с определенными ситуациями). Однако, поскольку я использую свою функцию с большой степенью контроля над входом, я создал отдельную функцию. Его можно найти по следующей ссылке:

Пользовательская функция MySQL для синтаксиса долготы долготы

1 ответ

Эта отличная функция mySQL, которую я написал, определенно должна сделать трюк для вас.

BEGIN
 DECLARE x decimal(18,15);
 DECLARE EarthRadius decimal(7,3);
 DECLARE distInSelectedUnit decimal(18, 10);
 IF originLatitude = relativeLatitude AND originLongitude = relativeLongitude THEN
 RETURN 0; -- same lat/lon points, 0 distance
 END IF;
 -- default unit of measurement will be miles
 IF measure != 'Miles' AND measure != 'Kilometers' THEN
 SET measure = 'Miles';
 END IF;
 -- lat and lon values must be within -180 and 180.
 IF originLatitude < -180 OR relativeLatitude < -180 OR originLongitude < -180 OR relativeLongitude < -180 THEN
 RETURN 0;
 END IF;
 IF originLatitude > 180 OR relativeLatitude > 180 OR originLongitude > 180 OR relativeLongitude > 180 THEN
 RETURN 0;
 END IF;
 SET x = 0.0;
 -- convert from degrees to radians
 SET originLatitude = originLatitude * PI() / 180.0,
 originLongitude = originLongitude * PI() / 180.0,
 relativeLatitude = relativeLatitude * PI() / 180.0,
 relativeLongitude = relativeLongitude * PI() / 180.0;
 -- distance formula, accurate to within 30 feet
 SET x = Sin(originLatitude) * Sin(relativeLatitude) + Cos(originLatitude) * Cos(relativeLatitude) * Cos(relativeLongitude - originLongitude);
 IF 1 = x THEN
 SET distInSelectedUnit = 0; -- same lat/long points
 -- not enough precision in MySQL to detect this earlier in the function
 END IF;
 SET EarthRadius = 3963.189;
 SET distInSelectedUnit = EarthRadius * (-1 * Atan(x / Sqrt(1 - x * x)) + PI() / 2);
 -- convert the result to kilometers if desired
 IF measure = 'Kilometers' THEN
 SET distInSelectedUnit = MilesToKilometers(distInSelectedUnit);
 END IF;
 RETURN distInSelectedUnit;
END

Он принимает originLatitude, originLongitude, relativeLatitude, relativeLongitude и измеряет как параметры. Измерение может быть просто Miles или Kilometers

Надеюсь, что это поможет!

licensed under cc by-sa 3.0 with attribution.