Иерархия Entity

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

Entity не является изолированным объектом. Он всегда существует внутри EntityCollection или DataSource, а его поведение и визуализация определяются набором динамических свойств. Именно через эти свойства формируется логическая и графическая структура сцены, включая иерархию объектов.

EntityCollection как контейнер и основа группировки

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

Основные характеристики EntityCollection:

  • хранение набора Entity;
  • реактивное обновление сцены при изменении данных;
  • поддержка идентификаторов (id) для быстрых операций поиска;
  • управление жизненным циклом сущностей.

Структурно EntityCollection можно рассматривать как плоский список, однако внутри логики CesiumJS он участвует в построении иерархических связей через свойства самих Entity.

Пример добавления сущности:

const entity = viewer.entities.add({
    id: "city-center",
    position: Cesium.Cartesian3.fromDegrees(30.5, 50.45),
    point: {
        pixelSize: 10,
        color: Cesium.Color.YELLOW
    }
});

Иерархия через DataSource и композицию коллекций

Entity редко используется в одиночку. Более распространённый сценарий — использование DataSource. Каждый DataSource содержит собственную EntityCollection, а Viewer агрегирует несколько источников.

Иерархическая структура выглядит следующим образом:

  • Viewer

    • DataSourceDisplay

      • DataSource (GeoJSON, CZML, Custom)

        • EntityCollection

          • Entity
          • Entity
          • Entity

Такая организация позволяет:

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

Пример добавления источника:

const geoJsonSource = new Cesium.GeoJsonDataSource();
viewer.dataSources.add(geoJsonSource);

Родительско-дочерняя модель Entity

Внутри CesiumJS реализована мягкая иерархия Entity через свойства parent и children. Это не строгая сцепка сценографического графа, как в WebGL-движках низкого уровня, но логическая структура, используемая для группировки и наследования поведения.

Свойство parent

Каждая сущность может ссылаться на родительскую:

const parent = viewer.entities.add({
    id: "building",
    position: Cesium.Cartesian3.fromDegrees(30.5, 50.45)
});

const child = viewer.entities.add({
    id: "roof",
    parent: parent,
    position: Cesium.Cartesian3.fromDegrees(30.5, 50.45, 50)
});

Механизм children

Хотя children не всегда явно задаётся пользователем, CesiumJS формирует его автоматически на основе связей parent.

Такой подход позволяет:

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

Наследование свойств в иерархии Entity

Иерархия Entity влияет не только на логическую структуру, но и на поведение свойств.

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

Типы свойств:

  • PositionProperty
  • MaterialProperty
  • HeightReference
  • ShowProperty

Пример наследуемой логики:

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

Временная модель и иерархия состояний

Entity в CesiumJS поддерживает временные свойства через JulianDate и интервалы времени. Иерархия в этом контексте становится многослойной: каждый уровень может иметь собственную временную динамику.

Пример:

  • город (родитель) активен всегда;
  • транспорт (дочерние сущности) активен по расписанию;
  • события внутри транспорта имеют собственные временные интервалы.

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

const position = new Cesium.SampledPositionProperty();

position.addSample(Cesium.JulianDate.fromIso8601("2026-01-01T10:00:00Z"),
    Cesium.Cartesian3.fromDegrees(30.5, 50.45));

position.addSample(Cesium.JulianDate.fromIso8601("2026-01-01T11:00:00Z"),
    Cesium.Cartesian3.fromDegrees(30.6, 50.46));

Композиция графических примитивов внутри иерархии

Entity может включать несколько визуальных компонентов одновременно:

  • Billboard
  • Label
  • Point
  • Polygon
  • Polyline
  • Model

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

Иерархия проявляется в том, что:

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

Пример:

viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(30.5, 50.45),
    billboard: {
        image: "marker.png"
    },
    label: {
        text: "Объект",
        pixelOffset: new Cesium.Cartesian2(0, -20)
    }
});

Вложенные геометрии и логическая структура

Некоторые типы геометрий внутри Entity поддерживают вложенность, которая фактически формирует подуровни иерархии.

Полигон с отверстиями

polygon: {
    hierarchy: {
        positions: Cesium.Cartesian3.fromDegreesArray([
            30.0, 50.0,
            31.0, 50.0,
            31.0, 51.0,
            30.0, 51.0
        ]),
        holes: [{
            positions: Cesium.Cartesian3.fromDegreesArray([
                30.3, 50.3,
                30.7, 50.3,
                30.7, 50.7,
                30.3, 50.7
            ])
        }]
    }
}

Здесь hierarchy внутри polygon формирует подиерархию геометрии:

  • внешний контур;
  • внутренние отверстия;
  • дополнительные уровни вложенности.

Иерархия моделей и привязка к Entity

3D-модели также вписываются в структуру Entity как зависимые визуальные компоненты.

model: {
    uri: "building.glb",
    scale: 1.0
}

Модель наследует:

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

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

Связь Entity и Scene Graph

Хотя CesiumJS не предоставляет пользователю явного scene graph API на уровне Entity, внутренняя система рендеринга трансформирует Entity в граф примитивов.

Соответствие:

  • Entity → логический узел
  • Primitive → графический объект WebGL
  • Scene Graph → результирующая структура рендера

Иерархия Entity существует на уровне данных, тогда как scene graph — на уровне визуализации.

Динамическая модификация и перестройка иерархий

Entity может изменять свою структуру во время выполнения:

  • добавление дочерних сущностей;
  • изменение parent;
  • замена визуальных компонентов;
  • переключение DataSource.

Пример переноса в иерархии:

child.parent = newParent;

Это вызывает перерасчёт отображения и обновление сцены без полного пересоздания объектов.

DataSource как механизм логической сегментации иерархий

Каждый DataSource может представлять отдельную область иерархии:

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

При этом все они объединяются в Viewer, но сохраняют автономность.

Структура:

  • Viewer

    • DataSource A (город)

      • Entity (здания)
    • DataSource B (транспорт)

      • Entity (автобусы)
    • DataSource C (события)

      • Entity (метки)

Итеративная композиция сложных объектов

Иерархия Entity позволяет строить сложные составные структуры:

  • здание → этажи → комнаты → объекты интерьера;
  • транспортный узел → платформы → поезда → вагоны;
  • территория → зоны → маркеры → события.

Каждый уровень реализуется через:

  • parent/child связи;
  • логическую группировку;
  • общие свойства трансформации.

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