2015-02-07 3 views
0

Я использую следующий запрос, чтобы получить следующие локальные события, используя их местоположение. Моя база данных растет, и у меня есть события со всей Европы. Таким образом, в основном, запрос вычисляет расстояния от событий двух разных стран (например, Испании и Германии), что действительно не полезно, так как я ищу следующие события в пределах 20 км.Ограничение количества местоположений GPS в запросе MySQL

# latitude & longitude are the fields in DB 
# 43.57 & 3.85 are given values representing the local test point 
SELECT (6366 * ACOS(COS(RADIANS(43.57)) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS(3.85)) + SIN(RADIANS(43.57)) * SIN(RADIANS(latitude)))) dist 
FROM events 
HAVING dist >0 AND dist <=20 
ORDER BY event_time ASC 
LIMIT 0 , 5 

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

Есть ли лучший способ?

+2

@OllieJones Принятый ответ на вопрос, который вы связали, - это именно то, что OP уже использует. Этот вопрос нуждается в улучшении. –

+0

@HoboSapiens, правда, но мой ответ на этот вопрос, а не принятый, точно решает его вопрос. Я не хотел набирать его снова. Здесь написано. http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/ –

ответ

2

Рассчитать долготу и широту четырех точек ящика, который охватывает радиус, окружающий контрольную точку. На расстоянии нескольких километров вы можете игнорировать ошибки из-за кривизны Земли.

Мы можем использовать грубое приближение, чтобы ограничить первоначальный поиск, а затем уточнить детали позже. В 50 градусах северного (примерно в Париже) градус широты (север/юг) составляет приблизительно 111,229 км. Степень долготы (Восток/Запад) составляет приблизительно 71,695 км (я получил эти цифры от this page. Из этого 20 км составляет приблизительно 10,8 секунды широты и 16,74 секунды долготы. Рассчитайте ограничивающий прямоугольник, добавив и вычитая эти числа из широты и долгота тестовой точки.

Запрос на местах в этом окне, используя широту и долготу.

Если вы беспокоитесь, что ваш ограничивающая коробка может быть слишком большим, или что событие в углу коробки вне радиуса, вычислить точное расстояние для тех точек, которые вы уже идентифицировали, и отфильтровать те немногие, которые вы не хотите.

Примечание Эти цифры приблизительны для 50deg North. Когда вы двигаетесь к северу от этого, ваше значение для километра долготы станет слишком длинным, а к югу от него оно будет слишком коротким. Вы можете использовать небольшую таблицу значений поиска или рассчитать фактическое расстояние от широты или просто увеличить начальный ограничивающий прямоугольник в направлении долготы. Коробка только в первом приближении, так что, если она больше целевой области, то это точный размер не имеет большого значения.

+0

Я искал окно с четырьмя точками, и кажется, что я нашел библиотеку PHP, которая бы это сделала. После вызова boundingCoordinates() я должен иметь возможность использовать границы широты и долготы и, следовательно, иметь гораздо более быстрый запрос. https://github.com/anthonymartin/GeoLocation.php –

+0

@AlainZelink Я добавил метод приближения, основанный на эмпирических данных, но я вижу, что вы нашли библиотеку. Удачи! –