矢量瓦片图层(VectorTileLayer)
矢量瓦片图层(VectorTileLayer)是三维场景中最常用的图层:它加载 mvt 格式的矢量瓦片数据,并在浏览器端按样式实时渲染。
与传统的栅格瓦片底图相比,矢量瓦片有以下特点:
- 数据与样式分离:瓦片数据只包含矢量几何与属性,不含任何样式信息。底图的最终呈现由渲染引擎按样式实时计算,修改样式不需要重新生成瓦片。
- 三维更清晰:三维场景中地图常被旋转、倾斜,栅格瓦片会出现明显的拉伸模糊,而矢量瓦片始终是实时矢量渲染,文字与线条保持清晰锐利。
- 支持三维元素:矢量数据可以直接参与三维构建,例如将建筑面按高度属性挤出为立体模型。
更详细的原理介绍见什么是矢量瓦片。
加载矢量瓦片
创建 VectorTileLayer 时,通过 urlTemplate 指定瓦片服务的地址模板:
js
import { Map } from "maptalks";
import { GroupGLLayer, VectorTileLayer } from "@maptalks/gl-layers";
const map = new Map("map", {
center: [-74.00912099912109, 40.71107610933129],
zoom: 16,
pitch: 56,
});
const vt = new VectorTileLayer("vt", {
urlTemplate: "https://tiles.maptalks.com/test/{z}/{x}/{y}.mvt",
});
const groupLayer = new GroupGLLayer("group", [vt]).addTo(map);{z}、{x}、{y} 会被替换为瓦片的缩放级别与行列号。也可以使用支持坐标系参数的其他瓦片服务,例如 maptiler 的矢量瓦片:
js
const vt = new VectorTileLayer("vt", {
urlTemplate:
"https://api.maptiler.com/tiles/v3/{z}/{x}/{y}.pbf?key=YOUR_MAPTILER_KEY",
});如果瓦片数据使用 EPSG:4326 坐标系(而不是默认的 web mercator),需要在地图上指定 spatialReference,例如加载 maptiler 4326 瓦片示例:
js
const map = new Map("map", {
center: [-74.00912099912109, 40.71107610933129],
zoom: 12,
spatialReference: "EPSG:4326",
});样式
VectorTileLayer 的 style 配置是可选的,不设置时图层只做基础渲染。设置样式后,图层会按样式实时渲染瓦片中的矢量数据。
样式可以是一个插件式样式数组,直接写在代码里,或存放为独立的 json 文件后用路径引用。以道路样式示例使用的样式文件为例,它的结构是:
json
[
{
"filter": ["all", ["==", "$layer", "water"], ["==", "$type", "Polygon"]],
"renderPlugin": {
"type": "water",
"dataConfig": { "type": "fill" }
},
"symbol": {
"waterBaseColor": [0.72, 0.82, 1, 1],
"animation": true,
"waterSpeed": 1
}
},
{
"filter": ["all", ["==", "$layer", "building"], ["==", "$type", "Polygon"]],
"renderPlugin": {
"type": "lit",
"dataConfig": {
"type": "3d-extrusion",
"altitudeProperty": "height",
"altitudeScale": 1,
"defaultAltitude": 10,
"top": true,
"side": true
}
},
"symbol": {
"material": {
"baseColorFactor": [1, 1, 1, 1],
"roughnessFactor": 1,
"metallicFactor": 0
}
}
}
]样式数组中的每一项由三个部分组成:
filter:数据过滤条件,决定这条样式作用于哪些数据。支持$layer(瓦片源数据中的图层名)、$type(几何类型)以及数据的属性字段。renderPlugin:渲染插件,决定数据如何被渲染。type为插件名(如fill填充、line线、water水面、lit光照渲染),dataConfig为数据配置,其中type决定渲染的数据形态:fill面、line线、3d-extrusion将面按高度属性挤出为三维体。symbol:样式的具体参数,例如填充色polygonFill、线宽lineWidth、材质material等。不同渲染插件的symbol参数不同。
样式的渲染插件与参数非常丰富,完整定义见 VectorTileLayer API。也可以使用 MapTalks IDE 以所见即所得的方式定制样式。
样式随缩放级别变化
symbol 中的数值参数支持按缩放级别渐变。例如道路线宽随缩放级别从 2 增加到 200:
json
{
"symbol": {
"lineColor": [1, 1, 1, 1],
"lineWidth": {
"type": "exponential",
"default": 2,
"stops": [
[14, 2],
[15, 4],
[16, 10],
[17, 20],
[18, 50],
[20.7, 100],
[22, 200]
]
}
}
}三维场景中的矢量瓦片
矢量瓦片通过 GroupGLLayer 加入三维场景。因为瓦片中的矢量数据在浏览器端实时渲染,可以与其他三维图层(gltf 模型、3dtiles 等)无缝叠加,也可以结合场景配置(光照、环境、阴影)获得更真实的三维效果。一个完整的示例:
js
import { Map } from "maptalks";
import { GroupGLLayer, VectorTileLayer } from "@maptalks/gl-layers";
import "maptalks/dist/maptalks.css";
const map = new Map("map", {
center: [-74.01493663, 40.705559],
zoom: 17.8,
pitch: 43.2,
bearing: 57.1,
lights: {
directional: { direction: [0.5, 0, -1], color: [1, 1, 1] },
ambient: { color: [1, 1, 1] },
},
});
const vt = new VectorTileLayer("vt", {
urlTemplate: "https://tiles.maptalks.com/test/{z}/{x}/{y}.mvt",
style: [
/* 样式数组,见上文 */
],
});
const groupLayer = new GroupGLLayer("gl", [vt], {
sceneConfig: {
environment: { enable: true, mode: 1, level: 0, brightness: 0.489 },
ground: {
enable: true,
renderPlugin: { type: "fill" },
symbol: { polygonFill: [0.8, 0.8, 0.8, 1] },
},
},
}).addTo(map);