2015-04-21 5 views
3

Я хранил координаты как широта долготы в моей базе данных. Теперь мне нужно получить все записи, находящиеся в заданном радиусе, от заданной координаты lat-long. Например, если заданные координаты 48.796777, 2.371140 и расстояние 20 километров, он будет извлекать все записи в пределах 20 километров от этой точки.Как получить информацию о ближайших местоположениях из базы данных?

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

Как это можно достичь с помощью Django? Более конкретно, как следует построить представление (и, возможно, модель) для такого запроса?

ответ

7

Вы должны использовать GeoDjango. Он позволяет выполнять distance queries в ваших записях географической базы данных.

from django.contrib.gis.measure import D 
from django.contrib.gis.geos import * 
from myapp.models import MyResult 

pnt = fromstr('POINT(48.796777 2.371140)', srid=4326) 
qs = MyResult.objects.filter(point__distance_lte=(pnt, D(km=20))) 
+0

Спасибо! Я посмотрю. – manabreak

+0

@Timmy Я сохранил координаты в 2 столбцах (lat и lng), как добавить к этому запрос? Я не использую ГИС. – Pbms

+0

Могу ли я использовать Mysql? –

1

Вы можете использовать geopy

>>> from geopy **import** distance 
>>> _, ne = g.geocode('Newport, RI') 
>>> _, cl = g.geocode('Cleveland, OH') 
>>> distance.distance(ne, cl).miles 
    538.37173614757057 

To **optimize** a bit you can **filter** user objects to get a rough estimate of **nearby users first**. This way you don't have to loop over all the users in the db. This rough estimate is optional. To meet all your project requirements you maybe have to write some extra logic: 


#The location of your user. 
lat, lng = 41.512107999999998, -81.607044999999999 

min_lat = lat - 1 # You have to calculate this offsets based on the user location. 
max_lat = lat + 1 # Because the distance of one degree varies over the planet. 
min_lng = lng - 1 
max_lng = lng + 1  

users = User.objects.filter(lat__gt=min_lat, lat__lt=max__lat, lat__gt=min_lat, lat__lt=max__lat) 

# If not 20 fall back to all users. 
if users.count() <= 20: 
    users = User.objects.all() 
+1

У меня были аналогичные требования, и я также использовал геофизику. Я нашел этот смысл полезным: https://gist.github.com/renyi/3385043. Он включает приблизительный расчет расстояния, чтобы сделать запрос более эффективным. – Jordan

0

Я думаю, что лучший способ пойти с GeoDjango как говорит Тимми, но тогда вы должны иметь Geo с поддержкой Backend (как PosGis). Тем не менее, я не думаю, что это можно использовать, если у вас есть модель с пользовательскими полями широты и долготы, например

class CustomGeoModel(models.Model): 
    lat = models.CharField(max_length=30) 
    lon = models.CharField(max_length=30) 
0

попробуйте этот код. Я использую python, sqlalchemy

этот запрос sqlalchemy возвращает ближайшие объекты в заданной точке. Работает корректно. Но этот запрос возвращает все модели. Но его работа прекрасна.

моя модель класса

#
class City(Base): 
    __tablename__ = "tbl_City" 
    city_id = Column(Integer, primary_key=True, unique=True) 
    geo_coordinates = Column(Geometry('POINT', srid=4326)) 

мой запрос

#
point = city.geo_coordinates 
near_citylist = City.query.order_by(City.geo_coordinates.distance_box(point)) 
Смежные вопросы