OrbPro2 a Cesium distribution

EntityCollection

new Cesium.EntityCollection(owner)

An observable collection of Entity instances where each entity has a unique id.
Name Type Description
owner DataSource | CompositeEntityCollection optional The data source (or composite entity collection) which created this collection.

Members

Gets the event that is fired when entities are added or removed from the collection. The generated event is a EntityCollection.CollectionChangedEventCallback.
Gets a globally unique identifier for this collection.
Gets the number of members in this collection, packed sites included. Identical to EntityCollection#totalLength, and to values.length.
Gets the owner of this entity collection, ie. the data source or composite entity collection which created it.
Gets the number of packed sites in this collection, tombstones excluded.
Gets whether or not this entity collection should be displayed. When true, each entity is only displayed if its own show property is also true.
Gets the number of ordinary plus packed members.
Gets the array of Entity instances in the collection, packed members included. This array should not be modified directly.

A collection with no packed blocks returns the SAME array object it always did - the stock fast path, byte for byte, with no wrapper of any kind.

A collection that holds packed sites (see EntityCollection#addBulkPacked) returns a lazy EntityMemberView: Array.isArray is true, length counts every member, values[i], for...of, spread and every Array.prototype read method work, and a packed site becomes a real Entity only when something reads it. indexOf, lastIndexOf, includes and slice answer from the block's typed arrays and materialize nothing at all; filter/map/forEach and the rest materialize each member as they visit it, which costs an ordinary Entity for every member the caller RETAINS and nothing for the ones it does not. The view is read-only: assigning into it throws.

Known gap - the object IDENTITY changes at the first block and at the last one. A reference taken while the collection had no packed blocks is the stock array, and it goes on being the stock array: it does not follow the packed members that arrive afterwards, and held !== collection.values from that moment. The same flip happens in reverse when the last block is dropped. Once a view exists it IS live - one object for the life of the collection, always reporting membership as it is now - so the gap is exactly the first EntityCollection#addBulkPacked and the last EntityCollection#removePacked.

Deliberate, and the alternative was measured: making every collection return a Proxy from the start would put the trap on the hot path of every application that never packs anything, at roughly 100x per element read against a raw array index. An existing caller must measure byte-identical to what it measured before this layer existed, and that is the trade - paid once, at the moment a collection stops being an ordinary one. Pinned by DIVERGENCE 8 in `entityMemberViewDifferential.test.mjs`; closing it is `orbpro-flyweight-entity-facade`'s to decide, not something to paper over here.

Methods

Iterates every member, packed sites included. A packed site is materialized as the iteration reaches it and is retained only by the bounded materialization ring, so a loop that keeps nothing costs nothing.
Returns:
The iterator.
Add an entity to the collection.
Name Type Description
entity Entity | Entity.ConstructorOptions The entity to be added.
Returns:
The entity that was added.
Throws:
Add multiple entities to the collection in one event window.
Name Type Description
entities Array.<(Entity|Entity.ConstructorOptions)> Incoming entities.
Returns:
Added entities in input order.
Throws:
Adds a block of static sites stored entirely in typed arrays.

Transparency contract

A packed site is a full member of this collection in EVERY public sense. No caller can tell a packed member from an ordinary one except by measuring memory: a site costs about 122 bytes at rest against about 3.4 kilobytes for an ordinary Entity, so a million of them fit where a million entities do not.

  • EntityCollection#values, EntityCollection#length, EntityCollection#get, iteration and the Array.prototype read methods all cover packed members. A packed member becomes a real Entity the moment something reads it, through the same bounded identity machinery EntityCollection#getById uses, so a scan that retains nothing costs nothing and a caller that retains a million members pays for a million entities - its own choice, made explicitly.
  • EntityCollection#collectionChanged fires for a packed add, remove or change, batched by suspendEvents exactly like an ordinary one. The payloads are lazy EntityMemberView arrays: adding a million sites emits ONE event whose added.length is one million and which materializes zero entities. Every stock visualizer reads EntityMemberView.denseOf and skips the packed runs it cannot draw; PointVisualizer reads the runs themselves and hands each block to its PointPrimitiveCollection.
  • EntityCollection#getById returns a real Entity for a packed id, with the full entity API.
  • EntityCollection#contains returns true for it, so selection, tracking, zoomTo and DataSourceDisplay#getBoundingSphere work.
  • Identity: an entity handed out by getById, by picking or by EntityCollection#unpackById is PINNED - every later lookup returns that same object for as long as anything holds it. An entity first seen through a bulk values scan is held only by the bounded materialization ring (EntityCollection#setPackedMaterializationLimit, default 4096), because pinning a million of them would retain them all.
  • A materialization is a LIVE VIEW of its site, not a snapshot. entity.position, entity.show and entity.point follow every block mutation, and a write through any of them - entity.show = false, entity.point.color = Color.RED, entity.point.pixelSize = 12, entity.position.setValue(...) - goes back into the site's typed arrays and re-commits exactly one vertex. No PointGraphics is ever cloned per site.
  • Assigning anything the packed vertex cannot hold - billboard, label, model, path, polyline, any geometry, orientation, a non-constant position, an availability, a NON-CONSTANT colour, pixel size, outline width or show, or a point property the style GROUP owns (outlineColor, heightReference, scaleByDistance, translucencyByDistance, distanceDisplayCondition, disableDepthTestDistance, splitDirection) given a value that differs from the group's - AUTO-PROMOTES that one site to an ordinary member, so the assignment renders exactly as it would on any entity. Nothing is ever silently dropped. A promoted site costs a full ordinary Entity, about 3.4 kilobytes, so promoting a hundred thousand sites costs about 340 MB. EntityCollection#unpackById performs the same promotion explicitly, and preserves object identity either way.
  • A materialized site that is WRITTEN TO is pinned: the object the caller put state on is the object every later getById, pick and re-read returns. A site merely READ through values[i] is not, so a bulk enumeration of a million members still leaves the identity map exactly as it found it.
  • entity.show and entity.point.show ALIAS one another on a packed site, where on an ordinary entity they are independent: a packed vertex carries one SHOW bit and both accessors read and write it. Promote the site when the two must be separate.
  • EntityCollection#computeAvailability treats a packed site exactly as an ordinary entity whose availability is undefined: it neither narrows nor widens the interval. Assigning an availability to a materialized site PROMOTES it, for the same reason a billboard does: the packed vertex carries one show bit and no notion of time, so a site that kept its slot would report isAvailable(t) === false through the entity API and go on drawing on screen. After promotion the site is time-gated by PointVisualizer and counted by computeAvailability exactly like any other entity.
  • CompositeEntityCollection borrows a child's packed blocks BY REFERENCE, so a composite's values, length, getById, contains, iteration and computeAvailability all cover them. Only an id collision between a packed site and an ordinary entity materializes anything, and only that one site. addBulkPacked itself still throws through a composite: a composite owns no storage.

All sites in a style group share one PointGraphics - that sharing is why a million sites cost no graphics objects. A MATERIALIZED site gets its OWN PointGraphics, built from the group plus the site's own overrides and assigned through the public setter, so it behaves exactly like an ordinary entity's; there are at most a few thousand of those at a time. Per-site colour, pixel size and outline width live in the block's typed arrays - four bytes, four bytes and four bytes - allocated on first use and never before.

The block subscribes to each group's graphics ONCE - per group, never per site - so a style group is writable after construction: a write through PackedEntityBlock#setStyleColor or block.styleGraphics(group) re-bakes that group and restyles every site wearing it, under the same per-frame chunk budget as the initial build.

Name Type Description
descriptor PackedEntityDescriptor The packed site description.
Returns:
The block that was added.
Throws:
  • DeveloperError : Packed entities are not supported inside a CompositeEntityCollection.
Example:
const block = viewer.entities.addBulkPacked({
  count: sites.count,
  lonLatE6: sites.lonLatE6,
  styleGroups: RADIO_STYLE_GROUPS,
  styleIndex: sites.radioIndex,
  idPrefix: "cell-",
});

applyVisibilityMask(mask)number

Apply a caller-supplied visibility mask to the whole collection in one pass. This is the counterpart to EntityCollection#queryVisibilityMaskByName and EntityCollection#queryVisibilityMaskBySql: feed either result straight back in. The mask does not have to come from this collection's own query surface — a semantic/embedding search, a worker, or a server can build one.

Two lengths are accepted, and on a collection with no packed sites they are the same number:

  • Dense-aligned — one byte per ORDINARY member. This is what this collection's own query surface produces (see EntityCollection.VisibilityMaskResult); packed sites keep the visibility they already had.
  • Member-aligned — one byte per member of EntityCollection#values, ordinary members first and then each packed run in order, so a mask built over a EntityCollection#queryRegionEntities selection hides and shows packed sites too. Packed sites are written straight into the block's show bits: one staged run per block, no Entity materialized.
When the WASM backend holds handles for every ordinary entity the dense half is applied as a single batched call; otherwise the collection falls back to setting Entity#show, with events suspended so listeners see one update.
Name Type Description
mask Uint8Array One byte per member: 1 shows, 0 hides.
Returns:
The number of entities left visible.
Throws:
Example:
const result = viewer.entities.queryVisibilityMaskByName("starlink");
viewer.entities.applyVisibilityMask(result.mask);
Computes the maximum availability of the entities in the collection. If the collection contains a mix of infinitely available data and non-infinite data, it will return the interval pertaining to the non-infinite data only. If all data is infinite, an infinite interval will be returned.
Returns:
The availability of entities in the collection.
Returns true if the provided entity is in this collection, false otherwise.
Name Type Description
entity Entity The entity.
Returns:
true if the provided entity is in this collection, false otherwise.
Gets the member at an index, packed sites included.

The same resolution values[index] performs, without the Proxy hop.

Name Type Description
index number The member index.
Returns:
The member, or undefined when the index is out of range.
Gets an entity with the specified id.
Name Type Description
id string The id of the entity to retrieve.
Returns:
The entity with the provided id or undefined if the id did not exist in the collection.
Gets an entity with the specified id or creates it and adds it to the collection if it does not exist.
Name Type Description
id string The id of the entity to retrieve or create.
Returns:
The new or existing object.
Returns the packed blocks in this collection.
Returns:
The blocks.
The FlatSQL catalogs of this collection's packed blocks, built on demand.
Returns:
The catalogs.

queryEntityIdsByName(query, maxCount)Array.<string>

Query entity IDs using collection-wide full-text search.
Name Type Default Description
query string Text query.
maxCount number 100 optional Max ids to return.
Returns:
Matching entity IDs.

queryEntityIdsBySql(sql, maxCount)Array.<string>

Execute an arbitrary shared SQL query and extract unique entity ids from the projected `entity_id`/`ENTITY_ID` column.
Name Type Default Description
sql string SQL query text.
maxCount number 100 optional Max ids to return.
Returns:
Matching entity ids.

queryEntityRowsByName(query, maxCount)Array.<object>

Query entities using collection-wide full-text search. Search spans all entity subclasses and known standards metadata fields.
Name Type Default Description
query string Text query.
maxCount number 100 optional Max rows to return.
Returns:
Matching rows.

queryEntityRowsBySql(sql, maxRows)Array.<object>

Execute an arbitrary shared SQL query against the collection-wide FlatSQL entity metadata table. The SQL result should project `entity_id`/`ENTITY_ID` when the caller intends to derive ids or visibility from the result.
Name Type Default Description
sql string SQL query text.
maxRows number 1000 optional Max rows to materialize.
Returns:
Query rows.

queryPackedRowsBySql(sql, options)object

Runs a broad-phase statement against a packed block's PackedEntityCatalog and refines its candidates exactly.

The statement is the ONLY source of candidates - it names contiguous runs of sites through FIRST_ROW/ROW_COUNT - and the exact phase is Analysis' own containment math plus the caller's attribute ranges, read straight out of the block's typed arrays. Nothing is materialized: filtering a million sites costs zero Entity objects.

Name Type Description
sql string A statement over the block's tile table.
options object optional Options.
Name Type Description
block PackedEntityBlock optional The block, required when the collection holds more than one.
region object optional Region descriptor for the exact phase.
attributeRanges object optional Per-attribute [low, high].
maxRows number optional Cap on returned rows.
Returns:
{rowIds, slots, block, catalog, candidateCount, sql}. rowIds and slots are INDEX-ALIGNED and both are ordered by slot: slots[i] is the block slot of the site rowIds[i] names, and catalog.order[rowIds[i]] === slots[i] for every i. candidateCount is how many rows the broad phase produced before the exact phase, which is the selectivity of the tiling and not the size of the answer.

queryRegionEntities(region, options)Array.<Entity>

The members inside a region, as a lazy Entity list.

This is the lasso / rectangle / country selection path. Packed sites are selected through their PackedEntityCatalog - a SQL tile prefilter plus Analysis' exact containment - and ordinary members through the same containment test on their evaluated position. The result is an Entity[] in every sense that matters: selection.length is free, selection[0] is a real Entity suitable for viewer.selectedEntity, trackedEntity or zoomTo, and nothing is materialized until it is read.

Name Type Description
region object A region descriptor from Analysis.createCartographicRectangleRegion, Analysis.createCartographicPolygonRegion or any other region constructor.
options object optional Options.
Name Type Default Description
time JulianDate optional Time at which ordinary positions are read.
attributeRanges object optional Per-attribute [low, high] applied to packed sites.
maxRows number optional Cap on packed rows per block.
includeOrdinary boolean true optional Whether ordinary members are tested too.
Returns:
The selection.
Build a dense-aligned visibility mask using collection-wide full-text search — one byte per ORDINARY member. See EntityCollection.VisibilityMaskResult for why packed sites are not covered and how to hide them.
Name Type Description
query string Text query.
Returns:
Visibility result.
Execute an arbitrary shared SQL query and build a dense-aligned visibility mask from the projected `entity_id`/`ENTITY_ID` column — one byte per ORDINARY member. See EntityCollection.VisibilityMaskResult.
Name Type Description
sql string SQL query text.
Returns:
Visibility result.

refreshEntitySearchIndex(entity)

Re-index one entity for collection-wide full-text search. Use this after metadata-only updates that do not emit definitionChanged.
Name Type Description
entity Entity The entity to re-index.
Removes an entity from the collection.
Name Type Description
entity Entity The entity to be removed.
Returns:
true if the item was removed, false if it did not exist in the collection.
Removes all Entities from the collection, packed members included: every packed block is removed and its materializations detached.
Removes an entity with the provided id from the collection.

A packed site's slot is tombstoned instead: it stops being a member, its vertex is hidden, and any live materialization is detached from the collection.

Name Type Description
id string The id of the entity to remove.
Returns:
true if the item was removed, false if no item with the provided id existed in the collection.

removePacked(block)boolean

Removes a packed block and drops every live materialization it owns.
Name Type Description
block PackedEntityBlock The block to remove.
Returns:
Whether the block was removed.
Resumes raising EntityCollection#collectionChanged events immediately when an item is added or removed. Any modifications made while while events were suspended will be triggered as a single event when this function is called. This function is reference counted and can safely be called multiple times as long as there are corresponding calls to EntityCollection#resumeEvents.
Throws:
  • DeveloperError : resumeEvents can not be called before suspendEvents.

rowsToEntities(rowIds, block)Array.<Entity>

Resolves catalog rows to members.

Identity holds: rowsToEntities(rows, block)[k] is the same object getById returns for that site.

Name Type Description
rowIds Uint32Array | Array.<number> Catalog rows.
block PackedEntityBlock optional The block, required when the collection holds more than one.
Returns:
A lazy list of the rows' members.

setPackedMaterializationLimit(limit)

Sets how many materialized packed entities are held strongly.

Beyond this bound a materialization survives only while something else holds a reference to it - a selection, a tracked entity, an application array.

Name Type Description
limit number The number of entities to retain.
Prevents EntityCollection#collectionChanged events from being raised until a corresponding call is made to EntityCollection#resumeEvents, at which point a single event will be raised that covers all suspended operations. This allows for many items to be added and removed efficiently. This function can be safely called multiple times as long as there are corresponding calls to EntityCollection#resumeEvents.
Promotes a packed site to an ordinary, independently styled member.

The site's slot is tombstoned, the entity gains its own PointGraphics clone, and from then on it behaves exactly like any entity added with EntityCollection#add.

Name Type Description
id string The packed site id.
Returns:
The promoted entity, or undefined when no packed site has that id.

Type Definitions

Cesium.EntityCollection.CollectionChangedEventCallback(collection, added, removed, changed, carriesPackedMembers)

The signature of the event generated by EntityCollection#collectionChanged. When the batch carries packed members (see EntityCollection#addBulkPacked) the three payloads are lazy EntityMemberView arrays rather than plain arrays: Array.isArray is still true and every read method still works, but a packed member becomes an Entity only when the listener actually indexes it. A listener that only needs the ordinary members should take EntityMemberView.denseOf of each payload; one that draws packed sites should read EntityMemberView.packedSegmentsOf.
Name Type Description
collection EntityCollection The collection that triggered the event.
added Array.<Entity> The array of Entity instances that have been added to the collection.
removed Array.<Entity> The array of Entity instances that have been removed from the collection.
changed Array.<Entity> The array of Entity instances that have been modified.
carriesPackedMembers boolean Whether the three lists can hold PACKED members (see EntityCollection#addBulkPacked) and are therefore lazy EntityMemberViews rather than plain arrays. A listener that draws something a packed site does not carry reads past the packed runs with EntityMemberView.denseOf when this is true, and takes the list as it stands when it is false - which is the case for every collection that has never held a packed block. Existing listeners that ignore this argument behave exactly as they always did.

Cesium.EntityCollection.VisibilityMaskResult

A visibility result: one byte per entity, in values order, where 1 means visible and 0 means hidden. Pass one straight to EntityCollection#applyVisibilityMask to show the result in the scene. A mask built anywhere else — a semantic/embedding search, a server response, a worker — is equally valid.

Alignment. This collection's own name/SQL query surface searches the shared entity-metadata catalog, which holds a row per ORDINARY member: a packed site's searchable attributes live in its own PackedEntityCatalog instead, reached through EntityCollection#queryPackedRowsBySql and EntityCollection#queryRegionEntities. A mask these producers build is therefore dense-aligned — one byte per ordinary member, which is values.length exactly when the collection holds no packed sites. EntityCollection#applyVisibilityMask accepts EITHER a dense-aligned mask (packed sites untouched) or a full length mask covering every member, packed sites included.

Properties:
Name Type Description
mask Uint8Array One byte per ordinary entity.
visibleCount number Number of entries set to 1.
Need help? The fastest way to get answers is from the community and team on the Cesium Forum.