2012-07-19 179 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」)。