fcb_core/writer/
feature_writer.rs1use cjseq::CityJSONFeature;
2
3use crate::serializer::*;
4
5use super::attribute::{cityfeature_to_index_entries, AttributeIndexEntry, AttributeSchema};
6
7use crate::packed_rtree::NodeItem;
8
9pub struct FeatureWriter<'a> {
14 city_feature: &'a CityJSONFeature,
16 fbb: flatbuffers::FlatBufferBuilder<'a>,
18 attr_schema: AttributeSchema,
20
21 semantic_attr_schema: Option<AttributeSchema>,
22 pub(super) bbox: NodeItem,
23
24 attr_indices: Option<Vec<String>>,
25
26 pub(super) attribute_feature_offsets: AttributeFeatureOffset,
27}
28
29#[derive(Clone, PartialEq, Debug)]
30pub(super) struct AttributeFeatureOffset {
31 pub(super) offset: usize,
32 pub(super) size: usize,
33 pub(super) index_entries: Vec<AttributeIndexEntry>,
34}
35
36impl<'a> FeatureWriter<'a> {
37 pub fn new(
43 city_feature: &'a CityJSONFeature,
44 attr_schema: AttributeSchema,
45 semantic_attr_schema: Option<AttributeSchema>,
46 attr_indices: Option<Vec<String>>,
47 ) -> FeatureWriter<'a> {
48 FeatureWriter {
49 city_feature,
50 fbb: flatbuffers::FlatBufferBuilder::new(),
51 attr_schema,
52 semantic_attr_schema,
53 bbox: NodeItem::create(0),
54 attr_indices,
55 attribute_feature_offsets: AttributeFeatureOffset {
56 offset: 0,
57 size: 0,
58 index_entries: Vec::new(),
59 },
60 }
61 }
62
63 pub fn finish_to_feature(&mut self) -> Vec<u8> {
72 self.reset_bbox();
73 self.reset_attribute_feature_offsets();
74 self.extract_indexable_attributes();
75 let (cf_buf, bbox) = to_fcb_city_feature(
76 &mut self.fbb,
77 self.city_feature.id.as_str(),
78 self.city_feature,
79 &self.attr_schema,
80 self.semantic_attr_schema.as_ref(),
81 );
82 self.bbox = bbox;
83 self.fbb.finish_size_prefixed(cf_buf, None);
84 let buf = self.fbb.finished_data().to_vec();
85 self.fbb.reset();
86 buf
87 }
88
89 pub fn add_feature(&mut self, feature: &'a CityJSONFeature) {
95 self.city_feature = feature;
96 }
97
98 fn extract_indexable_attributes(&mut self) {
99 if let Some(attr_indices) = &self.attr_indices {
100 let index_entries =
101 cityfeature_to_index_entries(self.city_feature, &self.attr_schema, attr_indices);
102 self.attribute_feature_offsets.index_entries = index_entries;
103 }
104 }
105
106 fn reset_bbox(&mut self) {
107 self.bbox = NodeItem::create(0);
108 }
109
110 fn reset_attribute_feature_offsets(&mut self) {
111 self.attribute_feature_offsets.index_entries.clear();
112 self.attribute_feature_offsets.offset = 0;
113 self.attribute_feature_offsets.size = 0;
114 }
115}