📌 学习目标
- 掌握用全局状态过滤图层符号的实现方法
- 理解相关API的使用
- 能够独立完成类似功能开发
🎯 核心概念
使用全局状态过滤图层符号。
💻 完 整 代 码
<!DOCTYPE html>
<html lang='en'>
<head>
<title>Filter layer symbols using global state</title>
<meta property="og:description" content="使用 setGlobalStateProperty() 根据用户输入过滤图层符号。" />
<meta property="og:created" content="2006-06-25" />
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css' />
<script src='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script>
<style>
body {
margin: 0;
padding: 0;
}
html,
body,
#map {
height: 100%;
}
fieldset {
position: absolute;
top: 10px;
left: 10px;
background-color: white;
padding: 10px;
}
</style>
</head>
<body>
<div id='map'></div>
<fieldset>
Filter by type
<select name="type">
<option value="" selected>All</option>
<option value="lift">Aerial lift</option>
<option value="railway">Cable railway</option>
</select>
</fieldset>
</body>
<script>
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [9.0679, 45.8822],
zoom: 9
});
map.on('load', () => {
map.addSource('railways_and_lifts', {
type: 'geojson',
data: 'https://maplibre.org/maplibre-gl-js/docs/assets/funicolares-and-funivias-como.json'
});
map.addLayer({
id: 'railways_and_lifts_labels',
type: 'symbol',
source: 'railways_and_lifts',
layout: {
'text-field': '{name}',
'text-font': ['Open Sans Semibold'],
'text-offset': [0, 1],
'text-anchor': 'top'
},
paint: {
'text-color': '#000000',
'text-halo-color': '#ffffff',
'text-halo-width': 2
},
filter: [
'case',
['==', ['to-string', ['global-state', 'type']], ''],
true,
['==', ['get', 'type'], ['global-state', 'type']]
]
});
map.addLayer({
type: 'circle',
id: 'railways_and_lifts_points',
source: 'railways_and_lifts',
paint: {
'circle-radius': 5,
'circle-color': '#000000',
},
filter: [
'case',
['==', ['to-string', ['global-state', 'type']], ''],
true,
['==', ['get', 'type'], ['global-state', 'type']]
]
});
const select = document.querySelector('select[name="type"]');
map.setGlobalStateProperty('type', select.value);
select.addEventListener('change', (e) => {
const value = e.target.value;
map.setGlobalStateProperty('type', value);
});
});
</script>
</html>
🔍 代码解析
1. 初始化地图
使用 new maplibregl.Map() 创建地图实例,配置了意大利科莫湖区域,展示索道和缆车数据。
2. 关键配置项
- setGlobalStateProperty(): 设置全局状态属性,可被所有图层的表达式访问
- global-state表达式: 在filter中读取全局状态值
- case表达式: 根据全局状态值动态过滤图层内容
⚙️ 参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| setGlobalStateProperty(key, value) | method | - | 设置全局状态属性 |
| global-state | expression | 是 | 在表达式中读取全局状态值 |
| to-string | expression | 是 | 将值转换为字符串进行比较 |
| case | expression | 是 | 条件分支表达式 |
🎨 效果说明

运行代码后,地图显示意大利科莫湖区域的索道和缆车位置。页面顶部有一个下拉选择框,用户可以选择:
- All: 显示所有类型的索道和缆车
- Aerial lift: 只显示架空索道
- Cable railway: 只显示缆索铁路
选择不同选项时,地图会实时更新显示的图层内容,无需重新加载数据。
💡 常 见 问 题
Q1: 全局状态没有生效怎么办?
A: 检查以下几点:
- 确认使用
map.setGlobalStateProperty()设置了全局状态 - 确认在filter表达式中正确使用
['global-state', 'key'] - 检查全局状态的键名是否一致
Q2: 全局状态支持哪些数据类型?
A: 全局状态支持字符串、数字、布尔值等基本类型:
map.setGlobalStateProperty('type', 'lift'); // 字符串
map.setGlobalStateProperty('zoom', 10); // 数字
map.setGlobalStateProperty('enabled', true); // 布尔值
Q3: 如何清除全局状态属性?
A: 使用 deleteGlobalStateProperty() 方法:
map.deleteGlobalStateProperty('type');
📝 练习任务
- 基础练习:添加更多过滤选项,如按名称过滤
- 进阶挑战:创建多个过滤条件的组合筛选功能
- 拓展思考:如何实现全局状态的持久化存储?
- 综合实践:创建一个完整的图层过滤面板,支持多条件筛选
🌟 最佳实践
- 状态管理: 使用全局状态集中管理跨图层的共享配置
- 性能优化: 全局状态变化会触发图层重新渲染,避免频繁更新
- 默认值处理: 在case表达式中提供默认分支处理未设置状态的情况
- 类型转换: 使用to-string/to-number确保类型一致性
- 事件监听: 结合事件监听器实现响应式UI交互
🔗 延伸阅读
-
[下一课预告]:将继续学习地图图层的基础知识
530

被折叠的 条评论
为什么被折叠?



