Skip to main content

ecitygml_core/model/building/
abstract_building.rs

1use crate::model::building::building_room::BuildingRoom;
2use crate::model::building::{
3    BuildingConstructiveElement, BuildingInstallation, BuildingSubdivisionKind,
4};
5use crate::model::construction::{
6    AbstractConstruction, AsAbstractConstruction, AsAbstractConstructionMut,
7};
8use crate::model::core::{AsAbstractOccupiedSpaceMut, CityObjectRef};
9use egml::model::basic::Code;
10use nalgebra::Isometry3;
11
12#[derive(Debug, Clone, PartialEq)]
13pub struct AbstractBuilding {
14    pub abstract_construction: AbstractConstruction,
15    pub(crate) class: Option<Code>,
16    pub(crate) functions: Vec<Code>,
17    pub(crate) usages: Vec<Code>,
18    pub(crate) roof_type: Option<Code>,
19    pub(crate) storeys_above_ground: Option<i64>,
20    pub(crate) storeys_below_ground: Option<i64>,
21    pub building_constructive_elements: Vec<BuildingConstructiveElement>,
22    pub building_installations: Vec<BuildingInstallation>,
23    pub building_rooms: Vec<BuildingRoom>,
24    pub building_subdivisions: Vec<BuildingSubdivisionKind>,
25}
26
27impl AbstractBuilding {
28    pub fn new(abstract_construction: AbstractConstruction) -> Self {
29        Self {
30            abstract_construction,
31            class: None,
32            functions: Vec::new(),
33            usages: Vec::new(),
34            roof_type: None,
35            storeys_above_ground: None,
36            storeys_below_ground: None,
37            building_constructive_elements: Vec::new(),
38            building_installations: Vec::new(),
39            building_rooms: Vec::new(),
40            building_subdivisions: Vec::new(),
41        }
42    }
43
44    pub fn iter_city_object<'a>(&'a self) -> impl Iterator<Item = CityObjectRef<'a>> + 'a {
45        self.building_constructive_elements
46            .iter()
47            .flat_map(|x| x.iter_city_object())
48            .chain(
49                self.building_installations
50                    .iter()
51                    .flat_map(|x| x.iter_city_object()),
52            )
53            .chain(
54                self.building_rooms
55                    .iter()
56                    .flat_map(|x| x.iter_city_object()),
57            )
58    }
59}
60pub trait AsAbstractBuilding: AsAbstractConstruction {
61    fn abstract_building(&self) -> &AbstractBuilding;
62
63    fn class(&self) -> &Option<Code> {
64        &self.abstract_building().class
65    }
66
67    fn functions(&self) -> &Vec<Code> {
68        &self.abstract_building().functions
69    }
70
71    fn usages(&self) -> &Vec<Code> {
72        &self.abstract_building().usages
73    }
74
75    fn roof_type(&self) -> &Option<Code> {
76        &self.abstract_building().roof_type
77    }
78
79    fn storeys_above_ground(&self) -> Option<i64> {
80        self.abstract_building().storeys_above_ground
81    }
82
83    fn storeys_below_ground(&self) -> Option<i64> {
84        self.abstract_building().storeys_below_ground
85    }
86}
87
88pub trait AsAbstractBuildingMut: AsAbstractConstructionMut + AsAbstractBuilding {
89    fn abstract_building_mut(&mut self) -> &mut AbstractBuilding;
90
91    fn set_class(&mut self, class: Option<Code>) {
92        self.abstract_building_mut().class = class;
93    }
94
95    fn set_functions(&mut self, functions: Vec<Code>) {
96        self.abstract_building_mut().functions = functions;
97    }
98
99    fn set_usages(&mut self, usages: Vec<Code>) {
100        self.abstract_building_mut().usages = usages;
101    }
102
103    fn set_roof_type(&mut self, roof_type: Option<Code>) {
104        self.abstract_building_mut().roof_type = roof_type;
105    }
106
107    fn set_storeys_above_ground(&mut self, storeys_above_ground: Option<i64>) {
108        self.abstract_building_mut().storeys_above_ground = storeys_above_ground;
109    }
110
111    fn set_storeys_below_ground(&mut self, storeys_below_ground: Option<i64>) {
112        self.abstract_building_mut().storeys_below_ground = storeys_below_ground;
113    }
114
115    fn apply_transform(&mut self, m: &Isometry3<f64>) {
116        AsAbstractOccupiedSpaceMut::apply_transform(self, m);
117    }
118}
119
120impl AsAbstractBuilding for AbstractBuilding {
121    fn abstract_building(&self) -> &AbstractBuilding {
122        self
123    }
124}
125
126impl AsAbstractBuildingMut for AbstractBuilding {
127    fn abstract_building_mut(&mut self) -> &mut AbstractBuilding {
128        self
129    }
130}
131
132#[macro_export]
133macro_rules! impl_abstract_building_traits {
134    ($type:ty) => {
135        $crate::impl_abstract_construction_traits!($type);
136
137        impl $crate::model::construction::AsAbstractConstruction for $type {
138            fn abstract_construction(&self) -> &$crate::model::construction::AbstractConstruction {
139                use $crate::model::building::AsAbstractBuilding;
140                &self.abstract_building().abstract_construction
141            }
142        }
143
144        impl $crate::model::construction::AsAbstractConstructionMut for $type {
145            fn abstract_construction_mut(
146                &mut self,
147            ) -> &mut $crate::model::construction::AbstractConstruction {
148                use $crate::model::building::AsAbstractBuildingMut;
149                &mut self.abstract_building_mut().abstract_construction
150            }
151        }
152    };
153}
154
155impl_abstract_building_traits!(AbstractBuilding);