An observable collection of
Entity instances where each entity has a unique id.
Members
Gets a globally unique identifier for this collection.
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.
Returns:
The entity that was added.
Throws:
Add multiple entities to the collection in one event window.
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.
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-",
});
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:
-
-
DeveloperError
: mask length must equal the number of entities in the collection.
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.
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.
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.
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.
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.
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.
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.
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.
Removes a packed block and drops every live materialization it owns.
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:
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.
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. |
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)
| 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. |
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. |