Фильтрация данных слоёв в MapLibre GL JS строится на выражениях, которые позволяют задавать условия выборки объектов на основе свойств их источников данных. При необходимости сложной логики несколько условий объединяются в единые логические конструкции, формируя многоуровневую систему отбора, работающую на стороне рендеринга карты.
Базовая фильтрация опирается на булевы операторы, которые интерпретируются движком рендеринга как выражения с возвращаемым значением true или false для каждого объекта слоя. Основные механизмы объединения:
Каждое условие в фильтре представляет собой массив или выражение, где первый элемент задаёт оператор, а последующие — аргументы.
Оператор all используется для объединения нескольких
условий, которые должны выполняться одновременно. Он формирует
логическое пересечение множества фильтров.
map.addLayer({
id: 'buildings',
type: 'fill',
source: 'cadastre',
'source-layer': 'objects',
filter: [
'all',
['==', ['get', 'type'], 'building'],
['>=', ['get', 'height'], 20],
['!=', ['get', 'status'], 'planned']
],
paint: {
'fill-color': '#4a90e2',
'fill-opacity': 0.6
}
});
В данном случае объект отображается только при одновременном выполнении всех условий: принадлежность к типу здания, минимальная высота и отсутствие статуса планирования.
Внутренняя интерпретация all эквивалентна
последовательной проверке логического И для всех вложенных
выражений.
Оператор any задаёт логическое объединение условий, при
котором достаточно выполнения хотя бы одного из них. Такой подход
применяется для расширения выборки по нескольким независимым
признакам.
filter: [
'any',
['==', ['get', 'landuse'], 'park'],
['==', ['get', 'leisure'], 'garden'],
['==', ['get', 'natural'], 'wood']
]
Логика выражения сводится к объединению нескольких категорий природных или рекреационных территорий в единый визуальный слой.
При обработке данных выполняется короткое замыкание: при первом истинном условии остальные не влияют на итоговый результат.
Оператор none применяется для исключения объектов,
соответствующих любому из перечисленных условий. Он формирует отрицание
объединённого набора.
filter: [
'none',
['==', ['get', 'access'], 'private'],
['==', ['get', 'disused'], true]
]
Такой подход позволяет строить фильтры исключения, когда слой отображает всё, кроме закрытых или неиспользуемых объектов.
Логические операторы могут вкладываться друг в друга, формируя древовидные структуры условий. Это позволяет реализовать сложные правила классификации объектов.
filter: [
'all',
[
'any',
['==', ['get', 'highway'], 'primary'],
['==', ['get', 'highway'], 'secondary']
],
[
'none',
['==', ['get', 'tunnel'], true]
],
['>=', ['get', 'lanes'], 2]
]
В данной конструкции выполняется следующая логика:
Вложенные конструкции обрабатываются рекурсивно, где каждый уровень возвращает булево значение, участвующее в следующем уровне вычислений.
Базовые операторы сравнения интегрируются в логические конструкции без ограничений по глубине. Наиболее часто используются:
Пример комплексной фильтрации по нескольким атрибутам:
filter: [
'any',
[
'all',
['==', ['get', 'type'], 'residential'],
['>=', ['get', 'floors'], 5]
],
[
'all',
['==', ['get', 'type'], 'commercial'],
['>=', ['get', 'area'], 1000]
]
]
Здесь объединены две группы условий, каждая из которых формирует собственный логический блок отбора.
При обращении к отсутствующим атрибутам через
['get', 'property'] возвращается null, что
влияет на результат сравнений. В логических выражениях это может
приводить к исключению объекта из выборки, если явно не предусмотрена
обработка null.
Пример защиты от отсутствующих значений:
filter: [
'all',
['has', 'height'],
['>=', ['get', 'height'], 10]
]
Оператор has обеспечивает проверку существования
свойства перед его использованием в числовом сравнении.
Глубоко вложенные выражения увеличивают стоимость вычислений на этапе рендеринга. Оптимизация достигается за счёт:
Перестановка условий внутри all и any не
влияет на результат, но может влиять на производительность из-за порядка
вычислений.
Фильтры часто используют выражения get, in,
match, что позволяет расширять логику до сопоставления со
списками значений и регулярными структурами.
filter: [
'all',
['in', ['get', 'class'], 'primary', 'secondary', 'tertiary'],
['match', ['get', 'surface'],
'asphalt', true,
'concrete', true,
false
]
]
Такая конструкция позволяет одновременно проверять принадлежность к множеству и соответствие типу покрытия.
Комбинирование фильтров используется для построения иерархической визуализации данных. Каждый уровень слоя может представлять отдельную категорию, уточняемую дополнительными условиями.
filter: [
'all',
['==', ['get', 'building'], true],
[
'any',
['==', ['get', 'use'], 'residential'],
['==', ['get', 'use'], 'apartments']
],
['!=', ['get', 'height'], null]
]
Такой подход позволяет отделять базовую категорию объектов от уточняющих характеристик, не создавая избыточного количества слоёв.
Сложные исключающие конструкции часто строятся через комбинацию
none и дополнительных условий включения.
filter: [
'all',
[
'none',
['==', ['get', 'seasonal'], true],
['==', ['get', 'temporary'], true]
],
['>=', ['get', 'capacity'], 50]
]
В данном случае исключаются временные и сезонные объекты, при этом сохраняются только объекты с достаточной вместимостью.
MapLibre GL JS выполняет нестрогое приведение типов в некоторых
операциях сравнения. Это может приводить к различиям между числовыми и
строковыми представлениями значений. Для предсказуемого результата
используются явные преобразования через выражения to-number
или to-string внутри фильтров.
filter: [
'>=',
['to-number', ['get', 'rank']],
10
]
При изменении состояния карты фильтры могут пересобираться программно. Комбинированные выражения позволяют сохранять структуру логики при динамическом обновлении параметров.
const baseFilter = [
'all',
['==', ['get', 'active'], true]
];
const extendedFilter = [
...baseFilter,
['>=', ['get', 'score'], 80]
];
map.setFilter('points-layer', extendedFilter);
Такой подход позволяет масштабировать фильтрационную логику без разрушения исходной структуры условий.