ecitygml_core/model/building/
building.rs1use 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}