Пользовательские terrain данные

Работа с рельефом в CesiumJS строится вокруг абстракции TerrainProvider, которая определяет способ получения высотной информации для глобуса. Система изначально рассчитана на заменяемые источники данных, что позволяет подключать как облачные сервисы, так и локально размещённые тайловые наборы.

Вся геометрия поверхности Земли в CesiumJS представляет собой иерархическую сетку тайлов, где каждый тайл содержит уплотнённое представление высот. При перемещении камеры движок подгружает более детализированные участки, заменяя грубые данные на более точные.


Архитектура TerrainProvider и роль пользовательских источников

TerrainProvider является базовым интерфейсом, определяющим контракт для всех типов рельефа. Он отвечает за:

  • определение доступных уровней детализации (LOD)
  • загрузку тайлов по координатам
  • декодирование высотных данных
  • кэширование и управление памятью

Стандартные реализации включают CesiumTerrainProvider и EllipsoidTerrainProvider. Однако ключевым моментом является возможность создания кастомных провайдеров, которые используют собственный формат хранения высот.

Базовый контракт включает методы:

  • requestTileGeometry(x, y, level)
  • getLevelMaximumGeometricError(level)
  • readyPromise

Формат данных пользовательского рельефа

На практике используются три основных формата:

Heightmap (растровая сетка высот)

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

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

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

Используется для начальных уровней детализации или локальных сцен.


Quantized-Mesh

Основной формат высокодетализированного рельефа в экосистеме Cesium.

Ключевые характеристики:

  • триангулированная нерегулярная сетка
  • сжатие высот в 16-битные значения
  • встроенные нормали и bounding volume
  • поддержка “skirts” для устранения щелей между тайлами

Структура файла включает:

  • header с метаданными
  • vertex buffer
  • index buffer
  • edge indices
  • per-tile bounding sphere/rectangle

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


Terrains на основе glTF-подобных структур

Иногда рельеф представляется через 3D-меши, где высота интегрирована в вершины. Такой подход используется в специализированных визуализациях, но хуже масштабируется для глобуса.


Создание собственного TerrainProvider

Базовая реализация кастомного провайдера сводится к расширению интерфейса TerrainProvider и реализации загрузки тайлов.

Основная логика:

class CustomTerrainProvider {
    constructor(options) {
        this._ready = true;
        this._tilingScheme = new Cesium.GeographicTilingScheme();
        this._errorEvent = new Cesium.Event();
    }

    requestTileGeometry(x, y, level) {
        const url = `/terrain/${level}/${x}/${y}.bin`;

        return fetch(url)
            .then(response => response.arrayBuffer())
            .then(buffer => decodeTerrain(buffer));
    }

    getLevelMaximumGeometricError(level) {
        return 1000 / Math.pow(2, level);
    }
}

Ключевая часть — функция декодирования, которая преобразует бинарный формат в структуру, совместимую с Cesium Native Terrain Data API.


Генерация тайлов пользовательского рельефа

Подготовка данных обычно проходит через этапы:

  1. Загрузка исходного DEM (SRTM, ASTER, LiDAR)
  2. Ресэмплинг к единой сетке
  3. Триангуляция или квантование
  4. Разбиение на тайлы по quadtree
  5. Кодирование в quantized-mesh или heightmap

Инструментальная цепочка часто включает GDAL:

  • gdal_translate для преобразования форматов
  • gdalwarp для ресэмплинга
  • gdal_dem для нормализации высот

Использование Cesium Terrain Server

Ряд реализаций базируется на серверной выдаче тайлов через HTTP. Структура URL обычно соответствует схеме:

/terrain/{level}/{x}/{y}.terrain

Каждый запрос возвращает бинарный пакет, содержащий:

  • вершины
  • индексы
  • bounding volumes
  • материалы (опционально)

Такая архитектура позволяет использовать CDN для кэширования и масштабирования.


Интеграция с Cesium Ion и приватные датасеты

Cesium предоставляет облачную инфраструктуру Cesium ion, где пользовательские рельефы могут быть загружены и автоматически преобразованы в оптимизированный quantized-mesh формат.

