2013-10-02 46 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领域,并避免上述情况。