一、矢量切片技术简介
矢量切片是采用一些新技术来控制动态可交互的地图展示方式,这种新技术允许在移动端或浏览器端自定义修改地图样式。矢量切片底图可以将基础底图和工作数据进行融合,扩展了底图的交互性。人们可以动态的赋予基础底图样式以及通过配合可交互的工作数据来设计底图样式,根据内容进行智能制图和实时分析并展示在基础地图上。
可以理解为将矢量数据以建立金字塔的方式,像栅格切片那样分割成一个一个描述性文件,以GeoJson格式或者以pbf等自定义格式组织,然后在前端根据显示需要按需请求不同的矢量瓦片数据进行Web绘图。而 ArcGIS 的矢量切片是采用协议缓冲(Protocol Buffers)技术的紧凑的二进制格式来传递信息。前端通过解析样式动态渲染矢量切片数据。一个矢量切片会以紧凑的解析的格式包含所有相对应的几何图形和元数据,比如道路名称、土地类型等。因此矢量切片是一种高性能的格式,这种格式在样式、输出格式以及交互性方面提供了高度的灵活性。
ArcGIS矢量切片的优势:
支持更改样式:可以使用一组矢量切片生成许多不同的地图样式。支持更改矢量切片图层上标注的符号、字体或语言,而不需要重新生成切片。
体积小:矢量切片比相应栅格切片的尺寸小很多。因此其构建时间更短,切图速度快,存储所需的磁盘空间也更少
传输快、渲染速度快
支持高清屏:矢量切片图层在高分辨率显示器上的显示效果要优于栅格切片。在 ArcGIS Pro 等桌面应用程序中,可以以任何比例级别显示矢量切片,同时保证符号和标注清晰可见。
动态切换不同语言标注
目前 在 ArcGIS 平台上已经初步形成一个从矢量切片的生产- 发布-使用的完整路线。
二、发布矢量切片图层
在arcgis pro中我们可以直接通过右键图层以共享矢量切片图层方式发布托管矢量切片图层到portal门户中,也可以通过共享矢量切片包(.vtpk 文件)方式上传至ArcGIS Online 或 portal门户,利用共享矢量切片包在门户中发布一个相应的托管矢量切片图层。
2.1、构建并共享矢量切片包(.vtpk 文件)方式
1、制作地图,还可以根据需求创作多比例地图。详见创作多比例地图和为创建矢量切片创作地图。
2、在创建矢量切片包之前,还可以利用Create Vector Tile Index工具建立一个矢量切片索引(可选)
矢量切片索引是对地图内的要素进行分析,要素多的地方就有更多的切片,要素少的地方切片就比较少,几何复杂度较低的地方切片就较大,必要的时候再创建较小的瓦片,尽量节约时间以及控制矢量切片包的大小。
这里选择的切片方案使用自定义矢量切片方案,利用Generate Map Server Cache Tiling Scheme生成自定义矢量切片方案,切片方案尺寸必须为 512 × 512,并且连续缩放比例之间为 2倍的关系,另外还需注意下切片方案的起始点和比例尺须覆盖整个地图的范围。
Maximum vertex_count(可选):表示输出要素类中每个面包括的理想折点数(来自所有可见图层),默认值为10000 个折点数。
3、使用Create Vector Tile Package工具构建矢量切片包
参数说明:
· Input Map:选择用来制作矢量切片的地图,注意去掉map中自带的底图。
· Output File:选择.vtpk的存储位置;
· Tiling Format:意译的话,是切片模式,有indexed和flat两种:
· Indexed模式:在制作切片前,需要通过Create Vector Tile Index工具来对数据创建索引,工具会根据数据的疏密程度,创建不同LOD层级的索引网格,数据密集的地方切片层级较高,稀疏的地方层级较低。
· Flat模式:不创建索引,所有范围内的数据按照同样的规则进行切图;
· Indexed方式创建的切片包,相比flat模式时间短,数据量小;
· Minimum Cached Scale:生成切图的最小比例尺,这并不一定是你的瓷砖计划中最小的比例。缓存的最小比例决定了哪些比例用于生成缓存;
· Maximum Cached Scale:生成切图的最大比例尺
· Index Polygons:输入通过Create Vector Tile Index工具创建的索引多边形;如果选择了indexed模式,需要制定索引多边形,如果没有事先做好的多边形,此参数可以不填,切图工具会默认生成索引并按照索引进行切图,但生成的索引并不输出为要素图层;
另外一定记得对Map进行描述,否则生成切片包的时候会报错。
4、矢量切片服务的发布
**方式一:**可以直接在portal门户中添加vtpk包并发布托管矢量切片图层。
注意:若vtpk包小于2g可以直接上传到ArcGISonline或者Portal并发布。
若大于2g必须先使用arcgis pro的share package工具上传。
方式二:使用arcgis pro的share package工具上传, 在最新版的pro2.5中,share package还提供了publish_web_layer的选项,
publish_web_layer(可选):指定是否将包作为 Web 图层发布到门户。仅支持切片包、矢量切片包和场景图层包。
FALSE —包将被上传且不被发布。这是默认设置。
TRUE —包将被上传并发布为具有相同名称的 web 图层
当勾选了该选项后点击运行后,此时在上传包的同时并将其发布成web图层。
而在pro2.5之前的版本,share package工具只有上传的功能,没有提供这个选项,具体发布web图层的步骤,还需在portal门户中找到我们刚上传的vtpk包,点击右侧publish将其发布成web图层。见下图。
最终发布的托管矢量切片图层出现在portal内容列表中。
2.2、共享矢量切片图层方式发布
1、数据加载,制作地图,右键图层选择共享web图层。
2、在共享web图层窗口,Data选择copy data, Layer type选择Vector Tile 。
3、切换到configuration页面进行设置,选择切片方案及比例尺级别
这里切片模式Tiling Format,有indexed和flat两种:
· Indexed模式:在制作切片前,需要通过Create Vector Tile Index工具来对数据创建索引,工具会根据数据的疏密程度,创建不同LOD层级的索引网格,数据密集的地方切片层级较高,稀疏的地方层级较低。
· Flat模式:不创建索引,所有范围内的数据按照同样的规则进行切图;
4、点击Analyze进行分析,如果没有错误点击publish进行发布,然后在portal门户内容列表中就可以看到刚才发布的托管矢量切片图层了。
三、矢量切片结构
发布后的矢量切片服务,会在arcgis server的工作目录下的\directories\arcgiscache\VectorCache\Hosted下找到已发布的服务名称一致的文件夹,其中记录了该矢量切片的所有信息。
resources:存放的是与矢量切片服务有关的资源,包括服务的字体文件,样式文件及sprites文件等,其中styles文件夹下的root.json文件,里面记录了该矢量切片服务的样式,修改服务的样式就是通过修改该文件来实现的;
tile:该目录中存放的是制作好的矢量切片
tilemap:有一个名为root.json的文件,记录了矢量切片服务第一次加载有关的信息
root.json文件:记录整个矢量切片的服务信息,包括服务名称、服务的范围、坐标参考、切图等级、比例尺等信息。
四、在Portal门户使用矢量切片服务并更改样式
在Portal门户中可以修改矢量切片底图的样式,在server的服务器目录\arcgisserver\directories\arcgiscache\VectorCache\Hosted\ChinaProvince0\VectorTileServer\resources\styles下找到root.json文件,该文件控制图层的样式,通过修改此文件可以修改图层的样式。具体步骤如下:
1、在map viewer中加载发布好的矢量切片图层;
2、 复制并重命名复制的图层;
3、 保存该图层;
4、 进入到该图层的item详细信息页面(或直接在 矢量切片服务目录中找到该图层的样式文件);
5、 在下拉列表中选择“下载样式”;
6、 对下载的样式进行修改;
7、 在item详细信息页面中,点击“更新”,将修改的样式上传;
8、 修改样式成功后可在map viewer中进行查看。
而从enterprise10.8版本开始,可以使用新的ArcGIS Vector Tile Style Editor应用程序直接在Map Viewer地图查看器中自定义矢量切片图层, 设置矢量图层和底图的样式,以最适合地图的制图需求-从轮廓,填充,透明度等。根据自己的喜好更改颜色,图案、图标和标签。
在ArcGIS Enterprise Map Viewer中,选择矢量底图或矢量图块图层,然后单击“ 内容”。然后单击更改样式按钮。
编辑器会自动保存所有编辑内容,因此不必担心会丢失所做的更改!完成后,只需单击“ 保存样式并关闭”按钮,您将返回到Map Viewer,在其中将看到新样式的底图!
五、利用arcgis api for javascript使用矢量切片服务
在ArcGIS API for JavaScript中提供了对矢量地图切片的支持,提供了一个特定的VectorTileLayer 类用来调用矢量切片服务。
var vtlLayer = new VectorTileLayer(properties),其中properties中的url属性,有3种用法来加载矢量切片服务:
1、 使用vector tile service的服务地址
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
<title>VectorTileLayer - 4.14</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/themes/light/main.css"/>
<script src="https://js.arcgis.com/4.14/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/VectorTileLayer"
], function(Map, MapView, VectorTileLayer) {
var map = new Map();
// Make map view and bind it to the map
var view = new MapView({
container: "viewDiv",
map: map,
center:[116.40,39.90],
zoom: 3
});
var tileLayer = new VectorTileLayer({
url:"https://wl.arcgisonline.cn/server/rest/services/Hosted/ChinaProvince0/VectorTileServer"
});
map.add(tileLayer);
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
2、 直接传入矢量切片服务的样式文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
<title>VectorTileLayer - 4.14</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/themes/light/main.css"/>
<script src="https://js.arcgis.com/4.14/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/VectorTileLayer"
], function(Map, MapView, VectorTileLayer) {
// Create a Map
var map = new Map();
var view = new MapView({
container: "viewDiv",
map: map,
center:[116.40,39.90],
zoom: 3
});
var tileLayer = new VectorTileLayer({
url: "https://wl.arcgisonline.cn/server/rest/services/Hosted/ChinaProvince0/VectorTileServer/resources/styles/root.json"
});
map.add(tileLayer);
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
3、矢量切片的style JSON对象,用于渲染图层。 如果使用style JSON对象初始化图层,则会从样式对象中指定的 tile servers中获取切片。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
<title>VectorTileLayer - 4.14</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/themes/light/main.css"/>
<script src="https://js.arcgis.com/4.14/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/VectorTileLayer"
], function(Map, MapView, VectorTileLayer) {
// Create a Map
var map = new Map();
var view = new MapView({
container: "viewDiv",
map: map,
center:[116.40,39.90],
zoom: 3
});
var vtLayer = new VectorTileLayer({
style: {
layers:
[{
"id": "ChinaProvince/ ",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 0],
"layout": {},
"paint": {"fill-color": "#C3FDB2", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/上海市",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 1],
"layout": {},
"paint": {"fill-color": "#D0B3FE", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/云南省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 2],
"layout": {},
"paint": {"fill-color": "#FECCBF", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/内蒙古自治区",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 3],
"layout": {},
"paint": {"fill-color": "#B2EDFD", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/北京市",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 4],
"layout": {},
"paint": {"fill-color": "#FEB6DC", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/台湾省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 5],
"layout": {},
"paint": {"fill-color": "#FEF6B8", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/吉林省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 6],
"layout": {},
"paint": {"fill-color": "#D5FFE1", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/四川省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 7],
"layout": {},
"paint": {"fill-color": "#C2D0FF", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/天津市",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 8],
"layout": {},
"paint": {"fill-color": "#F4D4FE", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/宁夏回族自治区",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 9],
"layout": {},
"paint": {"fill-color": "#FEB4FB", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/安徽省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 10],
"layout": {},
"paint": {"fill-color": "#FEEAC9", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/山东省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 11],
"layout": {},
"paint": {"fill-color": "#FDB6BF", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/山西省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 12],
"layout": {},
"paint": {"fill-color": "#FCCFE0", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/广东省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 13],
"layout": {},
"paint": {"fill-color": "#B5FFCD", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/广西壮族自治区",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 14],
"layout": {},
"paint": {"fill-color": "#B2FEF6", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/新疆维吾尔自治区",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 15],
"layout": {},
"paint": {"fill-color": "#D3ECFD", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/江苏省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 16],
"layout": {},
"paint": {"fill-color": "#EEFECE", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/江西省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 17],
"layout": {},
"paint": {"fill-color": "#BCBDFD", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/河北省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 18],
"layout": {},
"paint": {"fill-color": "#D2FCFE", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/河南省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 19],
"layout": {},
"paint": {"fill-color": "#E1FFBB", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/浙江省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 20],
"layout": {},
"paint": {"fill-color": "#EFBFFE", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/海南省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 21],
"layout": {},
"paint": {"fill-color": "#FDDAD7", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/湖北省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 22],
"layout": {},
"paint": {"fill-color": "#FDDDB2", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/湖南省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 23],
"layout": {},
"paint": {"fill-color": "#D8FED0", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/甘肃省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 24],
"layout": {},
"paint": {"fill-color": "#FDC6E8", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/福建省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 25],
"layout": {},
"paint": {"fill-color": "#FDB2E9", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/西藏自治区",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 26],
"layout": {},
"paint": {"fill-color": "#D6DBFD", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/贵州省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 27],
"layout": {},
"paint": {"fill-color": "#D8C3FD", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/辽宁省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 28],
"layout": {},
"paint": {"fill-color": "#FEF6C9", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/重庆市",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 29],
"layout": {},
"paint": {"fill-color": "#BCFEE1", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/陕西省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 30],
"layout": {},
"paint": {"fill-color": "#FDE1CF", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/青海省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 31],
"layout": {},
"paint": {"fill-color": "#C5E0FE", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/香港特别行政区",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 32],
"layout": {},
"paint": {"fill-color": "#E8B2FD", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/黑龙江省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 33],
"layout": {},
"paint": {"fill-color": "#FDC3C3", "fill-outline-color": "#6E6E6E"}
}, {
"id": "ChinaProvince/<all other values>",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 34],
"layout": {},
"paint": {"fill-color": "#828282", "fill-outline-color": "#6E6E6E"}
}],
glyphs:
"https://wl.arcgisonline.cn/server/rest/services/Hosted/ChinaProvince0/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf",
version: 8,
sprite:
"https://wl.arcgisonline.cn/server/rest/services/Hosted/ChinaProvince0/VectorTileServer/resources/sprites/sprite",
sources: {
esri: {
url:"https://wl.arcgisonline.cn/server/rest/services/Hosted/ChinaProvince0/VectorTileServer",
type: "vector"
}
}
}
});
map.add(vtLayer);
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
调用效果:
在前端也可以去设计样式:
颜色 :颜色的指令通过**“paint**”命令来控制。为一个多边形添加轮廓可以通过在“paint”中指定“fill-outline-color” : “#” , 调整透明度,可以使用“fill-opacity” : “”。
如:
{
"id": "ChinaProvince/四川省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 7],
"layout": {},
"paint": {"fill-color": "#C3FDB2", "fill-outline-color": "#6E6E6E",“fill-opacity” : “0.5” }
}
Layout 布局:Layout 属性的值 有visible"或"none". 默认 “visible”。
可以控制layer的可见性,如:
{
"id": "ChinaProvince/四川省",
"type": "fill",
"source": "esri",
"source-layer": "ChinaProvince",
"filter": ["==", "_symbol", 7],
"layout": {"visibility":"none"},
"paint": {"fill-color": "#C2D0FF", "fill-outline-color": "#6E6E6E"}
}
在api 4.10版本中新增了setLayoutProperties() 和setPaintProperties()方法,可以用来来更改样式层的布局和绘制属性。具体可以参考示例:https://developers.arcgis.com/javascript/latest/sample-code/sandbox/index.html?sample=layers-vectortilelayer-json