Любая визуализация в Deck.gl строится вокруг преобразования исходных данных в экранные координаты. Независимо от того, отображаются ли точки на карте, трёхмерные здания, спутниковые данные или произвольные объекты в пространстве, библиотека должна определить, каким образом координаты из набора данных будут интерпретированы и спроецированы на экран.
Система координат определяет:
От правильного выбора системы координат зависит точность позиционирования объектов, производительность рендеринга и корректность отображения данных на различных масштабах.
Deck.gl поддерживает несколько систем координат через параметр
coordinateSystem.
Основные варианты:
import {COORDINATE_SYSTEM} from '@deck.gl/core';
Наиболее часто используются:
COORDINATE_SYSTEM.LNGLAT
COORDINATE_SYSTEM.LNGLAT_OFFSETS
COORDINATE_SYSTEM.METER_OFFSETS
COORDINATE_SYSTEM.CARTESIAN
Каждая система предназначена для определённого типа данных и сценариев визуализации.
Наиболее распространённый режим работы.
Координаты задаются в формате:
[longitude, latitude]
или
[longitude, latitude, altitude]
Пример:
const points = [
{
position: [37.6176, 55.7558]
}
];
В данном случае:
37.6176 — долгота;55.7558 — широта.Использование слоя:
new ScatterplotLayer({
data: points,
getPosition: d => d.position,
coordinateSystem: COORDINATE_SYSTEM.LNGLAT
});
Deck.gl автоматически преобразует географические координаты в экранное пространство через проекцию Web Mercator.
Преимущества:
Недостатки:
Применение:
Третья координата интерпретируется как высота над поверхностью Земли.
Пример:
[
37.6176,
55.7558,
500
]
Высота задаётся в метрах.
Использование:
new ColumnLayer({
data,
getPosition: d => d.position,
getElevation: d => d.height
});
Deck.gl автоматически учитывает высоту при построении трёхмерной сцены.
Предназначена для ситуаций, когда имеется центральная точка и множество близлежащих объектов.
Указывается начало координат:
coordinateOrigin: [
37.6176,
55.7558
]
После этого все координаты задаются относительно данной точки.
Пример:
new ScatterplotLayer({
coordinateSystem:
COORDINATE_SYSTEM.LNGLAT_OFFSETS,
coordinateOrigin: [
37.6176,
55.7558
],
getPosition: d => d.offset
});
Координаты:
[
0.0001,
0.0002
]
означают смещение относительно начала.
Главное достоинство — повышение точности вычислений.
При работе с большими мировыми координатами графический процессор сталкивается с ограниченной точностью чисел с плавающей точкой.
Например:
[37.61761234567, 55.75581234567]
После многочисленных преобразований часть младших разрядов может теряться.
Использование локального начала координат уменьшает абсолютные значения и повышает точность.
Такой подход особенно полезен для:
В данной системе координаты задаются в метрах относительно выбранного центра.
Начало координат:
coordinateOrigin: [
37.6176,
55.7558
]
Координаты объекта:
[
150,
75,
20
]
Интерпретируются как:
Пример:
new ScatterplotLayer({
coordinateSystem:
COORDINATE_SYSTEM.METER_OFFSETS,
coordinateOrigin: [
37.6176,
55.7558
],
getPosition: d => d.position
});
Система особенно удобна для локальных сцен.
Например:
[
[0, 0],
[10, 0],
[20, 0],
[30, 0]
]
Каждая точка расположена на расстоянии 10 метров от предыдущей.
Подобное представление значительно проще по сравнению с вычислением географических координат вручную.
Типичные задачи:
Используется для данных, не связанных с географией.
Координаты трактуются как обычное декартово пространство.
Пример:
[
10,
20
]
или
[
10,
20,
30
]
Использование:
new ScatterplotLayer({
coordinateSystem:
COORDINATE_SYSTEM.CARTESIAN,
getPosition: d => d.position
});
Система подходит для:
Пример расположения объектов:
[
[0, 0],
[100, 0],
[100, 100],
[0, 100]
]
Здесь координаты не имеют отношения к широте и долготе.
Параметр coordinateOrigin задаёт базовую точку
отсчёта.
Пример:
coordinateOrigin: [
37.6176,
55.7558,
0
]
Deck.gl использует её для вычисления локальных координат.
Особенно важен для:
COORDINATE_SYSTEM.METER_OFFSETS
и
COORDINATE_SYSTEM.LNGLAT_OFFSETS
Без корректного указания начала координат объекты могут оказаться в неверном месте.
Земля имеет форму, близкую к сфере, а экран является плоской поверхностью.
Чтобы показать земную поверхность на экране, требуется математическое преобразование.
Этот процесс называется картографической проекцией.
Проекция преобразует:
Широта + долгота
↓
Плоские координаты
Любая карта является результатом подобного преобразования.
Deck.gl использует проекцию Web Mercator.
Она стала стандартом для веб-картографии.
Её используют:
Основная идея:
Географические координаты
↓
Mercator
↓
Пиксели карты
Благодаря этому Deck.gl может работать поверх популярных картографических движков.
Любая проекция вносит искажения.
Для Mercator характерно увеличение размеров объектов по мере приближения к полюсам.
Например:
При визуализации больших территорий этот эффект необходимо учитывать.
Во время рендеринга каждая точка проходит несколько этапов.
[37.6176, 55.7558]
Longitude/Latitude
↓
World Coordinates
World Space
↓
View Space
View Space
↓
Clip Space
Clip Space
↓
Screen Space
После этого объект становится видимым на экране.
Параметры камеры определяют способ отображения мира.
Основные параметры:
const viewState = {
longitude: 37.6176,
latitude: 55.7558,
zoom: 12,
pitch: 45,
bearing: 20
};
Где:
longitude — центр карты;latitude — центр карты;zoom — масштаб;pitch — наклон камеры;bearing — поворот.Изменение любого параметра приводит к перерасчёту экранных координат.
Различные свойства слоёв используют разные единицы.
Пример радиуса:
radiusUnits: 'meters'
или
radiusUnits: 'pixels'
Вариант в метрах:
new ScatterplotLayer({
radiusUnits: 'meters',
getRadius: 100
});
Объект будет занимать реальные 100 метров на местности.
Вариант в пикселях:
new ScatterplotLayer({
radiusUnits: 'pixels',
getRadius: 20
});
Размер останется визуально постоянным независимо от масштаба карты.
При отображении глобальных данных возникают проблемы точности.
Причина заключается в ограничениях GPU:
32-bit Float
Большие значения координат снижают точность дробной части.
Для решения проблемы Deck.gl использует:
Это позволяет корректно отображать объекты даже при сильном приближении.
COORDINATE_SYSTEM.LNGLAT
Подходит для:
COORDINATE_SYSTEM.METER_OFFSETS
Подходит для:
COORDINATE_SYSTEM.LNGLAT_OFFSETS
Подходит для:
COORDINATE_SYSTEM.CARTESIAN
Подходит для:
Чем сложнее преобразование координат, тем больше вычислений выполняет графический процессор.
Условно по стоимости:
CARTESIAN
↓
METER_OFFSETS
↓
LNGLAT_OFFSETS
↓
LNGLAT
Разница редко становится критичной, однако при миллионах объектов выбор более простой системы координат способен заметно снизить нагрузку на GPU.
Центральная точка объекта:
const origin = [
37.6176,
55.7558
];
Данные:
const sensors = [
{
id: 1,
position: [10, 5]
},
{
id: 2,
position: [25, 30]
},
{
id: 3,
position: [100, 50]
}
];
Создание слоя:
new ScatterplotLayer({
data: sensors,
coordinateSystem:
COORDINATE_SYSTEM.METER_OFFSETS,
coordinateOrigin: origin,
getPosition: d => d.position,
radiusUnits: 'meters',
getRadius: 2
});
В этом случае каждая координата интерпретируется как расстояние в метрах относительно центральной точки территории, что обеспечивает высокую точность позиционирования и упрощает работу с локальными пространственными данными.