2012-06-05 5 views
4

У меня есть веб-приложение на основе django, в котором хранятся местоположения.Найти пункты в пределах определенного диапазона заданной координаты

У меня есть мобильное приложение для Android, которое вытаскивает местоположения из веб-приложения и сохраняет места в веб-приложении. Места вернулись обратно ко мне. Я загружаю mapoverlay в свое приложение.

Я бы хотел отправить мои текущие координаты и вернуть список мест, находящихся в определенном диапазоне. Например, я отправляю свое местоположение и возвращаю предметы в радиусе 2 км. (Подобно тому, как работает Google Places API, просто просматривая мои данные).

Возможно, лучше всего отправить координаты местоположения и выполнить всю эту логику в моем приложении python django. Затем верните список правильных местоположений и просто покажите места на моей карте.

Я не знаю, с чего начать это делать. Как я могу отфильтровать мои сохраненные местоположения в пределах определенного радиуса (км) на основе заданного набора координат?

+0

Отправьте свою модель, чтобы понять, как выглядит ваша структура таблицы. –

+1

1) выберите все местоположения, расположенные рядом с вашим текущим местоположением (скажем, в пределах одной и той же линии lat/long). 2) используйте расчет расстояний для каждой из выбранных координат и устраните те, которые являются> желаемым диапазоном (2 км). Если вы забыли расстояние, это 'sqrt (dx ** 2 + dy ** 2)' –

ответ

11

Haversine Equation - ответ на ваш вопрос. Однако это немного трудно расшифровать так что здесь я приведу вам простое объяснение:

Проще говоря:

Вот образец/пример SQL заявление, которое будет найти ближайшие 20 мест, которые находятся в пределах радиуса 25 миль к координате 37, -122. Он вычисляет расстояние, основанное на широте/долготе этой строки и целевой широте/долготе (заданной lat/lng в приведенном ниже уравнении), а затем запрашивает только строки, где значение расстояния меньше 25, заказывает весь запрос по расстоянию, и ограничивает его до 20 результатов. Для поиска километров вместо миль, заменить 3959 на 6371.

SELECT id, (3959 * acos(cos(radians(37)) * cos(radians(lat)) * cos(radians(lng) - radians(-122)) + sin(radians(37)) * sin(radians(lat)))) AS distance FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20; 

Вы можете преобразовать SQL к чему вы хотите. Я имею в виду, что принцип остается тем же.

+1

спасибо. отредактировал его немного для postgresql 'SELECT distance FROM (SELECT (6371 * acos (cos (радианы (45)) * cos (радиан (широта)) * cos (радианы (долгота) - радианы (10)) + sin (радианы (45)) * sin (радиан (широта)))) AS distance FROM spot_spot) sub GROUP BY sub.distance HAVING sub.distance <2' и вот класс python [Haversine] (http: //www.platoscave .net/блог/2009/октябрь/5/вычисления расстояния-широта-долгота-питон /) – darren

1

Самый простой подход - рассчитать расстояние до каждого места и выбрать точки на определенном расстоянии. Если вы хотите выполнить поиск быстрее, вы можете организовать свои местоположения в более сложной структуре данных (например, kd-tree).

1

GeoDjango интегрируется с отличным PostGIS add on для Postgres, который предоставляет вам все эти дистанционные поиски бесплатно.

Если у вас есть LatLong, хранящийся в модели, которая хранится как тип Postgres, вы можете запустить тривиальный запрос ORM, чтобы получить все местоположения на определенном расстоянии до текущего LatLong.

GeoDjango очень мощный и имеет множество опций, и если все, что вам нужно сделать, это просто найти местоположения из списка, находящегося на заданном расстоянии, вы можете просто использовать простую математику: distance = sqrt (dx^2 + dy^2)

0

В настоящее время я работаю над этой функцией в приложении для Android, я наткнулся на это, надеюсь, что это поможет. Сначала я собирался отфильтровать результат JSON с сервера, затем я пришел к этому и понял, что Mysql намного сложнее, чем я его первоначально воспринимал.

https://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL

Комментарий выше не работает для меня, но они на деньги с выходом с Haversine уравнением.Его гораздо эффективнее делать большую часть этого на стороне сервера, чтобы телефон не переполнял информацией, которая не будет использоваться ни для чего. Это похоже на выпечку полностью выдутого 10-дюймового пирога только для того, чтобы нарезать восьмую часть и отбросить остальных, почему бы не просто испечь крошечный пирог с радиусом 2 дюйма? Может показаться, что это не очень отличается, но, как любая хорошая программа, получите только то, что вам нужно, если вам не нужно все это.

Чтобы использовать живую рабочую версию, выполните небольшой тест по собственному коду, используя эту ссылку ниже. http://sqlfiddle.com/#!2/abba1/2

Надеюсь, что это сообщение помогает.

Смежные вопросы