ReadonlyidThe CityObject's id -- the key it appears under in the emitted
CityObjects map. '' for a malformed object that omits it.
ReadonlytypeThe CityJSON type name ('Building', 'BuildingPart', ...). An
extension object's own extension_type string wins verbatim; a tag
outside the generated enum's range becomes '+UnknownCityObject' rather
than throwing.
This object's attributes, decoded against CityObjectView.columns.
{} both for an object that declares no attributes vector and for one
that declares an empty one -- use CityObjectView.hasAttributes to
tell those apart. Decoded fresh on every call, not cached.
The raw attribute bytes, or null when the object declares no attributes vector at all.
The schema that governs THIS object's attribute blob. Resolving this per object is not an optimisation, it is correctness: attribute records are not self-delimiting, so decoding with the header's schema when the object declares its own desynchronises the blob and yields plausible garbage rather than an error. In examples/data/delft.fcb every object with attributes declares its own columns and the header's 44 are never used.
Whether this object DECLARES an attributes vector. Distinct from that
vector being empty: present-but-empty must serialize as "attributes": {} while absent is omitted, and the corpus contains both.
Whether this object declares its OWN column schema, which then overrides the header's. Presence is what selects the override, not non-emptiness: an explicitly empty schema must not silently fall back to the header's.
The parsed FlatBuffers table behind this view.
For callers that need a field this view does not surface -- the CityJSON
emitter reads geometry, geometry_instances, children,
children_roles, parents and geographical_extent off it. Deliberately
a method rather than a public field, so it reads as "reach through to the
raw table" at every call site.
One CityObject inside a feature, with the attribute schema that governs it already resolved.