SQL расчет абс - используя широты и долготы - МАТ! - PullRequest
1 голос
/ 04 июля 2010

У меня есть SQL-запрос, который извлекает местоположения из базы данных на основе координат в определенном диапазоне. Теперь я пытаюсь упорядочить их по близости с небольшим количеством математики - но независимо от того, сколько раз я пишу это на бумаге, я не могу найти рабочее решение.

Давайте опишем несколько переменных:

  • $ плат (широта места)
  • $ plong (долгота места)
  • $ slat (широта искомого местоположения)
  • $ slong (долгота искомого местоположения)

Важно отметить, что я преобразовал все координаты в положительные числа и у меня есть другое поле, которое определяет положительные или отрицательные значения, но для этого предположим, что я уже правильно запросил соседние координаты.

Чтобы упорядочить это таким образом, я видел, как люди используют "ORDER BY abs (ordin-координаты)" для чего-то простого, но мне нужно что-то более похожее:

[($ slat - $ plat) * ($ slong - plong)] - но это вызывает проблемы, потому что если результат вычисления с одной стороны равен нулю, то после умножения результат также будет равен нулю - что делает его неточным.

Любые идеи -

Ответы [ 2 ]

1 голос
/ 04 июля 2010

Решение для расстояния между координатами широта / долгота называется формула haversine .Это сложно, потому что вам нужно принимать во внимание кривизну Земли, если ваши расстояния не очень короткие.

Вот статья об использовании PHP и MySQL для реализации приложения локатора: Создание локатора магазина с PHP, MySQL и Google Maps

Вы также можете найти много других вопросов здесь на Переполнение стека, касающихся вычисления расстояния между координатами: https://stackoverflow.com/search?q=longitude+distance

Если вам нужно толькоЧтобы рассчитать расстояние в пределах 5 км, искривление земли, вероятно, не является значительным.Вы можете использовать простую формулу расстояния .Вы даже можете пропустить вычисление квадратного корня, если вам нужно использовать это значение только для сортировки, какое из них ближе.

SELECT s.location_id,
  (s.lat-p.lat)*(s.lat-p.lat) + (s.long-p.long)*(s.long-p.long) AS distance_squared
FROM Locations s, Locations p
WHERE p.location_id = ?
ORDER BY distance_squared;

Таблица («местоположения»), из которой я выбираю, имеет широту / ширину.длинные координаты (назовем их $ plat и $ plong).

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

Проблема в том, что SQL обычно вычисляет только элементы из одной строки за раз.Таким образом, вам нужно как-то объединить две строки в одну, чтобы в расчете можно было использовать координаты двух мест.Вы делаете это с помощью самостоятельного соединения .Это в основном соединение каждой строки с другой строкой из той же таблицы.И именно поэтому я перечисляю Locations дважды и даю им два разных псевдонима s и p (технический термин имя корреляции ).

Если вы привыклиДля PHP это самостоятельное объединение аналогично вложенному циклу:

foreach ($locations as &$s) {
    foreach ($locations as &$p) {
        // calculate the distance between $s and $p
    }
}

Предложение WHERE ограничивает строки p только тем местом, с которого вы начинаете (вы могли бы заменить одинзначение для? placeholder), поэтому запрос состоит из одной строки со всеми строками таблицы.

Еще один совет: я пропустил использование SQRT(), так как нет необходимости просто сортировать по расстоянию.То есть, если три местоположения находятся в 10 км, 15 км и 20 км от меня, то я могу отсортировать по 100, 225 и 400 и получить такой же порядок, как если бы я сортировал по 10, 15 и 20. Преимущество в том, что я 'мы исключили вычисление квадратного корня, что несколько снижает стоимость моего запроса.

0 голосов
/ 04 июля 2010

Вы можете использовать формулу haversine для вычисления расстояний между парами широта / долгота, если хотите быть точными в этом.В противном случае вы можете воспользоваться либо формулой Пифагора для вычисления приближения, либо использовать квадрат расстояния (для устранения квадратного корня), если вы просто используете его для упорядочения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...