|
FlatCityBuf C++ reader 0.8.0
Native C++17 reader for FlatCityBuf, the cloud-optimized CityJSON format
|
Namespaces | |
| namespace | detail |
Classes | |
| struct | AttrCondition |
| One condition of an attribute query. More... | |
| struct | AttributeIndexEntry |
| One indexable (column, value) pair pulled out of a feature for the static B+tree builder (M6). More... | |
| struct | AttributeIndexInfo |
One attribute column's B+tree index metadata, as recorded in the header (AttributeIndex, header.fbs). More... | |
| struct | AttrIndexInfo |
| Where one column's B+tree index lives, and how it is shaped. More... | |
| struct | AttrQueryOptions |
| struct | AttrValue |
| One decoded attribute value. More... | |
| struct | BBox |
| A 2D query rectangle. More... | |
| struct | BtreeEntry |
| One (key, feature byte offset) pair to be indexed. More... | |
| class | BufferedRangeReader |
Caching decorator: over-fetches to min_req_size and serves subsequent reads inside the cached window without touching the inner reader. More... | |
| struct | BuiltBtreeIndex |
The finished index: the flat node array concatenated with the payload section (mirrors Stree::stream_write, stree.rs:1575-1589), plus the two header fields (AttributeIndexInfo.branching_factor/ .num_unique_items, M4's header_serializer.hpp) that only the builder itself can compute – branching_factor here is just the caller's own value echoed back (kept alongside the bytes so a caller building several columns' indices doesn't have to separately remember what it asked for each one), and num_unique_items counts distinct KEYS, not input entries. More... | |
| struct | ColumnInfo |
| One attribute column's schema, copied out of the header. More... | |
| struct | CoType |
A CityObjectType tag, plus the verbatim CityJSON name when the tag is ExtensionObject (which has no spelling of its own). More... | |
| struct | CurlOptions |
| class | CurlRangeReader |
| HTTP range-request adapter, opt-in via the FCB_WITH_CURL CMake option. More... | |
| struct | EncodedGeometry |
| Everything one CityJSON geometry object flattens to. More... | |
| class | Error |
| Every failure the library reports is one of these. More... | |
| class | FcbReader |
| The library's entry point. More... | |
| class | FcbWriter |
Streaming writer for one .fcb file, mirroring Rust's own FcbWriter (writer/mod.rs) shape: each add_feature call encodes and spools that feature's bytes to a private temporary file rather than keeping every encoded feature in memory at once – the same reason Rust's own writer uses the tempfile crate. More... | |
| struct | FcbWriterOptions |
Configuration for FcbWriter. More... | |
| class | Feature |
| One decoded feature that OWNS the bytes it points into. More... | |
| class | FeatureIterator |
| Single-pass iterator over features. Not copyable. More... | |
| struct | FileInfo |
| Everything a caller normally wants from the header, as owned values. More... | |
| struct | FileLayout |
| Byte offsets of each section. More... | |
| class | FileRangeReader |
| Local-file adapter. More... | |
| struct | GMBoundaries |
| Flattened geometry boundaries: a flat vertex-index list plus one count array per level of the dimensional hierarchy (rings-per-surface, surfaces-per-shell, shells-per-solid). More... | |
| struct | GMSemantics |
Flattened semantics: surfaces is the CityJSON semantics.surfaces array, passed through verbatim (FlatBuffers SemanticObject encoding, including its "other" attributes, is M3's job). More... | |
| class | HeaderView |
| A parsed header that OWNS its backing bytes. More... | |
| struct | HeaderWriterOptions |
| Configuration for header writing. More... | |
| class | KeyValue |
| A decoded index key. More... | |
| struct | LevelBound |
| Half-open [start, end) node index range for one tree level, in the flat node array shared by every level. More... | |
| struct | MaterialMapping |
| One theme's material mapping. More... | |
| struct | NodeItem |
| One R-tree node entry: 4 doubles then a u64, all little-endian, 40 bytes with no padding (packed_rtree/mod.rs:23-33). More... | |
| struct | ParsedReferenceSystem |
A metadata.referenceSystem URL, parsed into its OGC three-element form. More... | |
| struct | PocOffsets |
Builds the pointOfContact fields of a header from CityJSON metadata.pointOfContact. More... | |
| class | RangeReader |
| Synchronous byte-range source. More... | |
| struct | RangeRequest |
One range in a batched read. data is filled in place by read_batch(). More... | |
| struct | SearchResultItem |
| One hit from an index traversal. More... | |
| class | span |
| Minimal C++17 stand-in for std::span: a non-owning view over contiguous memory. More... | |
| struct | StreeLevelBound |
| Half-open [start, end) node index range for one tree level, in the flat node array shared by every level. More... | |
| struct | SurfaceType |
A SemanticSurfaceType tag, plus the verbatim CityJSON name when the tag is ExtraSemanticSurface. More... | |
| struct | TextureMapping |
| One theme's texture mapping. More... | |
Typedefs | |
| using | UIntView = span< const std::uint32_t > |
| using | bytes_view = span< const std::uint8_t > |
| The workhorse alias: a read-only view over bytes. | |
| using | AttrQuery = std::vector< AttrCondition > |
| using | AttributeSchema = std::map< std::string, std::pair< std::uint16_t, ::ColumnType > > |
| Attribute schema: name -> (column index, column type). | |
Enumerations | |
| enum class | ErrorCode { MissingMagicBytes , IllegalHeaderSize , InvalidFlatbuffer , NoIndex , AttributeIndexNotFound , NoColumnsInHeader , MissingRequiredField , UnsupportedColumnType , InvalidAttributeValue , QueryExecutionError , IoError , HttpError , JsonError } |
| Error categories, mirroring fcb_core::error::Error (src/rust/fcb_core/src/error.rs) so the two implementations report the same failures under the same names. More... | |
| enum class | GeometryKind : std::uint8_t { MultiPoint = 0 , MultiLineString = 1 , MultiSurface = 2 , CompositeSurface = 3 , Solid = 4 , MultiSolid = 5 , CompositeSolid = 6 , GeometryInstance = 7 } |
The FlatBuffers GeometryType enumerators, mirrored here so a caller can name a geometry type without pulling in the generated headers. More... | |
| enum class | KeyKind { Int8 , UInt8 , Int16 , UInt16 , Int32 , UInt32 , Int64 , UInt64 , Float32 , Float64 , Bool , DateTime , String20 , String50 , String100 } |
| The concrete key types the B+tree index can hold. More... | |
| enum class | IterationMode { SequentialScan , OffsetList } |
| How a FeatureIterator decides what to visit. More... | |
| enum class | Operator { Eq , Ne , Gt , Ge , Lt , Le } |
| Comparison operators the attribute index supports. More... | |
Functions | |
| std::vector< std::pair< std::string, AttrValue > > | decode_attributes (bytes_view blob, const std::vector< ColumnInfo > &schema) |
| Decode a feature's attribute blob against the column schema. | |
| nlohmann::json | attributes_to_json (bytes_view blob, const std::vector< ColumnInfo > &schema) |
| Same decode, rendered as a JSON object for CityJSON emission. | |
| nlohmann::json | to_cityjson_metadata (const HeaderView &header) |
| The CityJSON metadata envelope: type, version, transform, extent, CRS. | |
| nlohmann::json | to_cityjson_feature (const Feature &feature, const HeaderView &header) |
| One feature as a CityJSONFeature object. | |
| std::string | city_object_type_name (std::uint8_t type) |
| CityJSON name for a CityObjectType enumerator, e.g. | |
| std::string | semantic_surface_type_name (std::uint8_t type) |
| CityJSON name for a SemanticSurfaceType enumerator, e.g. | |
| nlohmann::json | decode_boundaries (GeometryKind type, UIntView solids, UIntView shells, UIntView surfaces, UIntView strings, UIntView indices) |
Rebuild CityJSON's nested boundaries from the five flattened arrays, at the depth type implies. | |
| nlohmann::json | decode_semantics_values (GeometryKind type, UIntView solids, UIntView shells, UIntView values) |
Rebuild the nested semantics values array from the flat run of semantic indices. | |
| nlohmann::json | decode_material_values (GeometryKind type, UIntView solids, UIntView shells, UIntView vertices) |
Rebuild the values array of one material theme from a MaterialMapping. | |
| nlohmann::json | decode_texture_values (GeometryKind type, UIntView solids, UIntView shells, UIntView surfaces, UIntView strings, UIntView vertices) |
Rebuild the values array of one texture theme from a TextureMapping. | |
| std::string | geometry_type_name (std::uint8_t type) |
| CityJSON name for a GeometryType enumerator, e.g. | |
| HeaderView | read_header (std::shared_ptr< RangeReader > reader) |
| Read and validate the file preamble and header. | |
| std::size_t | key_serialized_size (KeyKind kind) |
| Serialized width in bytes. DateTime is 12: i64 seconds + u32 nanos. | |
| std::vector< std::uint8_t > | encode_key (const KeyValue &v) |
| KeyValue | decode_key (KeyKind kind, bytes_view b) |
| int | compare_keys (const KeyValue &a, const KeyValue &b) |
| Three-way comparison. | |
| KeyValue | key_min (KeyKind kind) |
| Sentinels used to lower open-ended range queries. | |
| KeyValue | key_max (KeyKind kind) |
| KeyKind | key_kind_for_column (std::uint8_t column_type) |
| Column type to key kind, following what the WRITER emits. | |
| bool | check_magic_bytes (bytes_view b) |
| Mirrors fcb_core::check_magic_bytes (src/rust/fcb_core/src/lib.rs:56-58). | |
| std::uint64_t | rtree_index_size (std::uint64_t num_items, std::uint16_t node_size) |
| Mirrors PackedRTree::index_size (packed_rtree/mod.rs:879-898). | |
| FileLayout | compute_layout (std::uint32_t header_size, std::uint64_t features_count, std::uint16_t index_node_size, std::uint64_t attr_index_size) |
| Throws fcb::Error{IllegalHeaderSize} when header_size is out of range or any size arithmetic overflows. | |
| void | validate_layout_against_size (const FileLayout &l, std::uint64_t total_size) |
| Throws unless the computed sections fit inside the resource. | |
| std::uint64_t | rtree_num_nodes (std::uint64_t num_items, std::uint16_t node_size) |
| Total node count in the tree, per the Rust level-bounds loop (packed_rtree/mod.rs:342-375). | |
| std::vector< LevelBound > | rtree_level_bounds (std::uint64_t num_items, std::uint16_t node_size) |
Mirrors generate_level_bounds (packed_rtree/mod.rs:342-375). | |
| std::vector< SearchResultItem > | rtree_search_bbox (RangeReader &reader, std::uint64_t index_begin, std::uint64_t num_items, std::uint16_t node_size, const BBox &query) |
| Breadth-first bbox search over the packed R-tree, reading nodes through the supplied reader. | |
| bool | is_payload_ref (std::uint64_t off) |
| std::uint64_t | payload_offset (std::uint64_t off) |
| std::uint64_t | stree_num_nodes (std::uint64_t num_items, std::uint16_t branching_factor) |
| Total node count. | |
| std::vector< StreeLevelBound > | stree_level_bounds (std::uint64_t num_items, std::uint16_t branching_factor) |
Mirrors Stree::generate_level_bounds (stree.rs:474-508). | |
| std::vector< std::uint64_t > | decode_payload_entry (bytes_view b) |
| Decode a payload entry: u32 count then count x u64, all little-endian. | |
| void | encode_payload_entry (std::vector< std::uint8_t > &out, const std::vector< std::uint64_t > &offsets) |
Encode a payload entry: u32 count then count x u64, all little-endian (mirrors PayloadEntry::serialize, payload.rs:42-49). | |
| std::vector< SearchResultItem > | stree_query (RangeReader &reader, const AttrIndexInfo &index, KeyKind kind, Operator op, const KeyValue &value) |
| Run one condition against one column's index blob, returning candidate feature offsets (relative to the features section). | |
| void | add_attributes (AttributeSchema &schema, const nlohmann::ordered_json &attrs) |
Adds every member of a JSON object to schema, assigning each new, non-null name the next free column index, in the order attrs's own members appear (see the ordered_json note above) – NOT alphabetically. | |
| std::size_t | attr_size (::ColumnType coltype, const nlohmann::ordered_json &colval) |
Byte width one value of coltype occupies in the attribute blob, EXCLUDING the 2-byte column-index prefix every record also carries. | |
| std::vector< std::uint8_t > | encode_attributes_with_schema (const nlohmann::ordered_json &attr, const AttributeSchema &schema) |
Encodes attr (a CityJSON attributes object) against schema: repeated [u16 LE column index][value] records, one per schema member present and non-null in attr, in ascending column-index order (NOT attr's own JSON key order). | |
| ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::Column > > > | to_columns (::flatbuffers::FlatBufferBuilder &fbb, const AttributeSchema &schema) |
Builds the Column vector for Header.columns or CityObject.columns, in ascending column-index order. | |
| std::vector< AttributeIndexEntry > | attribute_to_index_entries (const nlohmann::ordered_json &attr, const AttributeSchema &schema, const std::vector< std::string > &indexing_attr) |
Extracts index entries for indexing_attr from one CityJSON attributes object. | |
| std::vector< AttributeIndexEntry > | cityfeature_to_index_entries (const nlohmann::ordered_json &city_feature, const AttributeSchema &schema, const std::vector< std::string > &indexing_attr) |
Same, over every object in one CityJSONFeature's CityObjects, visited in ascending object-id order (not JSON key order, which need not be stable) so that duplicate-key payload ordering in the eventual B+tree is reproducible. | |
| BuiltBtreeIndex | build_static_btree (const std::vector< BtreeEntry > &entries, KeyKind kind, std::uint16_t branching_factor) |
Builds one column's complete attribute index blob from its (key, offset) entries. | |
| CoType | city_object_type_from_name (const std::string &name) |
Maps a CityJSON CityObject type string to the FlatBuffers tag. | |
| SurfaceType | semantic_surface_type_from_name (const std::string &name) |
Maps a CityJSON semantic surface type string to the FlatBuffers tag. | |
| ::flatbuffers::Offset<::Appearance > | to_appearance (::flatbuffers::FlatBufferBuilder &fbb, const nlohmann::ordered_json &appearance) |
Builds the Appearance table (materials, textures, UV vertices, default themes) from a CityJSON appearance object. | |
| ::flatbuffers::Offset<::Geometry > | to_geometry (::flatbuffers::FlatBufferBuilder &fbb, const nlohmann::ordered_json &geometry, const AttributeSchema *semantic_attr_schema) |
Builds one Geometry table – boundaries, and whatever semantics, material and texture it carries – from a CityJSON geometry object (everything but a GeometryInstance, which to_geometry_instance handles). | |
| ::flatbuffers::Offset<::GeometryInstance > | to_geometry_instance (::flatbuffers::FlatBufferBuilder &fbb, const nlohmann::ordered_json &geometry) |
Builds a GeometryInstance table: the template index, the 4x4 transformation matrix, and the single-element boundaries array holding the reference vertex index. | |
| ::GeographicalExtent | to_geographical_extent (const std::array< double, 6 > &extent) |
Builds a GeographicalExtent struct from a 6-element [minx,miny,minz,maxx,maxy,maxz] array. | |
| ::flatbuffers::Offset<::CityObject > | to_city_object (::flatbuffers::FlatBufferBuilder &fbb, const std::string &id, const nlohmann::ordered_json &co, const AttributeSchema &attr_schema, const AttributeSchema *semantic_attr_schema) |
Builds one CityObject table: type, geographical extent, geometry (split into non-instance and GeometryInstance entries), attributes (against attr_schema, or the object's own schema when its attribute keys are not all present in attr_schema), children/children-roles/ parents. | |
| std::pair<::flatbuffers::Offset<::CityFeature >, NodeItem > | to_fcb_city_feature (::flatbuffers::FlatBufferBuilder &fbb, const std::string &id, const nlohmann::ordered_json &city_feature, const AttributeSchema &attr_schema, const AttributeSchema *semantic_attr_schema) |
Builds one CityFeature table – its CityObjects (visited in ascending id order), vertices, and optional feature-level appearance – from a CityJSONFeature JSON object, plus its 2D bounding box over the RAW (untransformed, still-integer) vertex coordinates. | |
| GeometryKind | geometry_kind_from_name (const std::string &name) |
Maps a CityJSON geometry type string to GeometryKind. | |
| GMBoundaries | encode_boundaries (GeometryKind kind, const nlohmann::ordered_json &boundaries) |
Flattens boundaries (nested CityJSON boundary arrays, straight off the JSON as parsed – no intermediate typed representation) at exactly the depth kind implies. | |
| GMSemantics | encode_semantics (const nlohmann::ordered_json &semantics, const GMBoundaries &boundaries) |
Flattens semantics (the CityJSON semantics object: surfaces plus values), using boundaries's shell/solid counts to expand a null shell or solid into the right number of per-surface nulls (there is no wire encoding for a whole-null shell in semantics, unlike material). | |
| std::vector< MaterialMapping > | encode_material (const nlohmann::ordered_json &material) |
Flattens material (the CityJSON geometry.material object: theme name -> {"value": N} / {"values": [...]} / {"values": null}). | |
| std::vector< TextureMapping > | encode_texture (const nlohmann::ordered_json &texture) |
Flattens texture (the CityJSON geometry.texture object). | |
| EncodedGeometry | encode (const nlohmann::ordered_json &geometry) |
| Flattens one CityJSON geometry object – its boundaries and whatever semantics, material and texture it carries – into the FlatCityBuf arrays. | |
| ::Transform | to_transform (const nlohmann::ordered_json &transform) |
Builds the Transform struct (scale + translate) from CityJSON's top-level transform member. | |
| std::optional< ParsedReferenceSystem > | parse_reference_system (const std::string &url) |
Parses a referenceSystem URL (https://www.opengis.net/def/crs/{authority}/{version}/{code}, per cjseq2's ReferenceSystem::from_url) into its three OGC elements. | |
| ::flatbuffers::Offset<::ReferenceSystem > | to_reference_system (::flatbuffers::FlatBufferBuilder &fbb, const ParsedReferenceSystem &ref_sys) |
Builds the ReferenceSystem table from a parsed metadata.referenceSystem URL. | |
| ::flatbuffers::Offset<::Extension > | to_extension (::flatbuffers::FlatBufferBuilder &fbb, const std::string &name, const std::string &url, const std::string &version) |
Builds one extensions entry: only name/url/version are written (the schema document itself is never fetched or embedded). | |
| ::flatbuffers::Offset<::flatbuffers::Vector< const ::DoubleVertex * > > | to_templates_vertices (::flatbuffers::FlatBufferBuilder &fbb, const nlohmann::ordered_json &vertices_templates) |
Builds Header.templates_vertices from CityJSON's geometry-templates.vertices-templates (f64 precision, unlike a feature's own int32 vertices). | |
| PocOffsets | to_point_of_contact (::flatbuffers::FlatBufferBuilder &fbb, const nlohmann::ordered_json &poc) |
| ::flatbuffers::Offset<::Header > | to_fcb_header (::flatbuffers::FlatBufferBuilder &fbb, const nlohmann::ordered_json &cj, const HeaderWriterOptions &options, const AttributeSchema &attr_schema, const AttributeSchema *semantic_attr_schema, const std::vector< AttributeIndexInfo > *attribute_indices_info) |
Builds the whole Header table from the CityJSON metadata line (the first line of a CityJSONSeq: type/version/transform/metadata/ geometry-templates/appearance/extensions), the writer options, and the attribute schema(s). | |
| std::uint32_t | hilbert (std::uint32_t x, std::uint32_t y) |
| The Hilbert curve index of point (x, y) on a 65536x65536 grid (16 bits per axis). | |
| std::uint32_t | hilbert_bbox (const NodeItem &r, std::uint32_t hilbert_max, const NodeItem &extent) |
A NodeItem's Hilbert index: its bbox center, scaled into [0, hilbert_max] against extent, fed through hilbert. | |
| void | hilbert_sort (std::vector< NodeItem > &items, const NodeItem &extent) |
Sorts items in place by descending Hilbert index (the item furthest along the curve first) – a STABLE sort, matching Rust's slice sort_by guarantee. | |
| NodeItem | calc_extent (const std::vector< NodeItem > &nodes) |
The bbox union of every item, via repeated NodeItem::expand starting from NodeItem::empty(0). | |
| std::vector< NodeItem > | build_packed_rtree (const std::vector< NodeItem > &nodes, const NodeItem &extent, std::uint16_t node_size) |
Builds the full flat packed-R-tree node array (leaves first in nodes's own order at the array's tail per rtree_level_bounds, then every internal level above it, bottom-up) from already Hilbert-sorted leaf nodes with their FINAL byte offsets already set. | |
| std::vector< std::uint8_t > | encode_packed_rtree (const std::vector< NodeItem > &tree) |
Serializes every node in tree (as returned by build_packed_rtree) in array order, 40 bytes each. | |
Variables | |
| constexpr std::size_t | kMagicBytesSize = 8 |
| constexpr std::size_t | kHeaderSizeSize = 4 |
| constexpr std::size_t | kHeaderMinBufferSize = 8 |
| constexpr std::size_t | kHeaderMaxBufferSize = 1024ULL * 1024ULL * 512ULL |
| constexpr std::uint8_t | kVersion = 1 |
| constexpr std::size_t | kNodeItemSize = 40 |
| constexpr std::uint16_t | kDefaultNodeSize = 16 |
| constexpr std::uint64_t | kMaxFeatureSize = 256ULL * 1024ULL * 1024ULL |
| Hard ceiling on a single feature's byte length, enforced before allocating. | |
| constexpr std::uint64_t | kPayloadTag = 1ULL << 63 |
| The MSB of a leaf offset marks a payload reference rather than a direct feature offset (stree.rs:15-17). | |
| constexpr std::uint64_t | kPayloadMask = ~kPayloadTag |
| constexpr std::uint16_t | kDefaultBranchingFactor = 16 |
Mirrors static_btree::DEFAULT_BRANCHING_FACTOR (static_btree/mod.rs:19), used whenever a caller requests an attribute index without naming an explicit branching factor. | |
| static constexpr std::size_t | kBodyAlignPad = 0 |
| No padding needed. | |
| static constexpr std::size_t | kBodyAlignPad = 0 |
| No padding needed; see the note in header.cpp. | |
| using fcb::AttributeSchema = typedef std::map<std::string, std::pair<std::uint16_t, ::ColumnType> > |
Attribute schema: name -> (column index, column type).
std::map here is just a lookup table – its own key order is never read; every consumer (to_columns, encode_attributes_with_schema) sorts by the stored column INDEX before emitting anything. That index comes from schema.size() at insert time, so what actually determines column numbering is the ITERATION ORDER of the attrs object passed to add_attributes below – which is why that parameter is nlohmann::ordered_json, not the library's default nlohmann::json.
nlohmann::json's default object type is std::map (alphabetical), and the original design here assumed serde_json::Map was equivalently alphabetical (its documented default, a BTreeMap, absent the preserve_order feature). Empirically, it is not: this workspace's bson dependency (used by fcb_core and fcb_cli) transitively activates serde_json's preserve_order feature for the WHOLE build, so serde_json::Map is actually insertion-ordered here, and Rust's add_attributes assigns column indices in DOCUMENT order, not alphabetical order (confirmed against real fcb-CLI output in the M3 oracle tests – e.g. single_feature.city.jsonl's {"name":...,"n":...} gets name->0, n->1, the reverse of alphabetical). ordered_json preserves that same document order, so this stays byte-compatible.
Definition at line 42 of file attribute.hpp.
| using fcb::AttrQuery = typedef std::vector<AttrCondition> |
| using fcb::bytes_view = typedef span<const std::uint8_t> |
| using fcb::UIntView = typedef span<const std::uint32_t> |
Definition at line 16 of file geometry.hpp.
|
strong |
Error categories, mirroring fcb_core::error::Error (src/rust/fcb_core/src/error.rs) so the two implementations report the same failures under the same names.
|
strong |
The FlatBuffers GeometryType enumerators, mirrored here so a caller can name a geometry type without pulling in the generated headers.
The values are the declaration order in src/fbs/geometry.fbs and are checked against the generated enum with a static_assert in geometry.cpp.
| Enumerator | |
|---|---|
| MultiPoint | |
| MultiLineString | |
| MultiSurface | |
| CompositeSurface | |
| Solid | |
| MultiSolid | |
| CompositeSolid | |
| GeometryInstance | |
Definition at line 22 of file geometry.hpp.
|
strong |
How a FeatureIterator decides what to visit.
This is an explicit mode rather than "an empty offset list means scan everything": an empty list is also the perfectly normal result of a query that matched nothing, and conflating the two would silently turn a zero-result query into a full scan.
| Enumerator | |
|---|---|
| SequentialScan | walk the features section start to finish |
| OffsetList | visit exactly the offsets supplied (possibly none) |
Definition at line 29 of file reader.hpp.
|
strong |
|
strong |
| void fcb::add_attributes | ( | AttributeSchema & | schema, |
| const nlohmann::ordered_json & | attrs | ||
| ) |
Adds every member of a JSON object to schema, assigning each new, non-null name the next free column index, in the order attrs's own members appear (see the ordered_json note above) – NOT alphabetically.
A non-object attrs becomes a single "json" column, matching the writer's fallback for untyped attribute payloads. Existing names and null values are left alone.
Definition at line 222 of file attribute.cpp.
References key.
| std::size_t fcb::attr_size | ( | ::ColumnType | coltype, |
| const nlohmann::ordered_json & | colval | ||
| ) |
Byte width one value of coltype occupies in the attribute blob, EXCLUDING the 2-byte column-index prefix every record also carries.
Definition at line 244 of file attribute.cpp.
References UnsupportedColumnType.
Referenced by encode_attributes_with_schema().
| std::vector< AttributeIndexEntry > fcb::attribute_to_index_entries | ( | const nlohmann::ordered_json & | attr, |
| const AttributeSchema & | schema, | ||
| const std::vector< std::string > & | indexing_attr | ||
| ) |
Extracts index entries for indexing_attr from one CityJSON attributes object.
Only Bool, Int, UInt, Long, ULong, Float, Double, String and DateTime columns produce entries – Byte, UByte, Short, UShort, Json and Binary are silently skipped, matching the Rust writer's attribute_to_index_entries exactly (a known, deliberate gap: those types ARE supported by the B+tree builder itself, just never reached through this normal extraction path). A name in indexing_attr absent from attr or from schema is skipped.
Definition at line 382 of file attribute.cpp.
References fcb::KeyValue::from_bool(), fcb::KeyValue::from_datetime(), fcb::KeyValue::from_f32(), fcb::KeyValue::from_f64(), fcb::KeyValue::from_i32(), fcb::KeyValue::from_i64(), fcb::KeyValue::from_string(), fcb::KeyValue::from_u32(), fcb::KeyValue::from_u64(), index, and String50.
Referenced by cityfeature_to_index_entries().
| nlohmann::json fcb::attributes_to_json | ( | bytes_view | blob, |
| const std::vector< ColumnInfo > & | schema | ||
| ) |
Same decode, rendered as a JSON object for CityJSON emission.
Definition at line 181 of file attribute.cpp.
References fcb::AttrValue::Binary, fcb::AttrValue::Bool, decode_attributes(), fcb::AttrValue::Double, fcb::AttrValue::Int, fcb::AttrValue::Json, fcb::AttrValue::Null, fcb::AttrValue::String, and fcb::AttrValue::UInt.
Referenced by to_cityjson_feature().
| std::vector< NodeItem > fcb::build_packed_rtree | ( | const std::vector< NodeItem > & | nodes, |
| const NodeItem & | extent, | ||
| std::uint16_t | node_size | ||
| ) |
Builds the full flat packed-R-tree node array (leaves first in nodes's own order at the array's tail per rtree_level_bounds, then every internal level above it, bottom-up) from already Hilbert-sorted leaf nodes with their FINAL byte offsets already set.
Mirrors PackedRTree::build+init+generate_nodes (packed_rtree/mod.rs:327-397,432-451). Throws fcb::Error for node_size < 2, matching Rust's own assert!(node_size >= 2, ...) – its subsequent .clamp(2, 65535) only narrows the upper bound (a no-op for u16), it does not round an invalid low value up. nodes must be non-empty.
Definition at line 117 of file rtree_builder.cpp.
References fcb::NodeItem::empty(), fcb::LevelBound::end, fcb::NodeItem::expand(), IllegalHeaderSize, node_size, rtree_level_bounds(), and fcb::LevelBound::start.
Referenced by fcb::FcbWriter::write().
| BuiltBtreeIndex fcb::build_static_btree | ( | const std::vector< BtreeEntry > & | entries, |
| KeyKind | kind, | ||
| std::uint16_t | branching_factor | ||
| ) |
Builds one column's complete attribute index blob from its (key, offset) entries.
Every entry's key.kind() must be the same kind. branching_factor below 2 is silently clamped up to 2, matching Stree::build (stree.rs:638-640) exactly – unlike the packed R-tree's build_packed_rtree, which THROWS for an invalid node size, Stree:: build clamps branching_factor before its own init() ever gets a chance to reject it, so a sub-2 value never actually errors through this entry point. Throws fcb::Error only for an empty entries (mirrors Stree::init's OTHER check, Err(Error::InvalidFormat(...)) for zero leaf nodes, stree.rs:456-459 – an attribute with zero indexable values is a normal condition this writer's caller (M7) is expected to skip before ever calling this, not a programmer bug, but Rust's own build() does not special-case it away either).
Definition at line 163 of file btree_builder.cpp.
References AttributeIndexNotFound, encode_key(), key_serialized_size(), kind, stree_level_bounds(), and UnsupportedColumnType.
Referenced by fcb::FcbWriter::write().
The bbox union of every item, via repeated NodeItem::expand starting from NodeItem::empty(0).
Mirrors calc_extent (packed_rtree/mod.rs:308-313). nodes must be non-empty: the identity element (+inf/+inf/-inf/-inf) is never a meaningful result on its own and no caller here needs it (M7 only calls this when features exist).
Definition at line 110 of file rtree_builder.cpp.
References fcb::NodeItem::empty(), and fcb::NodeItem::expand().
Referenced by fcb::FcbWriter::write().
| bool fcb::check_magic_bytes | ( | bytes_view | b | ) |
Mirrors fcb_core::check_magic_bytes (src/rust/fcb_core/src/lib.rs:56-58).
Compares only bytes [0,3) and [4,7); byte 7 is never validated.
Definition at line 14 of file layout.cpp.
References fcb::span< T >::data(), kMagicBytesSize, kVersion, and fcb::span< T >::size().
| CoType fcb::city_object_type_from_name | ( | const std::string & | name | ) |
Maps a CityJSON CityObject type string to the FlatBuffers tag.
A name outside CityJSON's ~33 known object types becomes ExtensionObject plus the name verbatim – never an error. Mirrors to_co_type (writer/serializer.rs:745-792).
Definition at line 126 of file feature_serializer.cpp.
Referenced by to_city_object().
| std::string fcb::city_object_type_name | ( | std::uint8_t | type | ) |
CityJSON name for a CityObjectType enumerator, e.g.
"BuildingPart".
A tag with no CityJSON name of its own – ExtensionObject, whose real name lives in the object's extension_type string, or anything a newer encoder added – becomes "+UnknownCityObject". See the unknown-tag policy note at the top of cityjson.cpp.
Definition at line 559 of file cityjson.cpp.
Referenced by to_cityjson_feature().
| std::vector< AttributeIndexEntry > fcb::cityfeature_to_index_entries | ( | const nlohmann::ordered_json & | city_feature, |
| const AttributeSchema & | schema, | ||
| const std::vector< std::string > & | indexing_attr | ||
| ) |
Same, over every object in one CityJSONFeature's CityObjects, visited in ascending object-id order (not JSON key order, which need not be stable) so that duplicate-key payload ordering in the eventual B+tree is reproducible.
An object with no attributes member, or an explicit "attributes": null, contributes nothing.
Definition at line 447 of file attribute.cpp.
References attribute_to_index_entries().
Referenced by fcb::FcbWriter::add_feature().
| FileLayout fcb::compute_layout | ( | std::uint32_t | header_size, |
| std::uint64_t | features_count, | ||
| std::uint16_t | index_node_size, | ||
| std::uint64_t | attr_index_size | ||
| ) |
Throws fcb::Error{IllegalHeaderSize} when header_size is out of range or any size arithmetic overflows.
Definition at line 49 of file layout.cpp.
References fcb::FileLayout::header_len, IllegalHeaderSize, kHeaderMaxBufferSize, kHeaderSizeSize, kMagicBytesSize, and rtree_index_size().
| std::vector< std::pair< std::string, AttrValue > > fcb::decode_attributes | ( | bytes_view | blob, |
| const std::vector< ColumnInfo > & | schema | ||
| ) |
Decode a feature's attribute blob against the column schema.
Wire format (reader/deserializer.rs:249-372): repeated records of a u16 little-endian column index followed by the value, encoded per the column's type. Fixed-width types are packed little-endian; String, DateTime and Json are a u32 little-endian byte length then UTF-8, and Binary is that same length prefix followed by raw bytes.
Throws on a column index absent from the schema, a truncated record, or an out-of-range ColumnType (whose width is unknown, so the rest of the blob cannot be parsed).
Byte, UByte and Binary are decoded here. The Rust reader used to hit unreachable!() on them despite the writer emitting them; that has been fixed upstream, so both implementations handle them.
Definition at line 47 of file attribute.cpp.
References fcb::AttrValue::Binary, fcb::AttrValue::Bool, fcb::span< T >::data(), fcb::AttrValue::Double, fcb::span< T >::empty(), found, fcb::AttrValue::Int, InvalidAttributeValue, fcb::AttrValue::Json, fcb::ColumnInfo::name, fcb::span< T >::size(), fcb::AttrValue::String, fcb::ColumnInfo::type, and fcb::AttrValue::UInt.
Referenced by attributes_to_json(), and fcb::FcbReader::select_attr().
| nlohmann::json fcb::decode_boundaries | ( | GeometryKind | type, |
| UIntView | solids, | ||
| UIntView | shells, | ||
| UIntView | surfaces, | ||
| UIntView | strings, | ||
| UIntView | indices | ||
| ) |
Rebuild CityJSON's nested boundaries from the five flattened arrays, at the depth type implies.
The encoder always writes one redundant count level above the geometry's own depth (a MultiSurface carries a one-entry shells, a Solid a one-entry solids), except for the 5-deep types. This reader ignores that top count entirely; the old cascading reader used it as its depth signal, which is where all the ambiguity came from.
Mirrors decode_points/decode_rings/decode_surfaces/decode_shells/ decode_solids (geom_decoder.rs:106-146), except for one DELIBERATE divergence: a cursor overrun throws here, where the reference clamps and yields a short array.
This is a choice, not a constraint. Clamping is perfectly safe in C++ – the three appearance decoders below do exactly that, and do not throw. We choose to error because count arrays that disagree with the index array mean the file is corrupt, and reporting corruption is more useful to a caller than a plausible-looking short geometry. Only reachable on a file our own writer could not have produced.
The same reasoning settles an unknown type: it never reaches this function, because geometry_type_name rejects it first. The default: arm in the switch is a C++ formality with no fallback semantics – see the policy note at the top of cityjson.cpp.
Definition at line 164 of file geometry.cpp.
References CompositeSolid, CompositeSurface, GeometryInstance, MultiLineString, MultiPoint, MultiSolid, MultiSurface, shells, fcb::span< T >::size(), Solid, strings, and surfaces.
| KeyValue fcb::decode_key | ( | KeyKind | kind, |
| bytes_view | b | ||
| ) |
| nlohmann::json fcb::decode_material_values | ( | GeometryKind | type, |
| UIntView | solids, | ||
| UIntView | shells, | ||
| UIntView | vertices | ||
| ) |
Rebuild the values array of one material theme from a MaterialMapping.
Material indices sit two levels shallower than boundaries: one index per SURFACE, not per ring. So there is no surfaces/strings argument – shells[i] is the number of material indices in shell i.
material.values is nullable at EVERY level (verified against geomprimitives.schema.json), so a UINT32_MAX entry in shells or solids is a whole null shell or solid and comes back as JSON null, never as an empty array.
Mirrors decode_materials (geom_decoder.rs:339). Unlike decode_boundaries this NEVER throws: the reference reads a missing count as zero and clamps every slice to the vertex array, so a mapping that over-claims yields short or empty entries rather than an error.
Definition at line 268 of file geometry.cpp.
References CompositeSolid, MultiSolid, shells, fcb::span< T >::size(), Solid, vertex, and vertices.
| std::vector< std::uint64_t > fcb::decode_payload_entry | ( | bytes_view | b | ) |
Decode a payload entry: u32 count then count x u64, all little-endian.
Definition at line 331 of file stree.cpp.
References AttributeIndexNotFound, and fcb::span< T >::size().
| nlohmann::json fcb::decode_semantics_values | ( | GeometryKind | type, |
| UIntView | solids, | ||
| UIntView | shells, | ||
| UIntView | values | ||
| ) |
Rebuild the nested semantics values array from the flat run of semantic indices.
semantics.values is one level shallower than the boundaries. A semantics mapping carries no count arrays of its own, so the group sizes come from the boundary solids/shells.
UINT32_MAX is null at the leaf. There is no wire encoding for a null shell or solid in semantics; the encoder expands one to a null per surface. Mirrors decode_semantics (geom_decoder.rs:226).
Definition at line 224 of file geometry.cpp.
References CompositeSolid, MultiSolid, shells, fcb::span< T >::size(), and Solid.
| nlohmann::json fcb::decode_texture_values | ( | GeometryKind | type, |
| UIntView | solids, | ||
| UIntView | shells, | ||
| UIntView | surfaces, | ||
| UIntView | strings, | ||
| UIntView | vertices | ||
| ) |
Rebuild the values array of one texture theme from a TextureMapping.
Texture values nest exactly as deeply as the boundaries – solid, shell, surface, ring – except the innermost list is [texture index, then one UV-vertex index per ring vertex] rather than vertex indices.
Unlike a material, texture.values is nullable ONLY at the leaf: the schema types every intermediate level as a plain "array". So nothing here decodes an intermediate null.
Mirrors decode_textures (geom_decoder.rs:468). Also never throws; see above.
Definition at line 331 of file geometry.cpp.
References CompositeSolid, CompositeSurface, MultiSolid, MultiSurface, shells, fcb::span< T >::size(), Solid, strings, surfaces, and vertices.
| EncodedGeometry fcb::encode | ( | const nlohmann::ordered_json & | geometry | ) |
Flattens one CityJSON geometry object – its boundaries and whatever semantics, material and texture it carries – into the FlatCityBuf arrays.
geometry is read directly off the parsed JSON (type, boundaries, and optionally semantics/material/texture); a GeometryInstance carries none of these except a differently-shaped boundaries (a single reference vertex index, not nested arrays) that this never touches – it is encoded separately by M3's to_geometry_instance, and yields empty arrays here. Mirrors encode (writer/geom_encoder.rs:102-120).
Definition at line 415 of file geom_encoder.cpp.
References fcb::EncodedGeometry::boundaries, encode_boundaries(), encode_material(), encode_semantics(), encode_texture(), geometry_kind_from_name(), kind, fcb::EncodedGeometry::materials, fcb::EncodedGeometry::semantics, and fcb::EncodedGeometry::textures.
Referenced by encode_packed_rtree(), and to_geometry().
| std::vector< std::uint8_t > fcb::encode_attributes_with_schema | ( | const nlohmann::ordered_json & | attr, |
| const AttributeSchema & | schema | ||
| ) |
Encodes attr (a CityJSON attributes object) against schema: repeated [u16 LE column index][value] records, one per schema member present and non-null in attr, in ascending column-index order (NOT attr's own JSON key order).
A schema member absent from attr, or explicitly null, is skipped – not zero-filled. Returns an empty vector for a non-object or empty attr.
Definition at line 279 of file attribute.cpp.
References attr_size(), index, and offset.
| GMBoundaries fcb::encode_boundaries | ( | GeometryKind | kind, |
| const nlohmann::ordered_json & | boundaries | ||
| ) |
Flattens boundaries (nested CityJSON boundary arrays, straight off the JSON as parsed – no intermediate typed representation) at exactly the depth kind implies.
Mirrors encode_boundaries (writer/geom_encoder.rs:160-189). GeometryKind::GeometryInstance yields an empty GMBoundaries; it is encoded separately (M3).
Definition at line 216 of file geom_encoder.cpp.
References CompositeSolid, CompositeSurface, GeometryInstance, kind, MultiLineString, MultiPoint, MultiSolid, MultiSurface, ring, fcb::GMBoundaries::shells, Solid, surface, and fcb::GMBoundaries::surfaces.
Referenced by encode().
| std::vector< std::uint8_t > fcb::encode_key | ( | const KeyValue & | v | ) |
Definition at line 147 of file key.cpp.
Referenced by build_static_btree().
| std::vector< MaterialMapping > fcb::encode_material | ( | const nlohmann::ordered_json & | material | ) |
Flattens material (the CityJSON geometry.material object: theme name -> {"value": N} / {"values": [...]} / {"values": null}).
Themes are visited in ascending name order – sorted EXPLICITLY, unlike an attribute schema's document order (writer/attribute.hpp): material corresponds to Rust's HashMap<String, CjMaterialReference>, genuinely unordered, so Rust sorts theme names itself (themes.sort_unstable()) rather than trusting iteration order, and this does the same regardless of what order the input JSON's material object happens to have. A null shell or solid – legal at every level – is recorded as a UINT32_MAX count, not dropped, so it decodes back as null rather than an empty array.
As with encode_semantics, the depth of a values array is determined by sniffing its own JSON shape shallowest-first, mirroring Rust's untagged MaterialValues enum, rather than from the enclosing geometry's type – see that function's doc comment for why this matters for cardinality-inconsistent-but-schema-valid files. Mirrors encode_material (writer/geom_encoder.rs:204-284).
Definition at line 295 of file geom_encoder.cpp.
References fcb::MaterialMapping::kind, fcb::MaterialMapping::NullValues, shell, fcb::MaterialMapping::solids, fcb::MaterialMapping::theme, fcb::MaterialMapping::Value, fcb::MaterialMapping::value, fcb::MaterialMapping::Values, and fcb::MaterialMapping::vertices.
Referenced by encode().
| std::vector< std::uint8_t > fcb::encode_packed_rtree | ( | const std::vector< NodeItem > & | tree | ) |
Serializes every node in tree (as returned by build_packed_rtree) in array order, 40 bytes each.
Mirrors PackedRTree::stream_write (packed_rtree/mod.rs:900-906).
Definition at line 173 of file rtree_builder.cpp.
References encode(), and fcb::NodeItem::kSize.
Referenced by fcb::FcbWriter::write().
| void fcb::encode_payload_entry | ( | std::vector< std::uint8_t > & | out, |
| const std::vector< std::uint64_t > & | offsets | ||
| ) |
| GMSemantics fcb::encode_semantics | ( | const nlohmann::ordered_json & | semantics, |
| const GMBoundaries & | boundaries | ||
| ) |
Flattens semantics (the CityJSON semantics object: surfaces plus values), using boundaries's shell/solid counts to expand a null shell or solid into the right number of per-surface nulls (there is no wire encoding for a whole-null shell in semantics, unlike material).
The depth is determined by SNIFFING values's own JSON shape – trying the shallowest interpretation (a flat array of number-or-null) first, then one array level deeper, then two – rather than from the enclosing geometry's type. This mirrors what Rust's SemanticsValues actually does (an untagged serde enum, whose variants are tried shallowest-first): for ordinary, cardinality-consistent files the sniffed depth always agrees with the geometry-type-implied depth, but they can disagree for a schema-valid-yet-inconsistent file (e.g. a Solid whose semantics.values is written as a flat one-element array instead of properly nested) – shape-sniffing is what makes this port byte-compatible with Rust on those files too, not just the well-formed ones. Mirrors encode_semantics (writer/geom_encoder.rs:379-447).
Definition at line 248 of file geom_encoder.cpp.
References shell, fcb::GMBoundaries::solids, fcb::GMSemantics::surfaces, and fcb::GMSemantics::values.
Referenced by encode().
| std::vector< TextureMapping > fcb::encode_texture | ( | const nlohmann::ordered_json & | texture | ) |
Flattens texture (the CityJSON geometry.texture object).
texture.values nests exactly as deeply as boundaries itself (one UV-vertex index per boundary vertex index), unlike material, which is one level shallower. Nullable only at the leaf: unlike material, there is no wire encoding for a whole-null intermediate level, so nothing here decodes an intermediate null.
As with encode_semantics/encode_material, depth is sniffed from values's own JSON shape (shallowest-first: a list of TexturedSurface, then of TexturedShell, then of shell-lists), mirroring Rust's untagged TextureValues enum, rather than taken from the enclosing geometry's type. Mirrors encode_texture (writer/geom_encoder.rs:290-361).
Definition at line 369 of file geom_encoder.cpp.
References fcb::TextureMapping::has_values, shell, fcb::TextureMapping::shells, fcb::TextureMapping::solids, surface, and fcb::TextureMapping::theme.
Referenced by encode().
| GeometryKind fcb::geometry_kind_from_name | ( | const std::string & | name | ) |
Maps a CityJSON geometry type string to GeometryKind.
Throws Error{InvalidAttributeValue} on any string outside CityJSON's eight known geometry types.
Definition at line 196 of file geom_encoder.cpp.
References CompositeSolid, CompositeSurface, GeometryInstance, InvalidAttributeValue, MultiLineString, MultiPoint, MultiSolid, MultiSurface, and Solid.
Referenced by encode(), and to_geometry().
| std::string fcb::geometry_type_name | ( | std::uint8_t | type | ) |
CityJSON name for a GeometryType enumerator, e.g.
"MultiSurface".
Throws on a tag outside the eight the spec defines. CityJSON offers no '+'-prefixed extension mechanism for geometry types (unlike City Object types and semantic surface types, which get "+UnknownCityObject" and "+GenericSurface" respectively), so there is no schema-valid string to return and no honest alternative to an error. Mirrors GeometryType::to_cj (geom_decoder.rs); see the policy note at the top of cityjson.cpp.
Definition at line 376 of file geometry.cpp.
References InvalidFlatbuffer.
| std::uint32_t fcb::hilbert | ( | std::uint32_t | x, |
| std::uint32_t | y | ||
| ) |
The Hilbert curve index of point (x, y) on a 65536x65536 grid (16 bits per axis).
A fixed bit-twiddling function with no branches or loops – every operation is ^/&/|/<</>> on uint32_t, none of which can overflow in the sense Rust's debug-mode overflow checks mean (those only instrument +/-/*), so this is a direct transliteration of hilbert (packed_rtree/mod.rs:236-289) with no wraparound-semantics concerns.
Definition at line 21 of file rtree_builder.cpp.
Referenced by hilbert_bbox().
| std::uint32_t fcb::hilbert_bbox | ( | const NodeItem & | r, |
| std::uint32_t | hilbert_max, | ||
| const NodeItem & | extent | ||
| ) |
A NodeItem's Hilbert index: its bbox center, scaled into [0, hilbert_max] against extent, fed through hilbert.
Mirrors hilbert_bbox (packed_rtree/mod.rs:291-298); hilbert_max is always (1 << 16) - 1 in practice (HILBERT_MAX), taken as a parameter only to keep the two constants visible together at the call site, as in Rust.
Definition at line 94 of file rtree_builder.cpp.
References hilbert(), fcb::NodeItem::max_x, fcb::NodeItem::max_y, fcb::NodeItem::min_x, and fcb::NodeItem::min_y.
Sorts items in place by descending Hilbert index (the item furthest along the curve first) – a STABLE sort, matching Rust's slice sort_by guarantee.
Mirrors hilbert_sort (packed_rtree/mod.rs:300-306).
Definition at line 102 of file rtree_builder.cpp.
Referenced by fcb::FcbWriter::write().
|
inline |
Definition at line 41 of file stree.hpp.
References kPayloadTag.
| KeyKind fcb::key_kind_for_column | ( | std::uint8_t | column_type | ) |
Column type to key kind, following what the WRITER emits.
Byte maps to UInt8, not Int8 – see the Byte note in key.cpp.
Takes the raw ubyte rather than the generated ::ColumnType so that consumers of this header never see the generated FlatBuffers API. ColumnInfo::type carries exactly this value.
Definition at line 387 of file key.cpp.
References Bool, DateTime, Float32, Float64, Int16, Int32, Int64, String100, String50, UInt16, UInt32, UInt64, UInt8, and UnsupportedColumnType.
Referenced by fcb::FcbReader::select_attr(), and fcb::FcbWriter::write().
Definition at line 350 of file key.cpp.
References Bool, DateTime, Float32, Float64, fcb::KeyValue::from_bool(), fcb::KeyValue::from_datetime(), fcb::KeyValue::from_f32(), fcb::KeyValue::from_f64(), fcb::KeyValue::from_i16(), fcb::KeyValue::from_i32(), fcb::KeyValue::from_i64(), fcb::KeyValue::from_i8(), fcb::KeyValue::from_string(), fcb::KeyValue::from_u16(), fcb::KeyValue::from_u32(), fcb::KeyValue::from_u64(), fcb::KeyValue::from_u8(), Int16, Int32, Int64, Int8, key_serialized_size(), kind, String100, String20, String50, UInt16, UInt32, UInt64, UInt8, and UnsupportedColumnType.
Referenced by stree_query().
Sentinels used to lower open-ended range queries.
These reproduce the reference's quirks deliberately: the float maximum is +inf even though NaN sorts above it (so NaN-keyed features are invisible to range queries), and the DateTime minimum is epoch 0 even though the wire format allows negative seconds.
Definition at line 313 of file key.cpp.
References Bool, DateTime, Float32, Float64, fcb::KeyValue::from_bool(), fcb::KeyValue::from_datetime(), fcb::KeyValue::from_f32(), fcb::KeyValue::from_f64(), fcb::KeyValue::from_i16(), fcb::KeyValue::from_i32(), fcb::KeyValue::from_i64(), fcb::KeyValue::from_i8(), fcb::KeyValue::from_string(), fcb::KeyValue::from_u16(), fcb::KeyValue::from_u32(), fcb::KeyValue::from_u64(), fcb::KeyValue::from_u8(), Int16, Int32, Int64, Int8, kind, String100, String20, String50, UInt16, UInt32, UInt64, UInt8, and UnsupportedColumnType.
Referenced by stree_query().
| std::size_t fcb::key_serialized_size | ( | KeyKind | kind | ) |
Serialized width in bytes. DateTime is 12: i64 seconds + u32 nanos.
Definition at line 61 of file key.cpp.
References Bool, DateTime, Float32, Float64, Int16, Int32, Int64, Int8, kind, String100, String20, String50, UInt16, UInt32, UInt64, UInt8, and UnsupportedColumnType.
Referenced by build_static_btree(), and key_max().
| std::optional< ParsedReferenceSystem > fcb::parse_reference_system | ( | const std::string & | url | ) |
Parses a referenceSystem URL (https://www.opengis.net/def/crs/{authority}/{version}/{code}, per cjseq2's ReferenceSystem::from_url) into its three OGC elements.
version/code default to 0 when their segment is absent OR fails to parse as a whole int32 (matching Rust's .parse::<i32>().ok(). unwrap_or(0) exactly – a segment like "7415x" does NOT parse as 7415; it fails whole, same as Rust). Returns std::nullopt when url matches neither the http:// nor https:// OGC prefix – Rust's TryFrom<String> would fail the WHOLE document's deserialization in that case instead, which this milestone does not replicate (out of scope; disclosed here rather than silently matched).
Definition at line 104 of file header_serializer.cpp.
References fcb::ParsedReferenceSystem::authority, fcb::ParsedReferenceSystem::code, and fcb::ParsedReferenceSystem::version.
Referenced by to_fcb_header().
|
inline |
Definition at line 42 of file stree.hpp.
References kPayloadMask.
| HeaderView fcb::read_header | ( | std::shared_ptr< RangeReader > | reader | ) |
Read and validate the file preamble and header.
Takes SHARED ownership so it can construct its own per-query BufferedRangeReader internally (over-fetching the header plus the top R-tree levels in one request, as the Rust HTTP reader does).
Definition at line 199 of file header.cpp.
Referenced by fcb::FcbReader::open().
| std::uint64_t fcb::rtree_index_size | ( | std::uint64_t | num_items, |
| std::uint16_t | node_size | ||
| ) |
Mirrors PackedRTree::index_size (packed_rtree/mod.rs:879-898).
Returns bytes. Throws on node_size < 2, num_items == 0, or arithmetic overflow.
Definition at line 26 of file layout.cpp.
References IllegalHeaderSize, kNodeItemSize, and node_size.
Referenced by compute_layout().
| std::vector< LevelBound > fcb::rtree_level_bounds | ( | std::uint64_t | num_items, |
| std::uint16_t | node_size | ||
| ) |
Mirrors generate_level_bounds (packed_rtree/mod.rs:342-375).
Shared by the reader (rtree_search_bbox) and the writer's R-tree builder (M5) – both need the exact same per-level array layout to agree on where a child index or search cursor actually lands.
Definition at line 125 of file packed_rtree.cpp.
References fcb::detail::ceil_div(), fcb::detail::checked_add(), IllegalHeaderSize, node_size, and NoIndex.
Referenced by build_packed_rtree(), and rtree_search_bbox().
| std::uint64_t fcb::rtree_num_nodes | ( | std::uint64_t | num_items, |
| std::uint16_t | node_size | ||
| ) |
Total node count in the tree, per the Rust level-bounds loop (packed_rtree/mod.rs:342-375).
Breaks at n == 1 – note this differs from the B+tree, which breaks at n < branching_factor.
Definition at line 107 of file packed_rtree.cpp.
References fcb::detail::ceil_div(), fcb::detail::checked_add(), IllegalHeaderSize, and node_size.
Referenced by rtree_search_bbox().
| std::vector< SearchResultItem > fcb::rtree_search_bbox | ( | RangeReader & | reader, |
| std::uint64_t | index_begin, | ||
| std::uint64_t | num_items, | ||
| std::uint16_t | node_size, | ||
| const BBox & | query | ||
| ) |
Breadth-first bbox search over the packed R-tree, reading nodes through the supplied reader.
Results are returned sorted by feature offset so the caller reads forward through the file.
Definition at line 161 of file packed_rtree.cpp.
References fcb::detail::checked_add(), fcb::detail::checked_mul(), fcb::NodeItem::decode(), index_begin, fcb::NodeItem::intersects(), fcb::NodeItem::kSize, node_size, NoIndex, fcb::NodeItem::offset, fcb::RangeReader::read(), reader, rtree_level_bounds(), and rtree_num_nodes().
Referenced by fcb::FcbReader::select_bbox().
| SurfaceType fcb::semantic_surface_type_from_name | ( | const std::string & | name | ) |
Maps a CityJSON semantic surface type string to the FlatBuffers tag.
A name outside CityJSON's 18 known surface types becomes ExtraSemanticSurface plus the name verbatim. Mirrors FcbSemanticSurfaceType::from (writer/serializer.rs:820-883).
Definition at line 134 of file feature_serializer.cpp.
| std::string fcb::semantic_surface_type_name | ( | std::uint8_t | type | ) |
CityJSON name for a SemanticSurfaceType enumerator, e.g.
"RoofSurface".
A tag with no CityJSON name of its own – ExtraSemanticSurface, whose real name lives in the surface's extension_type string, or anything a newer encoder added – becomes "+GenericSurface". Same policy note.
Definition at line 572 of file cityjson.cpp.
| std::vector< StreeLevelBound > fcb::stree_level_bounds | ( | std::uint64_t | num_items, |
| std::uint16_t | branching_factor | ||
| ) |
Mirrors Stree::generate_level_bounds (stree.rs:474-508).
Mirrors Stree::generate_level_bounds (stree.rs:462-497).
Shared by the reader (stree_query) and the writer's B+tree builder (M6) – both need the exact same per-level array layout to agree on where a child index or search cursor actually lands. Named Stree... (not LevelBound, unlike the R-tree's fcb::LevelBound in packed_rtree.hpp) only to avoid a name collision between the two headers – the two types are structurally identical and otherwise unrelated.
The loop divides by branching_factor and stops at n < branching_factor – NOT at n == 1 as the R-tree does. Searching, meanwhile, uses branching_factor - 1 entries per node. Both asymmetries are real: the entry count per node is one less than the fan-out because each entry is a separator key, and the level loop stops as soon as a level fits in one node's worth of separators.
Definition at line 20 of file stree.cpp.
References AttributeIndexNotFound, fcb::detail::ceil_div(), and fcb::detail::checked_add().
Referenced by build_static_btree(), and stree_query().
| std::uint64_t fcb::stree_num_nodes | ( | std::uint64_t | num_items, |
| std::uint16_t | branching_factor | ||
| ) |
Total node count.
NOTE the loop breaks at n < branching_factor, unlike the R-tree's n == 1 (stree.rs:462-497). The asymmetry is deliberate in the reference; do not "fix" it.
Definition at line 313 of file stree.cpp.
References AttributeIndexNotFound, fcb::detail::ceil_div(), and fcb::detail::checked_add().
Referenced by stree_query().
| std::vector< SearchResultItem > fcb::stree_query | ( | RangeReader & | reader, |
| const AttrIndexInfo & | index, | ||
| KeyKind | kind, | ||
| Operator | op, | ||
| const KeyValue & | value | ||
| ) |
Run one condition against one column's index blob, returning candidate feature offsets (relative to the features section).
Definition at line 360 of file stree.cpp.
References AttributeIndexNotFound, fcb::detail::checked_add(), fcb::detail::checked_mul(), Eq, Ge, Gt, index, key_max(), key_min(), kind, Le, Lt, Ne, QueryExecutionError, reader, stree_level_bounds(), stree_num_nodes(), String100, String20, and String50.
Referenced by fcb::FcbReader::select_attr().
| flatbuffers::Offset<::Appearance > fcb::to_appearance | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const nlohmann::ordered_json & | appearance | ||
| ) |
Builds the Appearance table (materials, textures, UV vertices, default themes) from a CityJSON appearance object.
Mirrors to_appearance (writer/serializer.rs:533-622); fb_wrap_mode/fb_texture_type/ fb_texture_format are folded in directly since nothing else calls them.
Definition at line 142 of file feature_serializer.cpp.
Referenced by to_fcb_city_feature(), and to_fcb_header().
| flatbuffers::Offset<::CityObject > fcb::to_city_object | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const std::string & | id, | ||
| const nlohmann::ordered_json & | co, | ||
| const AttributeSchema & | attr_schema, | ||
| const AttributeSchema * | semantic_attr_schema | ||
| ) |
Builds one CityObject table: type, geographical extent, geometry (split into non-instance and GeometryInstance entries), attributes (against attr_schema, or the object's own schema when its attribute keys are not all present in attr_schema), children/children-roles/ parents.
Mirrors to_city_object (writer/serializer.rs:632-730).
Definition at line 419 of file feature_serializer.cpp.
References city_object_type_from_name(), to_columns(), to_geographical_extent(), to_geometry(), and to_geometry_instance().
Referenced by to_fcb_city_feature().
| nlohmann::json fcb::to_cityjson_feature | ( | const Feature & | feature, |
| const HeaderView & | header | ||
| ) |
One feature as a CityJSONFeature object.
Attributes are decoded against each CityObject's OWN column schema when it declares one, falling back to the header's – see the per-object schema note in the plan. Using the wrong schema yields silent garbage.
Definition at line 682 of file cityjson.cpp.
References attributes_to_json(), fcb::Feature::city_object_count(), city_object_type_name(), fcb::FileInfo::columns, fcb::detail::FeatureAccess::get(), fcb::Feature::id(), fcb::HeaderView::info(), MissingRequiredField, fcb::Feature::object_attributes(), fcb::Feature::object_columns(), fcb::Feature::object_extent(), fcb::Feature::object_has_attributes(), fcb::Feature::object_has_columns(), fcb::Feature::object_id(), and fcb::FileInfo::semantic_columns.
| nlohmann::json fcb::to_cityjson_metadata | ( | const HeaderView & | header | ) |
The CityJSON metadata envelope: type, version, transform, extent, CRS.
This is the first line of a CityJSONSeq stream.
Definition at line 585 of file cityjson.cpp.
References fcb::detail::HeaderAccess::get(), and fcb::HeaderView::info().
| flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::Column > > > fcb::to_columns | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const AttributeSchema & | schema | ||
| ) |
Builds the Column vector for Header.columns or CityObject.columns, in ascending column-index order.
Definition at line 366 of file attribute.cpp.
Referenced by to_city_object(), and to_fcb_header().
| flatbuffers::Offset<::Extension > fcb::to_extension | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const std::string & | name, | ||
| const std::string & | url, | ||
| const std::string & | version | ||
| ) |
Builds one extensions entry: only name/url/version are written (the schema document itself is never fetched or embedded).
Mirrors to_extension (writer/serializer.rs:378-397).
Definition at line 138 of file header_serializer.cpp.
Referenced by to_fcb_header().
| std::pair<::flatbuffers::Offset<::CityFeature >, NodeItem > fcb::to_fcb_city_feature | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const std::string & | id, | ||
| const nlohmann::ordered_json & | city_feature, | ||
| const AttributeSchema & | attr_schema, | ||
| const AttributeSchema * | semantic_attr_schema | ||
| ) |
Builds one CityFeature table – its CityObjects (visited in ascending id order), vertices, and optional feature-level appearance – from a CityJSONFeature JSON object, plus its 2D bounding box over the RAW (untransformed, still-integer) vertex coordinates.
Applying the file's Transform scale/translate to that bbox, and everything about hilbert ordering and index assembly, is the caller's job (M7's FcbWriter). Mirrors to_fcb_city_feature (writer/serializer.rs:410-489).
Definition at line 537 of file feature_serializer.cpp.
References to_appearance(), and to_city_object().
Referenced by fcb::FcbWriter::add_feature().
| flatbuffers::Offset<::Header > fcb::to_fcb_header | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const nlohmann::ordered_json & | cj, | ||
| const HeaderWriterOptions & | options, | ||
| const AttributeSchema & | attr_schema, | ||
| const AttributeSchema * | semantic_attr_schema, | ||
| const std::vector< AttributeIndexInfo > * | attribute_indices_info | ||
| ) |
Builds the whole Header table from the CityJSON metadata line (the first line of a CityJSONSeq: type/version/transform/metadata/ geometry-templates/appearance/extensions), the writer options, and the attribute schema(s).
attribute_indices_info is nullptr before M6 exists / when no attribute indices were configured. Mirrors to_fcb_header (writer/serializer.rs:52-231).
EVERY fbb.CreateString/CreateVector call this function makes – directly or through a helper – happens in the exact sequence Rust's own let bindings run in, never as an inline call argument: FlatBuffers builder calls are side-effecting and append to the buffer in call order, so call order is part of the wire format (a real bug caught by M3's byte-exact oracle, documented in feature_serializer.cpp).
The table itself is assembled via the generated CreateHeader free function, not a hand-sequenced HeaderBuilder: flatc emits Create* in a fixed, width-sorted add_* order (identical across every language backend), and a field's byte offset WITHIN the table is determined by that call order, not by which vtable slot it occupies. Building the HeaderBuilder calls by hand – even with every field present and correct – lays the table out differently from Rust's output and fails byte-exactness despite decoding to identical values; this was a real regression caught by this milestone's own oracle test (test_writer_oracle.cpp).
Definition at line 203 of file header_serializer.cpp.
References fcb::PocOffsets::address_country, fcb::PocOffsets::address_locality, fcb::PocOffsets::address_postcode, fcb::PocOffsets::address_thoroughfare_name, fcb::PocOffsets::address_thoroughfare_number, fcb::PocOffsets::contact_name, fcb::PocOffsets::contact_type, fcb::PocOffsets::email, fcb::HeaderWriterOptions::feature_count, fcb::HeaderWriterOptions::geographical_extent, fcb::HeaderWriterOptions::index_node_size, parse_reference_system(), fcb::PocOffsets::phone, fcb::PocOffsets::role, to_appearance(), to_columns(), to_extension(), to_geographical_extent(), to_geometry(), to_point_of_contact(), to_reference_system(), to_templates_vertices(), to_transform(), and fcb::PocOffsets::website.
Referenced by fcb::FcbWriter::write().
| GeographicalExtent fcb::to_geographical_extent | ( | const std::array< double, 6 > & | extent | ) |
Builds a GeographicalExtent struct from a 6-element [minx,miny,minz,maxx,maxy,maxz] array.
Shared with the header (M4), which has its own geographicalExtent. Mirrors to_geographical_extent (writer/serializer.rs:233-250).
Definition at line 383 of file feature_serializer.cpp.
Referenced by to_city_object(), and to_fcb_header().
| flatbuffers::Offset<::Geometry > fcb::to_geometry | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const nlohmann::ordered_json & | geometry, | ||
| const AttributeSchema * | semantic_attr_schema | ||
| ) |
Builds one Geometry table – boundaries, and whatever semantics, material and texture it carries – from a CityJSON geometry object (everything but a GeometryInstance, which to_geometry_instance handles).
semantic_attr_schema is nullptr when the file has no semantic attribute schema at all; a present-but-empty schema is a distinct, valid state. Mirrors to_geometry (writer/serializer.rs:891-1065).
Definition at line 257 of file feature_serializer.cpp.
References fcb::EncodedGeometry::boundaries, encode(), geometry_kind_from_name(), fcb::GMBoundaries::indices, kind, fcb::EncodedGeometry::materials, fcb::MaterialMapping::NullValues, fcb::EncodedGeometry::semantics, fcb::GMBoundaries::shells, shells, fcb::GMBoundaries::solids, fcb::GMBoundaries::strings, strings, surface, fcb::GMBoundaries::surfaces, surfaces, fcb::EncodedGeometry::textures, fcb::MaterialMapping::Value, fcb::MaterialMapping::Values, and vertices.
Referenced by to_city_object(), and to_fcb_header().
| flatbuffers::Offset<::GeometryInstance > fcb::to_geometry_instance | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const nlohmann::ordered_json & | geometry | ||
| ) |
Builds a GeometryInstance table: the template index, the 4x4 transformation matrix, and the single-element boundaries array holding the reference vertex index.
Throws fcb::Error if geometry's type is not "GeometryInstance" (Rust panic!s here instead – a programmer-error assertion that becomes a catchable exception in a library rather than an abort). Mirrors to_geometry_instance (writer/serializer.rs:1067-1102).
Definition at line 358 of file feature_serializer.cpp.
References InvalidAttributeValue.
Referenced by to_city_object().
| PocOffsets fcb::to_point_of_contact | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const nlohmann::ordered_json & | poc | ||
| ) |
Definition at line 166 of file header_serializer.cpp.
References fcb::PocOffsets::address_country, fcb::PocOffsets::address_locality, fcb::PocOffsets::address_postcode, fcb::PocOffsets::address_thoroughfare_name, fcb::PocOffsets::address_thoroughfare_number, fcb::PocOffsets::contact_name, fcb::PocOffsets::contact_type, fcb::PocOffsets::email, fcb::PocOffsets::phone, fcb::PocOffsets::role, and fcb::PocOffsets::website.
Referenced by to_fcb_header().
| flatbuffers::Offset<::ReferenceSystem > fcb::to_reference_system | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const ParsedReferenceSystem & | ref_sys | ||
| ) |
Builds the ReferenceSystem table from a parsed metadata.referenceSystem URL.
Mirrors to_reference_system (writer/serializer.rs:273-301); code_string is always absent, matching Rust's own None there.
Definition at line 132 of file header_serializer.cpp.
References fcb::ParsedReferenceSystem::authority, fcb::ParsedReferenceSystem::code, and fcb::ParsedReferenceSystem::version.
Referenced by to_fcb_header().
| flatbuffers::Offset<::flatbuffers::Vector< const ::DoubleVertex * > > fcb::to_templates_vertices | ( | ::flatbuffers::FlatBufferBuilder & | fbb, |
| const nlohmann::ordered_json & | vertices_templates | ||
| ) |
Builds Header.templates_vertices from CityJSON's geometry-templates.vertices-templates (f64 precision, unlike a feature's own int32 vertices).
A non-3-number-array element is skipped, not guessed at. Mirrors to_templates_vertices (writer/serializer.rs:1107-1125).
Definition at line 148 of file header_serializer.cpp.
Referenced by to_fcb_header().
| Transform fcb::to_transform | ( | const nlohmann::ordered_json & | transform | ) |
Builds the Transform struct (scale + translate) from CityJSON's top-level transform member.
Mirrors to_transform (writer/serializer.rs:257-265).
Definition at line 95 of file header_serializer.cpp.
Referenced by to_fcb_header().
| void fcb::validate_layout_against_size | ( | const FileLayout & | l, |
| std::uint64_t | total_size | ||
| ) |
Throws unless the computed sections fit inside the resource.
Call this immediately after compute_layout, before issuing any index read.
Definition at line 70 of file layout.cpp.
References fcb::FileLayout::feature_begin, and IllegalHeaderSize.
|
staticconstexpr |
No padding needed.
FlatBuffers aligns a size-prefixed buffer's contents relative to the START OF THE BUFFER (prefix included), so placing the buffer at an 8-aligned address – which std::vector's allocation already guarantees – makes every struct inside correctly aligned. Kept as a named constant so the reasoning stays visible and the slicing arithmetic reads the same.
Definition at line 20 of file header.cpp.
Referenced by fcb::FeatureIterator::next().
|
staticconstexpr |
No padding needed; see the note in header.cpp.
Definition at line 18 of file reader.cpp.
|
constexpr |
Mirrors static_btree::DEFAULT_BRANCHING_FACTOR (static_btree/mod.rs:19), used whenever a caller requests an attribute index without naming an explicit branching factor.
Definition at line 16 of file btree_builder.hpp.
Referenced by fcb::FcbWriter::write().
|
constexpr |
Definition at line 16 of file layout.hpp.
|
constexpr |
Definition at line 13 of file layout.hpp.
Referenced by compute_layout().
|
constexpr |
Definition at line 12 of file layout.hpp.
|
constexpr |
Definition at line 11 of file layout.hpp.
Referenced by compute_layout().
|
constexpr |
Definition at line 10 of file layout.hpp.
Referenced by check_magic_bytes(), and compute_layout().
|
constexpr |
Hard ceiling on a single feature's byte length, enforced before allocating.
A crafted 4-byte prefix would otherwise request up to 4 GiB.
Definition at line 20 of file layout.hpp.
Referenced by fcb::FeatureIterator::next().
|
constexpr |
Definition at line 15 of file layout.hpp.
Referenced by rtree_index_size().
|
constexpr |
Definition at line 39 of file stree.hpp.
Referenced by payload_offset().
|
constexpr |
The MSB of a leaf offset marks a payload reference rather than a direct feature offset (stree.rs:15-17).
Definition at line 38 of file stree.hpp.
Referenced by is_payload_ref().
|
constexpr |
Definition at line 14 of file layout.hpp.
Referenced by check_magic_bytes().