Экспорт в форматы данных

CesiumJS опирается на набор стандартизированных и де-факто общепринятых форматов геопространственных данных, обеспечивая совместимость между 3D-графикой, ГИС-системами и веб-приложениями. Экспорт данных в CesiumJS обычно связан с преобразованием внутренних структур сцены (entities, primitives, data sources) в форматы, пригодные для хранения, передачи и повторного использования.

Ключевыми направлениями экспорта выступают GeoJSON, CZML, KML, glTF и 3D Tiles, каждый из которых обслуживает разные классы задач — от обмена векторной геометрией до потоковой передачи сложных 3D-сцен.


GeoJSON как универсальный формат векторных данных

GeoJSON используется для описания геометрических объектов в формате JSON и широко применяется для обмена данными между веб-картографическими сервисами.

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

Экспорт сущностей в GeoJSON требует преобразования объектов Entity в стандартизированные геометрии:

function entityToGeoJSON(entity) {
  const position = entity.position.getValue(Cesium.JulianDate.now());
  const cartographic = Cesium.Cartographic.fromCartesian(position);

  return {
    type: "Feature",
    geometry: {
      type: "Point",
      coordinates: [
        Cesium.Math.toDegrees(cartographic.longitude),
        Cesium.Math.toDegrees(cartographic.latitude),
        cartographic.height
      ]
    },
    properties: {
      name: entity.name
    }
  };
}

Для коллекций объектов формируется FeatureCollection:

function exportEntitiesToGeoJSON(viewer) {
  const features = viewer.entities.values.map(entityToGeoJSON);

  return {
    type: "FeatureCollection",
    features: features
  };
}

Готовый объект затем сериализуется:

const geojson = exportEntitiesToGeoJSON(viewer);
const blob = new Blob([JSON.stringify(geojson)], { type: "application/json" });

CZML как специализированный потоковый формат Cesium

CZML представляет собой JSON-формат, ориентированный на описание динамических сцен во времени. Он поддерживает временные интервалы, анимацию, стилизацию и сложные траектории объектов.

Экспорт в CZML особенно актуален при работе с движущимися объектами и временными рядами координат.

Структура CZML-пакета включает пакетную декларацию и последовательность пакетов:

const czml = [
  {
    id: "document",
    version: "1.0"
  },
  {
    id: "dynamicPoint",
    position: {
      epoch: "2026-01-01T00:00:00Z",
      cartographicDegrees: [
        0, 37.0, 55.0, 1000,
        60, 37.5, 55.2, 1500,
        120, 38.0, 55.5, 2000
      ]
    }
  }
];

Экспорт динамических данных из SampledPositionProperty:

function sampledPositionToCZML(entity) {
  const positionProperty = entity.position;
  const samples = positionProperty._property._times; // внутреннее представление

  const czmlPositions = [];

  samples.forEach(time => {
    const pos = positionProperty.getValue(time);
    const carto = Cesium.Cartographic.fromCartesian(pos);

    czmlPositions.push(
      Cesium.JulianDate.secondsDifference(time, samples[0]),
      Cesium.Math.toDegrees(carto.longitude),
      Cesium.Math.toDegrees(carto.latitude),
      carto.height
    );
  });

  return czmlPositions;
}

KML и совместимость с классическими ГИС-системами

KML (Keyhole Markup Language) применяется в Google Earth и ряде ГИС-инструментов. CesiumJS поддерживает импорт через KmlDataSource, но экспорт требует ручной генерации XML-структуры.

Пример преобразования точки в KML:

function entityToKML(entity) {
  const position = entity.position.getValue(Cesium.JulianDate.now());
  const carto = Cesium.Cartographic.fromCartesian(position);

  return `
<Placemark>
  <name>${entity.name}</name>
  <Point>
    <coordinates>
      ${Cesium.Math.toDegrees(carto.longitude)},
      ${Cesium.Math.toDegrees(carto.latitude)},
      ${carto.height}
    </coordinates>
  </Point>
</Placemark>`;
}

Формирование KML-документа:

function exportToKML(viewer) {
  const placemarks = viewer.entities.values.map(entityToKML).join("\n");

  return `<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
${placemarks}
</Document>
</kml>`;
}

glTF как стандарт 3D-геометрии

glTF используется для описания 3D-моделей и сцен. CesiumJS активно работает с этим форматом через Model и Cesium.Model.

Экспорт в glTF обычно не выполняется напрямую из CesiumJS, так как сцена Cesium не хранит полноценную DCC-модель. Однако возможно извлечение загруженных моделей и их повторное сохранение через pipeline ассетов.

Основная схема включает:

  • загрузку модели glTF/glb
  • модификацию трансформаций
  • повторную сериализацию через внешние инструменты (например, glTF-Transform)

Пример извлечения модели:

const modelMatrix = model.modelMatrix;
const url = model._resource.url;

Дальнейшая обработка требует внешнего конвертера, так как CesiumJS не предоставляет API обратной сериализации.


3D Tiles как формат потоковой передачи сцен

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

Экспорт в 3D Tiles обычно осуществляется не из CesiumJS, а из инструментов подготовки данных (Cesium ion, tilers, pipelines на основе PDAL, FME, Blender).

Тем не менее сцена Cesium может быть использована для анализа структуры tileset:

viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
  url: "tileset.json"
}));

Извлечение метаданных:

tileset.tileLoad.addEventListener(tile => {
  console.log(tile.content.featuresLength);
});

Фактически экспорт в 3D Tiles сводится к подготовке источника данных и его публикации, а не к преобразованию из runtime-сцены.


Преобразование координат при экспорте

Любой экспорт в внешние форматы требует перехода от внутренней модели Cesium (Cartesian3) к географическим координатам.

Основная цепочка преобразования:

const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
const lon = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
const height = cartographic.height;

Для обратного преобразования при импорте:

const cartesian = Cesium.Cartesian3.fromDegrees(lon, lat, height);

Ошибки экспорта часто связаны с игнорированием эллипсоида WGS84 и неправильной интерпретацией высот.


Экспорт данных сцены Viewer

Cesium Viewer содержит три основных источника данных:

  • viewer.entities
  • viewer.dataSources
  • viewer.scene.primitives

Экспорт entities в структурированный JSON:

function exportViewerState(viewer) {
  return viewer.entities.values.map(entity => ({
    id: entity.id,
    name: entity.name,
    position: entity.position ? entity.position.getValue(Cesium.JulianDate.now()) : null
  }));
}

Для DataSource:

function exportDataSources(viewer) {
  return viewer.dataSources._dataSources.map(ds => ds.name);
}

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


Сохранение экспортированных данных в файл

Любой формат после генерации преобразуется в Blob и сохраняется через механизм загрузки браузера:

function download(data, filename, type) {
  const blob = new Blob([data], { type });
  const url = URL.createObjectURL(blob);

  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();

  URL.revokeObjectURL(url);
}

Этот механизм универсален для GeoJSON, CZML и KML.


Ограничения и особенности сериализации CesiumJS

Экспорт из CesiumJS не является симметричным процессом относительно импорта. Основные ограничения связаны с тем, что:

  • Entities могут содержать процедурные свойства (CallbackProperty), которые невозможно сериализовать напрямую
  • Primitives не имеют стандартного формата хранения
  • Анимационные данные требуют дискретизации во времени
  • 3D Tiles и glTF формируют отдельный пайплайн вне runtime-сцены

Поэтому экспорт чаще строится как выборочная сериализация значимых слоёв сцены, а не полное восстановление состояния визуализации.