Пользовательские проекции

В основе CesiumJS лежит глобальная модель Земли, построенная на эллипсоиде WGS84. Все пространственные данные в движке в конечном итоге приводятся к трёхмерной декартовой системе координат ECEF, где центр совпадает с центром масс планеты.

Переход между географическими координатами (широта, долгота, высота) и ECEF осуществляется через классы эллипсоида и преобразования Cesium. Однако при работе с 2D-тайлами и растровыми слоями появляется дополнительный уровень абстракции — картографическая проекция.

CesiumJS поддерживает два базовых варианта:

  • географическая проекция (псевдо-Plate Carrée),
  • проекция Web Mercator.

Обе реализуют интерфейс Projection, определяющий правила перехода между географическими координатами и плоскостью тайлов.

Интерфейс проекции в CesiumJS

Любая проекция в CesiumJS представляет собой объект, реализующий методы:

  • project(cartographic, result)
  • unproject(cartesian, result)

где:

  • Cartographic — широта, долгота, высота,
  • Cartesian2 — координаты на плоскости проекции.

Базовая абстракция задаётся классом Projection, а конкретные реализации наследуются от него.

Ключевые встроенные реализации:

  • GeographicProjection
  • WebMercatorProjection

Географическая проекция

Географическая проекция напрямую отображает:

  • долготу → X,
  • широту → Y,

без нелинейных преобразований.

Это упрощённая модель, соответствующая равнопромежуточной (equirectangular) схеме.

Web Mercator

Проекция Web Mercator используется большинством веб-карт.

Формулы:

  • ( x = R )
  • ( y = R (( + )) )

где:

  • ( ) — долгота,
  • ( ) — широта,
  • ( R ) — радиус эллипсоида.

Эта проекция нелинейно искажает площади, но обеспечивает удобную тайловую структуру.

Тиллинговая система как часть проекции

Проекция в CesiumJS тесно связана с TilingScheme. Именно он определяет разбиение пространства на тайлы и их соответствие координатам.

Интерфейс включает:

  • rectangleToNativeRectangle
  • tileXYToRectangle
  • positionToTileXY
  • getNumberOfXTilesAtLevel
  • getNumberOfYTilesAtLevel

Через TilingScheme определяется не только проекция, но и логика LOD (levels of detail).

Основные реализации:

  • GeographicTilingScheme
  • WebMercatorTilingScheme

Каждая из них использует соответствующую проекцию.

Пользовательская проекция: базовые принципы

Создание собственной системы координат в CesiumJS возможно на двух уровнях:

  1. реализация Projection,
  2. реализация TilingScheme.

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

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

Реализация пользовательского Projection

Минимальная структура кастомной проекции включает методы преобразования между Cartographic и Cartesian2.

Пример линейной аффинной проекции

Аффинная проекция используется для локальных систем координат:

  • масштабирование,
  • смещение,
  • поворот (опционально).

Общая форма:

  • ( x = a + b )
  • ( y = c + d )

Где коэффициенты задают трансформацию.

В CesiumJS это выражается через:

  • project — перевод в плоскость,
  • unproject — обратное преобразование.

Особенность: Cesium ожидает согласованность между методами, иначе ломается пространственная согласованность сцены.

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

Все географические координаты в Cesium привязаны к эллипсоиду Ellipsoid.

При создании кастомной проекции часто требуется:

  • использовать Ellipsoid.WGS84,
  • либо заменить его на локальную модель.

Изменение эллипсоида влияет на:

  • вычисление нормалей поверхности,
  • геодезические линии,
  • позиционирование камер.

Пользовательский TilingScheme

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

TilingScheme определяет:

  • географические границы каждого тайла,
  • количество тайлов на уровне,
  • преобразование tile → rectangle.

Ключевая логика

Любой тайл определяется:

  • уровнем zoom level,
  • индексами x, y,
  • прямоугольником в координатах проекции.

Пример базовой логики:

  • уровень 0: один тайл покрывает всю проекцию,
  • каждый следующий уровень делит пространство на 2×2.

Пример кастомного TilingScheme

При создании собственного TilingScheme реализуются методы:

  • getNumberOfXTilesAtLevel(level)
  • getNumberOfYTilesAtLevel(level)
  • tileXYToRectangle(x, y, level, result)
  • positionToTileXY(position, level, result)

Логика равномерного деления

Для простой равнопромежуточной модели:

  • количество тайлов по X: (2^level)
  • количество тайлов по Y: (2^level)

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

Нелинейные пользовательские проекции

В более сложных случаях проекция может включать:

  • локальные инженерные системы координат,
  • картографические искажения,
  • полярные преобразования,
  • псевдо-сферические модели.

Полярная проекция

Пример трансформации:

  • ( r = f() )
  • ( x = r () )
  • ( y = r () )

Такая модель требует строгого согласования с TilingScheme, иначе тайлы будут перекрываться.

Интеграция с ImageryProvider

Пользовательская проекция почти всегда используется совместно с ImageryProvider.

Ключевой момент:

  • ImageryProvider.tilingScheme должен совпадать с кастомной проекцией.

Иначе:

  • текстуры будут искажены,
  • тайлы перестанут совпадать с геометрией.

Геометрическая согласованность сцены

CesiumJS объединяет:

  • геометрию в ECEF,
  • проекции в 2D,
  • тайловую сетку,
  • камеры и преобразования.

Ключевые преобразования:

  • Cartographic → Cartesian3
  • Cartesian3 → Cartographic
  • Projection ↔︎ TilingScheme

Несогласованность любого элемента приводит к:

  • смещению тайлов,
  • разрыву текстур,
  • артефактам при зуме.

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

Внутренние преобразования Cesium используют матрицы:

  • Matrix3 — 2D преобразования,
  • Matrix4 — переходы между системами координат,
  • Transforms — набор геодезических преобразований.

Пользовательская проекция может опираться на:

  • линейные матрицы масштабирования,
  • поворот в плоскости проекции,
  • смещение относительно глобального нуля.

Ограничения пользовательских проекций

Несмотря на гибкость, существуют ограничения:

  • сцена всегда рендерится в ECEF,
  • террейн ожидает геодезическую модель,
  • часть API оптимизирована под Web Mercator.

Поэтому сложные проекции часто требуют:

  • кастомного ImageryProvider,
  • синхронизации с terrain provider,
  • ручного контроля LOD.

Согласование уровней детализации

LOD зависит от:

  • масштаба проекции,
  • плотности тайлов,
  • кривизны преобразования.

Нелинейные проекции требуют адаптивного:

  • увеличения числа тайлов,
  • коррекции диапазонов уровней,
  • перерасчёта bounding boxes.

Иначе возникает эффект:

  • переразбиения текстур,
  • “растяжения” тайлов,
  • резких скачков детализации.

Пространственная точность и численные ошибки

При пользовательских проекциях критичны:

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

CesiumJS использует 64-битную точность, но при кастомных формулах возможны:

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