Система визуализации Deck.gl разделяет понятия данных, слоёв, камеры и viewport. Такое разделение позволяет независимо управлять отображением объектов и параметрами наблюдения сцены.
Камера (View State) определяет положение наблюдателя относительно визуализируемых данных:
Viewport представляет собой результат применения параметров камеры к области отображения. Именно viewport отвечает за преобразование географических или мировых координат в экранные пиксели.
Схематически процесс выглядит следующим образом:
Данные → Слой → Камера (View State)
↓
Viewport
↓
Canvas
Изменение данных обновляет содержимое сцены, а изменение камеры меняет только способ наблюдения за этой сценой.
В Deck.gl состояние камеры обычно хранится в объекте
viewState.
Для картографических визуализаций чаще всего используются следующие параметры:
const viewState = {
longitude: 37.6176,
latitude: 55.7558,
zoom: 10,
pitch: 45,
bearing: 0
};
| Свойство | Назначение |
|---|---|
longitude |
Центральная долгота |
latitude |
Центральная широта |
zoom |
Масштаб |
pitch |
Наклон камеры |
bearing |
Поворот карты |
position |
Смещение камеры |
maxZoom |
Максимальный масштаб |
minZoom |
Минимальный масштаб |
Передача состояния камеры выполняется через экземпляр
Deck:
new Deck({
initialViewState: {
longitude: 37.6176,
latitude: 55.7558,
zoom: 10
},
controller: true,
layers: []
});
Deck.gl поддерживает два принципиально разных режима управления камерой.
Камера управляется самим Deck.gl.
new Deck({
initialViewState: {
longitude: -122.4,
latitude: 37.8,
zoom: 12
},
controller: true
});
После инициализации библиотека самостоятельно изменяет состояние камеры в ответ на действия пользователя.
Состояние камеры хранится во внешнем приложении.
new Deck({
viewState,
controller: true
});
Обновление осуществляется вручную:
deck.setProps({
viewState: {
longitude: 30,
latitude: 50,
zoom: 8
}
});
Такой подход широко используется в React-приложениях.
Для включения стандартных механизмов навигации используется свойство:
controller: true
Пример:
new Deck({
initialViewState,
controller: true,
layers
});
После активации контроллера становятся доступны:
При каждом изменении положения камеры вызывается обработчик
onViewStateChange.
new Deck({
controller: true,
onViewStateChange: ({viewState}) => {
console.log(viewState);
}
});
Получаемый объект содержит актуальные параметры:
{
longitude: 37.6,
latitude: 55.7,
zoom: 11,
pitch: 30,
bearing: 15
}
Это позволяет синхронизировать камеру с состоянием приложения.
Наиболее распространённый подход заключается в хранении состояния через React Hooks.
const [viewState, setViewState] = useState({
longitude: -122.4,
latitude: 37.8,
zoom: 11
});
Передача в DeckGL:
<DeckGL
viewState={viewState}
controller={true}
onViewStateCha nge={({viewState}) => {
setViewState(viewState);
}}
>
</DeckGL>
В этом случае React становится единственным источником состояния камеры.
Во многих проектах требуется запретить перемещение камеры за пределы допустимого региона.
Пример ограничения масштаба:
new Deck({
initialViewState: {
longitude: 37.6,
latitude: 55.7,
zoom: 10,
minZoom: 5,
maxZoom: 18
},
controller: true
});
Дополнительный контроль можно реализовать через
onViewStateChange.
onViewStateChange: ({viewState}) => {
viewState.longitude = Math.max(
-180,
Math.min(180, viewState.longitude)
);
return viewState;
}
Подобная техника применяется для ограничения камеры территорией страны, города или промышленного объекта.
Резкое изменение координат ухудшает восприятие визуализации. Deck.gl поддерживает анимированные переходы.
Простейший пример:
deck.setProps({
viewState: {
longitude: 2.3522,
latitude: 48.8566,
zoom: 12,
transitionDuration: 3000
}
});
Камера плавно переместится к новой позиции за три секунды.
Для управления характером анимации используются специальные интерполяторы.
Наиболее популярный вариант — FlyToInterpolator.
import {FlyToInterpolator} from '@deck.gl/core';
Использование:
deck.setProps({
viewState: {
longitude: 139.6917,
latitude: 35.6895,
zoom: 13,
transitionInterpolator:
new FlyToInterpolator(),
transitionDuration: 4000
}
});
Эффект напоминает перелёт камеры между точками на карте.
Технология Fly-To автоматически рассчитывает:
Пример:
{
longitude: -74.006,
latitude: 40.7128,
zoom: 14,
transitionInterpolator:
new FlyToInterpolator(),
transitionDuration: 'auto'
}
При значении "auto" длительность вычисляется
автоматически на основе расстояния между точками.
Настройка времени выполняется через:
transitionDuration
Пример:
{
transitionDuration: 2000
}
Две секунды анимации обычно воспринимаются комфортно для большинства интерфейсов.
Для сложных презентационных визуализаций используются интервалы от 3 до 8 секунд.
Deck.gl поддерживает несколько независимых viewport одновременно.
Пример конфигурации:
views: [
new MapView({
id: 'main'
}),
new MapView({
id: 'mini'
})
]
Для каждого представления задаётся собственное состояние камеры.
viewState: {
main: {
longitude: 37,
latitude: 55,
zoom: 10
},
mini: {
longitude: 37,
latitude: 55,
zoom: 4
}
}
Подобная архитектура используется в:
Абстракция View описывает правила построения
viewport.
Базовый импорт:
import {
MapView
} from '@deck.gl/core';
Создание:
const view = new MapView({
repeat: true
});
Каждый объект View отвечает за:
Наиболее распространённый тип представления.
new MapView()
Подходит для:
Пример:
views: new MapView()
Режим обзора от первого лица.
Импорт:
import {
FirstPersonView
} from '@deck.gl/core';
Создание:
views: new FirstPersonView()
Особенности:
Используется для визуализации зданий, заводов, складов и виртуальных туров.
OrbitView применяется для просмотра объектов со всех сторон.
import {
OrbitView
} from '@deck.gl/core';
views: new OrbitView()
Камера вращается вокруг центральной точки сцены.
Типичные области применения:
Ортографическая проекция исключает перспективные искажения.
import {
OrthographicView
} from '@deck.gl/core';
views: new OrthographicView()
Особенности:
Подходит для инженерных схем и аналитических панелей.
Viewport выполняет преобразование между различными системами координат.
Основные этапы:
Географические координаты
↓
Мировые координаты
↓
Координаты камеры
↓
Экранные координаты
В результате объект:
[37.6176, 55.7558]
может быть отображён в конкретной точке canvas:
[512, 348]
Именно viewport отвечает за подобное преобразование.
Доступ к активному viewport можно получить через объект Deck.
const viewport =
deck.getViewports()[0];
Полученный экземпляр содержит:
viewport.width
viewport.height
viewport.zoom
viewport.latitude
viewport.longitude
Эти данные часто используются при реализации пользовательских инструментов навигации.
Метод:
viewport.project()
Преобразует координаты карты в координаты экрана.
const pixel =
viewport.project([
37.6176,
55.7558
]);
Результат:
[524, 301]
Это полезно при интеграции пользовательских HTML-элементов поверх canvas.
Для получения географических координат по экранной позиции используется:
viewport.unproject()
Пример:
const coordinates =
viewport.unproject([
500,
300
]);
Результат:
[
37.6176,
55.7558
]
Такой механизм часто используется при создании инструментов выделения и редактирования объектов.
Нередко требуется отображать несколько карт с общей камерой.
Пример общего состояния:
const sharedViewState = {
longitude: 37.6176,
latitude: 55.7558,
zoom: 10
};
Обе визуализации используют один объект:
<DeckGL
viewState={sharedViewState}
/>
При изменении камеры на одной карте автоматически обновляются остальные.
Подобная схема активно применяется в геоаналитике, когда одновременно отображаются различные наборы пространственных данных.
Для обычных картографических приложений
controller: true
initialViewState: {...}
Для React-приложений
viewState
onViewStateChange
Для презентационных сценариев
FlyToInterpolator
transitionDuration
Для многовидовых интерфейсов
views
viewState
Для точного контроля навигации
minZoom
maxZoom
onViewStateChange
Грамотное управление камерой и viewport является фундаментом любой интерактивной визуализации в Deck.gl. Именно эти механизмы определяют способ перемещения по данным, плавность навигации, корректность преобразования координат и качество взаимодействия пользователя с двумерными и трёхмерными сценами.