ecitygml_core/model/core/
city_model.rs1use crate::model::building::Building;
2use crate::model::city_furniture::CityFurniture;
3use crate::model::core::{
4 AbstractFeature, AsAbstractFeature, AsAbstractFeatureMut, CityObjectKind, CityObjectRef,
5};
6use crate::model::transportation::Road;
7use crate::model::vegetation::SolitaryVegetationObject;
8use crate::operations::{Visitable, Visitor};
9use egml::model::base::Id;
10use egml::model::geometry::Envelope;
11use nalgebra::Isometry3;
12use rayon::prelude::*;
13
14#[derive(Debug, Clone, PartialEq)]
15pub struct CityModel {
16 pub(crate) abstract_feature: AbstractFeature,
17 pub city_objects: Vec<CityObjectKind>,
18}
19
20impl CityModel {
21 pub fn new(abstract_feature: AbstractFeature, city_objects: Vec<CityObjectKind>) -> Self {
22 Self {
23 abstract_feature,
24 city_objects,
25 }
26 }
27
28 pub fn from_city_models(city_models: Vec<Self>) -> Self {
29 let abstract_feature = AbstractFeature::new(Id::generate_uuid_v4());
30
31 let combined_city_objects: Vec<CityObjectKind> = city_models
32 .into_iter()
33 .flat_map(|x| x.city_objects)
34 .collect();
35
36 CityModel::new(abstract_feature, combined_city_objects)
37 }
38
39 pub fn is_empty(&self) -> bool {
40 self.city_objects.is_empty()
41 }
42
43 pub fn city_objects(&self) -> &Vec<CityObjectKind> {
44 &self.city_objects
45 }
46
47 pub fn city_objects_len(&self) -> usize {
48 self.city_objects.len()
49 }
50
51 pub fn iter_city_object<'a>(&'a self) -> impl Iterator<Item = CityObjectRef<'a>> + 'a {
52 self.city_objects.iter().flat_map(|x| x.iter_city_object())
53 }
54
55 pub fn refresh_bounded_by_recursive(&mut self) {
56 self.city_objects
57 .par_iter_mut()
58 .for_each(|x| x.refresh_bounded_by_recursive());
59
60 let envelopes: Vec<Envelope> = self
61 .city_objects
62 .iter()
63 .filter_map(|x| x.bounded_by())
64 .cloned()
65 .collect();
66
67 self.set_bounded_by(Envelope::from_envelopes(&envelopes));
68 }
69
70 pub fn apply_transform_recursive(&mut self, m: &Isometry3<f64>) {
71 self.city_objects
72 .par_iter_mut()
73 .for_each(|x| x.apply_transform_recursive(m));
74 }
75
76 pub fn filter_city_objects_by_envelope(&mut self, filter_envelope: &Envelope) {
77 self.city_objects.retain(|obj| {
78 obj.bounded_by()
79 .is_some_and(|env| filter_envelope.contains_envelope_partially(env))
80 });
81 }
82
83 pub fn roads(&self) -> Vec<&Road> {
84 self.city_objects
85 .iter()
86 .filter_map(|x| match x {
87 CityObjectKind::Road(x) => Some(x),
88 _ => None,
89 })
90 .collect()
91 }
92
93 pub fn buildings(&self) -> Vec<&Building> {
94 self.city_objects
95 .iter()
96 .filter_map(|x| match x {
97 CityObjectKind::Building(x) => Some(x),
98 _ => None,
99 })
100 .collect()
101 }
102
103 pub fn solitary_vegetation_objects(&self) -> Vec<&SolitaryVegetationObject> {
104 self.city_objects
105 .iter()
106 .filter_map(|x| match x {
107 CityObjectKind::SolitaryVegetationObject(x) => Some(x),
108 _ => None,
109 })
110 .collect()
111 }
112
113 pub fn city_furniture_objects(&self) -> Vec<&CityFurniture> {
114 self.city_objects
115 .iter()
116 .filter_map(|x| match x {
117 CityObjectKind::CityFurniture(x) => Some(x),
118 _ => None,
119 })
120 .collect()
121 }
122}
123
124impl AsAbstractFeature for CityModel {
125 fn abstract_feature(&self) -> &AbstractFeature {
126 &self.abstract_feature
127 }
128}
129
130impl AsAbstractFeatureMut for CityModel {
131 fn abstract_feature_mut(&mut self) -> &mut AbstractFeature {
132 &mut self.abstract_feature
133 }
134}
135
136impl Visitable for CityModel {
137 fn accept<V: Visitor>(&self, visitor: &mut V) {
138 visitor.visit_city_model(self);
139
140 for feature in &self.city_objects {
141 match feature {
142 CityObjectKind::Building(x) => {
143 x.accept(visitor);
144 }
145 CityObjectKind::BuildingConstructiveElement(x) => {
146 x.accept(visitor);
147 }
148 CityObjectKind::BuildingInstallation(x) => {
149 x.accept(visitor);
150 }
151 CityObjectKind::BuildingRoom(x) => {
152 x.accept(visitor);
153 }
154 CityObjectKind::CityFurniture(x) => {
155 x.accept(visitor);
156 }
157 CityObjectKind::ReliefFeature(x) => {
158 x.accept(visitor);
159 }
160 CityObjectKind::Road(x) => {
161 x.accept(visitor);
162 }
163 CityObjectKind::SolitaryVegetationObject(x) => {
164 x.accept(visitor);
165 }
166 CityObjectKind::Storey(x) => {
167 x.accept(visitor);
168 }
169 CityObjectKind::TinRelief(x) => {
170 x.accept(visitor);
171 }
172 CityObjectKind::TrafficSpace(x) => {
173 x.accept(visitor);
174 }
175 CityObjectKind::AuxiliaryTrafficSpace(x) => {
176 x.accept(visitor);
177 }
178 CityObjectKind::TrafficArea(x) => {
179 x.accept(visitor);
180 }
181 CityObjectKind::AuxiliaryTrafficArea(x) => {
182 x.accept(visitor);
183 }
184 CityObjectKind::Section(x) => {
185 x.accept(visitor);
186 }
187 CityObjectKind::Intersection(x) => {
188 x.accept(visitor);
189 }
190 CityObjectKind::DoorSurface(x) => {
191 x.accept(visitor);
192 }
193 CityObjectKind::GroundSurface(x) => {
194 x.accept(visitor);
195 }
196 CityObjectKind::RoofSurface(x) => {
197 x.accept(visitor);
198 }
199 CityObjectKind::WallSurface(x) => {
200 x.accept(visitor);
201 }
202 CityObjectKind::WindowSurface(x) => {
203 x.accept(visitor);
204 }
205 }
206 }
207 }
208}