Комбинирование фильтров

В Kepler.gl система фильтрации построена вокруг декларативного состояния visState, где каждый фильтр является независимым объектом, но при этом участвует в общей логике отбора данных. Комбинирование фильтров — ключевой механизм, позволяющий строить сложные аналитические запросы к геоданным без изменения исходного датасета.


Каждый фильтр в Kepler.gl существует как элемент массива:

visState: {
  filters: [
    { ...filterA },
    { ...filterB }
  ]
}

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

По умолчанию используется логика:

FILTER_A ∩ FILTER_B ∩ FILTER_C

То есть данные должны удовлетворять всем условиям одновременно.


Типы фильтров и их совместимость

Фильтры в Kepler.gl делятся на несколько категорий:

Диапазонные фильтры (range filter)

Используются для числовых значений: температура, скорость, высота, стоимость.

{
  name: "speed",
  type: "range",
  value: [10, 80]
}

При комбинировании нескольких range-фильтров происходит пересечение диапазонов по разным полям:

  • speed ∈ [10, 80]
  • altitude ∈ [100, 1000]

Временные фильтры (time filter)

Позволяют ограничивать данные по временной шкале.

{
  name: "timestamp",
  type: "timeRange",
  value: [1609459200000, 1640995200000]
}

При комбинации с другими фильтрами временной фильтр работает как дополнительное ограничение, не влияя на структуру других условий.


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

Используются для строковых значений: тип объекта, регион, статус.

{
  name: "country",
  type: "multiSelect",
  value: ["KZ", "RU", "CN"]
}

Комбинация с числовыми фильтрами позволяет формировать гибридные условия:

  • country ∈ {KZ, RU}
  • speed ∈ [20, 60]

Механизм пересечения фильтров

Внутренне Kepler.gl применяет фильтры последовательно:

  1. Берётся исходный dataset
  2. Применяется первый активный фильтр
  3. Результат передаётся следующему фильтру
  4. Процесс повторяется до конца массива

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


Комбинация фильтров в visState

Полный пример состояния:

const visState = {
  filters: [
    {
      name: "speed",
      type: "range",
      value: [10, 100],
      enabled: true
    },
    {
      name: "timestamp",
      type: "timeRange",
      value: [1620000000000, 1630000000000],
      enabled: true
    },
    {
      name: "country",
      type: "multiSelect",
      value: ["KZ", "US"],
      enabled: true
    }
  ]
}

Итоговая выборка будет удовлетворять одновременно всем трём условиям.


Логика включения и выключения фильтров

Каждый фильтр имеет флаг:

enabled: true | false

Отключённые фильтры:

  • игнорируются в вычислениях
  • остаются в состоянии UI
  • сохраняют параметры диапазонов

Это позволяет динамически переключать сценарии анализа без потери контекста.


Взаимодействие фильтров с слоями

Фильтры в Kepler.gl действуют глобально на dataset, но их эффект проявляется через слои.

Пример:

  • слой A отображает точки доставки
  • слой B отображает маршруты

Оба слоя используют один dataset, но:

  • фильтр скорости влияет только на слой A, если он использует соответствующее поле
  • временной фильтр влияет на оба слоя, если оба зависят от timestamp

Комбинирование фильтров с разными типами данных

Сильная сторона Kepler.gl — возможность объединять фильтры разных типов без дополнительных преобразований.

Пример логики:

  • числовой фильтр: altitude
  • временной фильтр: timestamp
  • категориальный фильтр: vehicleType

Результат:

(vehicleType ∈ {truck, drone})
AND (altitude ∈ [200, 2000])
AND (timestamp ∈ [t1, t2])

Поведение при пересечении пустых множеств

Если комбинация фильтров приводит к пустому результату, Kepler.gl:

  • отображает пустую карту
  • не вызывает ошибку
  • сохраняет активные фильтры без изменений

Это важно для интерактивного анализа, где пользователь может «пережать» условия.


Производительность при множественных фильтрах

При увеличении числа фильтров возрастает нагрузка на:

  • CPU (CPU-based filtering в стандартном режиме)
  • GPU (при включённых оптимизациях визуализации)

Оптимизации включают:

  • кэширование промежуточных результатов
  • пропуск отключённых фильтров
  • агрегацию данных до фильтрации в некоторых слоях

Программное управление комбинациями фильтров

Фильтры можно динамически изменять через Redux action:

dispatch(
  updateFilter({
    id: 'speed-filter',
    value: [20, 90]
  })
);

Или добавлять новые:

dispatch(
  addFilter({
    name: 'temperature',
    type: 'range',
    value: [0, 30]
  })
);

Комбинация формируется автоматически системой состояния.


Синхронизация фильтров с UI

UI Kepler.gl отображает фильтры как независимые панели, но все они связаны с единым visState.

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

  • изменение одного фильтра мгновенно пересчитывает все слои
  • ползунки диапазонов синхронизируются с состоянием данных
  • мультивыбор обновляется без перезагрузки слоя

Вложенные сценарии комбинирования

Хотя Kepler.gl не использует явные вложенные логические выражения, их можно эмулировать:

AND-комбинация (по умолчанию)

Все фильтры активны:

A AND B AND C

Эмуляция OR через разделение слоёв

Создаются разные слои с разными фильтрами:

  • слой 1: country = KZ
  • слой 2: country = RU

И оба отображаются одновременно.


Комбинирование временных фильтров с шагом

Временные фильтры могут работать в режиме step:

  • по часам
  • по дням
  • по месяцам

При комбинировании с range-фильтрами получается аналитика вида:

  • скорость в диапазоне
  • за конкретный период
  • для выбранных категорий

Конфликты фильтров и их разрешение

Конфликты возникают при:

  • несовместимых диапазонах
  • некорректных типах данных
  • отсутствии поля в dataset

Система обработки:

  • игнорирует некорректный фильтр
  • не ломает остальные фильтры
  • логически исключает поле из цепочки

Практическая модель комбинирования

Абстрактно весь процесс можно представить так:

D_final = F1(D) ∩ F2(D) ∩ F3(D) ... ∩ Fn(D)

где:

  • D — исходный dataset
  • F — функция фильтра
  • ∩ — операция пересечения результатов

Масштабирование комбинаций

При больших наборах данных (миллионы точек):

  • фильтры начинают работать в потоковом режиме
  • используется инкрементальная фильтрация
  • визуализация обновляется частично

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


Поведение при динамическом изменении фильтров

Каждое изменение:

  • диапазона
  • списка значений
  • временной шкалы

триггерит перерасчёт pipeline:

updateFilter → recomputeVisState → updateLayers → rerender

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