地理网格模型

本文介绍了地理网格模型的用途、基本构成和快速入门等内容。

模型用途

简介

地理网格模型是一种统一、简单的地理空间划分和定位参考系统,依据统一规则,将地面区域按照一定经纬度或地面距离进行连续分割,并将空间不确定性控制在一定范围内,形成规则多边形,每个多边形均称为格网单元,从而构成分级、分层次的多级格网体系,实现地面空间离散化,并赋予统一编码。

Ganos GeomGrid是对象关系型数据库PostgreSQL兼容版本(PolarDB PostgreSQL版)的一个时空引擎扩展,用于表达和处理地理网格对象。此模型主要提供了地理网格以及地理网格数组类型的空间操作函数,空间关系判断函数,以及与Ganos中其他数据类型的转换计算函数

GeomGrid在Ganos中指代地理网格数据类型。地理网格是一种再现地球表面的多边形网格单元集合,可以用于表示地物在地理空间中的位置信息,融合其他各类时空数据。每个网格单元都会进行编码,网格与编码是一一对应的。三维地理网格不只考虑经纬度,还把高度维纳入剖分和编码范围。

GeomGrid模块目前涵盖GeoSOT和H3两种地理网格。GeoSOT是中国提出的一套地球空间剖分理论,并在此基础上发展出的一种离散化、多尺度区域位置标识体系。H3是Uber研发的一种覆盖全球表面的二维地理网格,采用的基本网格是正六边形。

功能概述

GeomGrid支持地理网格的输入输出,空间操作和空间关系判断:

  • 支持Text、Bytea、Geometry、Meshgeom、Sfmesh、Vomesh等类型与GeomGrid类型的互相转换。

  • 支持网格层级获取,网格坐标获取,父子节点计算,网格合并和网格剖分等空间查询操作。

  • 支持geomgrid与geometry、meshgeom、sfmesh、vomesh以及gemogrid类型之间的空间关系判断操作。

更多内容请参见GeomGrid SQL参考

主要业务场景

Ganos GeomGrid可支持多种业务场景,最常见的包括以下几个:

  • 网格查询

    给定一个网格或网格数组,查询是否与数据库中存储的网格相交。支持退化网格,即可以通过子网格查出父网格,反之亦然。例如在停放共享单车时,停放区的网格码存在数据库中,而用户的位置可以转换为网格码到库中搜索,找出最近的停放区。网格查询也常用于关联不同的图层,把不同图层的地物转化为网格存储,然后根据某一网格查出所有相关图层的地物。

  • 网格聚合

    物流、快送等行业中经常以网格为单位统计时空要素。例如船或车的轨迹数据可经过网格聚合生成热力图,先把轨迹转化为网格表达,然后统计每个网格中的轨迹数量作为热力进行绘制。再例如以街道为单位收集的人口数据可分配至网格进行可视化表达。

    image

  • 网格寻路

    无人机在复杂环境下可以借助三维网格进行航线规划,通过网格设置空间障碍物的穿越开销,借助路径规划算法可得到网格路径。

    image

基本构成

概述

基于GeoSOT和H3地理网格的理论框架,在Ganos GeomGrid模块中,两种网格分别被实现成GeomGrid数据类型和H3Grid数据类型。

编码

GeoSOT

GeoSOT将地球通过简单投影变换到平面,将180°×360° 地球表面空间扩展为512°×512°,并将该空间作为第0级剖分面片,且面片中心与赤道和本初子午线的交点重合。在此基础上,对第0级剖分面片进行递归四叉剖分,直到32级。这样,整个地球表面经纬度空间在经线方向和纬线方向可严格的整型二分,由此将整个地球分割为大到全球、小到厘米级的整度、整分和整秒的层次网格。

image

GeoSOT二维网格最长的编码位为32位四进制数值编码。第1-9位是度级网格编码,第10-15位是分级网格编码,第16-21位是秒级网格编码,第22-32位是秒以下网格编码,编码长度即为网格层级。

经度和纬度均采用A°B′C.D″的表达形式,将度由十进制数转换成8bit的二进制数A2;将分由十进制数转换成6bit的二进制数B2;将秒由十进制数转换成6bit的二进制数C2;将秒的小数部分由十进制数转换成11bit的二进制数D2;将二进制数A2、B2、C2 以及D2顺次拼接为31bit的二进制数。将纬度前置,经度后置,采用莫顿交叉的方式生成62位的混合代码。在混合代码前加上G0、G1、G2或G3即可得到网格代码。G0对应东北半球,G1对应西北半球,G2对应东南半球,G3对应西南半球。

GeoSOT三维网格在二维网格的基础上增加了高度域。为保证高度域的划分与经纬度一致,对应地表1º 网格,地面向上延伸至高空256个网格,向下延伸至地心256个网格。而后对应不同层级进行二分处理得到垂直方向的层数,并以此进行二进制编码,与经纬度编码莫顿交叉形成三维网格编码。

H3

H3采用的投影方式是以二十面体近似地球球体,如下图所示,这个二十面体的每一个面都是球面三角形,有12个顶点,称为球形二十面体。

image

如下图所示,H3在每个三角面上都划分相同排列方式的六边形,进而将全球划分成122个基本单元,然后对每个基本单元再进行六边形剖分。

image

H3从122个基本单元开始,对每个单元递归地细分为7个子单元,如下图所示,以编号为20的基本单元为例进行分解。

image

H3的编码值最多占63个比特位,可以用一个长整型表示,通常序列化为十六进制字符串。H3编码的位布局提供了一个相对紧凑的结构,用于存储有关给定索引的信息并定义其地理位置,如下图所示。

image

索引

