A block of static sites stored entirely in typed arrays.
Nothing per-site is a JavaScript object. A packed site is 24 bytes of
position, one byte of style index, one byte of state, and the vertex-array
bytes the GPU already requires. Entity, PointGraphics,
PointPrimitive and pick ids are materialized on demand and bounded.
Create one with EntityCollection#addBulkPacked; the constructor is
not part of the public API.
Style groups are shared, and writable. All sites in a group reference
one PointGraphics instance, and that instance is assigned to a
materialized entity's private field so a shared graphics object cannot
retain a million entities through its definitionChanged event.
The block subscribes to that event once per GROUP, so a write to the shared
object - PackedEntityBlock#setStyleColor,
block.styleGraphics(group).pixelSize = 42, or the same write
made THROUGH a materialized entity - re-bakes the group and restyles every
site wearing it. Nothing else can change a group's pixel size, outline,
scale-by-distance, translucency, depth-test distance or show. The affected
sites are rewritten under the per-frame chunk budget, so restyling a
million-site group takes as many frames as building it did; see
PackedEntityBlock#dirtyVertices. A site carrying a per-site colour
override holds a CLONE of its group's graphics instead, so a write through
that clone reaches only that one entity. Use
EntityCollection#unpackById to obtain an independently styled site.
Slots are never compacted, and there is no compact().
PackedEntityBlock#removeAt tombstones a slot: it keeps its vertex,
its 24 bytes of position and its pick key for the life of the block, which
is what lets every surviving index, id and pick key keep its meaning across
any number of removals. Rebuild the block to reclaim tombstoned slots.
See:
Members
The number of sites that have not been removed.
Queryable per-site attribute columns, as
{name: {array, tile}}. The arrays are the caller's - adopted,
never copied - and they are what a SQL attribute filter and a WASM
analysis batch both read.
The block's FlatSQL broad-phase catalog, built on first use.
Lazy on purpose: the catalog is the query surface, and a block that is
only ever drawn should not pay for one. Building it is measured and
reported by PackedEntityCatalog#buildMilliseconds.
The show state of the collection that owns this block, ANDed with every
site's own show bit when its vertex is written.
Optional per-site describe hook, invoked once when a site materializes.
A DECORATION hook: it may set name, description,
properties, viewFrom, allowPicking
and trackingReferenceFrame on the entity being built.
Anything that would change what the SITE draws throws a
RuntimeError naming the property, because the hook runs for
the sites something happens to materialize and for no others. See
EntityCollection.PackedEntityDescriptor.
The number of vertices staged for rewrite and not yet written. Staged
writes are drained under the same per-frame chunk budget as the initial
build, so a whole-block restyle takes as many frames as the build did.
The ellipsoid the block's geodetic conversions used.
Whether a catalog has been built.
The number of slots whose show bit is clear, removed slots included.
Derived from the SAME writes that maintain the kernel's show mirror: a
mirror that drifted would show up as a hidden site being drawn, not as
silence.
The number of sites in this block, including tombstoned slots.
The number of vertices still awaiting their first write after a vertex
array rebuild.
The ECEF positions. Three
Float64 components per site with a
stride of
PackedEntityBlock#positionStride: 3 for JavaScript
storage, 4 when the block is backed by a 32-byte wasm static slot arena.
Adopted zero-copy when the descriptor supplied them.
An ACCESSOR, not a field, and that is the whole point: a wasm-backed
block's view is a window onto WebAssembly.Memory, and any
unrelated growth of that heap detaches it. A detached view is not an
error - it is a Float64Array of length zero that answers
undefined for every lane - so a consumer that had cached the
field silently computed with NaN positions instead of
throwing. Three consumers did (the region-refinement kernel, the analysis
batch handoff and the catalog's geodetic solve); rather than remember the
refreshStorage call at each one, reading the positions IS the
refresh. The JavaScript path is a single undefined compare
and the field.
The number of Float64 lanes between consecutive positions: 3
for JavaScript storage, 4 for a wasm static slot arena.
The FlatSQL-routed attribute source, when one was supplied.
Per-site state bits: bit 0 alive, bit 1 show, bit 2 color override.
Where this block's positions live: "js" or "wasm".
The number of style groups in this block.
The style-group index of every site.
The style-table lane indices. Shared and frozen; the renderer reads the
layout from the block rather than importing this module, which would
close an import cycle through the WASM integration package.
The number of floats per style group in the style table.
The wall time the visibility index took to build, in milliseconds.
The steady bytes the visibility index holds, or 0 without one.
Whether this block has a per-camera visibility index.
Methods
The number of live sites strictly below a slot - the live ordinal a slot
occupies, and the slot's position among this block's members.
| Name |
Type |
Description |
slot |
number
|
The slot index. |
Returns:
The live ordinal.
The slot of the
k-th live site.
While no site has been removed this is the identity, which is what keeps a
pristine million-site block at zero bytes of index. After a removal it costs
one number per REMOVED site and a binary search per lookup.
| Name |
Type |
Description |
k |
number
|
The live-site ordinal. |
Returns:
The slot index.
Counts the values of one attribute COLUMN over the sites a mask names.
The summary form of a selection - "how many of these towers belong to each
provider" - answered off the column the block already holds, so a caller
never materializes an Entity to describe a million-site selection.
| Name |
Type |
Description |
name |
string
|
The attribute column. |
mask |
Uint8Array
|
One byte per slot: non-zero is counted. |
Returns:
Value to count.
A contiguous batch of sites, addressed by CATALOG ROW, for a WASM analysis
kernel.
This is the interface an RF or coverage kernel is handed: positions and
attributes as flat typed arrays in one order, the row handles that name them
back, and one call to give a computed column back. Nothing in it is an
Entity, so filtering a million emitters by frequency and computing a
gain per match costs no JavaScript object at all - and the result is
readable as a catalog column AND, on the sites a caller actually opens, as
entity.properties[name].
| Name |
Type |
Description |
rowIds |
Uint32Array
|
Array.<number>
|
Catalog rows. |
Returns:
{count, rowIds, slots, positions, attributes, writeResults}.
Builds - or returns - this block's FlatSQL broad-phase catalog.
| Name |
Type |
Description |
options |
object
|
optional
Options forwarded to PackedEntityCatalog.
| Name |
Type |
Description |
level |
number
|
optional
Tile level. |
descriptor |
object
|
optional
The descriptor this block was built
from, so its geodetic source is reused instead of solved back out of ECEF. |
|
Returns:
The catalog.
Drops every per-site override, returning the site to its style group.
| Name |
Type |
Description |
index |
number
|
The site index. |
| Name |
Type |
Description |
mask |
Uint8Array
|
One byte per slot: non-zero loses its override. |
Returns:
The number of sites cleared.
Detaches this block from everything holding it and releases what it owns.
Detaching is the point, not a courtesy. A block dropped from its
EntityCollection while a PointPrimitiveCollection still
counted it kept its vertices in that collection's vertex array, kept being
written every frame, and kept answering picks - a destroyed block that is
still on screen. Both owners are released here, and the style-group
listeners with them: the shared PointGraphics objects belong to the
caller and outlive the block, so a listener left behind would keep the block
alive through them.
Idempotent, and safe to reach through EntityCollection#removePacked,
which calls this after doing its own half of the detach.
Reads the effective color of a site: its override when one was written,
otherwise its style group's color.
| Name |
Type |
Description |
index |
number
|
The site index. |
result |
Color
|
optional
The object onto which to store the result. |
Returns:
The color.
Returns the outline width of a site: its own override when it has one,
otherwise its style group's.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
The outline width.
Returns the pixel size of a site: its own override when it has one,
otherwise its style group's.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
The pixel size.
Reads the ECEF position of a site.
| Name |
Type |
Description |
index |
number
|
The site index. |
result |
Cartesian3
|
optional
The object onto which to store the result. |
Returns:
The position.
Whether a site's VERTEX is drawn: its own show bit ANDed with the show state
of the collection that owns the block.
The distinction is the same one an ordinary entity draws:
entity.point.show is the site's own bit and does not move when a
collection is hidden, while what reaches the renderer is
entity.isShowing && point.show - which does. This is the
second of those two, and it is what the vertex writer and a packed facade
report.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
Whether the site's vertex is drawn.
Returns whether a site is shown.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
Whether the site is shown.
Returns the style group of a site.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
The style group index.
Returns the id of the site at index.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
The site id.
Returns the index of
id within this block, or -1.
For a prefix-addressed block this is O(1) and costs no resident bytes. For a
packed string-id block it probes a hash table built on the first lookup.
| Name |
Type |
Description |
id |
string
|
The site id. |
Returns:
The index, or -1 when this block does not hold the id.
Returns true when the site at index has not been removed.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
Whether the slot is alive.
Returns:
True once the block has been destroyed.
Materializes the site at
index as a real
Entity.
Delegates to the owning collection so identity and the bounded cache are
honored.
A removed site materializes to nothing. Handing back an entity for a
tombstoned slot would contradict every other door into the same site -
EntityCollection#getById, EntityCollection#contains and the
pick resolver all treat it as gone - and would register a live
materialization under an id the collection no longer holds.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
The entity, or undefined when the site was removed or the block has no collection.
Re-derives the position view when the block is backed by a wasm arena.
WASM memory growth invalidates every TypedArray view into the heap. The
shared view cache notices the buffer identity change and hands back a fresh
view; for a JavaScript-backed block this is a no-op.
Tombstones a site. The slot is never compacted, so every other index and id
keeps its meaning.
| Name |
Type |
Description |
index |
number
|
The site index. |
Returns:
Whether a live site was removed.
Overrides the color of one site and stages the one vertex it affects. The
override array is allocated on the first call and never before.
| Name |
Type |
Description |
index |
number
|
The site index. |
color |
Color
|
The new color. |
Overrides the colour of every site a MASK names, in one pass.
The bulk form of PackedEntityBlock#setColor, and the reason it exists
is the same reason PackedEntityBlock#applyShowMask exists: a caller
holding a selection of a million sites must not be reduced to a loop with a
staged dirty range per site. The run this touches is staged ONCE, from the
first slot written to the last, so a selection is one sub-commit however
scattered it is.
| Name |
Type |
Description |
mask |
Uint8Array
|
One byte per slot: non-zero takes the colour. |
color |
Color
|
The colour. |
maxCount |
number
|
optional
Stop after this many sites, in slot order. |
Returns:
The number of sites written.
Overrides the outline width of ONE site and stages the one vertex it
affects.
| Name |
Type |
Description |
index |
number
|
The site index. |
outlineWidth |
number
|
The new outline width. |
Overrides the pixel size of ONE site and stages the one vertex it affects.
A per-site override is four bytes in a typed array, never a
PointGraphics of its own: the style group stays shared by every site
that wears it, so restyling one site of a million costs the same as
restyling one site of ten.
| Name |
Type |
Description |
index |
number
|
The site index. |
pixelSize |
number
|
The new pixel size. |
Writes the ECEF position of a site and stages the one vertex it affects.
| Name |
Type |
Description |
index |
number
|
The site index. |
position |
Cartesian3
|
The new position. |
Sets whether a site is shown and stages the one vertex it affects.
| Name |
Type |
Description |
index |
number
|
The site index. |
show |
boolean
|
Whether the site is shown. |
Sets whether a contiguous run of sites is shown.
The run is clamped to this block at both ends, and a removed site is skipped
exactly as PackedEntityBlock#setShow skips it.
| Name |
Type |
Description |
first |
number
|
The first site index. |
count |
number
|
The number of sites. |
show |
boolean
|
Whether the sites are shown. |
Recolors one style group and stages every site that wears it.
Equivalent to writing block.styleGraphics(group).color = color:
the block is subscribed to each group's PointGraphics, so any write
to the shared object - this one, or entity.point.pixelSize = 42
through a materialized site - re-bakes the group and stages its sites.
| Name |
Type |
Description |
group |
number
|
The style group index. |
color |
Color
|
The new color. |
Moves a site to a different style group and stages the one vertex it affects.
| Name |
Type |
Description |
index |
number
|
The site index. |
group |
number
|
The style group index. |
| Name |
Type |
Description |
group |
number
|
The style group index. |
Returns:
The shared graphics object.