В контексте WebGL-визуализаций библиотека Deck.gl рассматривает высоту как один из ключевых параметров перехода от плоской карты к объёмной сцене. Высота в слоях данных не является геометрическим свойством в классическом смысле — она вычисляется процедурно на основе атрибутов данных и затем преобразуется в 3D-геометрию через механизм экструзии (extrusion).
Экструзия в Deck.gl представляет собой процесс «вытягивания»
2D-геометрии вдоль оси Z, где значение высоты определяется функцией
данных getElevation или аналогичными мапперами атрибутов.
Это позволяет преобразовывать полигоны, точки и гексагоны в объёмные
объекты.
Практически все 3D-слои в Deck.gl используют единый подход:
elevationScaleКлючевая концепция: высота не хранится в геометрии напрямую, а вычисляется на этапе рендеринга.
new ColumnLayer({
id: 'columns',
data,
getPosition: d => [d.lng, d.lat],
getElevation: d => d.value,
elevationScale: 10,
radius: 50
});
Здесь getElevation возвращает «сырое» значение, а
elevationScale преобразует его в визуальную высоту.
Одной из основных задач при работе с экструзией является корректная нормализация значений. Данные могут иметь широкий диапазон — от единиц до миллионов, поэтому прямое использование приводит к визуальным артефактам.
Линейное масштабирование
elevationScale: 0.1
Логарифмическая трансформация
getElevation: d => Math.log(d.value + 1)
Кастомная нормализация
getElevation: d => (d.value - min) / (max - min)
Выбор метода зависит от распределения данных и цели визуализации.
Deck.gl предоставляет ColumnLayer как один из наиболее
прямолинейных способов работы с высотой.
import {ColumnLayer} from '@deck.gl/layers';
const layer = new ColumnLayer({
id: 'column-layer',
data: points,
diskResolution: 12,
radius: 200,
extruded: true,
pickable: true,
getPosition: d => [d.longitude, d.latitude],
getFillColor: d => [255, 140, 0],
getElevation: d => d.height
});
PolygonLayer позволяет экструзировать произвольные
полигоны, превращая их в 3D-призмы.
import {PolygonLayer} from '@deck.gl/layers';
const layer = new PolygonLayer({
id: 'polygons',
data,
extruded: true,
wireframe: false,
getPolygon: d => d.coordinates,
getElevation: d => d.population,
getFillColor: d => [0, 128, 255],
elevationScale: 5
});
GeoJsonLayer объединяет точки, линии и полигоны в единую
модель и поддерживает экструзию на уровне Feature.
import {GeoJsonLayer} from '@deck.gl/layers';
const layer = new GeoJsonLayer({
id: 'geojson',
data: geojson,
extruded: true,
stroked: false,
filled: true,
getElevation: f => f.properties.height,
elevationScale: 20,
getFillColor: [200, 200, 200]
});
Этот слой особенно полезен при работе с административными границами и тематическими картами.
HexagonLayer агрегирует точки в шестиугольные ячейки и вычисляет высоту на основе статистической функции.
import {HexagonLayer} from '@deck.gl/aggregation-layers';
const layer = new HexagonLayer({
id: 'hex',
data,
radius: 1000,
extruded: true,
getPosition: d => [d.lng, d.lat],
getElevationWeight: d => d.value,
elevationScale: 50
});
Высота каждой ячейки становится результатом агрегирования.
На уровне WebGL высота преобразуется в смещение по оси Z в вершинном шейдере.
Упрощённая логика:
float elevation = getElevation(attribute);
float scaledElevation = elevation * u_elevationScale;
position.z += scaledElevation;
Также учитываются:
Высота в Deck.gl зависит от системы координат. В географических слоях используется Web Mercator, где единицы измерения не равны метрам.
В связке с Mapbox GL JS часто применяется синхронизация систем координат:
COORDINATE_SYSTEM.LNGLATCOORDINATE_SYSTEM.METER_OFFSETSCOORDINATE_SYSTEM.CARTESIANОшибки выбора системы приводят к:
3D-экструзия без освещения теряет читаемость. Deck.gl использует модель направленного света:
import {AmbientLight, DirectionalLight} from '@deck.gl/core';
const lightingEffect = new LightingEffect({
ambientLight: new AmbientLight({intensity: 0.4}),
directionalLight: new DirectionalLight({
color: [255, 255, 255],
intensity: 1.0,
direction: [-1, -1, -1]
})
});
Освещение усиливает восприятие глубины и делает экструзию визуально различимой.
Высота может изменяться во времени без пересоздания слоя.
setInterval(() => {
layer.setProps({
getElevation: d => d.value * Math.random()
});
}, 1000);
Также поддерживаются плавные переходы:
transitions: {
getElevation: 1000
}
Это создаёт эффект анимации роста или изменения рельефа.
Высота отражает интенсивность явления:
Слишком большие значения elevationScale приводят к:
Несоответствие координатных систем приводит к визуальному «разъезду» геометрии.
Высота сама по себе не влияет на FPS напрямую, но влияет на:
Оптимизации:
diskResolutionGPU aggregationDeck.gl позволяет комбинировать слои:
TerrainLayerColumnLayerScatterplotLayerЭто создаёт сложные 3D-сцены, где высота становится частью многослойной визуальной модели, а не отдельным параметром.