.. _demogeosot3_label: 基于混合层级空间网格编码的查询 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :ref:`geosotintroduce_label` 中详述了空间网格编码的基本原理,空间网格编码通常为 GeoSOTGrid 类型的数组。 Yukon提供的接口 ST_GeoSOTGrid( ),可通过指定的网格层级参数计算空间网格编码,但这种方式构造出的网格均为同一网格层级。当对象的空间范围较大时,仍使用同一层级的网格,构造出的空间网格编码数组长度将超过设定值域范围,无法存储。另一方面,对于这些范围大的对象,采用太小尺度的网格进行管理和查询等,也是没有必要的,特别是在要素查询中,获得同等查询精度的前提下,小尺度的网格将带来更多的性能损耗。 因此,Yukon提供接口 ST_GeoSOTGridAgg( ),通过设置一个范围的网格层级(level_min,level_max),计算混合层级的空间网格编码。每个对象对应的空间网格编码数组将包含(level_min,level_max)范围下多个层级的空间网格编码,并提供对此空间网格编码数组创建 GIN 索引,进行查询。 |geosotagg.png| 以下将对基于此混合层级空间网格编码,进行数据查询的过程进行说明。 示例数据: `region_test.udbx <../../_static/files/region_test.udbx>`__ 主要步骤及结果说明: -------------------- 1. 创建数据库中空间对象的空间网格编码。数据集名region_test,对应的网格编码表region_grid22_15。 .. code:: SQL 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| 2. 对空间网格编码数组创建 GIN 索引。 .. code:: SQL CREATE INDEX idx_region_grid22_15 ON region_grid22_15 USING gin (grids22_15); 3. 创建查询范围的空间网格编码。下图圆框为查询范围,查询范围的数据集名roi,对应的网格编码表roi_grid22_15。 .. code:: SQL 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| 4. 执行网格相交查询,采用操作符&&,对两个网格编码表求交集。 .. code:: SQL 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. 根据4中的查询结果,关联到对应的空间对象,得到最终查询结果。 .. code:: SQL 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,查询结果可以更加准确。 最后,在选择单层级空间网格编码还是混合层级空间网格编码时,需考虑的情况是比较复杂的。因此还需要综合考虑实际情况,选择最合适的方式。 .. |geosotagg.png| image:: /../_static/images/demo_geosot/geosotagg.png :width: 600px .. |geosotagg1.png| image:: /../_static/images/demo_geosot/geosotagg1.png :width: 600px .. |geosotagg2.png| image:: /../_static/images/demo_geosot/geosotagg2.png :width: 600px .. |geosotagg3.png| image:: /../_static/images/demo_geosot/geosotagg3.png :width: 600px .. |geosotagg4.png| image:: /../_static/images/demo_geosot/geosotagg4.png :width: 600px