use crate::error::Result;
use crate::packed_rtree::PackedRTree;
use crate::serializer::to_fcb_header;
use cjseq::CityJSON;
use flatbuffers::FlatBufferBuilder;
use super::{attribute::AttributeSchema, serializer::AttributeIndexInfo};
pub struct HeaderWriter<'a> {
pub fbb: FlatBufferBuilder<'a>,
pub cj: CityJSON,
pub header_options: HeaderWriterOptions,
pub attr_schema: AttributeSchema,
pub semantic_attr_schema: Option<AttributeSchema>,
pub(super) attribute_indices_info: Option<Vec<AttributeIndexInfo>>,
}
#[derive(Debug, Clone)]
pub struct HeaderWriterOptions {
pub write_index: bool,
pub feature_count: u64,
pub index_node_size: u16,
pub attribute_indices: Option<Vec<(String, Option<u16>)>>, pub geographical_extent: Option<[f64; 6]>,
}
impl Default for HeaderWriterOptions {
fn default() -> Self {
HeaderWriterOptions {
write_index: true,
index_node_size: PackedRTree::DEFAULT_NODE_SIZE,
feature_count: 0,
attribute_indices: None,
geographical_extent: None,
}
}
}
impl<'a> HeaderWriter<'a> {
pub(super) fn new(
cj: CityJSON,
header_options: Option<HeaderWriterOptions>,
attr_schema: AttributeSchema,
semantic_attr_schema: Option<AttributeSchema>,
) -> HeaderWriter<'a> {
Self::new_with_options(
header_options.unwrap_or_default(),
cj,
attr_schema,
semantic_attr_schema,
)
}
fn new_with_options(
mut options: HeaderWriterOptions,
cj: CityJSON,
attr_schema: AttributeSchema,
semantic_attr_schema: Option<AttributeSchema>,
) -> HeaderWriter<'a> {
let fbb = FlatBufferBuilder::new();
let index_node_size = if options.write_index {
PackedRTree::DEFAULT_NODE_SIZE
} else {
0
};
options.index_node_size = index_node_size;
HeaderWriter {
fbb,
cj,
header_options: options,
attr_schema,
semantic_attr_schema,
attribute_indices_info: None,
}
}
pub(super) fn finish_to_header(mut self) -> Result<Vec<u8>> {
let header = to_fcb_header(
&mut self.fbb,
&self.cj,
self.header_options,
&self.attr_schema,
self.semantic_attr_schema.as_ref(),
self.attribute_indices_info
.as_ref()
.filter(|info| !info.is_empty())
.map(|info| info.as_slice()),
)?;
self.fbb.finish_size_prefixed(header, None);
Ok(self.fbb.finished_data().to_vec())
}
}