使用django.contrib.gis.measure.D时GeoDjango dwithin出错

时间:2014-06-12 22:11:14

标签: python django postgresql postgis geodjango

首先关闭: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。一旦我找出了正确的解决方案,我就会在这里添加答案。

1 个答案:

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