icon-symbol
本文回答:
vjmap.Symbol图标符号图层 —— iconImage / iconSize / iconOffset / 碰撞。
一、最小示例
await map.loadImageEx("pin", "/icons/pin.png");
const symbol = new vjmap.Symbol({
data: map.toLngLat(features),
iconImage: "pin",
iconSize: 1,
iconAnchor: "bottom",
iconAllowOverlap: true
});
symbol.addTo(map);
二、核心参数(图标)
| 参数 | 默认 | 说明 |
|---|---|---|
iconImage |
— | 图标名;需 sprite 或 loadImage |
iconSize |
1 | 缩放比例 |
iconRotate |
0 | 旋转角(度) |
iconAnchor |
"center" | 9 向 |
iconOffset |
[0,0] |
像素偏移 |
iconOpacity |
1 | 透明度 |
iconColor |
— | 只对 SDF 图标有效 |
iconHaloColor |
— | 光晕色 |
iconHaloWidth |
0 | 光晕宽度 |
iconAllowOverlap |
false | 是否允许重叠 |
iconIgnorePlacement |
false | 是否忽略位置冲突 |
iconRotationAlignment |
"auto" | map / viewport |
iconPitchAlignment |
"auto" | map / viewport |
iconPadding |
2 | 碰撞的像素间距 |
iconTextFit |
"none" | none / width / height / both |
iconTextFitPadding |
[0,0,0,0] |
text-fit 的内边距 |
三、加载图标
// Promise 式(vjmap 扩展)
await map.loadImageEx("pin", "/icons/pin.png");
await map.loadImageEx("star", "data:image/svg+xml;base64,...");
// SDF(可改色)
map.loadImage("/icons/pin.png", (err, img) => {
if (!err) map.addImage("pin-sdf", img, { sdf: true });
});
多图标批量:
const icons = { pin: "/a.png", star: "/b.png", dot: "/c.png" };
await Promise.all(Object.entries(icons).map(
([name, url]) => map.loadImageEx(name, url)
));
四、数据驱动图标
new vjmap.Symbol({
data,
iconImage: ["get", "icon"], // 按属性选图标
iconSize: ["interpolate", ["linear"], ["zoom"], 10, 0.5, 16, 1.5],
iconRotate: ["get", "bearing"]
});
五、旋转对齐 / 倾斜对齐
// 图标随地图旋转(道路指示最常用)
iconRotationAlignment: "map",
iconPitchAlignment: "map"
// 图标始终正对屏幕(默认)
iconRotationAlignment: "viewport",
iconPitchAlignment: "viewport"
六、碰撞与优先级
iconAllowOverlap: false:同层图标挤压时自动剔除;iconAllowOverlap: true:全部显示;symbolSortKey: ["get", "priority"]:小值优先显示。
七、图标 + 文字组合
new vjmap.Symbol({
data,
iconImage: "pin",
iconAnchor: "bottom",
textField: ["get", "name"],
textFont: ["Arial Unicode MS Regular"], // 官方示例用的 fontstack
textSize: 12,
textOffset: [0, 1],
textAnchor: "top",
textColor: "#000",
textHaloColor: "#fff",
textHaloWidth: 1
}).addTo(map);
八、可拉伸图标 icon-text-fit
让气泡图标自动适应文字宽度:
new vjmap.Symbol({
data,
iconImage: "bubble",
iconTextFit: "both",
iconTextFitPadding: [4, 8, 4, 8], // top/right/bottom/left
textField: ["get", "label"]
});
九、hover / click
symbol.clickLayer(e => alert(e.features[0].properties.name));
symbol.hoverPopup(f => `<b>${f.properties.name}</b>`);
symbol.hoverFeatureState();
十、更新
symbol.setData(newFc);
symbol.setIconImage(["get", "icon2"]);
symbol.setIconSize(1.5);
symbol.setProperty("iconOpacity", 0.5);
十一、常见坑
- 图标不显示 → sprite 里没这个名字;或
loadImage还没完成。 - iconColor 无效 → 必须 SDF 图标。
- 挤压看不见 →
iconAllowOverlap: true硬显示。 - 图标在旋转地图后歪 → 要用
iconRotationAlignment: "viewport"始终正对屏幕。 - 点击无响应 → hit-test 忽略了图标的边缘;扩
iconPadding。