# FlatGeobuf格式技术专题

# 概述

FlatGeobuf(以下简称:FGB)是一种用于存储地理要素的坐标、类型的二进制编码格式,能够存储简单要素规范 (opens new window)下的要素数据(如点、线、面等)。

FGB 格式与传统的 Shapefile、GeoJSON 等文件格式类似,均支持地理空间矢量数据的存储,但 FGB 格式具有更高的存储效率和更快的读写速度,适用于大量静态数据的编码与传输。使用 FGB 格式存储和传输数据,可以加快网络传输速度,缩短矢量要素的渲染时间,从而优化用户的使用体验。

为了便于您了解 FGB 数据的生成与使用,本文档提供了两种 FGB 数据生成与使用场景下的方案,您可以根据自身需求进行选择。

  • FGB 数据生成与使用场景1:通过使用 SuperMap iServer 的任意方式查询或分析生成 FGB 格式的分析结果,然后将分析结果(或其他任何来源的 FGB 数据)作为静态数据存储至对象存储服务中,以便后续在 iClient 客户端中随时进行 FGB 数据的访问与可视化,适用于静态分析结果的展示。
  • FGB 数据生成与使用场景2:在 SuperMap iClient 客户端中调用 iServer 相应的服务能力,分析返回 FGB 格式的结果并对其可视化,适用于需要对数据进行实时分析并展示分析结果的情况。

支持情况

云 GIS 网络客户端开发平台 SuperMap iClient for Leaflet / OpenLayers / MapboxGL / MapLibreGL 均支持 FGB 格式的数据。

在 SuperMap iServer 提供的一系列服务能力中,以下服务能力除了支持生成 JSON、GeoJSON 等文件格式的分析结果,现在还支持生成 FGB 格式的分析结果。

表1 iServer 中支持输出 FGB 格式的服务能力
服务能力 服务类
地图 地图查询 queryResult
数据 数据查询 featureResult
空间分析(数据集) 数据集缓冲区分析 datasetBufferResult
数据集叠加分析 datasetOverlayResult
数据集等值线分析 datasetIsolineResult
数据集等值面分析 datasetIsoregionResult
数据集泰森多边形 datasetThiessenPolygonResult
空间分析(几何对象) 几何对象缓冲区分析 geometryBufferResult
几何对象叠加分析 geometryOverlayResult
几何对象等值线分析 geometryIsolineResult
几何对象等值面分析 geometryIsoregionResult
几何泰森多边形 geometryThiessenPolygonResult
网络分析 连通性分析 connectedEdges
上游追踪分析 traceUp
下游追踪分析 traceDown

注1:请使用超图官网上最新的 SuperMap iServer 和 SuperMap iClient JavaScript 版本。

SuperMap iServer: http://support.supermap.com.cn/product/iServer.aspx (opens new window)
SuperMap iClient JavaScript: http://support.supermap.com.cn/product/iClient.aspx (opens new window)

注2:在 SuperMap iServer 中发布服务需要您拥有 SuperMap iServer 产品,并且角色为系统管理员(ADMIN)或服务发布者(PUBLISHER)。

# FGB数据生成与使用场景1

在 SuperMap iServer(以下简称:iServer)中可使用 表1 中提供的服务能力对数据进行查询或分析,生成 FGB 格式的分析结果并存储至本地,便于随时在 iClient 客户端中访问加载 FGB 数据。

本章节以 数据查询 服务能力中的 SQL查询 为例,为您介绍在 iServer 中分析生成 FGB 数据并将其存储至对象存储服务,然后在 iClient 客户端中可视化的具体流程。

# 1.发布数据服务

本小节采用 SuperMap 官方网站提供的地图示例数据 SampleData2D 中的世界地图 World_Common(示例数据下载链接:技术资源中心 | 地图示例下载 (opens new window)),在 iServer 中将其发布为数据服务。

