基于混合层级空间网格编码的查询

空间网格编码通常为 GeoSOTGrid 类型的数组。Yukon 提供的接口 ST_GeoSOTGrid() 可通过指定的网格层级参数计算空间网格编码,但这种方式构造出的网格均为同一网格层级。

当对象的空间范围较大时,仍使用同一层级的网格,构造出的空间网格编码数组长度将超过设定值域范围,无法存储。另一方面,对于这些范围大的对象,采用太小尺度的网格进行管理和查询等,也是没有必要的,特别是在要素查询中,获得同等查询精度的前提下,小尺度的网格将带来更多的性能损耗。

因此,Yukon 提供接口 ST_GeoSOTGridAgg(),通过设置一个范围的网格层级(level_min, level_max),计算混合层级的空间网格编码。每个对象对应的空间网格编码数组将包含 level_minlevel_max 范围下多个层级的空间网格编码,并提供对此空间网格编码数组创建 GIN 索引进行查询。

混合层级网格示意

以下将对基于混合层级空间网格编码进行数据查询的过程进行说明。

示例数据:region_test.udbx

1. 创建空间对象的空间网格编码

数据集名 region_test,对应的网格编码表 region_grid22_15

CREATE TABLE region_grid22_15 (
    id serial4 NOT NULL,
    tablename TEXT NULL,
    smid INT8 NULL,
    grids22_15 GeoSOTGrid[] NULL
);

INSERT INTO region_grid22_15 (tablename, smid, grids22_15)
SELECT 'region_test', smid, ST_GeoSOTGridAgg(smgeometry, 22, 15)
FROM region_test;

网格示意图:

空间对象混合层级网格

2. 对空间网格编码数组创建 GIN 索引

CREATE INDEX idx_region_grid22_15
    ON region_grid22_15 USING GIN (grids22_15);

3. 创建查询范围的空间网格编码

下图圆框为查询范围,查询范围的数据集名 roi,对应的网格编码表 roi_grid22_15

CREATE TABLE roi_grid22_15 (
    id serial4 NOT NULL,
    tablename TEXT NULL,
    smid INT8 NULL,
    grids22_15 GeoSOTGrid[] NULL
);

INSERT INTO roi_grid22_15 (tablename, smid, grids22_15)
SELECT 'roi', smid, ST_GeoSOTGridAgg(smgeometry, 22, 15)
FROM roi;

查询示意图:

查询范围示意 查询范围网格化

4. 执行网格相交查询

采用 && 操作符,对两个网格编码表求交集。

SELECT region_grid22_15.smid
FROM region_grid22_15, roi_grid22_15
WHERE roi_grid22_15.grids22_15 && region_grid22_15.grids22_15;

特殊说明:查询框的网格编码层级 level_min 必须小于等于空间数据网格编码的 level_min,才能将查询框覆盖的空间对象完整查出。

5. 关联原始数据,得到最终查询结果

WITH region_roi AS (
    SELECT region_grid22_15.smid
    FROM region_grid22_15, roi_grid22_15
    WHERE roi_grid22_15.grids22_15 && region_grid22_15.grids22_15
)
SELECT region_test.*
FROM region_test, region_roi
WHERE region_test.smid = region_roi.smid;

查询结果示意图:

查询结果

空间网格编码层级如何设置?

这里设置的是查询范围的空间网格编码层级。

空间网格编码层级的设置,需要考虑查询精度和性能两个因素。层级越高,意味着网格单元对应的空间范围越小,查询的精度会相对提高,但性能会相应降低。

以下场景建议使用混合层级的空间网格编码进行查询:

  • 查询范围面积较大,采用同一层级的空间网格编码无法存储。

  • 查询范围面积较大,虽然可以采用同一层级编码,但性能较差,在不相对损失精度的前提下,采用混合层级的空间网格编码。

当选择了混合层级的空间网格编码后,层级范围的选择需注意:

  • 查询框的 level_min ≤ 空间对象的 level_min,才能将查询框覆盖的空间对象完整查询。

  • 查询框的 level_max ≥ 空间对象的 level_max,查询结果可以更加准确。

最后,在选择单层级空间网格编码还是混合层级空间网格编码时,需综合考虑实际情况,选择最合适的方式。