В Mapbox GL JS фильтрация объектов реализуется на уровне слоёв и основана на выражениях (filter expressions), которые вычисляются для каждого фиче-объекта источника данных. Фильтр определяет, будет ли объект отображён в конкретном слое в зависимости от его свойств, геометрии и контекста отображения.
Фильтрация задаётся через свойство filter в описании
слоя и поддерживается как в стиле при инициализации карты, так и
динамически через метод setFilter.
Базовая структура фильтра:
{
id: 'cities-layer',
type: 'circle',
source: 'cities',
'source-layer': 'cities-data',
filter: ['==', ['get', 'type'], 'capital']
}
Здесь выражение означает: отображать только те объекты, у которых
свойство type равно capital.
Для работы с атрибутами feature используется оператор
get:
['get', 'property_name']
Пример фильтрации по числовому свойству:
filter: ['>', ['get', 'population'], 1000000]
Такой фильтр пропускает только объекты с населением больше миллиона.
Свойства могут быть строковыми, числовыми, булевыми и использоваться в логических выражениях без предварительного преобразования.
Поддерживается набор базовых операторов сравнения:
['==', ['get', 'category'], 'park']
['!=', ['get', 'status'], 'closed']
['>', ['get', 'rating'], 4.5]
['>=', ['get', 'area'], 50]
['<', ['get', 'depth'], 100]
['<=', ['get', 'level'], 10]
Эти выражения вычисляются для каждого объекта независимо.
Фильтрация может включать сложные условия через логические операторы.
filter: [
'all',
['==', ['get', 'type'], 'restaurant'],
['>', ['get', 'rating'], 4]
]
Объект проходит фильтр только при выполнении всех условий.
filter: [
'any',
['==', ['get', 'type'], 'cafe'],
['==', ['get', 'type'], 'bar']
]
filter: [
'!',
['==', ['get', 'status'], 'inactive']
]
Для работы с неполными данными используется оператор
has:
filter: ['has', 'name']
Противоположная проверка:
filter: ['!has', 'temporary']
Это важно при работе с источниками, где часть атрибутов может отсутствовать.
Если свойство содержит массив, используется оператор
in:
filter: [
'in',
'category',
'park',
'forest',
'reserve'
]
Также можно проверять наличие значения внутри массива:
filter: ['in', 'tag', ['get', 'tags']]
Для сложной логики используется case:
filter: [
'case',
['>', ['get', 'population'], 1000000],
true,
false
]
В фильтрах это используется реже, но позволяет формировать вычисляемые условия.
Фильтрация может учитывать тип объекта:
filter: ['==', ['geometry-type'], 'Point']
Поддерживаются значения:
PointLineStringPolygonПример исключения полигонов:
filter: ['!=', ['geometry-type'], 'Polygon']
Реальные сценарии часто используют вложенные выражения:
filter: [
'all',
['==', ['get', 'type'], 'restaurant'],
['any',
['>', ['get', 'rating'], 4.5],
['==', ['get', 'featured'], true]
],
['!', ['==', ['get', 'status'], 'closed']]
]
Такая конструкция реализует многокритериальный отбор объектов.
Mapbox GL JS позволяет изменять фильтры после инициализации карты без пересоздания слоя.
Метод:
map.setFilter('cities-layer', ['>', ['get', 'population'], 500000]);
Удаление фильтра:
map.setFilter('cities-layer', null);
Это приводит к отображению всех объектов слоя без ограничений.
Фильтрация тесно связана с визуальным представлением данных. Часто
фильтр используется вместе с paint и layout
свойствами:
{
id: 'parks',
type: 'fill',
source: 'landuse',
filter: ['==', ['get', 'class'], 'park'],
paint: {
'fill-color': '#2ecc71',
'fill-opacity': 0.6
}
}
Здесь фильтр выделяет только парки, а стиль определяет их визуализацию.
Фильтры вычисляются на уровне рендеринга WebGL и оптимизируются движком. Однако сложные вложенные выражения с множеством логических операторов могут влиять на производительность при большом количестве объектов.
Наиболее эффективны:
==, >,
<any/allМенее эффективны:
caseПри работе с vector tiles фильтрация выполняется после загрузки тайлов, но до рендеринга слоя. Это позволяет уменьшить количество отрисовываемых объектов без изменения исходного набора данных.
{
id: 'buildings',
type: 'fill-extrusion',
source: 'composite',
'source-layer': 'building',
filter: ['>=', ['get', 'height'], 20]
}
Фильтры часто изменяются в ответ на действия интерфейса:
map.on('click', (e) => {
const category = e.features[0].properties.category;
map.setFilter('highlight-layer', [
'==',
['get', 'category'],
category
]);
});
Таким образом создаются сценарии динамического выделения объектов по их свойствам.
Система фильтров в Mapbox GL JS имеет ряд ограничений:
Эти ограничения обеспечивают предсказуемость и высокую производительность отображения картографических данных.