gpt4 book ai didi

python - 如何在 Django ORM 中使用 PostGIS 聚合函数 ST_AsMVT

转载 作者:行者123 更新时间:2023-12-03 17:09:47 26 4
gpt4 key购买 nike

问题
我想使用 ORM 在 Django 中创建一个 Mapbox 矢量瓦片 (MVT)。
在 SQL(PostgreSQL、PostGIS)中,对于缩放=8、x=137、y=83 的图块,SQL 查询如下所示:

SELECT ST_AsMVT(tile)
FROM (SELECT id, ST_AsMVTGeom(geometry, ST_TileEnvelope(8, 137, 83)) AS "mvt_geom"
FROM geomodel
WHERE ST_Intersects(geometry, ST_TileEnvelope(8, 137, 83))
) AS tile;
ST_AsMVT聚合所有行,输出是一个二进制字段( bytea ),可以作为响应发送。
由于 GeoDjango 不包含特定的 PostGIS 函数,我为它们创建了自定义函数:
class TileEnvelope(Func):
function = "ST_TileEnvelope"
arity = 3
output_field = models.GeometryField()


class AsMVTGeom(GeoFunc):
function = "ST_AsMVTGeom"
arity = 2
output_field = models.GeometryField()
我设法创建了内部子查询并且它有效:
tile_envelope = TileEnvelope(8, 137, 83)
tile_geometries = GeoModel.objects.filter(geometry__intersects=tile_envelope)
tile_geometries_mvt = tile_geometries.annotate(mvt_geom=AsMVTGeom("geometry", tile_envelope))
tile_geometries_mvt = tile_geometries_mvt.values("id", "mvt_geom")

print(tile_geometries_mvt)
>> <QuerySet [{'id': 165, 'mvt_geom': <Point object at 0x7f552f9d3490>}, {'id': 166, 'mvt_geom': <Point object at 0x7f552f9d3590>},...>
现在缺少最后一部分。我想跑 ST_AsMVTtile_geometries_mvt :
SELECT ST_AsMVT(tile)
FROM 'tile_geometries_mvt' AS tile;

我试图为 ST_AsMVT 创建一个自定义的聚合函数,但没有成功。
通常聚合函数如 MAX ,例如,期望一列作为输入,而 ST_AsMVT期待 anyelement set row .
怎么转ST_AsMVT进入 Django Aggregate (类似于 this SO question )?
我知道,我可以使用 raw_sql在 Django 中查询,但这个问题明确地是关于用 Django ORM 解决它。

最佳答案

我已经尝试使 AsMVT 聚合,但似乎无法实现(目前)。

  • ST_ASMVT 设计应该有子查询。*,而不是 (geom, column_1, ...),虽然它不起作用但 ST_ASMVT 不保留列名(重命名为 f1、f2、f3 等)
  • 如果我们在聚合模板中使用 subquery.*,没关系,ST_ASMVT 保留属性名称.. 但 django orm 重命名子查询中的列.. 所以属性被命名为 __col1, __col2 等。此机制在 SQLAggregateCompiler 中定义,无法覆盖

  • 例子 :
    class AsMVT(Aggregate):
    name = "AsMVT"
    function = "ST_ASMVT"
    template = (
    "%(function)s((%(distinct)s%(expressions)s), '%(layer_name)s', %(extent)s)"
    )


    features.aggregate(
    tile=AsMVT(
    F("geom_prepared"),
    F("name"),
    extent=self.vector_tile_extent,
    layer_name=self.get_vector_tile_layer_name(),
    )
    )
    生成矢量切片,但属性名称被 ST_ASMVT 重命名为 f1。 ST_ASMVT 需要真正的行集而不是子查询列表字段
    class AsMVT(Aggregate):
    name = "AsMVT"
    function = "ST_ASMVT"
    template = "%(function)s(subquery.*, '%(layer_name)s', %(extent)s)"


    features.aggregate(
    tile=AsMVT(
    F("geom_prepared"),
    F("name"),
    extent=self.vector_tile_extent,
    layer_name=self.get_vector_tile_layer_name(),
    )
    )
    生成一个矢量平铺,但属性名称在聚合连接中被 django ORM 重命名为 __col1

    关于python - 如何在 Django ORM 中使用 PostGIS 聚合函数 ST_AsMVT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65508291/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com