2012-07-19 180 views
5

我正在使用geodjango并在我的数据库中有点的集合。在一定区域我用这个范围内获得积分的查询集:如何使用geodjango返回距离点最近距离的记录?

queryset = Spot.objects.filter(point__distance_lte=(origin, distance_m)) 

我的问题是我怎么能只返回一个点,从我已经过了它的点(与最低距离点)?

编辑

我要指出,我传递的坐标,并希望创建一个Point对象他们。然后将该点作为原点并对其进行过滤。 例如,我曾尝试:

from spots.models import * 
from django.contrib.gis.geos import * 

origin = Point(28.011030, -26.029430) 
distance_m = 1000 

queryset = Spot.objects.filter(point__distance_lte=(origin, distance_m)) 
for q in queryset: 
    print q.distance 

的这段代码给了我这个错误:

Traceback (most recent call last): 
    File "<console>", line 2, in <module> 
AttributeError: 'Spot' object has no attribute 'distance' 

有趣的是,如果我做到以下几点:

origin = Spot.objects.get(name='Montecasino').point 
distance_m = 1000 

for city in Spot.objects.distance(origin): 
    print(city.name, city.distance) 

(u'Design Quarter Parking', Distance(m=677.347841801)) 
(u'Montecasino', Distance(m=0.0)) 
(u'Fourways', Distance(m=1080.67723755)) 

回答

4

最后一个解决方案从GeoDjango distance filter with distance value stored within model - query的线索中收集到,并将其导向post。根据这些信息,我可以收集到你在距离查询中测量参数时你必须指定。 您会在下面的代码片段中看到我导入的尺寸为D。然后在查询中使用它。 如果不指定它,你就会得到这个错误:

ValueError: Tuple required for `distance_lte` lookup type. 

仅举与我以前order_by('distance')[:1][0]

from spots.models import * 
from django.contrib.gis.geos import * 
from django.contrib.gis.measure import D 

distance_m = 20000 
origin = Point(28.011030, -26.029430) 

closest_spot = Spot.objects.filter(point__distance_lte=(origin, D(m=distance_m))).distance(origin).order_by('distance')[:1][0] 
+0

你能解释为什么你在末尾有'[:1] [0]' – Sevenearths 2014-03-20 14:36:22

+1

请在调试之前仔细阅读本文:[https://docs.djangoproject.com/en/1.6/ref/contrib/gis/db-api /#compatibility-tables]当Mysql不支持它时,花了几个小时毫无意义地调试了point__distance_lte – PKaura 2014-06-24 12:16:54

0
queryset = Spot.objects.distance(origin).filter(distance__lte=distance_m) 
point = queryset.order_by('distance')[:1][0] 

https://docs.djangoproject.com/en/dev/ref/contrib/gis/geoquerysets/#distance

+2

尝试您的建议我收到错误消息。 FieldError:无法将关键字'距离'解析为字段。选择是:author,created_on,id,name,point,slug,updated_on'我的模型没有距离字段。 – darren 2012-07-19 09:55:53

+0

@darren当你忘记用户'objects = GeoManager()'时它可能发生它来自'django.contrib.gis.db.models.manager'在设置中导入GeoManager'数据库记得使用''ENGINE':' django.contrib.gis.db.backends。postgis',' – andi 2017-05-12 23:57:24

0

最低距离我一直在寻找如何排序为例点结果与geodjango的位置,所以我的用例非常接近这个。虽然接受的解决方案有效,但对于大数据集(超过140000行),性能非常糟糕。

小故事:distance_lte函数必须计算表中每行的距离,并且不能使用地理索引。看来,dwithin功能可以利用这样的指标,并不需要真正的计算,以产地为限制之前完成之前,各行的距离,所以它的方式更高效:

origin = Point(28.011030, -26.029430) 
closest_spot = Spot.objects.filter(point__dwithin=(origin, 1)) \ 
    .distance(origin).order_by('distance')[:1][0] 

的dwithin功能与度数的地理数据一起工作(查询中的“1”)。