Система координат и проекции

Любая визуализация в Deck.gl строится вокруг преобразования исходных данных в экранные координаты. Независимо от того, отображаются ли точки на карте, трёхмерные здания, спутниковые данные или произвольные объекты в пространстве, библиотека должна определить, каким образом координаты из набора данных будут интерпретированы и спроецированы на экран.

Система координат определяет:

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

От правильного выбора системы координат зависит точность позиционирования объектов, производительность рендеринга и корректность отображения данных на различных масштабах.


Координатные системы в 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

Каждая система предназначена для определённого типа данных и сценариев визуализации.


Географическая система координат LNGLAT

Наиболее распространённый режим работы.

Координаты задаются в формате:

[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.


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

Преимущества:

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

Недостатки:

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

Применение:

  • GPS-треки;
  • транспортные данные;
  • спутниковые наблюдения;
  • географические объекты;
  • тепловые карты;
  • визуализация городов.

Высота в системе LNGLAT

Третья координата интерпретируется как высота над поверхностью Земли.

Пример:

[
  37.6176,
  55.7558,
  500
]

Высота задаётся в метрах.

Использование:

new ColumnLayer({
  data,
  getPosition: d => d.position,
  getElevation: d => d.height
});

Deck.gl автоматически учитывает высоту при построении трёхмерной сцены.


Система LNGLAT_OFFSETS

Предназначена для ситуаций, когда имеется центральная точка и множество близлежащих объектов.

Указывается начало координат:

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
]

означают смещение относительно начала.


Преимущества LNGLAT_OFFSETS

Главное достоинство — повышение точности вычислений.

При работе с большими мировыми координатами графический процессор сталкивается с ограниченной точностью чисел с плавающей точкой.

Например:

[37.61761234567, 55.75581234567]

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

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

Такой подход особенно полезен для:

  • инженерных моделей;
  • BIM-визуализации;
  • локальных датчиков;
  • отображения оборудования на территории предприятия;
  • аэродромных систем.

Система METER_OFFSETS

В данной системе координаты задаются в метрах относительно выбранного центра.

Начало координат:

coordinateOrigin: [
  37.6176,
  55.7558
]

Координаты объекта:

[
  150,
  75,
  20
]

Интерпретируются как:

  • 150 метров на восток;
  • 75 метров на север;
  • 20 метров вверх.

Пример:

new ScatterplotLayer({
  coordinateSystem:
    COORDINATE_SYSTEM.METER_OFFSETS,

  coordinateOrigin: [
    37.6176,
    55.7558
  ],

  getPosition: d => d.position
});

Когда использовать METER_OFFSETS

Система особенно удобна для локальных сцен.

Например:

[
  [0, 0],
  [10, 0],
  [20, 0],
  [30, 0]
]

Каждая точка расположена на расстоянии 10 метров от предыдущей.

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

Типичные задачи:

  • промышленные объекты;
  • логистические терминалы;
  • аэропорты;
  • строительные площадки;
  • навигация роботов;
  • цифровые двойники.

Система CARTESIAN

Используется для данных, не связанных с географией.

Координаты трактуются как обычное декартово пространство.

Пример:

[
  10,
  20
]

или

[
  10,
  20,
  30
]

Использование:

new ScatterplotLayer({
  coordinateSystem:
    COORDINATE_SYSTEM.CARTESIAN,

  getPosition: d => d.position
});

Где применяется CARTESIAN

Система подходит для:

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

Пример расположения объектов:

[
  [0, 0],
  [100, 0],
  [100, 100],
  [0, 100]
]

Здесь координаты не имеют отношения к широте и долготе.


Coordinate Origin

Параметр coordinateOrigin задаёт базовую точку отсчёта.

Пример:

coordinateOrigin: [
  37.6176,
  55.7558,
  0
]

Deck.gl использует её для вычисления локальных координат.

Особенно важен для:

COORDINATE_SYSTEM.METER_OFFSETS

и

COORDINATE_SYSTEM.LNGLAT_OFFSETS

Без корректного указания начала координат объекты могут оказаться в неверном месте.


Что такое проекция

Земля имеет форму, близкую к сфере, а экран является плоской поверхностью.

Чтобы показать земную поверхность на экране, требуется математическое преобразование.

Этот процесс называется картографической проекцией.

Проекция преобразует:

Широта + долгота
        ↓
Плоские координаты

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


Проекция Web Mercator

Deck.gl использует проекцию Web Mercator.

Она стала стандартом для веб-картографии.

Её используют:

Основная идея:

Географические координаты
           ↓
Mercator
           ↓
Пиксели карты

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


Искажения проекции Mercator

Любая проекция вносит искажения.

Для Mercator характерно увеличение размеров объектов по мере приближения к полюсам.

Например:

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

При визуализации больших территорий этот эффект необходимо учитывать.


Путь преобразования координат

Во время рендеринга каждая точка проходит несколько этапов.

Исходные данные

[37.6176, 55.7558]

Мировые координаты

Longitude/Latitude
      ↓
World Coordinates

Координаты камеры

World Space
     ↓
View Space

Проекция

View Space
     ↓
Clip Space

Экранные координаты

Clip Space
     ↓
Screen Space

После этого объект становится видимым на экране.


Viewport и преобразование координат

Параметры камеры определяют способ отображения мира.

Основные параметры:

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
});

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