sprite 里没有这个图标名,符号层直接不画
icon-image 写了一个名字,地图上什么都不出现,也没有任何报错。
现象
一个 symbol 图层,layout['icon-image'] = 'poi-restaurant'。
地图上该点位完全不渲染,既没有图标,也没有文字。
网络面板里 sprite.json 与 sprite.png 都返回 200。
打开 sprite.json 搜索 poi-restaurant,找不到该键。
原因
Mapbox 的图标不是图片 URL,而是 sprite 表里的名字。
sprite.json 记录每个图标的尺寸与位置,
sprite.png 是所有图标拼成的一张图。
引擎按名字查表,查不到时该符号被视为无法渲染,
整个符号(含文字)都被跳过,且不产生控制台错误。
名字区分大小写,也区分连字符与下划线:poi_restaurant 与
poi-restaurant 是两个不同的键。
| 引用值 | sprite 中的键 | 结果 |
|---|---|---|
poi-restaurant | poi_restaurant | 不渲染 |
restaurant | restaurant | 正常 |
Restaurant | restaurant | 不渲染 |
排查过程
- 请求
sprite.json,搜索icon-image的实际值。 - 打印该图层
layout['icon-image'],注意是字符串还是表达式。 - 若用了
['get','icon'],检查属性值是否与键名完全一致。 - 确认 sprite 版本与样式里的
sprite路径一致,不要同时加载两份。
const sprite = await fetch('/sprite.json').then(r => r.json());
console.log(Object.keys(sprite)); // ['restaurant', 'hospital', 'parking', ...]
console.log(map.getLayer('poi').layout['icon-image']); // 'poi-restaurant'
console.log('poi-restaurant' in sprite); // false
解决方案
图标名与 sprite 键严格对齐。数据里存图标名时,用白名单校验, 不匹配的退回通用图标。
// 生成 sprite(spritezero)
spritezero sprite ./icons
# 生成 sprite.json / sprite.png,键名取自文件名(不含扩展名)
# icons/restaurant.svg -> 键 'restaurant'
// 图标名做一次白名单映射,避免脏数据导致整层符号消失
const ICONS = new Set(['restaurant', 'hospital', 'parking', 'school']);
fc.features.forEach(f => {
const raw = f.properties.icon;
f.properties.icon = ICONS.has(raw) ? raw : 'marker-default';
});
map.addLayer({
id: 'poi',
type: 'symbol',
source: 'poi',
layout: {
'icon-image': ['get', 'icon'],
'icon-size': 1,
'icon-allow-overlap': true
}
});
缺图标时不要依赖报错。Mapbox GL 对 sprite 缺失是静默的,
上线前用脚本把数据里的 icon 值与 sprite.json 的键做一次差集检查。
验证
数据中的所有 icon 值都能在 sprite.json 中找到;
地图上每个点位都显示图标,queryRenderedFeatures 数量与数据一致。
const missing = [...new Set(fc.features.map(f => f.properties.icon))]
.filter(k => !(k in sprite));
console.assert(missing.length === 0, '缺图标:' + missing.join(','));
const r = map.queryRenderedFeatures({ layers: ['poi'] });
console.assert(r.length === fc.features.length, '仍有符号未渲染');
适用版本
| 组件 | 版本 | 说明 |
|---|---|---|
| Mapbox GL JS | 2.15 / 3.x | sprite 缺键时静默跳过整个符号 |
| MapLibre GL JS | 3.x / 4.x | 行为一致 |
| spritezero-cli | 1.3.0 | 按文件名生成键,区分大小写 |
经纬志(2026)。《sprite 里没有这个图标名,符号层直接不画》。https://www.jingweizhi.com/cookbook/sprite-icon-missing.html(访问日期 2026-11-03)。