【发布时间】:2021-04-07 00:51:32
【问题描述】:
问题
我想在 Django 中使用 ORM 创建一个 Mapbox 矢量图块 (MVT)。 在 SQL(PostgreSQL、PostGIS)中,对于 zoom=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>},...>
现在最后一部分不见了。我想在tile_geometries_mvt 上运行ST_AsMVT:
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)?
我知道,我可以在 Django 中使用 raw_sql 查询,但这个问题明确是关于使用 Django ORM 解决它。
【问题讨论】:
-
django-vectortiles(免责声明:我贡献了一些 PR)已经实现了第一部分,但问题本身并没有解决。 github.com/submarcos/django-vectortiles/blob/…
标签: python django postgresql postgis vector-tiles