首页 / MapLibre / API 文档
setFilter
先看结论
给图层换一个属性过滤器,只让符合条件的要素参与渲染,不需要重建数据源。
map.setFilter(layerId, filter) → this
filter 传 null 表示清除过滤,图层恢复显示全部要素。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
layerId | string | 目标图层 id |
filter | FilterSpecification | null | 过滤表达式,null 清除 |
表达式写法
推荐用表达式:第一个元素是操作符,后面是参数,属性用 ['get', '字段名'] 读取。
/* 只要等级为 primary 的道路 */
map.setFilter('roads', ['==', ['get', 'class'], 'primary']);
/* 人口大于 100 万且未隐藏 */
map.setFilter('cities', [
'all',
['>=', ['get', 'population'], 1000000],
['!', ['has', 'hidden']]
]);
/* 名称匹配前缀 */
map.setFilter('poi', ['==', ['slice', ['get', 'name'], 0, 2], '北京']);
旧式语法
旧写法把属性名直接放在数组里,仍然可用,但表达力有限,新代码不要再用。
map.setFilter('roads', ['==', 'class', 'primary']);
map.setFilter('polygons', ['in', 'kind', 'park', 'garden']);
常见操作符
| 操作符 | 含义 | 示例 |
|---|---|---|
== / != | 相等与不等 | ['==', ['get', 'type'], 'park'] |
< / <= / > / >= | 数值比较 | ['>', ['get', 'area'], 500] |
in | 属于集合 | ['in', ['get', 'level'], 'A', 'B'] |
has | 属性是否存在 | ['has', 'name'] |
all / any / none | 逻辑组合 | ['any', cond1, cond2] |
! | 取反 | ['!', ['has', 'hidden']] |
切换筛选
var current = 'all';
function showCategory(category) {
current = category;
if (category === 'all') {
map.setFilter('poi-circle', null);
return;
}
map.setFilter('poi-circle', ['==', ['get', 'category'], category]);
}
document.querySelectorAll('[data-category]').forEach(function (btn) {
btn.addEventListener('click', function () {
showCategory(btn.dataset.category);
});
});
代价
过滤器变化会重建图层的要素索引与绘制批次,大数据量下有明显停顿。
高频交互(悬停、逐帧动画)不要靠 setFilter 驱动,
改用 setFeatureState 配合 feature-state 表达式,
只改变单个要素的状态。
每次调用只影响一个图层。同一份数据挂了填充与描边两个图层时, 两个都要设置,否则会出现「填充筛掉了、边界还在」的现象。
表达式里不要用 $id 之外的特殊变量。
过滤阶段拿不到几何坐标,['get', ...] 只读属性。
需要按位置筛选,应在数据侧预先写入一个字段,或用 queryRenderedFeatures 做交互层过滤。
经纬志(2026)。《setFilter》。https://www.jingweizhi.com/maplibre/api/set-filter.html(访问日期 2026-11-03)。