1.启动 iServer 服务:默认在 iServer 的 bin 目录下运行 startup.bat(Windows 操作系统)或 startup.sh(Linux 操作系统)之后,iServer 处于启动的状态。

2.打开浏览器,在地址栏中输入 iServer 管理页面的地址(http://<server>:<port>/iserver/admin-ui/services/serviceManagement),登录管理员账户。登录成功后,在左侧导航菜单中依次点击 服务服务管理,然后在右侧页面中点击 快速创建服务

图 快速创建服务

3.在发布服务页面中,数据源选择 文件型工作空间,点击 下一步,然后点击 上传数据,上传工作空间 World.smwu,该工作空间在示例数据压缩包中的路径为:【示例数据压缩包】/2DMap/World/World.smwu。

图 上传示例数据 World.smwu

4.选择要发布的服务类型,服务类型勾选 REST-数据服务,然后点击 下一步 进行地图服务配置,由于所选服务没有配置项,所以点击 发布 即可进行服务发布,服务发布完成后如下图所示。

图 服务发布完成

5.浏览数据源和数据集信息:打开 data-World 数据服务的地址后,点击下一级目录下的 data,在数据服务子资源列表下选择 datasources,在数据源列表下点击 World,可查看数据源的详细信息,然后在包含的数据集下点击 datasets,即可查看每个数据集的信息。

# 2.分析生成FGB数据

本小节将对 World_Common 数据进行 SQL 查询,然后生成 FGB 格式的查询结果。

1.在 iServer 服务列表中点击 数据服务,打开 data-world 数据服务的地址,点击下一级目录中的 data,在数据服务的子资源下的列表中,点击 featureResults,进入 featureResult 资源页面。

2.在 featureResult 资源页面中进行数据查询操作,在 待查询的数据集数组文本框 中输入 ["World:rivers"],查询模式选择 SQL,在要素过滤器中输入 SMID>0,然后点击 createFeatureResults 进行数据查询。数据查询参数说明如下:

  • 待查询的数据集数组:格式为:["数据源名称:数据集名称"],数据源名称和数据集名称可在 FGB数据生成与使用场景1 > 第一步 发布数据服务 中的 浏览数据源和数据集信息 步骤中获取;

  • 查询模式:提供ID 查询,SQL 查询,范围查询,几何查询,缓冲区查询以及多种聚合查询模式。选择不同的查询模式后,查询模式下拉框下方将显示相应的查询过滤器。

图 featureResult 资源页面

3.点击 createFeatureResults 进行 SQL 查询后,浏览器的顶部会弹出消息提示框,显示数据查询操作的详细信息。

图 数据查询操作消息提示

4.数据查询操作成功执行后,点击 featureResults 资源页面底部出现的 featureResult 链接,即可浏览数据查询结果,在要素列表中将显示每一条查询要素结果的服务地址。点击当前页面右侧表述格式列表下的 fgb,即可将 FGB 格式的数据查询结果下载至本地。

图 数据查询结果

# 3.FGB数据存储

将 FGB 格式的分析结果下载至本地后,可通过用导入或者上传的方式将其存储至对象存储服务中,使得任何时候都能在 iClient 客户端中加载对象存储服务中存储的 FGB 数据。

  • 对象存储(Object-based Storage):是一种以对象形式管理数据的分布式存储架构,兼具高速直接访问磁盘以及分布式共享的特点。空间对象存储服务提供了基于 HTTP/HTTPS 协议的 Web 服务接口,在需要使用数据时候,用户可随时访问存储在对象存储服务中的数据。

SuperMap GIS 产品内置了云原生分布式对象存储服务 MinIO,提供对象存储环境的部署和运维管理能力。SuperMap iManager 在11.0.0 以上的版本中,支持一键创建 Minio 环境,是存放 FGB 数据较好的选择,在需要使用 FGB 数据的时候,可从 MinIO 中获取 FGB 数据的访问链接,即可在 iClient 客户端中实现 FGB 数据的访问与可视化。

除了MinIO,您还可以使用其他常用的云对象存储服务,比如商业领域的阿里云对象存储(OSS)、华为云对象存储(OBS)、腾讯云对象存储(COS)、亚马逊云存储(Amazon S3),以及开源领域的 Ceph 等。

# 4.FGB数据可视化

iClient 客户端支持将存储在对象存储服务中的 FGB 数据可视化。本小节将创建一个简单的 HTML 页面,构建基于 SuperMap iClient for Leaflet 的开发环境,并以 FGB 图层的形式将存储在对象存储服务中的 FGB 数据加载至页面中。

1.引入开发文件

(1)首先新建一个HTML文件,设置类似于如下格式的基本 HTML 文档。

<html>
  <head>
    <meta charset="UTF-8" />
    <title data-i18n="resources.title_fgb_all"></title>
  </head>
</html>

(2)在<head>标签中引入 Leaflet CSS 文件和 JS 文件,填入 BootCDN 的托管地址。

    <link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" rel="stylesheet"/>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>

(3)在<head>标签中继续引入 iclient-leaflet CSS 文件和 JS 文件,填入SuperMap iClient for Leaflet 在线站点地址。

    <link rel="stylesheet" href="https://iclient.supermap.io/dist/leaflet/iclient-leaflet.min.css"/>
    <script type="text/javascript" src="https://iclient.supermap.io/dist/leaflet/iclient-leaflet.js"></script>

2.添加底图

(1)创建一个<body>标签并设置样式,然后在<body>标签中创建一个<div>标签,用于放置地图。

<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
<div id="map" style="margin: 0 auto; width: 100%; height: 100%; position: absolute; top: 0; left: 0">
    </div>
</body>

(2)在<body>标签中继续创建一个<script>标签,在<script>标签中定义如下对象,将底图添加至地图容器 map 中。TiledMapLayer 的详细说明可见:L.supermap.TiledMapLayer (opens new window)

  • baseurl:底图所对应的地图服务地址,此处填写的是 iServer 在线站点提供的底图 map-world 的服务地址。
  • map:地图对象,用于叠加底图和 FGB 图层,可设置地图的坐标系、地图中心、缩放范围等参数。
     var map, baseUrl = 'https://iserver.supermap.io/iserver/services/map-world/rest/maps/World',
      map = L.map('map', {
        preferCanvas: true,
        crs: L.CRS.EPSG4326,
        center: { lon: 110, lat: 30 },
        maxZoom: 18,
        zoom: 3
      });
      new L.supermap.TiledMapLayer(baseUrl).addTo(map);

3.FGB图层加载

(1)在<script>标签中,以 FGB 图层的形式将 SQL 查询生成的 FGB 数据加载至地图中。FGBLayer 的详细说明可见:L.supermap.FGBLayer (opens new window)

  • fgburl:FGB 数据对应的服务地址,此处填写的是存储于对象存储服务 MinIO 中的 FGB 数据的访问链接。
fgbUrl = 'http://127.0.0.1:9090/fgb/waterways.fgb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=03GN9N5HZMWQ67DKT1YH%2F20230315%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230315T030921Z&X-Amz-Expires=604800&X-Amz-Security-Token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiIwM0dOOU41SFpNV1E2N0RLVDFZSCIsImV4cCI6MTY3ODg4NjM5NCwicGFyZW50IjoiYWRtaW4ifQ.fCobv6HLmjWEVzLFttzLCvKiCeTU5wExvkiw_v8VnrG5aMVhtIXGeKt_kYSPp76UdtlQKn1a338Fkz6BEg4j8Q&X-Amz-SignedHeaders=host&versionId=null&X-Amz-Signature=a09c7c42a6c820965f7c7f9924e7f4e83569d1c05e68c15f7bb9cd3a268be388';
new L.supermap.FGBLayer(fgbUrl, {
        strategy: 'all'
      }).addTo(map);

(2)在浏览器中打开 HTML 页面后,FGB 数据的可视化效果如下图所示。

图 FGB 数据在 iClient 客户端中的可视化结果

(3)FGB 数据可视化最终完整的代码如下所示:

<html>
  <head>
    <meta charset="UTF-8" />
    <title data-i18n="resources.title_fgb_all"></title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" rel="stylesheet"/>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
    <link rel="stylesheet" href="https://iclient.supermap.io/dist/leaflet/iclient-leaflet.min.css"/>
    <script type="text/javascript" src="https://iclient.supermap.io/dist/leaflet/iclient-leaflet.js"
    ></script>
  </head>
  <body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
    <div id="map" style="margin: 0 auto; width: 100%; height: 100%; position: absolute; top: 0; left: 0">
    </div>
    <script type="text/javascript">
      var map, 
      baseUrl = 'https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China_4326',
      fgbUrl = 'http://127.0.0.1:9090/fgb/waterways.fgb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=03GN9N5HZMWQ67DKT1YH%2F20230315%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230315T030921Z&X-Amz-Expires=604800&X-Amz-Security-Token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiIwM0dOOU41SFpNV1E2N0RLVDFZSCIsImV4cCI6MTY3ODg4NjM5NCwicGFyZW50IjoiYWRtaW4ifQ.fCobv6HLmjWEVzLFttzLCvKiCeTU5wExvkiw_v8VnrG5aMVhtIXGeKt_kYSPp76UdtlQKn1a338Fkz6BEg4j8Q&X-Amz-SignedHeaders=host&versionId=null&X-Amz-Signature=a09c7c42a6c820965f7c7f9924e7f4e83569d1c05e68c15f7bb9cd3a268be388',
      map = L.map('map', {
        preferCanvas: true,
        crs: L.CRS.EPSG4326,
        center: { lon: 110, lat: 30 },
        maxZoom: 18,
        zoom: 3
      });
      new L.supermap.TiledMapLayer(baseUrl).addTo(map);
      new L.supermap.FGBLayer(fgbUrl, {
        strategy: 'all'
      }).addTo(map);
    </script>
  </body>
</html>

# FGB数据生成与使用场景2

在 SuperMap iClient for Leaflet 中,可调用 iServer 在 表1 中提供的服务能力对数据进行查询或分析,返回 FGB 格式的分析结果并以 FGB 图层的形式对其可视化,便于对数据进行实时分析,并即时展示分析结果。

下面同样以 SQL查询 为例,为您介绍在 iClient 客户端中分析生成 FGB 数据并可视化的具体流程:

# FGB数据生成与可视化

1.引入开发文件 参照 FGB数据生成与使用场景1 > 第四步 FGB 数据可视化 中的 引入开发文件 的步骤,构建 iClient 客户端环境。

2.添加底图 参照 FGB数据生成与使用场景1 >第四步 FGB 数据可视化 中的 添加底图 的步骤,将底图 China_4326 添加至地图中。

3.FGB数据生成与可视化

(1)直接调用 iServer 中的 SQL 查询服务,对 World_Common 数据进行 SQL 查询,返回 FGB 类型的查询结果,然后通过回调函数将查询结果以 FGB 图层的形式添加至地图中,具体代码如下。FGBLayer 的详细说明可见:L.supermap.FGBLayer (opens new window)

function query() {
        //SQL查询参数
        var sqlParam = new L.supermap.GetFeaturesBySQLParameters({
          queryParameter: {
                name: "Countries@World",
                attributeFilter: "SMID = 234"//对应中国大陆区域
          },
          datasetNames: ["World:Countries"]
        });
        //调用SQL查询服务,返回结果的类型为FGB,通过回调函数将查询结果以FGB图层的形式添加至地图中
        new L.supermap.FeatureService(url).getFeaturesBySQL(
          sqlParam,
          function (serviceResult) {
            new L.supermap.FGBLayer(serviceResult.result.newResourceLocation, {
              strategy: 'all'
            }).addTo(map);
          },
          'FGB'
        );
      }
query();

(2)在浏览器中打开 HTML 页面后,FGB 数据的可视化效果如下图所示,相关示例可参考:iClient | examples | FGB-SQL查询 (opens new window)

图 FGB 数据在 iClient 客户端中的可视化结果

(3)完整的 FGB 数据生成与可视化的 HTML 代码如下所示:

<html>
  <head>
    <meta charset="UTF-8" />
    <title data-i18n="resources.title_fgb_all"></title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" rel="stylesheet"/>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
    <link rel="stylesheet" href="https://iclient.supermap.io/dist/leaflet/iclient-leaflet.min.css"/>
    <script type="text/javascript" src="https://iclient.supermap.io/dist/leaflet/iclient-leaflet.js"></script>
  </head>
  <body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
    <div id="map" style="margin: 0 auto; width: 100%; height: 100%; position: absolute; top: 0; left: 0">
    </div>
    <script type="text/javascript">
      var map, baseUrl = 'https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China_4326',
      map = L.map('map', {
        preferCanvas: true,
        crs: L.CRS.EPSG4326,
        center: { lon: 110, lat: 30 },
        maxZoom: 18,
        zoom: 4
      });
      new L.supermap.TiledMapLayer(baseUrl).addTo(map);
      query();
      function query() {
        var sqlParam = new L.supermap.GetFeaturesBySQLParameters({
          queryParameter: {
                name: "Countries@World",
                attributeFilter: "SMID = 234"
          },
          datasetNames: ["World:Countries"]
        });
        new L.supermap.FeatureService(url).getFeaturesBySQL(
          sqlParam,
          function (serviceResult) {
            new L.supermap.FGBLayer(serviceResult.result.newResourceLocation, {
              strategy: 'all'
            }).addTo(map);
          },
          'FGB'
        );
      }
    </script>
  </body>
</html>

# FGB图层样式修改

在 iClient 客户端中加载 FGB 数据时,可修改 FGBLayer 的 style 参数,定义 FGB 图层中点、线、面要素的样式。在 style 参数中支持修改的样式类型可参考:L.Path-option (opens new window)。以下代码对 FGB 图层中的线要素进行了颜色 color、宽度 weight 和透明度 opacity 的设置。

 new L.supermap.FGBLayer(fgbUrl, {
        strategy: 'all',
        style:{
          color:'#40E0D0',
          weight:1.5,
          opacity:0.5
        }
      }
    )
图 FGB 图层样式的修改

# FGB数据加载策略

在 iClient 客户端中加载海量 FGB 数据时,可能存在耗时较长的情况,而 FGB 数据有 全量加载按需加载 两种加载策略,此时可以通过修改 FGBLayer 的加载策略参数 strategy,选择 bbox(按需加载)来优化 FGB 数据的浏览体验。

fgbUrl = 'http://127.0.0.1:9090/fgb/waterways.fgb?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=03GN9N5HZMWQ67DKT1YH%2F20230315%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230315T030921Z&X-Amz-Expires=604800&X-Amz-Security-Token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiIwM0dOOU41SFpNV1E2N0RLVDFZSCIsImV4cCI6MTY3ODg4NjM5NCwicGFyZW50IjoiYWRtaW4ifQ.fCobv6HLmjWEVzLFttzLCvKiCeTU5wExvkiw_v8VnrG5aMVhtIXGeKt_kYSPp76UdtlQKn1a338Fkz6BEg4j8Q&X-Amz-SignedHeaders=host&versionId=null&X-Amz-Signature=a09c7c42a6c820965f7c7f9924e7f4e83569d1c05e68c15f7bb9cd3a268be388';
new L.supermap.FGBLayer(fgbUrl, {
        strategy: 'bbox'
      }).addTo(map);
图 FGB 图层的全量加载
图 FGB 图层的按需加载