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

Yukon支持GeoSOT编码的基本原理及特性 中详述了空间网格编码的基本原理,空间网格编码通常为 GeoSOTGrid 类型的数组。 Yukon提供的接口 ST_GeoSOTGrid( ),可通过指定的网格层级参数计算空间网格编码,但这种方式构造出的网格均为同一网格层级。当对象的空间范围较大时,仍使用同一层级的网格,构造出的空间网格编码数组长度将超过设定值域范围,无法存储。另一方面,对于这些范围大的对象,采用太小尺度的网格进行管理和查询等,也是没有必要的,特别是在要素查询中,获得同等查询精度的前提下,小尺度的网格将带来更多的性能损耗。

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

geosotagg.png

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

示例数据: 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);

网格示意图:

geosotagg1.png

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

CREATE INDEX idx_region_grid22_15 ON region_grid22_15 USING gin (grids22_15);
  1. 创建查询范围的空间网格编码。下图圆框为查询范围,查询范围的数据集名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);

查询示意图:

geosotagg2.png geosotagg3.png

  1. 执行网格相交查询,采用操作符&&,对两个网格编码表求交集。

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,才能将查询框覆盖的空间对象完整查出。

  1. 根据4中的查询结果,关联到对应的空间对象,得到最终查询结果。

with region_roi as (select region_grid22_15.smid from region_grid22_15, roi_grid where aa_1000_grid.grids22_15 && roi_grid.grids22_15)

select region_test.* from region_test, region_roi where region_test.smid = region_roi.smid;

查询结果示意图:

geosotagg4.png

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

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

空间网格编码层级的设置,需要考虑查询精度和性能两个因素。层级越高,意味着网格单元对应的空间范围越小,查询的精度会相对提高,但性能会相应降低。这里建议以下几种场景下使用混合层级的空间网格编码进行查询:

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

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

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

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

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

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