Экструзия на основе данных

Принцип формирования 3D-геометрии из атрибутивных данных

Экструзия в Kepler.gl представляет собой механизм преобразования числовых значений из набора данных в вертикальное измерение геометрии на карте. Каждый объект на карте может быть «вытянут» вдоль оси Z в зависимости от заданного атрибута, формируя объемные структуры, визуально отражающие интенсивность, плотность или величину показателя.

Основой служит связь между географической сущностью (точка, полигон, сетка) и числовым полем данных. Это поле интерпретируется как высота, масштаб или коэффициент, определяющий степень экструзии.


Базовая модель экструзии в Kepler.gl

В архитектуре Kepler.gl экструзия реализуется через слой (layer), поддерживающий 3D-рендеринг. Наиболее часто используются:

  • GeoJsonLayer
  • HexagonLayer
  • GridLayer
  • ColumnLayer

Каждый из этих слоёв способен преобразовывать входные данные в вертикальные столбцы или объёмные полигоны.

Ключевой параметр:

elevationScale: number

Он задаёт глобальный коэффициент усиления высоты объектов.


Экструзия в GeoJsonLayer

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

Пример структуры слоя:

const layer = {
  id: 'geojson-extrusion',
  type: 'geojson',
  data: geojsonData,
  stroked: false,
  filled: true,
  extruded: true,
  wireframe: true,
  getElevation: f => f.properties.height,
  getFillColor: f => [255, 140, 0],
  elevationScale: 10
};

Ключевые аспекты:

  • extruded: true активирует 3D-режим
  • getElevation определяет источник высоты
  • elevationScale масштабирует результат
  • filled управляет визуальной заливкой полигона

Функция getElevation выполняет роль адаптера между данными и геометрией сцены.


Маппинг данных на высоту

Экструзия напрямую зависит от функции отображения данных. Типовая схема:

getElevation: d => d.properties.value

или с нормализацией:

getElevation: d => Math.sqrt(d.properties.population)

Используются различные стратегии преобразования:

  • Линейное масштабирование
  • Логарифмическое сжатие
  • Квадратичная нормализация
  • Квантование значений

Пример логарифмического преобразования:

getElevation: d => Math.log(d.properties.income + 1)

Подобные преобразования уменьшают дисбаланс между экстремальными значениями и остальными объектами.


HexagonLayer и агрегационная экструзия

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

Конфигурация слоя:

const layer = {
  id: 'hex-extrusion',
  type: 'hexagon',
  data,
  radius: 1000,
  elevationScale: 50,
  extruded: true,
  getPosition: d => d.coordinates,
  getElevationWeight: d => d.value
};

Механизм работы:

  • точки группируются в hex-ячейки
  • для каждой ячейки вычисляется агрегат (sum, mean, max)
  • результат переводится в высоту столбца

Параметр агрегации:

elevationAggregation: 'SUM'

Возможные режимы:

  • SUM — суммарное значение
  • MEAN — среднее
  • MAX — максимальное значение

GridLayer и регулярная экструзия

GridLayer формирует квадратную сетку вместо шестиугольной. Экструзия работает аналогично HexagonLayer, но с иной топологией разбиения.

const layer = {
  id: 'grid-extrusion',
  type: 'grid',
  data,
  cellSize: 500,
  extruded: true,
  elevationScale: 30,
  getPosition: d => d.coordinates,
  getWeight: d => d.metric
};

GridLayer используется для:

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

ColumnLayer как прямое отображение величины

ColumnLayer представляет собой набор вертикальных цилиндров или столбцов, где каждый объект данных становится отдельной 3D-колонной.

const layer = {
  id: 'column-extrusion',
  type: 'column',
  data,
  diskResolution: 12,
  radius: 500,
  extruded: true,
  elevationScale: 20,
  getPosition: d => d.coordinates,
  getElevation: d => d.amount,
  getFillColor: d => [0, 128, 255]
};

Особенности:

  • точечная экструзия без агрегации
  • высокая детализация
  • прямое отображение метрик

Управление масштабом высоты

Параметр elevationScale играет роль глобального усилителя:

height = getElevation(data) * elevationScale

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

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

Часто применяется динамическая настройка:

elevationScale: Math.max(1, 1000 / maxValue)

Цвет и высота как связанная система

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

getFillColor: d => [
  255,
  Math.min(255, d.value * 2),
  100
]

Система интерпретации:

  • высота отражает абсолютную величину
  • цвет отражает категорию или относительную интенсивность

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


Производительность при работе с экструзией

3D-экструзия требует значительных ресурсов GPU. Оптимизация включает:

  • использование агрегационных слоёв вместо точечных
  • ограничение количества объектов
  • снижение diskResolution в ColumnLayer
  • кэширование вычислений getElevation

Особенно критичны большие наборы GeoJSON:

  • тысячи полигонов резко снижают FPS
  • рекомендуется предварительная генерация H3 или grid-структур

Работа с H3 и экструзией

Kepler.gl поддерживает H3-индексацию для оптимизации пространственной агрегации.

Принцип:

  • координаты переводятся в H3 индекс
  • индексы агрегируются
  • каждая ячейка получает высоту
getHexagon: d => h3.geoToH3(d.lat, d.lng, 7)

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


Динамическая экструзия и обновление данных

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

setInterval(() => {
  layer.data = updateData();
  layer.getElevation = d => d.newValue;
}, 1000);

Типовые сценарии:

  • потоковые данные (датчики, GPS)
  • временные ряды
  • интерактивные фильтры

При обновлении важно избегать полного пересоздания слоя, предпочтительнее частичное обновление props.


Связь экструзии с фильтрами

Фильтрация данных влияет на форму 3D-структуры:

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

Пример:

filter: [
  {
    id: 'time-filter',
    type: 'timeRange',
    value: [start, end]
  }
]

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


Интерпретация 3D-структур

Экструзия формирует визуальную модель, в которой:

  • ось X/Y — география
  • ось Z — числовая характеристика
  • форма поверхности — распределение значений

Такая модель позволяет выявлять:

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