样式表达式少了一个 dimension,整层要素都不显示
图层加上去了,图例也有,地图上却一个要素都没有,控制台只给了一条警告。
现象
控制台输出:
Error: layers.districts.paint.fill-color: Expected number but found string
in expression: ["get", "level"]
或者更隐蔽的一条:
Error: layers.districts.paint.fill-opacity: "level" is not a valid expression
两种情况下图层都没有任何要素被绘制,缩放、切换底图都无济于事,
只有把该图层 visibility 设为 none 才能让其它图层正常。
原因
Mapbox GL 的样式规范里,涉及要素属性的表达式必须写成数组形式
["get", "level"],不能直接写属性名 "level"。
纯色可以直接写字符串 "#ff0000",
但一旦进入表达式上下文,字符串会被当作字面量而不是属性名。
另一类错误是把 fill-color 与 fill-opacity 的类型混用:
fill-opacity 只接受数字,["get","name"] 返回字符串,
类型校验失败,整层被跳过。
排查过程
- 在控制台看
map.getStyle().layers,确认图层确实存在。 - 执行
map.getLayer('districts'),返回 undefined 说明 id 不匹配。 - 把 paint 表达式临时改成固定值,若要素出现,问题就在表达式。
- 用
["to-number", ["get","level"]]包一层,看是否恢复。
console.log(map.getStyle().layers.map(l => l.id));
// ['background', 'districts'] -> 图层存在
console.log(map.getLayer('districts')); // undefined 说明 id 写错
解决方案
按属性类型显式转换,不要指望引擎自动转型。
map.addLayer({
id: 'districts',
type: 'fill',
source: 'districts',
paint: {
// 数值属性:先 to-number 再分段
'fill-color': [
'interpolate', ['linear'], ['to-number', ['get', 'pop_density']],
0, '#e8f4ff',
5000, '#8ec4ff',
20000, '#1a6fd4'
],
// 字符串属性不能直接给 opacity
'fill-opacity': [
'case',
['==', ['get', 'level'], 'city'], 0.75,
0.45
]
}
});
表达式还可以在运行时验证,提前发现类型问题。
// 打开校验,错误会直接抛出而不是静默丢层
map.setPaintProperty('districts', 'fill-color', [
'match', ['get', 'level'],
'city', '#1a6fd4',
'county', '#8ec4ff',
'#cccccc'
]);
验证
控制台不再有 Expected number but found string;
map.queryRenderedFeatures() 能返回要素,
点击任意区块可以看到填充色随 pop_density 变化。
const f = map.queryRenderedFeatures({ layers: ['districts'] });
console.assert(f.length > 0, '图层仍无渲染要素');
适用版本
| 库 | 版本 | 说明 |
|---|---|---|
| Mapbox GL JS | 2.x / 3.x | 旧版 property 语法已移除 |
| MapLibre GL JS | 3.x / 4.x | 语法与 Mapbox GL 2.x 一致 |
| Mapbox 样式规范 | v8 | get 必须包在数组里 |
经纬志(2026)。《样式表达式少了一个 dimension,整层要素都不显示》。https://www.jingweizhi.com/cookbook/style-expression-missing-property.html(访问日期 2026-11-03)。