Skip to main content

ecitygml_core/model/building/
building.rs

1use crate::model::building::building_part_property::BuildingPartProperty;
2use crate::model::building::{AbstractBuilding, AsAbstractBuilding, AsAbstractBuildingMut};
3use crate::model::common::{ForEachFeatureMut, IterFeatures};
4use crate::model::core::refs::AbstractFeatureKindRef;
5use crate::model::core::refs::AbstractFeatureKindRefMut;
6use egml::model::base::Id;
7use egml::model::common::{ApplyTransform, ComputeEnvelope};
8use egml::model::geometry::Envelope;
9use nalgebra::{Isometry3, Rotation3, Scale3, Transform3, Vector3};
10
11#[derive(Debug, Clone, PartialEq)]
12pub struct Building {
13    pub(crate) abstract_building: AbstractBuilding,
14    building_parts: Vec<BuildingPartProperty>,
15}
16
17impl Building {
18    pub fn new(id: Id) -> Self {
19        Self::from_abstract_building(AbstractBuilding::new(id))
20    }
21
22    pub fn from_abstract_building(abstract_building: AbstractBuilding) -> Self {
23        Self {
24            abstract_building,
25            building_parts: Vec::new(),
26        }
27    }
28
29    pub fn building_parts(&self) -> &[BuildingPartProperty] {
30        &self.building_parts
31    }
32
33    pub fn building_parts_mut(&mut self) -> &mut [BuildingPartProperty] {
34        &mut self.building_parts
35    }
36
37    pub fn set_building_parts(&mut self, building_parts: Vec<BuildingPartProperty>) {
38        self.building_parts = building_parts;
39    }
40
41    pub fn push_building_part(&mut self, building_part: BuildingPartProperty) {
42        self.building_parts.push(building_part);
43    }
44
45    pub fn extend_building_parts(
46        &mut self,
47        building_parts: impl IntoIterator<Item = BuildingPartProperty>,
48    ) {
49        self.building_parts.extend(building_parts);
50    }
51}
52
53impl AsAbstractBuilding for Building {
54    fn abstract_building(&self) -> &AbstractBuilding {
55        &self.abstract_building
56    }
57}
58
59impl AsAbstractBuildingMut for Building {
60    fn abstract_building_mut(&mut self) -> &mut AbstractBuilding {
61        &mut self.abstract_building
62    }
63}
64
65crate::impl_abstract_building_traits!(Building);
66crate::impl_abstract_building_mut_traits!(Building);
67crate::impl_has_feature_type!(Building, Building);
68
69impl IterFeatures for Building {
70    fn iter_features(&self) -> Box<dyn Iterator<Item = AbstractFeatureKindRef<'_>> + '_> {
71        Box::new(
72            std::iter::once(self.into())
73                .chain(self.abstract_building.iter_features())
74                .chain(
75                    self.building_parts
76                        .iter()
77                        .filter_map(|x| x.object())
78                        .flat_map(|x| x.iter_features()),
79                ),
80        )
81    }
82}
83
84impl ForEachFeatureMut for Building {
85    fn for_each_feature_mut<F: FnMut(AbstractFeatureKindRefMut<'_>)>(&mut self, f: &mut F) {
86        f((&mut *self).into());
87        self.abstract_building.for_each_feature_mut(f);
88
89        for prop in &mut self.building_parts {
90            if let Some(x) = prop.object_mut() {
91                x.for_each_feature_mut(f);
92            }
93        }
94    }
95}
96
97impl ComputeEnvelope for Building {
98    fn compute_envelope(&self) -> Option<Envelope> {
99        self.abstract_building.compute_envelope()
100    }
101}
102
103impl ApplyTransform for Building {
104    fn apply_transform(&mut self, m: Transform3<f64>) {
105        self.abstract_building.apply_transform(m);
106
107        for prop in &mut self.building_parts {
108            if let Some(x) = prop.object_mut() {
109                x.apply_transform(m);
110            }
111        }
112    }
113
114    fn apply_isometry(&mut self, isometry: Isometry3<f64>) {
115        self.abstract_building.apply_isometry(isometry);
116
117        for prop in &mut self.building_parts {
118            if let Some(x) = prop.object_mut() {
119                x.apply_isometry(isometry);
120            }
121        }
122    }
123
124    fn apply_translation(&mut self, vector: Vector3<f64>) {
125        self.abstract_building.apply_translation(vector);
126
127        for prop in &mut self.building_parts {
128            if let Some(x) = prop.object_mut() {
129                x.apply_translation(vector);
130            }
131        }
132    }
133
134    fn apply_rotation(&mut self, rotation: Rotation3<f64>) {
135        self.abstract_building.apply_rotation(rotation);
136
137        for prop in &mut self.building_parts {
138            if let Some(x) = prop.object_mut() {
139                x.apply_rotation(rotation);
140            }
141        }
142    }
143
144    fn apply_scale(&mut self, scale: Scale3<f64>) {
145        self.abstract_building.apply_scale(scale);
146
147        for prop in &mut self.building_parts {
148            if let Some(x) = prop.object_mut() {
149                x.apply_scale(scale);
150            }
151        }
152    }
153}