2013-10-02 34 views
1

我想有一個基於半徑的距離搜索。爲此,我想圍繞點對象創建一個緩衝區,以過濾其內部的對象。Geodjango:如何從點緩衝

這是我在它那裏:

>>> lat = 37.7762179974 
>>> lon = -122.411562492 
>>> from django.contrib.gis.geos import Point 
>>> pnt = Point(lat, lon) 
>>> buf = pnt.buffer(0.0001) 

但我過濾Thing對象有問題的基礎上,他們是否在緩衝區內:

>>> z = Thing.objects.filter(pnt__intersects=buf) 

我知道,以上是不正確的,但我用它來詳細說明我正在嘗試做什麼。

我該如何創建在Point周圍的緩衝區,然後過濾Thingsbuffer裏面?


編輯:models.py

class Thing(models.Model): 
    lat = models.FloatField() 
    lon = models.FloatField() 

我怎樣才能過濾器的基礎上由這兩個模型場的組合的一個點?
這不能明顯地工作,因爲我沒有一個pnt場在我的模型:

>>> pnt = Point(lat, lon) 
>>> z = Thing.objects.filter(pnt__intersects=buf) 

可是我該怎麼做類似的事情?

+0

嗨,@NickB我發佈了一個稍晚(僅3年)的答案。看一看。 –

回答

0

我不確定你的意思是「緩衝區」,但如果你想要一個基於半徑的距離搜索,你可以嘗試使用...... distance!

這裏是一公里度量的例子:

from django.contrib.gis.measure import D 

Thing.objects.filter(pnt__distance_lte=(pnt,D(km=distance))) 

你當然應該看看文檔:https://docs.djangoproject.com/en/dev/ref/contrib/gis/db-api/#distance-lookups

+0

也許我的問題不清楚,但我認爲你錯過了我的觀點(雙關語意)。我沒有名爲'pnt'的模型字段,只有'lat'和'lon',所以我不能基於'pnt'進行過濾。我只想知道一種基於'lat + lon'過濾的方法。感謝您的任何想法! –

+0

如果模型中沒有'pnt'字段,'.filter(pnt __ *)'對我沒有意義。由於您將「lat」和「lon」作爲浮點數據存儲在數據庫中,因此首先使用GeoDjango有什麼意義? –

+0

我正在遵循[在此帖子中描述]的方法(https://groups.google.com/forum/#!searchin/geodjango/distance%2420search%2420geodjango%2420hekevintran/geodjango/butW7zJQhSw/4Os60LTdEywJ)。由於它是由「geodjango的首席開發人員」撰寫的,我認爲它是一個值得信賴的來源。但是,我不是這個主題的權威,並且願意接受更多的反饋。我非常感謝你的評論! –

0

PostGIS中有一個名爲ST_MakePoint方法,它可以創建一個2D,3D或4D點。

previous answer我們看到,有可能從現有的PostGIS的功能自定義數據庫功能:

from django.contrib.gis.db.models.functions import GeoFunc 

class MakePoint(GeoFunc): 
    function='ST_MakePoint' 

現在我們可以通過annotate()ing創建點並應用在其上的intersects

z = Thing.objects.annotate(pnt=MakePoint('lat', 'lon')) 
       .filter(pnt__intersects=buf) 

您可以通過使用GeoFunc()F()表達式來實現相同的效果:

from django.contrib.gis.db.models.functions import GeoFunc 

z = Thing.objects.annotate(pnt=GeoFunc(
     F('lat'), F('lon'), 
     function='ST_MakePoint' 
    ).filter(pnt__intersects=buf) 

注:你可以考慮在你的Thing模型添加pnt領域,並避免上述情況。