首先关闭:Python 2.7.6,Django 1.6.5,Postgres 9.3.4,PostGIS 2.1.3,RHEL 6.5上的psycopg2 2.5.3
以下是相关模型:
class Location(models.Model):
name = models.CharField(max_length=255)
geometry = models.MultiPolygonField(blank=True, default=None, null=True)
objects = models.GeoManager() # override the default manager with a GeoManager instance
parent = models.ForeignKey('self', blank=True, default=None, null=True)
def __unicode__(self):
return self.name
此查询应该有效according to the docs:
touching_locations = Location.objects.filter(geometry__dwithin=(location.geometry, D(km=5)))
logging.debug(type(touching_locations))
logging.debug(len(touching_locations))
但它没有。第一个调试调用有效,但第二个抛出ValueError
:
<class 'django.contrib.gis.db.models.query.GeoQuerySet'>
ValueError: Only numeric values of degree units are allowed on geographic DWithin queries.
如果我通过将D(km=5)
更改为5
来进行小幅更改:
touching_locations = Location.objects.filter(geometry__dwithin=(location.geometry, 5))
logging.debug(type(touching_locations))
logging.debug(len(touching_locations))
突然间它起作用了。我得到的输出是:
<class 'django.contrib.gis.db.models.query.GeoQuerySet'>
54
有谁知道为什么这不能按预期工作?这可能是一个错误,还是我犯了一个错误,我只是不明白?
[编辑]
我想这可能是一个Django错误。我继续开了一张票here。一旦我找出了正确的解决方案,我就会在这里添加答案。
答案 0 :(得分:3)
我收到了对我提交的机票的回复(https://code.djangoproject.com/ticket/22830)。显然,我发现dwithin
查询与Distance
个对象有一个看似无证(或至少没有明确记录)的问题。一个开发者说:
由于您的对象位于地理坐标中(几何字段为默认值) 到WGS84),你必须提供距离作为学位单位。这是 例如,匹配PostGIS定义:
boolean ST_DWithin(几何g1,几何g2,双精度 distance_of_srid);
distance_of_srid是WGS84的度数。所以这5个适用于你的 例子意味着5度,而不是5公里!
看起来他们要澄清文档以使其更清晰(太棒了!)。
因为我想要的是5公里,我需要将5公里转换为度数。 1度约111.325km。因此,1km = 1 / 111.325度。因此,5km约为0.0449或约0.05度。所以我只需要改变我的呼吁:
touching_locations = Location.objects.filter(geometry__dwithin=(location.geometry, 0.05))