Фильтрация в MapLibre GL JS строится вокруг выражений (expressions) и
параметра filter, который применяется к слоям карты. Этот
механизм определяет, какие объекты из источников данных будут
визуализированы или скрыты на основе их свойств, масштаба, состояния или
логики пользовательского интерфейса.
Каждый слой в стиле MapLibre GL JS может содержать поле
filter, которое представляет собой выражение в формате
JSON-массива. Это выражение проверяется для каждой геометрии,
поступающей из источника (vector tile или GeoJSON).
Простейшая форма фильтра:
map.addLayer({
id: 'cities',
type: 'circle',
source: 'points',
paint: {
'circle-radius': 6,
'circle-color': '#1978c8'
},
filter: ['==', ['get', 'type'], 'city']
});
Здесь отображаются только те объекты, у которых свойство
type равно "city".
Фильтрацию слоя можно изменять динамически без пересоздания слоя. Для
этого используется метод setFilter.
map.setFilter('cities', ['==', ['get', 'type'], 'town']);
При вызове:
Сброс фильтра:
map.setFilter('cities', null);
MapLibre GL JS использует выражения, схожие с Mapbox Style Specification. Основные операторы:
['==', value1, value2]
['!=', value1, value2]
['>', value1, value2]
['>=', value1, value2]
['<', value1, value2]
['<=', value1, value2]
Пример:
filter: ['>=', ['get', 'population'], 100000]
['all',
['==', ['get', 'type'], 'city'],
['>=', ['get', 'population'], 500000]
]
['any',
['==', ['get', 'type'], 'city'],
['==', ['get', 'type'], 'capital']
]
['!', ['==', ['get', 'status'], 'inactive']]
['in', 'capital', ['get', 'tags']]
['has', 'population']
Часто используется комбинированная логика для сегментации данных:
map.setFilter('cities', [
'all',
['>=', ['get', 'population'], 100000],
['<=', ['get', 'population'], 1000000],
['==', ['get', 'country'], 'Kazakhstan']
]);
Такая конструкция позволяет ограничивать выборку по нескольким критериям одновременно.
Фильтры часто управляются интерфейсом пользователя, например чекбоксами или селекторами.
function applyFilters(type) {
if (type === 'all') {
map.setFilter('cities', null);
return;
}
map.setFilter('cities', [
'==',
['get', 'type'],
type
]);
}
При переключении значений фильтр слоя обновляется без перезагрузки источника данных.
Фильтрация может учитывать текущий zoom через выражение
zoom().
map.setFilter('cities', [
'>=',
['zoom'],
6
]);
Более сложный пример:
map.setFilter('cities', [
'any',
['<', ['zoom'], 5],
['>', ['get', 'population'], 500000]
]);
Feature-state позволяет хранить временные состояния объектов без изменения исходных данных.
map.setFeatureState(
{ source: 'points', id: 123 },
{ selected: true }
);
Фильтр:
map.setFilter('cities', [
'==',
['feature-state', 'selected'],
true
]);
Такой подход используется для интерактивного выделения объектов.
Фильтр слоя влияет на рендеринг, тогда как
queryRenderedFeatures используется для запроса уже
отрисованных объектов.
const features = map.queryRenderedFeatures({
layers: ['cities'],
filter: ['>', ['get', 'population'], 100000]
});
Однако важно различать:
filter — управляет отображением слояqueryRenderedFeatures — выбирает уже отрисованные
элементыФильтры в MapLibre GL JS вычисляются для каждой фичи в GPU-ускоренном пайплайне, но сложные выражения могут влиять на производительность.
Факторы, влияющие на скорость:
any/allin на больших массивахsetFilterРекомендуется:
map.setFilter('places', [
'==',
['get', 'category'],
'restaurant'
]);
map.setFilter('places', [
'in',
['get', 'category'],
'restaurant',
'cafe',
'bar'
]);
const filters = {
traffic: ['==', ['get', 'type'], 'traffic'],
transit: ['==', ['get', 'type'], 'transit']
};
map.setFilter('transport', filters['traffic']);
map.setFilter('points', [
'all',
['any',
['==', ['get', 'status'], 'active'],
['==', ['get', 'status'], 'pending']
],
['>=', ['get', 'rating'], 4],
['!', ['==', ['get', 'archived'], true]]
]);
При использовании GeoJSON фильтрация происходит на уровне слоя, но данные остаются в источнике. Это означает:
Фильтрация часто используется вместе с динамическими стилями:
map.setPaintProperty('cities', 'circle-color', [
'case',
['==', ['get', 'type'], 'capital'],
'#ff0000',
'#1978c8'
]);
Таким образом фильтр определяет видимость, а стили — визуальное представление.
Фильтрация в MapLibre GL JS формирует основу интерактивной работы с картографическими данными:
filtersetFilter