В архитектуре CesiumJS группировка объектов опирается на разделение сценических данных на логические слои и коллекции, которые могут динамически включаться, выключаться и комбинироваться. Основная цель группировки заключается в управлении сложными наборами геопространственных данных без потери производительности и без усложнения логики рендеринга.
На уровне API группировка реализуется через несколько фундаментальных
механизмов: EntityCollection, DataSource,
PrimitiveCollection, а также через высокоуровневые
представления вроде GeoJsonDataSource и
Cesium3DTileset. Каждый из этих уровней решает задачу
агрегации объектов с различной степенью абстракции.
Entity-ориентированная модель позволяет объединять объекты в логические наборы, где каждый объект содержит набор свойств: геометрию, стили, временные интервалы, а также пользовательские атрибуты. При этом коллекции сущностей могут динамически изменяться во время выполнения, что делает группировку не статической, а реактивной.
EntityCollection выступает базовой структурой для
хранения и управления сущностями. Она позволяет объединять разнородные
объекты в единый контейнер, обеспечивая доступ к ним по идентификаторам
и возможность массовых операций.
При добавлении сущностей в коллекцию важно учитывать, что они не просто группируются логически, но и наследуют поведение коллекции: обновление, удаление и фильтрация применяются ко всей группе.
const collection = new Cesium.EntityCollection();
const entityA = collection.add({
id: "point-1",
position: Cesium.Cartesian3.fromDegrees(30, 50),
point: { pixelSize: 10 }
});
const entityB = collection.add({
id: "point-2",
position: Cesium.Cartesian3.fromDegrees(31, 51),
point: { pixelSize: 10 }
});
Группировка в этом контексте формируется не через иерархию, а через принадлежность к общей коллекции, что упрощает управление большим числом объектов.
DataSource расширяет концепцию группировки, вводя
тематические наборы данных. Каждый источник данных представляет собой
самостоятельный слой, который может быть добавлен в
DataSourceCollection.
Типичные реализации включают GeoJsonDataSource,
CzmlDataSource, KmlDataSource. Каждый из них
формирует логическую группу объектов на основе входного формата
данных.
const geoJsonSource = await Cesium.GeoJsonDataSource.load("data/map.geojson");
viewer.dataSources.add(geoJsonSource);
Группировка на уровне DataSource позволяет управлять
целыми слоями данных, включая их отображение, стилизацию и временную
фильтрацию.
На более низком уровне находится PrimitiveCollection,
которая работает напрямую с графическими примитивами. Здесь группировка
становится исключительно рендеринговой: объекты объединяются для
оптимизации отрисовки.
Примитивы не обладают семантикой сущностей, но обеспечивают высокую производительность при работе с большими массивами геометрии.
const primitives = new Cesium.PrimitiveCollection();
const primitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.BoxGeometry({
maximum: new Cesium.Cartesian3(1000000, 1000000, 1000000)
})
})
});
primitives.add(primitive);
viewer.scene.primitives.add(primitives);
Группировка здесь носит характер оптимизационного слоя, где логика полностью отделена от визуализации.
Фильтрация объектов в Cesium чаще всего реализуется через свойства
сущностей, условия отображения и динамические выражения. Основной
механизм — изменение свойств show, которое определяет
видимость объекта.
entity.show = false;
При работе с коллекциями возможно применение массовой фильтрации, основанной на обходе элементов и проверке их атрибутов:
collection.values.forEach(e => {
if (e.properties && e.properties.type === "restricted") {
e.show = false;
}
});
Фильтрация может быть как статической, так и динамической, когда состояние объекта зависит от времени или внешних данных.
Более гибкий механизм фильтрации реализуется через
Property API. Он позволяет привязывать видимость и стиль к
изменяющимся значениям.
entity.show = new Cesium.CallbackProperty(function (time) {
return Cesium.JulianDate.toDate(time).getHours() > 6;
}, false);
Такой подход превращает фильтрацию в непрерывный процесс, зависящий от временной шкалы или пользовательских данных.
Дополнительно используются ColorMaterialProperty,
DistanceDisplayConditionProperty, которые позволяют
скрывать или изменять объекты в зависимости от расстояния или других
параметров сцены.
Особое место занимает фильтрация в Cesium3DTileset, где
используется стильовая система на основе условий.
tileset.style = new Cesium.Cesium3DTileStyle({
color: "(${height} > 100) ? color('red') : color('white')"
});
Здесь фильтрация происходит на уровне GPU-пайплайна, что обеспечивает высокую производительность при работе с миллионами объектов.
Также применяется скрытие тайлов через show и управление
выборкой через maximumScreenSpaceError, влияющее на уровень
детализации.
Кластеризация применяется к точечным данным и реализуется через
EntityCluster. Она объединяет близко расположенные объекты
в один визуальный кластер.
viewer.entities.clustering.enabled = true;
viewer.entities.clustering.pixelRange = 50;
viewer.entities.clustering.minimumClusterSize = 3;
Кластеры формируют динамические группы, которые пересчитываются при изменении камеры, обеспечивая адаптивную визуализацию плотных наборов данных.
Каждый DataSource обладает свойством show,
позволяющим включать и отключать целые группы данных.
geoJsonSource.show = false;
Это создаёт эффективный механизм переключения тематических слоёв без необходимости обхода всех сущностей внутри источника.
В сочетании с несколькими источниками данных формируется система многослойной фильтрации, где каждый слой представляет отдельную логическую категорию.
Фильтрация может опираться на параметры камеры: положение, угол обзора, расстояние до объектов. Это используется для оптимизации и контекстного отображения данных.
const distance = Cesium.Cartesian3.distance(
viewer.camera.position,
entity.position.getValue(viewer.clock.currentTime)
);
entity.show = distance < 50000;
Такой подход позволяет строить адаптивные сцены, где объекты появляются или исчезают в зависимости от масштаба.
В реальных сценариях применяется комбинация нескольких уровней:
DataSourceEntityCollectionPrimitiveCollection3D TilesProperty APIСистема становится многослойной, где каждый уровень отвечает за свою
часть фильтрации. Например, DataSource может скрывать целый
слой, внутри которого Entity фильтрует объекты по времени,
а Tileset ограничивает детализацию.
Такое разделение позволяет масштабировать сцены до миллионов объектов без потери управляемости и производительности.