Combining фильтры

Фильтрация данных слоёв в 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);

Такой подход позволяет масштабировать фильтрационную логику без разрушения исходной структуры условий.