Понятие представления (View)

Система представлений (View) в Deck.gl определяет способ отображения сцены, параметры камеры, область визуализации и правила взаимодействия пользователя с данными. Представление является связующим звеном между геопространственными или абстрактными данными и механизмом их отображения на экране.

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

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

  • Layer — определяет способ отображения данных.
  • View — определяет камеру и область отображения.
  • ViewState — содержит текущее состояние камеры.
  • Controller — управляет взаимодействием пользователя с камерой.

Упрощённая схема:

Данные
   ↓
 Layer
   ↓
 View
   ↓
 ViewState
   ↓
 Экран

Что такое View

Объект View описывает конфигурацию области отображения.

Простейший пример:

import {MapView} from '@deck.gl/core';

const view = new MapView();

В данном случае создаётся картографическое представление, использующее привычную модель камеры с координатами широты и долготы.

Представление не содержит фактических координат камеры. Оно определяет только её тип и набор правил визуализации.

Координаты хранятся отдельно:

const viewState = {
  longitude: 37.6176,
  latitude: 55.7558,
  zoom: 10,
  pitch: 45,
  bearing: 0
};

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


Взаимосвязь View и ViewState

Очень важно различать эти два понятия.

View описывает:

  • тип камеры;
  • область рендеринга;
  • способ проецирования;
  • доступные элементы управления.

ViewState описывает:

  • текущие координаты;
  • масштаб;
  • наклон;
  • угол поворота;
  • позицию камеры.

Пример:

const deck = new Deck({
  views: new MapView(),
  viewState: {
    longitude: -122.4,
    latitude: 37.8,
    zoom: 12
  }
});

Здесь:

MapView      → определяет тип камеры
viewState    → определяет положение камеры

Такое разделение делает архитектуру Deck.gl гибкой и масштабируемой.


Базовый класс View

Все представления наследуются от базового класса View.

Упрощённая иерархия:

View
 ├─ MapView
 ├─ GlobeView
 ├─ OrbitView
 ├─ OrthographicView
 └─ FirstPersonView

Каждый тип решает собственный класс задач визуализации.


MapView

MapView является наиболее распространённым представлением в Deck.gl.

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

  • карт;
  • геоданных;
  • GPS-треков;
  • транспортных маршрутов;
  • пространственной аналитики.

Пример:

import {MapView} from '@deck.gl/core';

const deck = new Deck({
  views: new MapView(),
  viewState: {
    longitude: 30.3158,
    latitude: 59.9398,
    zoom: 11
  }
});

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

  • проекция Web Mercator;
  • поддержка широты и долготы;
  • совместимость с Mapbox;
  • поддержка наклона карты;
  • поддержка вращения карты.

Именно MapView используется в большинстве проектов.


GlobeView

GlobeView отображает Землю как сферу.

Пример:

import {GlobeView} from '@deck.gl/core';

const deck = new Deck({
  views: new GlobeView(),
  viewState: {
    longitude: 0,
    latitude: 0,
    zoom: 1
  }
});

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

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

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


OrbitView

OrbitView предназначен для трёхмерных сцен без привязки к географическим координатам.

Пример:

import {OrbitView} from '@deck.gl/core';

const deck = new Deck({
  views: new OrbitView(),
  viewState: {
    target: [0, 0, 0],
    rotationX: 30,
    rotationOrbit: 45,
    zoom: 2
  }
});

Типичные области применения:

  • инженерные модели;
  • научная визуализация;
  • просмотр облаков точек;
  • отображение трёхмерных объектов.

Камера вращается вокруг центра сцены.

        Камера
           *
          /
         /
        /
       O  ← объект

OrthographicView

OrthographicView использует ортографическую проекцию.

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

Пример:

import {OrthographicView} from '@deck.gl/core';

const deck = new Deck({
  views: new OrthographicView()
});

Сравнение проекций:

Перспективная:

[ближний объект]  █████
[дальний объект]    ██

Ортографическая:

[ближний объект]  █████
[дальний объект]  █████

Применяется для:

  • диаграмм;
  • схем;
  • CAD-систем;
  • научных визуализаций;
  • матриц данных.

FirstPersonView

FirstPersonView реализует камеру от первого лица.

Пример:

import {FirstPersonView} from '@deck.gl/core';

const deck = new Deck({
  views: new FirstPersonView()
});

