唯杰地图 logo唯杰地图
VJMAP
EN

expressions

vjmap/references/map-style/expressions.md 5.0 KB161 行
原文

本文回答:vjmap 样式表达式(get / case / match / interpolate / step / feature-state / zoom)实战。

一、表达式是什么

任何 paint / layout / filter 的值都可以写成表达式(一个 JSON 数组,第一个元素是操作符)。

// "line-width": 2
// 改为:按缩放级别变宽
"line-width": ["interpolate", ["linear"], ["zoom"], 10, 1, 16, 5]

二、常用操作

类别 典型
Lookup ["get", "name"], ["has", "color"], ["at", 0, arr], ["length", arr], ["properties"], ["id"], ["geometry-type"]
Feature-state ["feature-state", "hover"]
Decision ["case", cond1, val1, cond2, val2, defaultVal], ["match", input, val1, out1, val2, out2, default]
Ramps ["interpolate", ["linear"], ["zoom"], 0, a, 10, b], ["step", ["zoom"], a, 5, b, 10, c]
Comparison ["==", ..], ["!=", ..], [">", ..], ["<=", ..], ["in", ..]
Boolean ["all", a, b], ["any", a, b], ["!", cond]
Arithmetic ["+", a, b], ["-", a, b], ["*", a, b], ["/", a, b], ["%", a, b], ["^", a, b], ["abs", x], ["min", ...], ["max", ...]
Type ["to-string", x], ["to-number", x], ["to-boolean", x], ["to-color", x], ["typeof", x]
String ["concat", a, b], ["upcase", s], ["downcase", s]
Color ["rgb", r, g, b], ["rgba", r, g, b, a], ["to-color", "#f00"]
Let/Var ["let", "x", 1, ["+", ["var", "x"], 2]]

三、典型用法

按属性变色

"fill-color": ["get", "color"]

按属性分类

"fill-color": [
  "match", ["get", "type"],
  "road", "#0af",
  "building", "#f80",
  "park", "#8c0",
  "#aaa"                 // default
]

按 zoom 插值

"circle-radius": [
  "interpolate", ["linear"], ["zoom"],
  8,  2,
  14, 6,
  18, 12
]

按值插值(热力等级)

"fill-color": [
  "interpolate", ["linear"], ["get", "heat"],
  0,   "#00f",
  50,  "#0f0",
  100, "#f00"
]

step 分段

"line-color": [
  "step", ["zoom"],
  "#aaa",     // zoom < 10
  10, "#888", // 10 <= zoom < 14
  14, "#333"  // zoom >= 14
]

条件(hover 状态)

"fill-color": [
  "case",
  ["boolean", ["feature-state", "hover"], false], "#f00",
  ["get", "color"]
]

组合过滤 filter

filter: ["all",
  ["==", ["geometry-type"], "Polygon"],
  [">=", ["to-number", ["get", "h"]], 50]
]

四、feature-state 用法

feature-state 不是数据的属性,而是运行时附加的状态。

// feature 的 id 必须是整数或可以转整数的字符串
map.setFeatureState({ source: "states", id: 54 }, { hover: true });

// 样式中
"fill-opacity": [
  "case",
  ["boolean", ["feature-state", "hover"], false], 1,
  0.5
]

// 移除
map.removeFeatureState({ source: "states", id: 54 });

feature-state 只能用在 paint(支持数据驱动)的属性里。

五、zoom 与 properties 的差别

  • ["zoom"]:只能在 interpolate / step 的输入里;不能直接参与其他算术。违规写法(如 ["+", ["zoom"], 1] 直接给 line-width)不抛异常,而是走 map.on("error") 事件:layers.*.paint.*: "zoom" expression may only be used as input to...——静默失败,调试时记得挂 error 监听。
  • ["get", "name"]:任何地方都能用。
  • ["heatmap-density"]:只能在 heatmap-color 属性里。

六、样式规范约束

  • paint 随小数 zoom 插值(*-pattern、line-dasharray 例外,只按整数 zoom 求值)。
  • layout 多数按瓦片的整数 zoom 求值;但 text-size / icon-size 的 zoom 表达式会在小数 zoom 上插值(4.2→4.6 字号会连续变化)。

七、后端表达式(CAD 栅格样式)

CAD 栅格图渲染在后端,不是样式表达式,而是服务端表达式语法:

gOutColorRed := 255;   // 输出红色分量
gOutColorGreen := 0;
gOutColorBlue := 0;
gOutColorAlpha := 255;   // 透明度分量 0~255(不是 0~1,写 1.0 几乎全透明)

变量前缀:gIn* 是输入(层名、颜色、线型…),gOut* 是输出。详见 svrStyleVar / expr.md。

前端通过 map.updateStyle(svc, { expression: "..." }) 写入(内部 svc.cmdUpdateStyle + 刷新瓦片;单独调 svc.cmdUpdateStyle 地图不会刷新,还得 map.changeSourceTiles(svc.rasterTileUrl()))。

八、调试表达式

// 控制台会报错;开 Chrome DevTools
// 常用 console.log(JSON.stringify(style, null, 2)) 查看当前生效的样式

九、常见坑

  1. 类型错误:["==", ["get", "n"], 1] 里 n 如果是字符串会不等;显式 to-number。
  2. filter 中不支持 interpolate:只 paint/layout 支持 zoom 插值,filter 不行。
  3. feature-state 在 layout 不生效:只能用在 paint。
  4. id 不是整数 → feature-state 不生效;generateId: true 让 GeoJSON source 自动生成 id。