use crate::osm::model::relation::{Member, Relation};
use crate::osm::pbf::string_table_builder::StringTableBuilder;
use crate::osmpbf;
use crate::osmpbf::PrimitiveGroup;
pub(crate) struct RelationsGroupBuilder {
relations: Option<Vec<osmpbf::Relation>>,
date_granularity: i32,
}
impl RelationsGroupBuilder {
pub(crate) fn new(date_granularity: i32, relation: &Relation, string_table_builder: &mut StringTableBuilder) -> RelationsGroupBuilder {
let mut relations = Some(Vec::<osmpbf::Relation>::with_capacity(8000));
relations.as_mut().unwrap().push(Self::convert(relation, date_granularity, string_table_builder));
RelationsGroupBuilder {
relations,
date_granularity,
}
}
pub(crate) fn add(&mut self, relation: &Relation, string_table_builder: &mut StringTableBuilder) {
self.relations.as_mut().unwrap().push(Self::convert(relation, self.date_granularity, string_table_builder));
}
#[allow(clippy::field_reassign_with_default)]
fn convert(relation: &Relation, date_granularity: i32, string_table_builder: &mut StringTableBuilder) -> osmpbf::Relation {
let mut r = osmpbf::Relation::default();
r.id = relation.id();
let mut last_memid = 0;
for member in relation.members() {
let current_memid;
match member {
Member::Node { member } => {
current_memid = member.id();
r.types.push(osmpbf::relation::MemberType::Node as i32);
r.roles_sid.push(string_table_builder.add(member.role()))
}
Member::Way { member } => {
current_memid = member.id();
r.types.push(osmpbf::relation::MemberType::Way as i32);
r.roles_sid.push(string_table_builder.add(member.role()))
}
Member::Relation { member } => {
current_memid = member.id();
r.types.push(osmpbf::relation::MemberType::Relation as i32);
r.roles_sid.push(string_table_builder.add(member.role()))
}
}
r.memids.push(current_memid - last_memid);
last_memid = current_memid;
}
for tag in relation.tags() {
let key_index = string_table_builder.add(tag.k());
let val_index = string_table_builder.add(tag.v());
r.keys.push(key_index as u32);
r.vals.push(val_index as u32)
}
r.info = Some(osmpbf::Info::default());
r.info.as_mut().unwrap().visible = Some(relation.visible());
r.info.as_mut().unwrap().uid = Some(relation.uid());
r.info.as_mut().unwrap().changeset = Some(relation.changeset());
r.info.as_mut().unwrap().timestamp = Some(relation.timestamp() / date_granularity as i64);
r.info.as_mut().unwrap().version = Some(relation.version());
r.info.as_mut().unwrap().user_sid = Some(string_table_builder.add(relation.user()) as u32);
r
}
#[allow(clippy::field_reassign_with_default)]
pub(crate) fn build(&mut self) -> PrimitiveGroup {
let mut primitive_group = PrimitiveGroup::default();
primitive_group.relations = self.relations.replace(Vec::<osmpbf::Relation>::new()).unwrap();
primitive_group
}
}