矢量金字塔是为了能够快速显示大规模空间几何数据(千万级以上)而设计的一种结构。

概述

矢量金字塔对空间几何数据创建稀疏索引,按规则对密集区域预处理,可以输出标准的mvt-pbf格式数据。

通过Ganos提供的矢量金字塔,亿条空间几何记录可以实现分钟级预处理、秒级终端显示。

快速入门

  • 创建扩展。
    CREATE EXTENSION ganos_geometry_pyramid CASCADE;
  • 创建测试数据。
    CREATE TABLE test(id int primary key, geom geometry(Point,4326), code int, name text, width float);
    INSERT INTO test(id, geom)
        SELECT  i,
                ST_GeomFromText(
                  format('POINT(%s %s)', floor(i / 100) * 0.01, (i % 100) * 0.01),
                  4326)
        FROM generate_series(1,10000) i;
    CREATE INDEX ON test USING gist(geom);
  • 创建空间表的金字塔。
    --为数据表test创建金字塔。
    --指定表test的空间字段名称, 需要先为该字段创建空间索引。
    SELECT ST_BuildPyramid('test', 'geom', 'id', '');
  • 读取金字塔中MVT数据。
    --从金字塔中读取瓦片编号为'0_0_0'的数据(任意编号,不管金字塔中是否存在,都可返回数据)。
    --瓦片编号方式为: z_x_y,投影坐标系为EPSG:3857。
    SELECT ST_Tile('test', '0_0_0');
  • 删除金字塔。
    --删除名为test的金字塔。
    SELECT ST_DeletePyramid('test');
  • 删除扩展。
    DROP EXTENSION ganos_geometry_pyramid CASCADE;

参数设置

  • 为金字塔命名。

    金字塔默认和数据表同名,您也可以指定金字塔名称,实现一份数据对应多个金字塔。

    --为test表创建一个名为hello的金字塔。
    SELECT ST_BuildPyramid('test', 'geom', 'id', '{"name": "hello"}');
  • 并行构建。

    指定构建矢量金字塔的并行任务数,默认为0(表示并行最大化)。并行任务数最大不应该超过CPU数量的4倍。

    并行构建使用了两阶段事务机制,需要设置数据库max_prepared_transactions参数,需要设置max_prepared_transactions = 100或者更高,重启生效。

    --使用4个CPU来并行构建矢量金字塔。
    SELECT ST_BuildPyramid('test', 'geom', 'id','{"parallel": 4}');
  • 瓦片参数。

    您可以指定瓦片的尺寸、外扩大小。

    • 尺寸取值为0~4096,且必须是256的整数倍。
    • 外扩大小取值为0~256。
    --指定瓦片的大小为512,外扩大小为8。
    SELECT ST_BuildPyramid('test', 'geom', 'id','{
                            "tileSize": 512,
                            "tileExtend": 8
                           }');
  • 金字塔最大层级。

    您可以指定金字塔的最大层级(默认为16),当地图的zoom层级大于某级时,就不再使用这个图层或者不需要生成金字塔。如不设置,矢量金字塔会根据数据的密度自动计算出合理的最大层级。

    --指定金字塔的最大层级为12级,超过12级则会实时读取数据生成mvt。
    SELECT ST_BuildPyramid('test', 'geom', 'id', '{"maxLevel": 12}');
  • 分层处理。

    您可以为金字塔的每个层级设置不同的处理条件,例如显示字段、过滤条件等。

    通过添加buildRules规则,为每个层级设置生成条件。

    顶层金字塔生成耗时较长,可以通过分层规则跳过顶层的处理。

    --分层处理生成金字塔
    --第0层到第5层,不显示任何数据,设置过滤条件为"1!=1"生成空的mvt。
    --第6层到第9层,显示code=1的数据,并且包含name字段。
    --第10层到第15层,无过滤条件,包含name、width两个字段。
    SELECT ST_BuildPyramid('test', 'geom', 'id', '{
                            "buildRules":[
                              {
                                "level":[0,1,2,3,4,5],
                                "value": {
                                  "filter": "1 != 1"
                                }
                              },
                              {
                                "level":[6,7,8,9],
                                "value": {
                                  "filter": "code = 1",
                                  "attrFields": ["name"]
                                }
                              },
                              {
                                "level":[10,11,12,13,14,15],
                                "value": {
                                  "attrFields": ["name", "width"]
                                }
                              }                       
                            ]
                           }');

高级功能

按规则融合数据:您可以按属性规则对瓦片范围内的数据进行融合,减少数据量。
-- 将 code=1、code=2 的数据,分别进行融合处理
SELECT ST_BuildPyramid('test', 'geom', 'id', '{
                        "buildRules":[
                               {
                                   "level":[0,1,2,3,4,5],
                                   "value": {
                                       "merge": ["code=1","code=2"]
                                   }
                               }
                           ]
                       }');