ecitygml_core/model/
city_model.rs

1use crate::model::building::Building;
2use crate::model::city_furniture::CityFurniture;
3use crate::model::solitary_vegetation_object::SolitaryVegetationObject;
4use crate::model::transportation::Road;
5use crate::operations::{CityObjectVisitor, FeatureWithGeometry, Visitable};
6use egml::model::geometry::Envelope;
7use nalgebra::Isometry3;
8use rayon::prelude::*;
9
10#[derive(Debug, Clone, PartialEq, Default)]
11pub struct CitygmlModel {
12    pub building: Vec<Building>,
13    pub city_furniture: Vec<CityFurniture>,
14    pub road: Vec<Road>,
15    pub solitary_vegetation_object: Vec<SolitaryVegetationObject>,
16}
17
18impl CitygmlModel {
19    pub fn new(
20        building: Vec<Building>,
21        city_furniture: Vec<CityFurniture>,
22        road: Vec<Road>,
23        solitary_vegetation_object: Vec<SolitaryVegetationObject>,
24    ) -> Self {
25        Self {
26            building,
27            city_furniture,
28            road,
29            solitary_vegetation_object,
30        }
31    }
32
33    pub fn from_citygml_models(citygml_models: &Vec<Self>) -> Self {
34        let building: Vec<Building> = citygml_models
35            .iter()
36            .flat_map(|x| x.building.iter().cloned())
37            .collect();
38        let city_furniture: Vec<CityFurniture> = citygml_models
39            .iter()
40            .flat_map(|x| x.city_furniture.iter().cloned())
41            .collect();
42        let road: Vec<Road> = citygml_models
43            .iter()
44            .flat_map(|x| x.road.iter().cloned())
45            .collect();
46        let solitary_vegetation_object: Vec<SolitaryVegetationObject> = citygml_models
47            .iter()
48            .flat_map(|x| x.solitary_vegetation_object.iter().cloned())
49            .collect();
50
51        CitygmlModel::new(building, city_furniture, road, solitary_vegetation_object)
52    }
53
54    pub fn is_empty(&self) -> bool {
55        self.building.is_empty()
56            && self.city_furniture.is_empty()
57            && self.road.is_empty()
58            && self.solitary_vegetation_object.is_empty()
59    }
60
61    pub fn number_of_objects(&self) -> usize {
62        self.building.len()
63            + self.city_furniture.len()
64            + self.road.len()
65            + self.solitary_vegetation_object.len()
66    }
67}
68
69impl Visitable for CitygmlModel {
70    fn accept<V: CityObjectVisitor>(&self, visitor: &mut V) {
71        visitor.visit_city_model(self);
72        self.building.iter().for_each(|x| x.accept(visitor));
73        self.city_furniture.iter().for_each(|x| x.accept(visitor));
74        self.road.iter().for_each(|x| x.accept(visitor));
75        self.solitary_vegetation_object
76            .iter()
77            .for_each(|x| x.accept(visitor));
78    }
79}
80
81impl FeatureWithGeometry for CitygmlModel {
82    fn envelope(&self) -> Option<Envelope> {
83        let mut envelopes: Vec<Option<Envelope>> = vec![];
84        envelopes.extend(self.building.iter().map(|x| x.envelope()));
85        envelopes.extend(self.city_furniture.iter().map(|x| x.envelope()));
86        envelopes.extend(self.road.iter().map(|x| x.envelope()));
87        envelopes.extend(self.solitary_vegetation_object.iter().map(|x| x.envelope()));
88
89        Envelope::from_optional_envelopes(&envelopes).expect("should work")
90    }
91
92    fn apply_transform(&mut self, m: &Isometry3<f64>) {
93        self.building.iter_mut().for_each(|x| x.apply_transform(m));
94        self.city_furniture
95            .iter_mut()
96            .for_each(|x| x.apply_transform(m));
97        self.road.iter_mut().for_each(|x| x.apply_transform(m));
98        self.solitary_vegetation_object
99            .iter_mut()
100            .for_each(|x| x.apply_transform(m));
101    }
102}