# 矢量瓦片技术专题
# 概述
随着 Web GIS 的发展,用户对地图显示与传输有了更高的需求,地图瓦片是一种非常有效的提高地图服务访问效率的方式,是为改善用户体验,提高运行效率,节省工作时间而出现的一门技术,也是目前主流地理信息系统中普遍采用的一种图形显示技术手段。该技术的出现,大大缩短了用户的等待时间,同时提高了工作效率,使图形数据的浏览过程变得高效流畅。
目前,SuperMap 瓦片类型主要包括栅格瓦片、矢量瓦片和三维瓦片。其中,矢量瓦片将地图中的矢量图层以瓦片的形式进行切分和存储,与栅格瓦片相比,具有无级缩放,风格修改,数据量相对较小的优势,能更好地满足灵活多样的 Web 地图应用。
本文档主要阐述了从矢量地图准备、矢量瓦片的生成到在 SuperMap iClient JavaScript (以下简称:iClient)中的可视化等一系列流程,供用户参考。
# 矢量地图准备
在生成矢量瓦片之前,首先需要准备一幅有效的矢量地图。SuperMap 地图中的点、线、面、文本图层均支持生成矢量瓦片,并且 SuperMap 地图要素的符号化、图层设置等绝大多数样式都能被 MapBox 样式支持。但是,由于 MapBox 风格表达与 SuperMap 不同,所以在矢量地图的制作过程中存在一些局限性和注意事项。为了提高制图效率,同时避免矢量地图制图的局限性,您需要在制图过程中注意以下几点,详细要点可参考:矢量瓦片-制图最佳实践 (opens new window)。
- 数据坐标系:矢量数据集的坐标系尽量与最终地图显示坐标系保持一致,从而跳过矢量瓦片生成过程中的坐标系转换步骤,提高切图效率。
- 数据复杂度:确保不同显示比例尺下,地图对象具有合理的复杂度,可提高切图效率,同时避免抽稀显示导致对象明显变形。
- 地图符号化:避免使用复杂的符号制作地图,否则可能无法在矢量瓦片中正确显示(不支持的符号根据符号类型,在矢量瓦片中会分别显示为圆点、实线、纯色填充)。
- 文字效果:地图中的文本需设置固定大小和统一风格,否则矢量瓦片中的文字可能与原地图存在差异,且仅支持轮廓、加粗、斜体(计算机中需存在相应字体的粗体和斜体字体库),不支持阴影、下划线、删除线等文字效果。
- 专题图:避免制作点、线、面图层的单值标签专题图、分段标签专题图、复合标签专题图和矩阵标签专题图,否则生成矢量瓦片时将忽略这些图层。同时避免对单值专题图进行偏移设置,避免对标签专题图的标注字段使用 SQL 语句进行计算。
- 限制可见比例尺:建议设置图层的可见比例尺范围,可提升地图的显示性能,提高矢量瓦片的绘制效率。
# 矢量瓦片生成
矢量瓦片生成是在 iClient 中对矢量瓦片可视化之前不可或缺的步骤,针对不同的用户,本章节提供了两种矢量瓦片的生成方式:预先生成矢量瓦片、动态生成矢量瓦片。
- 预先生成矢量瓦片指的是在 SuperMap iDesktopX(以下简称:iDesktopX)中将矢量地图预先生成矢量瓦片,然后通过 SuperMap iServer(以下简称:iServer)发布为地图服务。这样在 iClient 请求时,服务器能够立即调用已经切好的矢量瓦片,从而在 iClient 中实现低延迟的瓦片渲染可视化。此方法生成的矢量瓦片在地图更新后需要重新进行切片,适用于地图更新不频繁,并需要提高瓦片响应效率的情况。此方法要求用户同时拥有 iDesktopX、iServer 和 iClient 等产品。
- 动态生成矢量瓦片指的是无需预先生成矢量瓦片,直接通过 iServer 将矢量地图所在的工作空间发布为地图服务,然后在 iClient 中向 iServer 发送调用矢量瓦片的请求,iServer 再根据请求,实时动态地生成相应层级和位置的矢量瓦片,并返回给 iClient 进行渲染可视化。此方法生成的矢量瓦片在地图更新后无需重新进行切片,适用于地图更新频繁的情况,当用户拥有 iServer 和 iClient 产品时可采用此方式。
两种方式各有各的特点与要求,您可以根据实际情况选择适合的矢量瓦片生成方式。此外,两种方式均需要您在 iServer 中的角色为系统管理员(ADMIN)或服务发布者(PUBLISHER)。
注:请使用超图官网上最新的 SuperMap iDesktopX、iServer 和 iClient 客户端版本。
SuperMap iDesktopX: http://support.supermap.com.cn/product/iDesktopX.aspx (opens new window)
SuperMap iClient JavaScript: http://support.supermap.com.cn/product/iClient.aspx (opens new window)
SuperMap iServer: http://support.supermap.com.cn/product/iServer.aspx (opens new window)
# 预先生成矢量瓦片
本小节将采用 iDesktopX 内置的示例数据 中国地图 中的 China_Light 地图来进行矢量瓦片的生成。首先在 iDesktopX 中采用 多任务切图 的方式预先生成 China_Light 地图的矢量瓦片,然后将矢量瓦片以地图服务和矢量瓦片服务的形式发布到 iServer 上,以便后续在 iClient 中对矢量瓦片进行可视化。具体的操作步骤如下:
# 在 iDesktopX 中生成矢量瓦片
- 在 iDesktopX 的起始页中,打开示例数据中的 中国地图,在 工作空间管理器 中会出现名为 China 的工作空间,然后打开 地图 下的地图 China_Light。
- 点击 地图 选项卡下的 属性 - 地图属性,重新设定地图坐标系为 WGS_1984_Web_Mercator,然后保存地图。
- 为了保证能够正确地生成矢量瓦片,请使用具有 EPSGCode 的坐标系。
- 在 工作空间管理器 中,展开 数据源,在数据源 China 的右键菜单中,选择 重新只读打开,将数据源设置为只读,并对工作空间进行保存。
- 数据源只读:并行切图要求 UDB 型数据源都是只读的,是由于多任务切图时每条进程会同时访问地图中图层所在的数据源,此时数据源就会存在被占用的问题,将数据源设置为只读,避免了数据源被占用而无法执行的问题。
- 在 工作空间管理器 中,展开 地图,在地图 China_Light 的右键菜单中,选择 生成地图瓦片(多任务),在弹出的对话框中选择 新建多任务切图 选项,然后点击 下一步,弹出 多任务生成地图瓦片 对话框。
- 多任务切图:根据地图的比例尺和地理范围等将地图切图任务拆分成多个子任务,然后将拆分后的任务部署在共享目录中从而实现多机同时访问。多机同时开启多条进程,每条进程会到指定的目录获取并执行切图任务,并将切图结果保存到同一个文件夹中,从而实现多任务并行切图。多任务切图方式能充分利用机器的硬件资源,综合利用多个节点并行切图,极大提升切图的效率。详情可参考:多任务切图 (opens new window)。
- 生成地图瓦片参数设置如下:
- 瓦片类型:选择“矢量瓦片”;
- 比例尺层级:勾选对话框左侧的复选框,设置矢量瓦片生成的比例尺层级为 0-5 级;
矢量瓦片采用的是全球剖分层级,因此不支持自定义比例尺。 - 抽稀显示:不勾选;
勾选该选项,程序将对小比例尺下的几何对象进行抽稀,可减少节点冗余,提高显示性能。 - 生成索引:勾选;
勾选该选项,生成的矢量瓦片中若存在矢量面,则会把矢量面三角化成三角网,将这个三角网索引生成出来,可加快在 WebGL 的加载速度; - 路径设置:设置瓦片名称和输出路径;
- 存储类型:选择“紧凑”;
当瓦片储存类型为紧凑型时,对原始的切片文件采用一定的压缩和加密机制,在结构上采用一组文件替代原始的图片格式的瓦片机制。此外,还有原始型:切片文件以单独的图片文件格式存放在磁盘上,不对数据进行压缩,能够直接读取; MongoDB 型:生成的瓦片切片文件,以分布式格式存储在服务器的数据库中,而本地会生成一个索引文件(*.sci)。详情可参考:瓦片存储类型 (opens new window)。 - 添加所有属性字段值:勾选;
勾选该选项,生成的瓦片结果包含了对应数据集几何对象所带的全部非系统字段,否则程序只输出该地图显示使用到的字段。 - 缓冲范围:默认值为 16,单位为像素;
每张瓦片按照设置的缓冲范围值向四周扩大,即生成的瓦片包含了缓冲区范围内的数据,以便相邻瓦片的边界可以无缝衔接。 - 分离数据与风格:勾选;
勾选该选项,表示分离数据与风格;不勾选,表示不分离数据与风格。当用户后期需要单独更新矢量瓦片的数据或者风格时,需要勾选该选项,方便单独更新矢量瓦片的数据或者风格。 - 生成矢量瓦片:在使用多任务生成矢量瓦片时,程序默认勾选该选项,不可更改;
勾选该选项,生成的矢量瓦片结果将存储在 tiles 文件夹中。 - 生成瓦片风格:在使用多任务生成矢量瓦片时,程序默认勾选该选项,不可更改;
勾选该选项,生成包含地图转换对应风格的 *.json 文件,生成结果将存储在 sprites 和 styles 两个文件夹中。 - 生成字体缓存文件:默认勾选,可更改。
iDesktopX 支持将矢量地图生成 MapBox MVT 规范的瓦片,建议勾选。
以上参数设置完成后,点击 下一步,设置生成地图瓦片的瓦片范围,此处保持默认范围,并点击 下一步。
点击 下一步 后,弹出 多任务切图 对话框,多任务切图的参数设置如下:
- 文件型工作空间 / 数据库型工作空间:选择“文件型工作空间”;
当选择文件型工作空间时,只需指定工作空间路径; 当选择数据库型工作空间,需选择工作空间类型、输入数据库连接信息。 - 工作空间路径:待切地图所在的工作空间路径;
需确保该工作空间中的待切地图与拆分任务时的地图一致,若不一致,会导致结果无法正确浏览,此时建议用户对更新后的地图重新拆分任务后,再切瓦片。 - 地图名称:设置待切的地图名称;
- 任务数:此处保持默认值 3 ,表示机器默认开启了3个进程来执行切图任务。
设置切图的任务数,进程数需要根据机器的配置和进程使用情况来设置,默认任务数为计算机 CPU 线程数 * 1.5倍,切图时 CPU 利用率为100%。可在切图过程中随时调整任务数,单击“应用”按钮,及时增加或减少正在执行切图的进程。 - 工作文件:此处保持默认值;
指定至瓦片工作目录下以瓦片名称命名的文件夹中的 *.sci 文件。多机多任务切图则设置为主机工作目录中的文件,主机的工作目录,必须是共享目录。 - 使用本机切图 / 加入主机切图:此处保持默认选项,使用本机执行切图任务;
选择加入主机切图时,需要在主机名中输入主机的 IP 地址,放置拆分任务的工作目录即为主机,其他机器调取主机任务协同执行切图。 - 端口号:此处保持默认值,主机执行切图的默认端口号为 31363;
用于唯一标识主机上的一个应用进程,方便不同应用进程之间的通信,指定端口可以提供可靠的数据传输,若在执行切图时该端口提示被占用,请检查端口使用情况,指定其他端口。
- 多任务切图参数设置完成后,点击 生成,开始多进程切图,可查看切图进度信息。并且支持调整某个切图比例尺的优先级,或暂停该比例尺的相关切图任务,操作方式为 选择待调整比例尺 - 右键,在右键菜单中设置暂停执行或优先执行。
- 切图进度:在对话框右侧面板中可实时刷新查看切图进度,包括总进度、总任务数、已完成任务数、待执行任务数、失败任务数及执行中的任务数。
- 切图进度列表框:可实时查看每个切图比例尺下子任务的详细进度信息。
- 输出信息:在对话框下侧可实时显示切图过程中的输出信息。
- 重置失败任务:若提示有失败任务数,可通过“重置失败任务”,对失败任务进行重新切图。若仍提示有失败任务,请进一步检查地图数据或拆分的任务,再重启多任务切图程序。
- 矢量瓦片的输出文件:切图任务完成后,在输出窗口会提示地图生成平面地图瓦片成功。在输出路径下,将产生如下图所示的文件夹和文件。
- fonts:矢量瓦片使用的字体文件;
- sprites:矢量瓦片图标相关风格内容资源;
- styles:矢量瓦片风格描述文件;
- tiles:矢量瓦片数据(.mvt 文件);
- *.sci 文件:矢量瓦片的元信息描述文件,记录了数据的投影、地理范围、层级比例尺等信息。
- 查看矢量地图瓦片:在 工作空间管理器 中的 China 工作空间中,在 数据源 节点的右键菜单中选择 打开文件型数据源,打开矢量瓦片结果文件夹中的 *.sci 文件,然后双击打开加载进来的文件,即可在地图窗口生成如下图所示的矢量瓦片。
# 在 iServer 中发布矢量瓦片
- 启动 iServer 服务:默认在 iServer 的 bin 目录下运行 startup.bat(Windows 操作系统)或 startup.sh(Linux 操作系统)之后,iServer 处于启动的状态。
- 打开浏览器,在地址栏中输入 iServer 管理页面的地址(http://<server>:<port>/iserver/admin-ui/services/serviceManagement),登录管理员账户,登录成功后,在左侧导航菜单中选择 服务 — 服务管理,然后在右侧页面中点击 快速创建服务。
- 在 发布服务 页面中,数据源选择 UGCV5(MVT)瓦片,点击 下一步,上传 在iDesktopX中生成矢量瓦片>步骤 9 中生成的瓦片配置文件(*.sci)。
- 如果是将本地生产的矢量瓦片发布到本地部署的 iServer 上,可直接在文件路径中浏览查找相应的瓦片配置文件;如果是将本地生产的矢量瓦片发布到其他机器上部署的 iServer 上,您可以点击 上传数据,从本地的文件路径中查找并上传相应的瓦片配置文件。
- 勾选 REST-地图服务 和 REST-矢量瓦片服务 复选框,然后点击 下一步 进行配置服务,由于所选服务没有配置项,所以点击 发布 即可进行服务发布,服务发布完成后如下图所示。
- 服务发布完成后,可在服务管理页面中进行查看,点击服务列表中相应的服务,将显示服务的详细信息。
- 在 基本信息 选项卡中,点击 服务地址 中的地图服务对应的链接,在弹出页面中的 下一级目录 下点击 maps,在弹出页面中的 地图列表 下的地图名称后面,选择浏览于 for MapboxGL,即可预览采用矢量瓦片发布的地图服务。
- 在 基本信息 选项卡中,点击 服务地址 中的地图服务,在弹出页面中的 下一级目录 下点击 maps,在 地图列表 中点击相应的地图,在 支持以下操作 中点击 tileFeature,然后在 支持以下操作 中点击 vectorStyles,在弹出的矢量风格页面中点击 获取风格 按钮,即可查看地图的矢量风格。
- 在上一步的矢量风格页面右侧的 表述格式 中选择 json,并在弹出页面的地址栏中的 URI 后添加参数
&styleonly=true
,即可查看地图矢量风格的 JSON 描述,其中包含了在 iClient 中载入矢量瓦片的相关参数与属性。
# 动态生成矢量瓦片
将工作空间发布为地图服务和矢量瓦片服务,是动态生成矢量瓦片前的一个必要步骤。本小节通过 iServer 将示例地图 China_Light 所在的工作空间发布为地图服务,在发布之前需要确保地图坐标系拥有正确的 EPSG code(暂不支持自定义的坐标系),以便后续能在 iClient 中正确调用矢量瓦片。具体操作步骤如下:
- 启动 iServer 服务:默认在 iServer 的 bin 目录下运行 startup.bat(Windows 操作系统)或 startup.sh(Linux 操作系统)之后,iServer 处于启动的状态。
- 打开浏览器,在地址栏中输入 iServer 管理页面的地址(http://<server>:<port>/iserver/admin-ui/services/serviceManagement),登录管理员账户,登录成功后,在管理页面左侧的导航菜单栏中选择 服务 — 服务管理,然后在右侧页面中点击 快速创建服务。
- 选择数据源为 文件型工作空间,点击 下一步,在 工作空间路径 中填写示例数据 China_Light 所在工作空间的路径,点击 下一步,服务类型勾选 REST-地图服务 和 REST-矢量瓦片服务,然后点击 下一步,选项 允许编辑 和 DPI 保持默认,最后点击 发布 即可将工作空间发布为地图服务。
- 注:iServer 发布服务时,请在 iDesktopX 中关闭要发布的工作空间,以免工作空间被占用导致发布不成功。
- 服务发布完成后,可在服务管理页面中进行查看,点击服务列表中相应的服务,将显示服务的详细信息。在 基本信息 选项卡中,在 地图列表 下的地图 China_Light 后方,选择地图浏览形式为 for MapboxGL,即可预览成功发布的地图服务。
- 在服务信息页面的 基本信息 选项卡中,点击 服务地址 中后缀为 rest 的链接,在弹出页面中的 下一级目录下点击 maps,在 地图列表中点击相应的地图,在 支持以下操作 中点击 tileFeature,然后在 支持以下操作 中点击 vectorStyles,在弹出的矢量风格页面右侧的 表述格式 中选择 json 即可查看地图矢量风格的 JSON 描述,JSON 描述中包含了在 iClient 中载入矢量瓦片的相关参数与属性。
- 在地址栏中的 URI 后添加
?type=MapBox_GL&styleonly=true
并重新载入页面,即可查看 MapBoxGL 类型的 JSON 描述。
# 矢量瓦片可视化
我们在上一个章节中成功生成了矢量瓦片,接下来将生成的矢量瓦片基于 MapBox 样式文件在 iClient 进行显示,本例采用 SuperMap iClient for MapboxGL 渲染矢量瓦片,具体的操作步骤如下:
- 首先新建一个 HTML 文件,设置类似于如下格式的基本 HTML 文档。
<html>
<head>
<meta charset="UTF-8" />
<title data-i18n="vectortile - visualization"></title>
</head>
</html>
- 在
<head>
标签中引入 MapboxGL v1 CSS 文件和 JS 文件,填入 BootCDN 的托管地址。
<link href="https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.13.2/mapbox-gl.css" rel="stylesheet" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.13.2/mapbox-gl.js"></script>
- 在
<head>
标签中继续引入 iclient-mapboxgl CSS 文件和 JS 文件,并填入 SuperMap iClient for MapboxGL 在线站点地址。
<link href="https://iclient.supermap.io/dist/mapboxgl/iclient-mapboxgl.min.css" rel="stylesheet" />
<script type="text/javascript" src="https://iclient.supermap.io/dist/mapboxgl/iclient-mapboxgl.js"></script>
- 在
<body>
标签中添加如下代码以创建地图容器。
<div
id="map"
style="
position: absolute;
left: 0px;
right: 0px;
width: 1920px;
height: 1080px;
"
></div>
- 在
<body>
标签中的<script>
标签中声明地图变量 map,其中 container 属性指定本小节步骤 3 中创建的地图容器,此外,center、zoom 等更多参数的说明可参考:Map | Mapbox GL JS | Mapbox (opens new window)。
- 如果您采用的是预先生成矢量瓦片的方式,style 属性内容填写 预先生成矢量瓦片>在 iserver 中发布矢量瓦片>步骤 8 中的地图矢量风格 JSON 描述地址;
- 如果您采用的是动态生成矢量瓦片的方式,style 属性内容填写 动态生成矢量瓦片>步骤 6 中的地图矢量风格 JSON 描述地址。
var map = new mapboxgl.Map({
container: 'map', // container id
style:
'http://localhost:8090/iserver/services/map-mvt-ZhuanTiTuJingJiFaZhanTongJi/rest/maps/%E4%B8%93%E9%A2%98%E5%9B%BE_%E7%BB%8F%E6%B5%8E%E5%8F%91%E5%B1%95%E7%BB%9F%E8%AE%A1/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
center: [104.35375913450572, 31.572093201149855], // starting position
zoom: 0,
attributionControl: false
});
- 通过
addControl()
方法可将地图控件添加到地图上,例如平移缩放控件和比例尺控件。
map.addControl(new mapboxgl.NavigationControl(), 'top-left');
map.addControl(new mapboxgl.ScaleControl({}));
- 矢量瓦片在 iClient 中可视化的完整示例代码如下。保存 HTML 文件并在浏览器中打开,页面中将显示如下地图。更多矢量瓦片示例可查看:SuperMap iClient for MapboxGL - 示例 - 可视化 - 矢量瓦片 (opens new window)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>UGCV5(MVT)</title>
<!-- 引入MapboxGL v1 CSS 文件和 JS 文件 引入iclient-mapboxgl CSS 文件和 JS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.13.2/mapbox-gl.css" rel="stylesheet" />
<link href="https://iclient.supermap.io/dist/mapboxgl/iclient-mapboxgl.min.css" rel="stylesheet" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mapbox-gl/1.13.2/mapbox-gl.js"></script>
<script type="text/javascript" src="https://iclient.supermap.io/dist/mapboxgl/iclient-mapboxgl.js"></script>
</head>
<body>
<!-- 地图显示的div -->
<div
id="map"
style="
position: absolute;
left: 0px;
right: 0px;
width: 1920px;
height: 1080px;
"
></div>
<script type="text/javascript">
var map = new mapboxgl.Map({
container: 'map', // container id
style:
'http://localhost:8090/iserver/services/map-China/rest/maps/China_Light/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
center: [104.35375913450572, 31.572093201149855], // starting position
zoom: 0, // starting zoom
attributionControl: false
});
map.addControl(new mapboxgl.NavigationControl(), 'top-left');
</script>
</body>
</html>