Синтаксис выражений filter

Общая структура выражений фильтрации в Mapbox GL JS основана на декларативной системе выражений, где фильтр описывается как JSON-подобный массив. Такой подход исключает использование функций в классическом JavaScript-стиле и заменяет их композиционной схемой операторов.

Фильтр слоя задаётся в свойстве filter и всегда представляет собой выражение, начинающееся с логического оператора или оператора сравнения. Все элементы выражения строго типизированы и интерпретируются движком рендеринга карты.


Фильтр слоя имеет следующий общий вид:

filter: ["operator", argument1, argument2, ...]

Первый элемент массива — строка-оператор, определяющая тип логики. Последующие элементы — операнды, которые могут быть:

  • литеральными значениями;
  • выражениями ["get", "property"];
  • вложенными логическими конструкциями;
  • служебными выражениями (например, ["geometry-type"], ["id"]).

Получение значений свойств фичи

Центральный элемент фильтрации — доступ к атрибутам объекта:

["get", "property_name"]

Пример:

["get", "type"]

Это выражение возвращает значение свойства type текущего объекта слоя.

Также используются встроенные источники данных:

["id"]

Возвращает идентификатор фичи.

["geometry-type"]

Возвращает тип геометрии: Point, LineString, Polygon.


Операторы сравнения

Операторы сравнения позволяют сопоставлять значения свойств с константами.

Равенство

["==", ["get", "class"], "primary"]

Фильтрует объекты, у которых свойство class строго равно "primary".

Неравенство

["!=", ["get", "class"], "secondary"]

Оставляет все объекты, кроме тех, у которых class равен "secondary".

Сравнение чисел

[">", ["get", "rank"], 5]

Поддерживаются также:

[">=", ...]
["<", ...]
["<=", ...]

Пример диапазона:

["all",
  [">=", ["get", "rank"], 1],
  ["<=", ["get", "rank"], 10]
]

Логические операторы

Логические операторы позволяют комбинировать условия.

all (логическое И)

["all",
  ["==", ["get", "type"], "road"],
  [">", ["get", "width"], 5]
]

Фильтр пропускает только те объекты, которые удовлетворяют всем условиям.


any (логическое ИЛИ)

["any",
  ["==", ["get", "class"], "primary"],
  ["==", ["get", "class"], "secondary"]
]

Фильтр пропускает объекты, соответствующие хотя бы одному условию.


none (логическое НЕ ИЛИ)

["none",
  ["==", ["get", "status"], "inactive"],
  ["==", ["get", "status"], "deprecated"]
]

Проходит только те объекты, которые не удовлетворяют ни одному из условий.


Проверка наличия свойств

Операторы has и !has проверяют существование атрибута в объекте.

["has", "population"]

Фильтрует объекты, у которых существует поле population.

["!has", "population"]

Фильтрует объекты без этого поля.

Это особенно полезно при работе с неоднородными наборами данных, где структура свойств может отличаться.


Оператор in (принадлежность к множеству)

Оператор in проверяет, содержится ли значение в списке.

["in", ["get", "category"], "road", "highway", "street"]

Логика: значение category должно совпадать с одним из перечисленных.

Отрицательная форма:

["!in", ["get", "category"], "water", "forest"]

Сложные комбинации условий

Фильтры часто строятся как вложенные выражения, где логические операторы объединяют более простые сравнения.

Пример сложной логики:

["all",
  ["==", ["geometry-type"], "LineString"],
  ["any",
    ["==", ["get", "class"], "primary"],
    ["==", ["get", "class"], "secondary"]
  ],
  [">", ["get", "width"], 2]
]

Такая конструкция означает:

  • объект должен быть линией;
  • класс должен быть либо primary, либо secondary;
  • ширина должна быть больше 2.

Фильтрация по типу геометрии

Часто используется явная фильтрация по геометрии:

["==", ["geometry-type"], "Polygon"]

Комбинации:

["in", ["geometry-type"], "Polygon", "MultiPolygon"]

Работа со строками

Хотя фильтры не предназначены для сложной текстовой обработки, базовые проверки строк возможны.

Точное совпадение

["==", ["get", "name"], "Central Park"]

Проверка набора значений

["in", ["get", "name"], "Park A", "Park B", "Park C"]

Особенности приведения типов

Все значения в выражениях интерпретируются движком Mapbox GL JS. Числа и строки не всегда автоматически приводятся к совместимому виду. Это означает, что:

["==", ["get", "rank"], "5"]

может не совпадать с числовым значением 5, если поле хранится как число.

Явная типизация данных в источнике снижает вероятность ошибок фильтрации.


Фильтрация с использованием идентификатора

["==", ["id"], 12345]

Полезно для выделения конкретных объектов или отладки источников данных.


Вложенные логические конструкции

Система выражений допускает неограниченную вложенность, что позволяет строить сложные фильтры без перехода к внешней логике JavaScript.

Пример комбинированного фильтра:

["any",
  ["all",
    ["==", ["geometry-type"], "Point"],
    ["has", "icon"]
  ],
  ["all",
    ["==", ["geometry-type"], "Polygon"],
    [">", ["get", "area"], 1000]
  ]
]

Такая структура разделяет логику обработки точек и полигонов внутри одного фильтра.


Отрицание условий

В Mapbox GL JS нет отдельного оператора not в классическом виде, но отрицание реализуется через:

  • !in
  • !has
  • комбинации none

Пример:

["none",
  ["==", ["get", "status"], "deleted"]
]

Эквивалент логического отрицания одного условия.


Практика построения фильтров

При построении фильтров ключевым принципом является композиционность. Каждый элемент выражения должен быть самодостаточным и легко комбинируемым.

Характерная структура:

  • атомарные проверки (==, >, has);
  • объединение через all и any;
  • группировка по смысловым блокам.

Пример структурированного фильтра для транспортных данных:

["all",
  ["in", ["get", "type"], "bus", "tram"],
  [">=", ["get", "frequency"], 10],
  ["has", "route"]
]

Ограничения системы фильтрации

Система выражений Mapbox GL JS намеренно ограничена:

  • отсутствуют циклы;
  • отсутствуют пользовательские функции;
  • отсутствует доступ к внешним данным;
  • отсутствует динамическое состояние вне feature-state.

Фильтр выполняется на стороне рендерера и должен оставаться детерминированным и быстрым.


Различие фильтров и выражений стилей

Важно различать:

  • filter — отвечает за включение/исключение объектов;
  • выражения в paint и layout — отвечают за визуальное представление.

Одинаковые операторы используются в обеих системах, но цель фильтра — бинарное решение: отображать объект или нет.


Типовые паттерны фильтрации

Категориальная фильтрация

["==", ["get", "category"], "residential"]

Диапазон значений

["all",
  [">=", ["get", "value"], 10],
  ["<", ["get", "value"], 100]
]

Множественный выбор категорий

["in", ["get", "type"], "road", "path", "cycleway"]

Сложная сегментация данных

["any",
  ["all",
    ["==", ["geometry-type"], "Point"],
    ["has", "icon"]
  ],
  ["all",
    ["==", ["geometry-type"], "LineString"],
    [">", ["get", "importance"], 3]
  ]
]