经纬志
首页 / MapLibre / API 文档

setFilter

先看结论

给图层换一个属性过滤器,只让符合条件的要素参与渲染,不需要重建数据源。

最后验证 2026-11-03 · MapLibre GL JS 4.x · 更新 2026-10-29 · 引用本文
map.setFilter(layerId, filter) → this

filter 传 null 表示清除过滤,图层恢复显示全部要素。

参数

参数类型说明
layerIdstring目标图层 id
filterFilterSpecification | 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)。