索引通过将数据组织到搜索树中来加速搜索,避免大数据量时全局“顺序扫描”带来的延迟。GeomGrid模块适用的索引主要包括以下几种:

索引名称

索引简介

索引特点

Btree

Btree索引作用于地理网格类型,通过对网格编码的大小比对进行查找。

Btree是数据库最通用的索引方法,可以加速的查询类型也最多。

GiST

GiST索引作用于地理网格类型,提供地理网格外包框的相交和包含查询。

GiST此处实现Rtree的结构,对于网格空间查询效率很高。

GridGin

GridGin索引拓展了Gin索引,可作用于地理网格类型和地理网格数组类型,提供了相交和包含关系判断,并进行了优化处理。

GridGin支持退化网格查询,并可以加速网格聚合计算。

快速入门

简介

快速入门文档帮助用户快速理解 Ganos GeomGrid 引擎的基本用法,包括扩展创建、建表、插入数据、计算网格码、创建索引、查询等内容。

语法说明

  • 创建扩展。

    CREATE EXTENSION Ganos_GeomGrid CASCADE;
    说明

    建议将扩展安装在public模式下,避免权限问题。

    CREATE extension ganos_geometry WITH schema public cascade;
  • GeoSOT网格操作。

    • 创建具有网格码的表。

       -- 可以为几何
       CREATE TABLE t_grid(id integer,
                           geom geometry,  -- 几何对象
                           grid1 geomgrid[], -- 网格码,精度1
                           grid2 geomgrid[], -- 网格码,精度2
                           grid3 geomgrid[] -- 网格码,精度3
                          );
    • 插入数据。

       --插入点数据
       INSERT INTO t_grid(id, geom)
       VALUES (1, ST_GeomFromText('POINT(116.31522216796875 39.910277777777778)', 4490)),
              (2, ST_GeomFromText('POINT(116.31522217796875 39.910277776777778)', 4490)),
              (3, ST_GeomFromText('POINT(116.31522217797875 39.910277776787778)', 4490)),
              (4, ST_GeomFromText('POINT(116.31522227796875 39.910277776775778)', 4490));
      
       -- 插入面数据
       INSERT INTO t_grid(id, geom) VALUES(5, 'SRID=4490;POLYGON((-0.08077 -0.02814, 0.0482 -0.03, 0.07426 0.03724, -0.08077 -0.02814))'::geometry);
      
       -- 插入三维数据
       INSERT INTO t_grid(id, geom) VALUES(6, 'SRID=4490;CIRCULARSTRING Z (-63.597471 44.8071 20,-63.597 44.807 0,-63.5974 44.807 40)'::geometry);
    • 计算网格码。

       -- 创建不同精度的网格码
       UPDATE t_grid
       SET grid1 = ST_AsGrid(geom, 10),
           grid2 = ST_AsGrid(geom, 15),
           grid3 = ST_AsGrid(geom, 26);
      
       -- 生成退化网格码
       UPDATE t_grid SET grid1 = st_asgrid(geom, 18, true) WHERE id = 5;
      
       -- 生成三维网格码
       UPDATE t_grid SET grid1 = st_as3dgrid(geom, 25) WHERE id=6;
    • 对网格码创建索引。

       -- 针对不同精度的网格码创建GIN索引
       CREATE INDEX idx_grid_gin1
       ON t_grid
       USING GIN(grid1);
      
       CREATE INDEX idx_grid_gin2
       ON t_grid
       USING GIN(grid2);
      
       CREATE INDEX idx_grid_gin3
       ON t_grid
       USING GIN(grid3);
    • 查询。

       -- 完全在某个网格中
       SELECT id
       FROM t_grid
       WHERE grid2 = ARRAY[ST_GridFromText('G001310322230230')];
      
       -- 和某个网格相交
       SELECT id
       FROM t_grid
       WHERE grid3 @> ARRAY[ST_GridFromText('G00131032223023031031033223')];
      
       -- 和某些网格相交
       SELECT id
       FROM t_grid
       WHERE grid3 && ARRAY[ST_GridFromText('G00131032223023031031211001'),
                                ST_GridFromText('G00131032223023031031211111')];
      
       -- 和某个几何对象在网格上相交
       SELECT id
       FROM t_grid
       WHERE grid3 &&
       ST_AsGrid(
         ST_GeomFromText('LINESTRING(116.31522216796875 39.910277777777778, 116.31522217797875 39.910277776787778)', 4490), 26);
  • H3网格操作。

    • 建表。

       CREATE TABLE h3_grid(
        id integer,
        geom geometry,  -- 几何对象
        h3 h3grid[]     -- H3对象类型
       );
    • 插入数据。

       INSERT INTO h3_grid VALUES (1, 'POINT(102.5 25.7)'::geometry);
       INSERT INTO h3_grid VALUES (2, 'POLYGON((-0.08077 -0.02814, 0.0482 -0.03, 0.07426 0.03724, -0.08077 -0.02814)'::geometry);
    • 计算H3网格码。

       -- 普通网格码
       UPDATE h3_grid SET h3 = ST_AsH3Grid(geom, 7);
      
       -- 退化网格码
       UPDATE h3_grid SET h3 = ST_AsH3Grid(geom, 7, true);
    • 建立索引。

      CREATE INDEX h3_grid_btree ON h3_grid(h3);
    • 查询。

       -- 显示H3编码
       SELECT st_astext(h3[1]) FROM h3_grid;
      
       -- 搜索
       SELECT * FROM h3_grid WHERE h3 > ARRAY[ST_H3FromText('884a126689fffff')];
  • 删除扩展(可选)。

    DROP EXTENSION Ganos_GeomGrid CASCADE;

SQL参考

详细SQL手册请参见GeomGrid SQL参考