# Web符号库技术专题
# 概述
SuperMap iClient for MapboxGL 通过扩展 MapboxGL 的 API,实现了对 Web 符号库的支持,为用户提供了前后端一致的 Web 符号化制图能力,并且支持自定义 Web 符号,满足用户多样化的制图需求。
为了便于您在 SuperMap iClient(以下简称:iClient)中快速上手 Web 符号制图,本文主要从以下几个部分对 Web 符号库进行了介绍:
- 支持情况:Web 符号库当前对桌面端产品 Supermap iDesktop/iDesktopX (以下简称:iDesktop/iDesktopX)中符号的覆盖情况;
- 制图效果:Web 符号库与 iDesktop/iDesktopX 中的点、线、面符号样式以及制图效果的对比展示;
- 使用说明:如何在 iClient 中为图层设置 Web 符号、进行数据驱动制图、自定义 Web 符号样式;
- 制图流程:从新建页面文件开始,在 iClient 中使用 Web 符号的完整制图流程;
- 参考示例:iClient for MapboxGL 提供的协助开发的参考示例,即 Web 符号库 和 Web 符号编辑器。
# 支持情况
iClient for MapboxGL 目前覆盖了桌面端产品 iDesktop/iDesktopX 中的大部分基础符号,下面列出了 Web 符号的覆盖情况:
桌面端基础符号 | Web符号库支持情况 | |
---|---|---|
点符号 | 城市 | √ |
行政等级组符号 | √ | |
人口等级 | √ | |
居民地及设施 | √ | |
定位基础 | √ | |
天气预报 | √ | |
交通 | √ | |
水系 | √ | |
土地调查 | - | |
防汛抗旱 | - | |
地貌 | - | |
管线 | - | |
线符号 | 行政界线 | √ |
交通 | √ | |
水系 | √ | |
道路方头 | √ | |
地铁 | √ | |
定位基础 | √ | |
居民地及设施 | √ | |
其他 | √ | |
土地调查 | - | |
防汛抗旱 | - | |
地貌 | - | |
管线 | - | |
面符号 | HTML命名颜色 | √ |
分类用地颜色 | √ | |
土地规划分类 | √ | |
常用区域颜色 | √ | |
网页安全色 | √ | |
蜡笔颜色 | √ | |
土地调查样式 | - |
# 制图效果
在 iClient 中使用 Web 符号,可快速制作出与桌面端产品 Supermap iDesktop/iDesktopX 符号一致的基础地图,下面对比展示了 Web 符号库与桌面端产品中的符号:
- 点符号样式,以基础符号中的交通符号为例。
- 线符号样式,以基础符号中的行政界线符号为例。
- 面符号样式,以基础符号中的土地分类符号为例。
Web 端符号和桌面端符号制图效果对比:
查看更多 Web 符号制图示例:iClient for MapboxGL | 可视化 | Web符号 (opens new window)。
# 使用方法
Web 符号是由 Mapbox 样式规范中 paint (opens new window), layout (opens new window)组成的符号对象,paint
和 layout
属性共同定义了符号的样式( layout
中的 visibility
属性除外)。Web 符号 API 的详细说明可见:iClient for MapboxGL | API | WebSymbol (opens new window)。
本小节主要介绍了 Web 符号的入门用法,包括:设置图层符号、数据驱动制图以及自定义 Web 符号样式。详细使用方法可参考:iClient for MapboxGL 开发指南 | Web符号 (opens new window) 。
# 设置图层符号
iClient for MapboxGL 支持直接传入 Web 符号库中的符号 ID 来快速设置图层符号,主要步骤和代码如下:
(1)配置符号资源路径;
(2)获取 Web 符号 ID,可以是 Web符号库 (opens new window) 中提供的 Web 符号 ID,也可以是自定义 Web 符号的 ID;
(3)使用接口 loadSymbol
和 addSymbol
,加载 Web 符号并将符号添加至地图;
(4)使用接口 addLayer
添加图层,在 symbol 属性中填入符号 ID 或者 符号表达式 来设置指定图层的 Web 符号。
注:iClient for MapboxGL 通过扩展 MapboxGL 的 API,在 Mapbox Layers 原有属性的基础上新增了 symbol
属性。因此使用接口 addLayer
或 setStyle
时,可以指定 符号ID 或者 符号表达式 来设置图层的符号样式。
// 配置符号资源路径
new mapboxgl.supermap.WebSymbol().init({basePath:"./resources/symbols"});
// Web符号ID
const symbolId = "line-962613";
// 加载Web符号
map.loadSymbol(symbolId, (error, symbol) => {
if (error) throw error;
// 添加Web符号到地图
map.addSymbol(symbolId, symbol);
// 给指定图层设置Web符号
map.addLayer({
"id": "pl@landuse(0_24)",
"source": "landuse",
"source-layer": "pl@landuse",
"type": "line",
"symbol": symbolId
});
});
# 数据驱动制图
使用接口 addLayer
或 setSymbol
为图层设置 Web 符号时,除了通过符号 ID 为单个图层指定统一的符号,还可以采用符号支持的 MapboxGL 表达式,以数据驱动的方式为图层中不同属性的要素指定不同的符号。
- 使用接口
setSymbol
以及 Match 表达式,进行线符号数据驱动制图。
map.setSymbol("layerId", [
"match",
["get", "DLBM"],
"011", "line-964458", //公路用地
"013", "line-964462", //农村道路
"021", "line-962613", //河流水面
"023", "line-962613", //河流水面
"line-962613"
]);
- 使用接口
addLayer
以及 Case 表达式,进行面符号数据驱动制图。
map.addLayer({
"id": "PopDensity_R@Population",
"source": "全国人口密度空间分布图",
"source-layer": "PopDensity_R@Population",
"type": "fill",
"symbol": [
"case",
["all", ["<=", ["get", "dMaxZValue"], 70]], "PoPdensity_R_MAX70",
["all", [">", ["get", "dMaxZValue"], 70],["<=", ["get", "dMaxZValue"], 140]], "PoPdensity_R_MAX140",
["all", [">", ["get", "dMaxZValue"], 210],["<=", ["get", "dMaxZValue"], 280]], "PoPdensity_R_MAX280",
["all", [">", ["get", "dMaxZValue"], 350],["<=", ["get", "dMaxZValue"], 420]], "PoPdensity_R_MAX420",
["all", [">", ["get", "dMaxZValue"], 490],["<=", ["get", "dMaxZValue"], 560]], "PoPdensity_R_MAX560",
["all", [">", ["get", "dMaxZValue"], 640],["<=", ["get", "dMaxZValue"], 700]], "PoPdensity_R_MAX700",
["all", [">", ["get", "dMaxZValue"], 770],["<=", ["get", "dMaxZValue"], 1000]], "PoPdensity_R_MAX1000",
["all", [">", ["get", "dMaxZValue"], 1000]], "PoPdensity_R_Exceed1000",
"Country_R"
]
});
# 自定义符号
支持用户根据符号规范自定义 Web 符号样式,可以创建全新的 Web 符号,也可以对原有 Web 符号的 paint
和 layout
属性进行更改(暂不支持设置符号 layout
中的 visibility
属性)。需要为自定义 Web 符号指定唯一 ID,然后可参考普通 Web 符号的使用方式,通过指定符号 ID 来为图层设置自定义符号。
- 创建自定义点符号
支持设置点符号的图片、大小、偏移、透明度等样式,可参考:Mapbox GL JS | STYLE SPECIFICATION | layers | symbol (opens new window)。
// 加载自定义点符号图片
map.loadImage("../img/cirecleRed.png", (error, image) => {
if (error) throw error;
// 自定义点符号图片
const imageId = "cityPoint";
// 添加点符号图片到地图
map.addImage(imageId, image);
// 自定义Web点符号
const customPointSymbol = {
"paint": {
"icon-translate": [0, 4]
},
"layout": {
"icon-image": imageId,
"icon-size": 0.1
}
};
// 自定义Web点符号ID
const pointSymbolId = "Province_P";
// 添加Web点符号到地图
map.addSymbol(pointSymbolId, customPointSymbol);
}
);
- 创建自定义线符号
支持设置线符号的线宽、颜色,端点样式、连接等样式,可参考:Mapbox GL JS | STYLE SPECIFICATION | layers | line (opens new window)。
// 自定义Web线符号
const customLineSymbol = {
"paint": {
"line-width": 0.38,
"line-dasharray": [
2.5,
2
],
"line-color": "#AE10FC"
}
};
// 自定义线符号ID
const lineSymbolId = "Province_L";
// 添加Web线符号到地图
map.addSymbol(lineSymbolId, customLineSymbol);
- 创建自定义面符号
支持设置纯色面符号的颜色、透明度,外轮廓线颜色、是否反走样等属性,可参考:Mapbox GL JS | STYLE SPECIFICATION | layers | fill (opens new window)。
map.addSymbol("custom_fill_ID", {
paint: {
"fill-color": "rgba(246,229,255,1.00)",
"fill-opacity": 0.5,
"fill-outline-color": "rgba(145,223,158,1.00)",
"fill-antialias": true
}
});
- 修改原有 Web 符号
首先通过接口 loadSymbol
加载出需要修改的 Web 符号,然后修改符号的 paint
和 layout
属性。为了与修改前的 Web 符号进行区别,将使用一个新的 ID 来标识修改后的 Web 符号。
const loadPreSymbol = async (preSymbolInfo) => {
const { symbolId, style ={} } = preSymbolInfo;
const id = uniqueId();
await map.loadSymbol("point-1", (err, symbol) => {
if (!err) return;
symbol.paint["icon-color"] = "red";
map.addSymbol("start", symbol);
});
return { id, symbolId };
}
# 制图流程
我们在上一个章节中对 Web 符号的使用方法进行了详细的介绍,接下来我们将从创建一个基本的 HTML 文件开始,为您介绍如何在 iClient 中采用 Web 符号进行制图,具体的操作步骤如下:
# 1.准备HTML文件
新建一个 HTML 文件,设置类似于如下格式的基本 HTML 文档。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>土地利用</title>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
</html>
# 2.引入
开发时需要以 文件方式
或 npm
方式引入 MapboxGL v1
和 SuperMap iClient for MapboxGL
,并且为了使用 Web 符号资源,需要指定符号资源的路径。引入方式可参考:iClient for MapboxGL | 开发指南 | Web符号 | 引入 (opens new window)。
# 3.添加地图
(1)在<body>
标签中添加如下代码,创建地图容器。
<div id="map"></div>
(2)在<script>
标签中添加以下代码,创建地图对象。其中,地图数据来源于 SuperMap iServer 站点提供的土地利用图的矢量瓦片, container
属性指定的是上一步骤中创建的地图容器。
var serverUrl = "https://iserver.supermap.io/iserver/services/map-mvt-landuse2/rest/maps/landuse";
var map = new mapboxgl.Map({
container: "map",
style: {
"sources": {
"landuse": {
"tiles": [
serverUrl + "/tileFeature.mvt?z={z}&x={x}&y={y}"
],
"type": "vector"
}
},
"name": "landuse",
"layers": [],
"version": 8
},
minZoom: 11,
maxZoom: 15,
zoom: 13,
center: [
108.9131713726414,
23.82622655814832
]
});
# 4.使用符号
采用数据驱动的方式为不同的土地利用类型的指定不同的 Web 符号。首先创建添加图层的方法,在方法中指定图层所采用的 Web 符号,然后在地图加载事件中,将图层添加至地图。
(1)创建方法 createLineLayer
,实现功能:以数据驱动的方式指定线图层使用的 Web 符号,并将线图层添加至地图中。
var createLineLayer = function () {
map.addLayer({
"id": "pl@landuse(0_24)",
"source": "landuse",
"source-layer": "pl@landuse",
"type": "line",
"symbol": [
"match",
["get", "DLBM"],
"011", "line-962543", //公路用地
"013", "line-962524", //农村道路
"021", "line-962613", //河流水面
"023", "line-962613", //河流水面
"line-964935"
]
});
};
(2)创建方法 createPolygonLayer
,实现功能:以数据驱动的方式指定面图层使用的 Web 符号,并将面图层添加至地图中。
// 添加面图层
var createPolygonLayer = function () {
map.addLayer({
"id": "landuse@landuse(0_24)",
"source": "landuse",
"source-layer": "landuse@landuse",
"type": "fill",
"symbol": [
"match",
["get", "DLBM"],
"011", "polygon-955880", //水田
"013", "polygon-955464", //旱地
"021", "polygon-955519", //果园
"023", "polygon-955879", //其他园地
"031", "polygon-955483", //有林地
"032", "polygon-955537", //灌木林地
"033", "polygon-955878", //其他林地
"043", "polygon-955398", //其他草地
"127", "polygon-955385", //裸地
"201", "polygon-955872", //城市
"203", "polygon-955527", //村庄
"101", "polygon-955452", //铁路用地
"102", "polygon-955550", //公路用地
"104", "polygon-955550", //农村道路
"117", "polygon-955400", //沟渠
"118", "polygon-955545", //水工建筑
"122", "polygon-955529", //设施农用地
"204", "polygon-955532", //采矿用地
"205", "polygon-955433", //风景名胜及特殊用地
"111", "polygon-955871", //河流水面
"112", "polygon-955871", //湖泊水面
"113", "polygon-955875", //水库水面
"114", "polygon-955525", //坑塘水面
"116", "polygon-955508", //内陆滩涂
"polygon-0"
]
});
};
(3)在地图加载事件中,配置 Web 符号资源的基础路径,然后使用方法 map.loadSymbol
批量加载土地利用图中用到的 Web 符号,同时使用方法createLineLayer
和 createPolygonLayer
将指定了 Web 符号的线图层和面图层添加至地图中。
map.on("load", function () {
// 配置 Web 符号资源的基础路径
new mapboxgl.supermap.WebSymbol().init({basePath: window.exampleWebSymbolBasePath});
// 批量加载 Web 符号
var symbolIds = [
"polygon-955452",
"polygon-955550",
"polygon-955871",
"polygon-955875",
"polygon-955525",
"polygon-955508",
"polygon-955400",
"polygon-955545",
"polygon-955529",
"polygon-955385",
"polygon-955872",
"polygon-955527",
"polygon-955532",
"polygon-955433",
"polygon-955880",
"polygon-955464",
"polygon-955519",
"polygon-955879",
"polygon-955878",
"polygon-955483",
"polygon-955537",
"polygon-955398",
"polygon-0"
];
map.loadSymbol(symbolIds, function (_error, symbols) {
symbols.forEach((symbol, index) => {
symbol && map.addSymbol(symbolIds[index], symbol);
});
createPolygonLayer();//添加面图层至地图
createLineLayer();//添加线图层至地图
});
});
# 5.可视化效果
至此,已成功采用 Web 符号进行制图,在浏览器中打开 HTML 页面后可查看如下图所示的土地利用图制图效果。相关示例及完整代码可参考:iClient for MapboxGL | examples | 土地利用图 (opens new window)。
# 参考示例
iClient for MapboxGL 在 iClient for MapboxGL | 可视化 | Web符号 (opens new window) 中提供了一系列 Web 符号示例,以便您快速上手 Web 符号制图,其中包括:Web 符号库、Web 符号编辑器以及若干 Web 符号制图成果,本小节将对 Web 符号库示例和 Web 符号编辑器示例进行介绍。
# Web符号库
为了便于用户了解 Web 符号库所支持符号的实现方式,iClient for MapboxGL 在 Web符号库 (opens new window) 示例中罗列了目前所有支持的 Web 符号,并提供了 Web 符号的名称、上图效果和 ID,点击符号可查看实现当前符号样式的代码。
# Web符号编辑器
为了便于用户了解在 iClient 中自定义 Web 符号的功能,在 Web符号编辑器 (opens new window) 示例中,可以对 Web 符号库中提供符号进行在线样式编辑,并在地图中显示自定义 Web 符号的效果。支持编辑的符号样式如下:
- 点符号:颜色、大小、透明度、相对偏移值、旋转角;
- 线符号:颜色、透明度、线宽、偏移量、模糊度、线段连接方式、线段端点样式、相对偏移值;
- 面符号:颜色、透明度。