map-sources
本文回答:vjmap 的常用数据源(
vector/raster/geojson/image/video)用法与注意事项。
一、总览
type = "vector" | "raster" | "geojson" | "image" | "video"
SourceSpecification联合类型其实还有第 6 个成员raster-dem(DEM 地形源,配合map.setTerrain()使用),仅做地形场景时才需要,日常五类即本节内容。
每个 source 有唯一 id,不能重复。vjmap.Map 提供标准的 addSource / getSource / removeSource 接口。
二、vector(矢量瓦片)
map.addSource("cad-vec", {
type: "vector",
// 形如 {服务地址}map/tile/{mapid}/{version}/{layer}/{z}/{x}/{y}.mvt?tag={fileid}&token=xxx
// layer 为样式图层名(默认 "main");tag 为 fileid(缓存标识,可省略)
tiles: ["https://host/api/v1/map/tile/{mapid}/{version}/main/{z}/{x}/{y}.mvt?token=xxx"]
});
CAD 的几何渲染模式支持自带矢量瓦片:
const { "vector-source": cadSrc } = svc.vectorStyle().sources; // 源键为 `${prefix}-source`,prefix 缺省 "vector"
map.addSource("cad", cadSrc);
// 或直接 style: svc.vectorStyle()
配合 map.enableVectorLayerHoverHighlight 做客户端高亮。
三、raster(栅格瓦片)
map.addSource("gaode", {
type: "raster",
tileSize: 256, // 默认 512
tiles: [tileUrl]
});
map.addLayer({ id: "gaode-l", type: "raster", source: "gaode" });
tileSize 对互联网地图一般 256;vjmap CAD 栅格(svc.rasterStyle())也是 256。
四、geojson
最常用的"业务数据图层"源。
map.addSource("points", {
type: "geojson",
data: { type: "FeatureCollection", features: [] }
});
// 动态更新
map.getSource("points").setData(newFeatureCollection);
支持加载 URL(返回 GeoJSON):
map.addSource("markers", {
type: "geojson",
data: "./data/points.geojson"
});
聚合(cluster)
map.addSource("pts", {
type: "geojson",
data,
cluster: true,
clusterRadius: 50,
clusterMaxZoom: 14
});
详见 marker/cluster。
五、image(覆盖图像)
map.addSource("flash", {
type: "image",
url: "./flash.gif",
coordinates: [
[lngLT, latLT], [lngRT, latRT],
[lngRB, latRB], [lngLB, latLB]
]
});
map.addLayer({ id: "flash-l", type: "raster", source: "flash" });
// 更新位置
map.getSource("flash").setCoordinates([...]);
场景:把一张 PNG/JPG/GIF 定位到特定经纬度范围(批注、缩略图、动画)。
六、video(视频)
map.addSource("vid", {
type: "video",
urls: ["https://host/a.mp4"],
coordinates: [[lngLT,latLT],[lngRT,latRT],[lngRB,latRB],[lngLB,latLB]]
});
map.addLayer({ id: "vid-l", type: "raster", source: "vid" });
七、常用操作
map.getSource("pts"); // 取 source(返回对象或 undefined)
!!map.getSource("pts"); // 判断是否存在(无 hasSource 方法)
map.removeSource("pts"); // 注意:先移除用到它的 layer 才能 removeSource
map.removeSourceEx("pts"); // vjmap 扩展:同时移除相关 layer
八、设计建议
- 一个 source 对应一批同类数据(比如所有 Marker 点共用一个 geojson source),避免创建成百上千个 source。
- setData 不要每帧调用:大 FeatureCollection 会触发 worker 解析,几十 ms。
- 一个 source 可以有多个 layer(比如同一个 points 加 circle、symbol、text 三个 layer)。
- 互联网底图放最底,
moveLayer(id, firstLayerId)。
九、常见坑
- removeSource 前没 removeLayer → 报
Source "x" cannot be removed while layer "y" is using it.。注意:它不是同步抛异常,而是fire(error)事件后提前返回——try/catch捕不到,要map.on("error", ...)才能截获;且 source 实际没被删除(之后getSource仍返回对象)。先removeLayer再removeSource,或直接用removeSourceEx。 - geojson
data是 URL 但 404 → 前端看不到任何图层;检查 Network。 - image source 的
coordinates顺序错 → 图像变形倒置。顺序:左上 → 右上 → 右下 → 左下。 - vector source 的
source-layer名错:vector 图层定义需要source-layer;若是 svc.vectorStyle() 已经配好,手动添加时记得配。 GeoJSONSource/ImageSource/CanvasSource/VideoSource类虽在 d.ts 声明、运行时顶层全是undefined——不能用new vjmap.GeoJSONSource({data})。正确姿势就是本文档的map.addSource(id, spec对象);getSource返回内部源实例(type='geojson',带setData等方法)。