Подходит для:

  • симуляторов;
  • виртуальных туров;
  • навигационных систем;
  • 3D-пространств.

Модель камеры напоминает игровой движок:

Пользователь
      ↓
    Камера
      ↓
   Направление взгляда

Перемещение камеры происходит относительно текущего направления обзора.


Настройка идентификаторов представлений

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

Пример:

const views = [
  new MapView({
    id: 'main-map'
  }),
  new OrbitView({
    id: 'model-view'
  })
];

Идентификатор используется для связи представления с соответствующим состоянием камеры.


Несколько представлений одновременно

Deck.gl позволяет отображать несколько независимых представлений в одном приложении.

Пример:

const views = [
  new MapView({
    id: 'map'
  }),
  new OrbitView({
    id: 'model'
  })
];

Состояния задаются отдельно:

const viewState = {
  map: {
    longitude: -74,
    latitude: 40.7,
    zoom: 10
  },

  model: {
    target: [0, 0, 0],
    zoom: 3
  }
};

В результате каждая область отображения получает собственную камеру.


Позиционирование представлений

Представление может занимать не весь экран, а только его часть.

Пример:

new MapView({
  id: 'mini-map',
  x: 20,
  y: 20,
  width: 300,
  height: 200
});

Параметры:

Свойство Назначение
x смещение по горизонтали
y смещение по вертикали
width ширина
height высота

Так реализуются мини-карты и вспомогательные панели.


Использование процентов

Размеры могут задаваться в процентах.

new MapView({
  width: '50%',
  height: '100%'
});

Пример разделения экрана:

const views = [
  new MapView({
    id: 'left',
    width: '50%'
  }),

  new MapView({
    id: 'right',
    x: '50%',
    width: '50%'
  })
];

Получается интерфейс сравнения двух карт.


Контроллеры представлений

Каждое представление может обладать собственным контроллером.

Пример:

new MapView({
  controller: true
});

Контроллер обеспечивает:

  • масштабирование колесом мыши;
  • перетаскивание карты;
  • вращение;
  • изменение наклона;
  • обработку жестов сенсорного экрана.

Отключение взаимодействия:

new MapView({
  controller: false
});

Подобный режим полезен для обзорных или справочных окон.


Связь слоёв с представлениями

Слой может отображаться только внутри определённого представления.

Пример:

new ScatterplotLayer({
  id: 'cities',
  data,
  viewId: 'map'
});

Здесь слой будет виден исключительно в представлении:

new MapView({
  id: 'map'
});

Это особенно важно при работе с несколькими окнами визуализации.


Использование одного слоя в нескольких представлениях

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

Пример:

new ScatterplotLayer({
  id: 'points',
  data
});

Если свойство viewId отсутствует, слой может участвовать в рендеринге всех совместимых представлений.

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


Синхронизация камер между представлениями

Иногда несколько окон должны использовать одинаковое положение камеры.

Пример:

const state = {
  longitude: 2.35,
  latitude: 48.85,
  zoom: 11
};

Далее одно состояние передаётся нескольким представлениям.

Результат:

View A ──┐
         ├── общий ViewState
View B ──┘

Панорамирование или масштабирование в одном окне автоматически отражается в другом.


Независимые камеры

Альтернативный вариант — полностью независимые состояния.

const viewState = {
  left: {
    longitude: 10,
    latitude: 50,
    zoom: 8
  },

  right: {
    longitude: 20,
    latitude: 40,
    zoom: 12
  }
};

Так реализуются сравнительные геоинформационные интерфейсы.


Viewport как результат работы View

Во время рендеринга объект View преобразуется во внутренний объект Viewport.

Схема преобразования:

View
  +
ViewState
  +
Размер Canvas
  ↓
Viewport

Viewport содержит вычисленные параметры камеры:

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

Большинство внутренних вычислений Deck.gl работают именно через Viewport.


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

Система представлений является фундаментом архитектуры Deck.gl. Она обеспечивает:

  • поддержку различных типов камер;
  • независимые области визуализации;
  • совместную работу нескольких окон отображения;
  • разделение конфигурации камеры и её состояния;
  • создание сложных аналитических интерфейсов;
  • построение картографических, научных и трёхмерных приложений на единой основе.

Понимание роли View позволяет правильно проектировать структуру визуализации, эффективно управлять камерами и строить масштабируемые приложения с несколькими независимыми областями отображения данных.