expression
本文回答:用表达式驱动 Symbol —— icon / color / size / filter。
一、数据驱动 iconImage
按属性选图标:
new vjmap.Symbol({
data,
iconImage: ["get", "icon"] // properties.icon = "car" / "bus" / ...
});
动态拼名:
iconImage: ["concat", "icon-", ["get", "type"]] // icon-car
按 fallback 用 coalesce:
iconImage: [
"coalesce",
["image", ["concat", "icon-", ["get", "type"]]], // 不能写 "icon-" + [...](JS 字符串拼接,得到 "icon-get,type")
["image", "icon-default"]
]
二、按 zoom 变大小
iconSize: [
"interpolate", ["linear"], ["zoom"],
10, 0.5,
14, 1.0,
18, 2.0
]
三、按属性变色(SDF)
iconImage: "pin-sdf",
iconColor: [
"match", ["get", "status"],
"ok", "#0f0",
"warn", "#ff0",
"err", "#f00",
"#888"
]
四、hover feature-state 变色
const symbol = new vjmap.Symbol({
data,
iconImage: "pin-sdf",
iconColor: [
"case",
["boolean", ["feature-state", "hover"], false], "#ff0",
"#0af"
],
isHoverFeatureState: true // vjmap 扩展,自动 setFeatureState
});
symbol.addTo(map);
要求要素有非 0 的 id。封装类不透传 generateId(且 generateId 从 0 编号,而 hoverFeatureState 忽略 id 0):FeatureCollection 须自带非 0 id;或传 [{points, properties}] 形式(自动 id = 序号 + 1);或先自建源(promoteId)再传 sourceId:
map.addGeoJSONSource("src", data, { promoteId: "code" }); // properties.code 非 0
new vjmap.Symbol({ sourceId: "src", iconImage: "pin-sdf", isHoverFeatureState: true }).addTo(map);
五、按属性组合文字
textField: [
"format",
["get", "name"], { "font-scale": 1.2, "text-color": "#000" },
" — ", {},
["to-string", ["get", "count"]], { "font-scale": 0.9, "text-color": "#888" }
]
六、filter 过滤
new vjmap.Symbol({
data,
iconImage: "pin",
filter: ["all",
[">=", ["to-number", ["get", "level"]], 3],
["==", ["get", "country"], "CN"]
]
});
运行时:
symbol.setFilter(["==", ["get", "type"], "POI"]);
七、symbolSortKey 控制绘制顺序
new vjmap.Symbol({
data,
symbolSortKey: ["-", 0, ["get", "priority"]], // key 越小越先放置:priority 大的碰撞时优先保留;允许重叠时 key 大的画在上面(此时 priority 大的反而在下)
textField: ["get", "name"]
});
八、textVariableAnchor 智能避让
new vjmap.Symbol({
data,
textField: ["get", "name"],
textVariableAnchor: ["top", "bottom", "left", "right"],
textJustify: "auto",
textRadialOffset: 0.8
});
渲染引擎会根据碰撞自动换方向。
九、动态改属性
symbol.setIconColor(["get", "newColor"]);
symbol.setTextSize(16);
symbol.setIconSize([
"interpolate", ["linear"], ["zoom"], 10, 0.3, 16, 1.5
]);
十、常见坑
- iconImage 不能写
["sprite", ...]:用["image", name]作 coalesce 备选;或直接字符串 /["get"]。 - 字符串与数字比较 filter 失败 →
["to-number", ["get", "x"]]。 - feature-state 无 id 不生效 →
generateId: true。 - 表达式嵌套太深卡顿 → 预处理属性;layout 属性尽量少表达式。