Поиск городов, расположенных близко друг к другу, с использованием долготы и широты

StackOverflow https://stackoverflow.com/questions/4661888

Вопрос

Каждый пользователь в моей базе данных связан с городом (с указанием его долготы и широты).

Как бы мне узнать, какие города находятся близко друг к другу?

т. е.в Англии Кембридж находится довольно близко к Лондону.

Итак, если у меня есть пользователь, который живет в Кембридже.Близкими к ним пользователями могут быть пользователи, живущие в близлежащих городах, таких как Лондон, Хартфорд и т.д.

Есть какие-нибудь идеи, как я мог бы это сделать?А также, как бы я определил, что близко?т. е.в Великобритании закрытие было бы намного ближе, чем если бы это было в США, поскольку США гораздо более разбросаны.

Идеи и предложения.Кроме того, знаете ли вы какие-либо сервисы, предоставляющие подобную функциональность?

Спасибо

Это было полезно?

Решение

Проверьте этот поток:

MySQL Расстояние по большому кругу (формула Хаверсина)

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

Ваше здоровье.

Другие советы

Если вы можете вызвать внешнюю веб-службу, вы можете использовать GeoNames API для определения местоположения близлежащих городов в пределах определенного вами радиуса:

http://www.geonames.org/export/web-services.html

Получение координат из названий городов называется обратным географическим кодированием.У Google Maps есть хороший Api для этого.

Существует также Географические названия проект, в котором вы получаете огромные базы данных городов, почтовых индексов и т.д. и их координат

Однако, если у вас уже есть координаты, это простой расчет, чтобы получить расстояние.

Самое сложное - получить его хорошую производительную версию.Вероятно, у вас это хранится в базе данных mysql, поэтому вам нужно сделать это там и быстро.

Это абсолютно возможно.Однажды я делал проект, включающий этот код, я извлеку его и опубликую здесь.

Однако, чтобы ускорить процесс, я бы рекомендовал сначала сделать прямоугольное выделение вокруг центральных координат.Это очень, очень быстро с использованием индексов пчелиного дерева или даже более качественных материалов, таких как поиск по многомерному диапазону.Затем внутри этого вы можете рассчитать точные расстояния по ограниченному набору данных.За пределами этого прямоугольного выделения направления настолько обширны, что их не нужно так точно отображать или вычислять.Или просто покажите страну, континент или что-то в этом роде.

Я все еще нахожусь в офисе, но когда вернусь домой, смогу принести вам коды.Тем временем было бы хорошо, если бы вы могли сообщить мне, как вы храните свои данные.

Редактировать:в то же время здесь у вас есть функция, которая выглядит правильно для меня (я сделал это без функции в одном запросе ...)

   CREATE FUNCTION `get_distance_between_geo_locations`(`lat1` FLOAT, `long1` FLOAT, `lat2` FLOAT, `long2` FLOAT)
  RETURNS FLOAT
  LANGUAGE SQL
  DETERMINISTIC
  CONTAINS SQL
  SQL SECURITY DEFINER
  COMMENT ''
BEGIN
DECLARE distance FLOAT DEFAULT -1;
DECLARE earthRadius FLOAT DEFAULT 6371.009;
-- 3958.761 --miles
-- 6371.009 --km
DECLARE axis FLOAT;

IF ((lat1 IS NOT NULL) AND (long1 IS NOT NULL) AND (lat2 IS NOT NULL) AND (long2 IS NOT NULL)) THEN -- bit of protection against bad data

  SET axis = (SIN(RADIANS(lat2-lat1)/2) * SIN(RADIANS(lat2-lat1)/2) + COS(RADIANS(lat1)) * COS(RADIANS(lat2)) * SIN(RADIANS(long2-long1)/2) * SIN(RADIANS(long2-long1)/2));
  SET distance = earthRadius * (2 * ATAN2(SQRT(axis), SQRT(1-axis)));

END IF;

RETURN distance;
END;

я процитировал это отсюда: http://sebastian-bauer.ws/en/2010/12/12/geo-koordinaten-mysql-funktion-zur-berechnung-des-abstands.html

а вот еще одна ссылка: http://www.andrewseward.co.uk/2010/04/sql-function-to-calculate-distance.html

Самый простой способ сделать это - вычислить ограничивающую рамку по широте и долготе города и расстоянию (путем преобразования расстояния в градусы долготы).

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

Оттуда вы можете при желании сузить список, используя реальную функцию "расстояние между точками на сфере".

Вам нужен пространственный индекс или функциональность ГИС.Какую базу данных вы используете?MySQL и PostgreSQL имеют поддержку ГИС, которая позволит вам найти N ближайших городов с помощью SQL-запроса.

Другой вариант, который вы, возможно, захотите рассмотреть, - поместить все города в дерево пространственного поиска, подобное kd-дереву.Kd-деревья эффективно поддерживают поиск по ближайшим соседям, а также быстрый поиск всех точек в заданной ограничивающей рамке.Затем вы могли бы найти близлежащие города, выполнив поиск по нескольким ближайшим соседям города, а затем, используя расстояние до этих соседей, получить приблизительный размер ограничивающей рамки для поиска.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top