В MapLibre GL JS механизм фильтрации применяется на уровне слоёв и
позволяет отображать только те объекты из источников данных, которые
соответствуют заданным условиям. Фильтр описывается через выражения
(expressions) и задаётся в свойстве filter слоя.
Фильтрация тесно связана с моделью данных GeoJSON и векторных тайлов,
где каждый объект содержит набор свойств (properties).
Именно эти свойства становятся основой для логических условий
отображения.
Фильтр задаётся как массив, где первый элемент — оператор, а последующие — аргументы:
map.addLayer({
id: 'cities-layer',
type: 'circle',
source: 'cities',
paint: {
'circle-radius': 6,
'circle-color': '#2b8cbe'
},
filter: ['==', ['get', 'type'], 'city']
});
В данном примере отображаются только объекты, у которых свойство
type равно "city".
Ключевые элементы:
['get', 'type'] — извлечение свойства объекта'==' — оператор сравнения'city' — значение для сравненияФильтрация в MapLibre GL JS опирается на выражения, аналогичные Mapbox Style Specification.
filter: ['==', ['get', 'class'], 'primary']
Отображает объекты с class = primary.
filter: ['!=', ['get', 'class'], 'secondary']
Исключает объекты с class = secondary.
filter: ['>', ['get', 'population'], 1000000]
Показывает города с населением больше 1 млн.
filter: ['>=', ['get', 'rank'], 10]
Включает объекты с рангом 10 и выше.
filter: ['<', ['get', 'elevation'], 500]
Фильтрация объектов по высоте.
filter: ['<=', ['get', 'score'], 50]
Оператор has позволяет отбирать объекты, у которых
существует указанное свойство.
filter: ['has', 'name']
Используется для исключения объектов без заданного атрибута.
Обратная логика:
filter: ['!', ['has', 'name']]
Отбирает объекты без свойства name.
inИспользуется для проверки принадлежности значения одному из нескольких вариантов.
filter: ['in', ['get', 'type'], 'city', 'town', 'village']
Альтернативная форма:
filter: ['in', 'city', ['get', 'type']]
Фильтрация часто требует комбинирования условий.
all)filter: [
'all',
['==', ['get', 'type'], 'city'],
['>', ['get', 'population'], 500000]
]
Отображает только крупные города.
any)filter: [
'any',
['==', ['get', 'capital'], true],
['>', ['get', 'population'], 1000000]
]
Объекты, которые являются столицами или имеют большую численность населения.
none)filter: [
'none',
['==', ['get', 'status'], 'inactive']
]
Исключение всех неактивных объектов.
Фильтры допускают глубокую композицию логических выражений.
filter: [
'all',
['any',
['==', ['get', 'type'], 'city'],
['==', ['get', 'type'], 'town']
],
['>=', ['get', 'population'], 100000],
['!=', ['get', 'status'], 'deprecated']
]
Логика:
deprecatedДля работы со строками используются операторы:
== и точные совпаденияfilter: ['==', ['get', 'country'], 'Kazakhstan']
!= и исключение
значенийfilter: ['!=', ['get', 'region'], 'excluded-region']
match
— сопоставление с несколькими значениямиfilter: [
'match',
['get', 'type'],
['city', 'town', 'village'],
true,
false
]
Если type входит в список — true, иначе
false.
Часто используется ограничение диапазона значений:
filter: [
'all',
['>=', ['get', 'population'], 10000],
['<', ['get', 'population'], 50000]
]
Отбор объектов среднего размера.
Фильтр слоя может изменяться после создания карты:
map.setFilter('cities-layer', [
'>', ['get', 'population'], 100000
]);
Сброс фильтра:
map.setFilter('cities-layer', null);
Удаление фильтра возвращает отображение всех объектов слоя.
Хотя напрямую масштаб не является свойством объектов, его можно учитывать через состояние карты:
map.on('zoom', () => {
const zoom = map.getZoom();
if (zoom > 10) {
map.setFilter('cities-layer', ['>=', ['get', 'population'], 50000]);
} else {
map.setFilter('cities-layer', ['>=', ['get', 'population'], 500000]);
}
});
Таким образом достигается адаптивная детализация данных.
Фильтры работают с различными типами слоёв:
circle — точкиline — линииfill — полигоныsymbol — подписи и иконкиПример для линий:
map.addLayer({
id: 'roads',
type: 'line',
source: 'transport',
paint: {
'line-color': '#ff6600',
'line-width': 2
},
filter: ['==', ['get', 'highway'], 'primary']
});
Часто используется разделение по типам геометрии или категории объектов:
filter: ['==', ['geometry-type'], 'Polygon']
или
filter: ['==', ['geometry-type'], 'Point']
Это позволяет разделять визуализацию разных типов геометрий из одного источника.
Фильтры выполняются на уровне рендеринга и оптимизированы для работы с большими наборами данных, однако сложные вложенные выражения могут увеличивать нагрузку.
Факторы влияния:
all / anysetFilterРекомендуется:
Фильтрация часто используется совместно с выражениями стилей
(paint, layout), создавая многослойную
визуализацию одного источника.
map.addLayer({
id: 'population-based-cities',
type: 'circle',
source: 'cities',
paint: {
'circle-radius': [
'interpolate',
['linear'],
['get', 'population'],
1000, 3,
1000000, 10
],
'circle-color': [
'case',
['>', ['get', 'population'], 1000000],
'#e31a1c',
'#3182bd'
]
},
filter: ['>=', ['get', 'population'], 1000]
});
Здесь фильтр задаёт базовый диапазон объектов, а стиль дополнительно уточняет визуальное представление.
Один источник данных часто разбивается на несколько слоёв:
map.addLayer({
id: 'cities-large',
type: 'circle',
source: 'cities',
filter: ['>', ['get', 'population'], 1000000]
});
map.addLayer({
id: 'cities-medium',
type: 'circle',
source: 'cities',
filter: [
'all',
['<=', ['get', 'population'], 1000000],
['>', ['get', 'population'], 100000]
]
});
Такой подход позволяет создавать иерархическую визуализацию без изменения исходных данных.