Фильтрация и сортировка

Фильтрация данных в deck.gl строится вокруг двух принципиально разных подходов: предварительной обработки на CPU и аппаратного отбора на GPU. Выбор стратегии зависит от объёма данных, требований к интерактивности и необходимости анимации. В большинстве реальных приложений оба подхода комбинируются, образуя многоуровневую систему управления видимостью объектов.

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

Типичная схема выглядит как преобразование исходного набора:

  • исходные данные хранятся в полном объёме
  • создаётся производный массив через filter, map, reduce
  • результат передаётся в data слоя

Основное преимущество — предсказуемость. Любая сложная логика, включая пространственные условия, агрегацию или комбинированные правила, реализуется без ограничений GPU.

Недостаток проявляется при больших объёмах: каждая интерактивная операция требует пересчёта массива и повторной передачи данных в WebGL-пайплайн. При десятках или сотнях тысяч объектов это становится узким местом.

Оптимизация CPU-фильтрации обычно строится вокруг мемоизации и инкрементальных обновлений:

  • кэширование результатов фильтра
  • разбиение данных по категориям заранее
  • использование структур пространственной индексации (quadtree, R-tree)

Однако deck.gl предоставляет более специализированный механизм, позволяющий перенести фильтрацию на GPU.


GPU-фильтрация через DataFilterExtension

Ключевой механизм высокопроизводительной фильтрации в deck.gl — расширение DataFilterExtension. Оно переносит вычисление видимости объектов в шейдерный пайплайн.

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

Типичная конфигурация включает:

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

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

  • getFilterValue: возвращает число (например, timestamp, категорию, интенсивность)
  • filterRange: задаёт границы видимости

Внутренне deck.gl компилирует это в фрагментный шейдер, где каждый фрагмент проверяется на попадание в диапазон. Объекты, не прошедшие проверку, отбрасываются без участия CPU.

Преимущества GPU-фильтрации

  • отсутствие пересборки массива данных
  • плавная анимация фильтров (time slider)
  • высокая производительность при сотнях тысяч объектов
  • минимальная нагрузка на JavaScript поток

Особенно важен сценарий временной фильтрации. Например, при отображении движения объектов во времени filterRange может динамически изменяться, создавая эффект воспроизведения без перерасчёта данных.

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

При использовании нескольких критериев применяется расширенный режим:

  • первый канал: время
  • второй канал: категория или состояние

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


Связь фильтрации и агрегирующих слоёв

В слоях агрегации (например, hexagon или grid-based представления) фильтрация работает на уровне входных точек до построения агрегатов. Это критически важно, поскольку изменение фильтра пересчитывает структуру кластеров.

В таких случаях pipeline выглядит следующим образом:

  1. входные точки
  2. GPU-фильтрация (DataFilterExtension)
  3. агрегация (hex, grid, tile)
  4. рендеринг результата

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


Анимационная фильтрация

Одним из ключевых сценариев использования GPU-фильтров является временная анимация. При изменении filterRange по кадрам создаётся эффект «сканирования» данных.

Особенности реализации:

  • обновление диапазона через setProps
  • отсутствие пересоздания слоя
  • использование плавных интерполяций

В отличие от CPU-фильтрации, где каждый кадр требует пересборки массива, GPU-подход ограничивается изменением uniform-переменных в шейдере.


Сортировка слоёв в DeckGL

Сортировка в deck.gl имеет две независимые плоскости: порядок слоёв и порядок объектов внутри слоя.

Порядок слоёв определяется массивом layers. Он является строго упорядоченным стеком рендеринга:

  • первый слой рисуется первым
  • последующие накладываются сверху

Это означает, что визуальная композиция сцены полностью зависит от порядка объявления слоёв. Любая сортировка объектов внутри слоя не может изменить перекрытие между слоями.


Сортировка внутри слоя

Внутри одного слоя порядок отрисовки зависит от типа геометрии и режима смешивания (blending).

Для точечных слоёв (ScatterplotLayer, IconLayer) порядок объектов обычно не имеет семантического значения, поскольку используется аддитивное или альфа-смешивание. Однако в случае прозрачности возникает проблема корректного наложения.

Для корректного отображения полупрозрачных объектов часто требуется предварительная сортировка на CPU:

  • сортировка по глубине (z-order)
  • сортировка по расстоянию до камеры
  • сортировка по интенсивности (для heatmap-подобных визуализаций)

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


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

При использовании alpha blending возникает зависимость результата от порядка рендеринга. Если объекты пересекаются, неправильный порядок приводит к визуальным артефактам.

Типичные стратегии:

  • сортировка «от дальних к ближним»
  • разбиение сцены на слои по глубине
  • использование additive blending вместо alpha blending

В аналитических приложениях часто выбирается второй вариант, поскольку он уменьшает вычислительную сложность и снижает требования к сортировке.


Косвенная сортировка через ключи

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

  • цветовые каналы (визуальная приоритизация)
  • высота (extrusion в 3D слоях)
  • радиус или толщина линий

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


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

Фильтрация и сортировка в deck.gl тесно связаны, поскольку оба процесса влияют на финальный набор примитивов, поступающих в GPU.

Типичная последовательность обработки:

  1. CPU-фильтрация (опционально)
  2. GPU-фильтрация (DataFilterExtension)
  3. сортировка данных (если требуется)
  4. передача в слой
  5. рендеринг с учётом порядка слоёв

В сложных визуализациях порядок выполнения этих шагов определяет как производительность, так и визуальную корректность сцены.


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

При работе с десятками миллионов объектов используются комбинированные стратегии:

  • предварительная пространственная индексация
  • разделение данных по временным сегментам
  • GPU-фильтрация для интерактивных изменений
  • минимизация CPU-сортировки
  • использование агрегирующих слоёв вместо точечных

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