无法使用GeoDjango合并范围聚合

时间:2017-08-14 09:37:08

标签: python django geodjango

当我在Coalesce聚合上尝试Extent时, 我得到一个字符串而不是预期的4元组。

解释:

这有效:

>>> Community.objects.annotate(extent=Extent('geometry')).get(...).extent
(2726459.05875, 1220672.3825, 2736397.89, 1227645.2375)

以及:

>>> Community.objects.annotate(extent=Extent('potential__geometry')).get(...).extent
(2726687.04049593, 1221917.0, 2732056.725, 1223760.94563836)

但是当我在Coalesce电话中一起使用它们时,这不起作用:

>>> Community.objects.annotate(extent=
... Coalesce(Extent('potential__geometry'), Extent('geometry'))).get(...).extent
'BOX(2726687.04049593 1221917,2732056.725 1223760.94563836)'

这也不是

>>> Community.objects.annotate(extent=
... Coalesce(Extent('potential__geometry'), Extent('geometry'),
...     output_field=ExtentField())).get(...).extent
'BOX(2726687.04049593 1221917,2732056.725 1223760.94563836)'

这是一个错误,还是我做错了什么?

1 个答案:

答案 0 :(得分:1)

似乎在convert_value调用期间没有调用Extent方法的Coalesce,就像它从左边返回第一个非空对象而不让它完成整个过程...
这确实很奇怪,可能应该通知@django团队(可能是设计,所以至少他们可以澄清这个问题!)

与此同时,您可以通过以下方式之一解决问题:

  1. 创建自己的convert_value函数:

    def my_convert_value(value):
        value = value[4:-1] 
        box_min, box_max = value.split(',') 
        xmin, ymin = map(int, box_min.split())
        xman, ymax = map(int, box_max.split())
        return (xmin, ymin, xmax, ymax)
    

    那:

    my_convert_value(
        Community.objects.annotate(
            extent=Coalesce(
                Extent('potential__geometry'), 
                Extent('geometry')
        )).get(...).extent
    )
    

    将返回:

    (2726687.04049593, 1221917.0, 2732056.725, 1223760.94563836)
    
  2. 省略Coalesce的使用并将其替换为:

    from django.db.models import CharField, Case, Value, When
    
    Community.objects.annotate(
        extent=Extent(
            Case(
                When(
                    potential__geometry__isnull=False,
                    then=Value('potential__geometry'),
                ),
                When(
                    geometry__isnull=False,
                    then=Value('geometry'),
                ),
                default=Value('geometry'),
                output_field=CharField(),
            )
        )
    ).get(...).extent
    

    说明:

    • Extent()方法需要将参数作为几何的名称 列。

    • Coalesce从左到右返回第一个非空字段的值。

    • 利用django conditional expressions,我们创建了一个类似Coalesce的方法,它返回第一列非空的名称,或'geometry'默认情况下。

    • 最后,我们在前一个返回的列上应用Extent

  3. 如果我发现其他任何事情,我会告诉你的!