vector-tile
本文回答:矢量瓦片(MVT)叠加 —— 第三方 MVT 服务、自建 MVT 服务、vjmap CAD 矢量瓦片。
一、什么是矢量瓦片
瓦片里存的是几何 + 属性(protobuf 格式),前端按样式实时绘制。
优点:
- 文件小、清晰(矢量可任意放大)
- 支持客户端高亮 / 条件染色
- 可 hover / click 单个要素
缺点:
- 前端渲染成本高
- 部分老设备卡顿
二、第三方矢量瓦片(国际服务)
map.addSource("mb-streets", {
type: "vector",
tiles: ["https://服务地址/{z}/{x}/{y}.pbf"]
});
map.addLayer({
id: "buildings",
type: "fill",
source: "mb-streets",
"source-layer": "building", // MVT 里的 layer 名
paint: { "fill-color": "#888" }
});
注意:矢量 source 必须配合 source-layer 使用。
三、自建 MVT 服务(tegola / martin / geoserver)
map.addSource("my-mvt", {
type: "vector",
tiles: ["https://host/mvt/{z}/{x}/{y}.mvt"],
minzoom: 0, maxzoom: 14
});
map.addLayer({
id: "road-layer",
type: "line",
source: "my-mvt",
"source-layer": "road",
paint: { "line-color": "#f00", "line-width": 1 }
});
四、vjmap CAD 矢量瓦片
svc.vectorStyle() 返回一个完整 style(含 MVT source + 默认 layers):
const map = new vjmap.Map({
container: "map",
style: svc.vectorStyle(), // 矢量瓦片打开 CAD
center: prj.toLngLat(center),
zoom: 2
});
对应底层为:
map.addSource("cad", {
type: "vector",
tiles: [`${base}/map/tile/${mapid}/{version}/{stylename}/{z}/{x}/{y}.mvt?token=...`]
});
五、矢量瓦片互动
// hover 高亮(⚠️ 签名是 (cb?, prefix?),不收 svc——与 enableLayerClickHighlight 区分)
map.enableVectorLayerHoverHighlight((eventName, feature, layer, event) => {
console.log('hover:', feature?.properties);
});
// 点击高亮(这个才收 svc,cb 签名是 (res, event),res 为 pointQueryFeature 结果):
// map.enableLayerClickHighlight(svc, (res, event) => { ... });
// 手写 hover
map.on("mousemove", "road-layer", e => {
const f = e.features[0];
map.setFeatureState({ source: "my-mvt", sourceLayer: "road", id: f.id }, { hover: true });
});
六、数据驱动样式
矢量瓦片的强项:
map.addLayer({
id: "pop",
type: "circle",
source: "my-mvt",
"source-layer": "city",
paint: {
"circle-radius": [
"interpolate", ["linear"], ["get", "population"],
0, 2,
1000000, 10,
10000000, 30
],
"circle-color": ["interpolate", ["linear"], ["get", "population"],
0, "#0f0",
1000000, "#ff0",
10000000, "#f00"
]
}
});
七、与栅格瓦片共存
可同时叠 raster 底图 + 矢量业务层:
// 底:OSM raster
map.addSource("osm", { type: "raster", tiles: [...] });
map.addLayer({ id: "osm", type: "raster", source: "osm" });
// 叠:自己的 MVT 业务线
map.addSource("biz", { type: "vector", tiles: [...] });
map.addLayer({ id: "biz-line", type: "line", source: "biz", "source-layer": "route", paint: { "line-color": "#06f" } });
八、常见坑
- 漏
source-layer→ 图层空白。source-layer= MVT 内部 layer 名(不是 source ID)。 minzoom/maxzoom设置不当 → 低 zoom 瓦片也被请求,网络慢;限定 maxzoom <= 14 + overzoom 渲染更佳。- 自建服务 worker 跨源 → vjmap 用 Web Worker 解析 MVT,服务端需 CORS 头。
- 手机端卡:大 MVT(>1MB/tile)在低端安卓卡顿;减少 layer 数或降 maxzoom。