Внутренний пайплайн включает:

  • анализ входного DEM
  • генерацию пирамиды уровней детализации
  • компрессию высот
  • генерацию метаданных тайлового дерева

Результат публикуется как TerrainProvider-совместимый endpoint.


Оптимизация пользовательских terrain данных

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

Управление геометрической ошибкой

Каждый уровень детализации имеет значение geometric error, определяющее момент подмены тайла:

  • слишком малое значение → избыточные запросы
  • слишком большое → визуальные артефакты

Формула часто строится как экспоненциальное уменьшение:

error = baseError / (2 ^ level);

Кэширование тайлов

CesiumJS использует встроенный LRU-кэш для terrain tiles. При кастомной реализации важно:

  • корректно задавать tileAvailability
  • не пересоздавать объекты Geometry
  • использовать ArrayBuffer без копирования

Устранение швов между тайлами

Проблема seam artifacts решается через:

  • skirts (дополнительные вертикальные полигоны)
  • согласование границ вершин соседних тайлов
  • единое квантование высот на уровне плитки

Работа с локальными источниками DEM

Часто пользовательский terrain строится из локальных данных:

  • GeoTIFF
  • HGT (SRTM)
  • LAS/LAZ (LiDAR)

Типичный pipeline:

  1. Конвертация LAS → raster DEM
  2. Фильтрация шумов
  3. Построение регулярной сетки
  4. Генерация quantized-mesh tiles

Особое внимание уделяется вертикальному датуму (EGM96 vs WGS84), так как несоответствие приводит к смещению поверхности.


Динамические и процедурные рельефы

Помимо статических данных, terrain может формироваться процедурно:

  • шум Перлина для генерации ландшафта
  • runtime deformation (вулканические модели, разрушения)
  • streaming height updates

В таких случаях TerrainProvider возвращает данные, вычисленные на лету:

requestTileGeometry(x, y, level) {
    const geometry = generateProceduralTerrain(x, y, level);
    return Promise.resolve(geometry);
}

Смешивание нескольких источников рельефа

Комбинированные сцены используют несколько TerrainProvider:

  • глобальный базовый рельеф
  • локальные high-resolution участки
  • маскированные зоны (например, города или шахты)

Механизм переключения реализуется через CompositeTerrainProvider или кастомную агрегацию запросов.


Влияние пользовательского terrain на 3D-слои

Рельеф напрямую влияет на:

  • декалькорацию 3D Tiles
  • позиционирование моделей
  • физику столкновений
  • навигационные вычисления

Ошибки в данных приводят к:

  • “плавающим” объектам
  • проваливанию зданий
  • смещению координатных привязок

Формирование LOD-структуры

Иерархия тайлов строится по quadtree:

  • уровень 0 — глобальный тайл
  • уровень 1–5 — континенты/страны
  • уровень 6+ — локальная детализация

Каждый узел содержит ссылки на 4 дочерних тайла и метаданные геометрической ошибки.


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

CesiumJS использует асинхронную подгрузку:

  • сначала загружается low-res mesh
  • затем происходит refinement
  • финальный уровень заменяет предыдущий

Это обеспечивает непрерывную визуализацию без блокировки сцены.


Сетевые аспекты и форматы передачи

Для передачи terrain данных используются:

  • binary ArrayBuffer (основной формат)
  • compressed quantized-mesh
  • gzip/brotli поверх HTTP

Важно учитывать CORS-заголовки при хостинге локальных серверов, так как CesiumJS выполняет кросс-доменные запросы.


Обработка ошибок и fallback-механизмы

При недоступности тайлов система использует:

  • fallback на более грубый уровень
  • EllipsoidTerrainProvider как резерв
  • повторные запросы с backoff стратегией

Это предотвращает разрушение визуальной целостности сцены.


Взаимодействие с геодезическими системами координат

Terrain тесно связан с EPSG:4326 (WGS84). При работе с пользовательскими данными необходимо:

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

Несоответствие координатных систем приводит к деформации поверхности и смещению тайловой сетки.