Skip to main content

ecitygml_core/model/building/
building.rs

1use crate::model::building::{AbstractBuilding, AsAbstractBuilding, AsAbstractBuildingMut};
2use crate::model::construction::{GroundSurface, RoofSurface, WallSurface};
3use crate::model::core::{
4    AsAbstractFeature, AsAbstractFeatureMut, AsAbstractOccupiedSpace, AsAbstractOccupiedSpaceMut,
5    AsAbstractSpaceMut, AsAbstractThematicSurfaceMut, CityObjectKind, CityObjectRef,
6};
7use crate::operations::{Visitable, Visitor};
8use egml::model::geometry::Envelope;
9use nalgebra::Isometry3;
10
11#[derive(Debug, Clone, PartialEq)]
12pub struct Building {
13    pub abstract_building: AbstractBuilding,
14    pub wall_surface: Vec<WallSurface>,
15    pub roof_surface: Vec<RoofSurface>,
16    pub ground_surface: Vec<GroundSurface>,
17}
18
19impl Building {
20    pub fn new(abstract_building: AbstractBuilding) -> Self {
21        Self {
22            abstract_building,
23            wall_surface: Vec::new(),
24            roof_surface: Vec::new(),
25            ground_surface: Vec::new(),
26        }
27    }
28
29    pub fn iter_city_object<'a>(&'a self) -> impl Iterator<Item = CityObjectRef<'a>> + 'a {
30        std::iter::once(CityObjectRef::Building(self))
31            .chain(self.abstract_building.iter_city_object())
32            .chain(self.wall_surface.iter().flat_map(|x| x.iter_city_object()))
33            .chain(self.roof_surface.iter().flat_map(|x| x.iter_city_object()))
34            .chain(
35                self.ground_surface
36                    .iter()
37                    .flat_map(|x| x.iter_city_object()),
38            )
39    }
40
41    pub fn refresh_bounded_by_recursive(&mut self) {
42        self.wall_surface
43            .iter_mut()
44            .for_each(|x| x.refresh_bounded_by_recursive());
45        self.roof_surface
46            .iter_mut()
47            .for_each(|x| x.refresh_bounded_by());
48        self.ground_surface
49            .iter_mut()
50            .for_each(|x| x.refresh_bounded_by());
51
52        let own_envelope = self.compute_envelope();
53        let envelopes: Vec<Envelope> = own_envelope
54            .as_ref()
55            .into_iter()
56            .chain(self.wall_surface.iter().filter_map(|x| x.bounded_by()))
57            .chain(self.roof_surface.iter().filter_map(|x| x.bounded_by()))
58            .chain(self.ground_surface.iter().filter_map(|x| x.bounded_by()))
59            .cloned()
60            .collect();
61
62        self.set_bounded_by(Envelope::from_envelopes(&envelopes));
63    }
64
65    pub fn apply_transform_recursive(&mut self, m: &Isometry3<f64>) {
66        AsAbstractBuildingMut::apply_transform(&mut self.abstract_building, m);
67
68        self.wall_surface
69            .iter_mut()
70            .for_each(|x| x.apply_transform(m));
71        self.roof_surface
72            .iter_mut()
73            .for_each(|x| x.apply_transform(m));
74        self.ground_surface
75            .iter_mut()
76            .for_each(|x| x.apply_transform(m));
77    }
78}
79
80impl AsAbstractBuilding for Building {
81    fn abstract_building(&self) -> &AbstractBuilding {
82        &self.abstract_building
83    }
84}
85
86impl AsAbstractBuildingMut for Building {
87    fn abstract_building_mut(&mut self) -> &mut AbstractBuilding {
88        &mut self.abstract_building
89    }
90}
91
92crate::impl_abstract_building_traits!(Building);
93
94impl From<Building> for CityObjectKind {
95    fn from(item: Building) -> Self {
96        CityObjectKind::Building(item)
97    }
98}
99
100impl Visitable for Building {
101    fn accept<V: Visitor>(&self, visitor: &mut V) {
102        visitor.visit_building(self);
103        self.wall_surface.iter().for_each(|x| x.accept(visitor));
104        self.roof_surface.iter().for_each(|x| x.accept(visitor));
105        self.ground_surface.iter().for_each(|x| x.accept(visitor));
106    }
107}