1

我想进行基于半径的距离搜索。为此,我想在点对象周围创建一个缓冲区,以过滤其中的对象。

这就是我的位置:

>>> 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) 

但是我怎么能做类似的事情呢?

4

2 回答 2

1

PostGIS 有一个名为的方法ST_MakePoint,可以创建 2D、3D 或 4D 点。

之前的回答中,我们看到可以从现有的 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()使用andF()表达式可以达到同样的效果:

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)

注意:您可以考虑pnt在模型中添加一个字段Thing并避免上述情况。

于 2017-08-25T11:04:19.467 回答
0

我不确定您所说的“缓冲区”是什么意思,但是如果您想要基于半径的距离搜索,您可以尝试使用...距离!

下面是一个以公里为单位的示例:

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

于 2013-10-03T00:12:15.643 回答