ecitygml_core/operations/
geometry_collector.rs1use crate::model::building::{Building, BuildingConstructiveElement};
2use crate::model::city_furniture::CityFurniture;
3use crate::model::city_model::CitygmlModel;
4use crate::model::common::{CityObjectClass, LevelOfDetail};
5use crate::model::construction::{
6 DoorSurface, GroundSurface, RoofSurface, WallSurface, WindowSurface,
7};
8use crate::model::core::{ImplicitGeometry, OccupiedSpace, Space, ThematicSurface};
9use crate::model::solitary_vegetation_object::SolitaryVegetationObject;
10use crate::model::transportation::{
11 AuxiliaryTrafficArea, AuxiliaryTrafficSpace, Intersection, Road, Section, TrafficArea,
12 TrafficSpace,
13};
14use crate::operations::CityObjectVisitor;
15use egml::model::base::{AbstractGml, Id};
16use egml::model::geometry::{MultiSurface, Solid};
17use std::collections::HashMap;
18
19#[derive(Debug, Clone, PartialEq)]
20pub struct CityObjectGeometryCollection {
21 pub abstract_gml: AbstractGml,
22 pub class: CityObjectClass,
23 pub implicit_geometries: HashMap<LevelOfDetail, ImplicitGeometry>,
24 pub multi_surfaces: HashMap<LevelOfDetail, MultiSurface>,
25 pub solids: HashMap<LevelOfDetail, Solid>,
26}
27
28impl CityObjectGeometryCollection {
29 pub fn from_space(class: CityObjectClass, space: &Space) -> Self {
30 let mut solids: HashMap<LevelOfDetail, Solid> = HashMap::new();
31 if let Some(g) = &space.lod1_solid {
32 solids.insert(LevelOfDetail::One, g.clone());
33 }
34 if let Some(g) = &space.lod2_solid {
35 solids.insert(LevelOfDetail::Two, g.clone());
36 }
37 if let Some(g) = &space.lod3_solid {
38 solids.insert(LevelOfDetail::Three, g.clone());
39 }
40
41 let mut multi_surfaces: HashMap<LevelOfDetail, MultiSurface> = HashMap::new();
42 if let Some(g) = &space.lod0_multi_surface {
43 multi_surfaces.insert(LevelOfDetail::Zero, g.clone());
44 }
45 if let Some(g) = &space.lod2_multi_surface {
46 multi_surfaces.insert(LevelOfDetail::Two, g.clone());
47 }
48 if let Some(g) = &space.lod3_multi_surface {
49 multi_surfaces.insert(LevelOfDetail::Three, g.clone());
50 }
51
52 Self {
53 abstract_gml: space.city_object.abstract_gml.clone(),
54 class,
55 implicit_geometries: HashMap::new(),
56 multi_surfaces,
57 solids,
58 }
59 }
60 pub fn from_occupied_space(class: CityObjectClass, occupied_space: &OccupiedSpace) -> Self {
61 let mut city_object_geometry_collection =
62 CityObjectGeometryCollection::from_space(class, &occupied_space.space);
63
64 if let Some(g) = &occupied_space.lod1_implicit_representation {
65 city_object_geometry_collection
66 .implicit_geometries
67 .insert(LevelOfDetail::One, g.clone());
68 }
69 if let Some(g) = &occupied_space.lod2_implicit_representation {
70 city_object_geometry_collection
71 .implicit_geometries
72 .insert(LevelOfDetail::Two, g.clone());
73 }
74 if let Some(g) = &occupied_space.lod3_implicit_representation {
75 city_object_geometry_collection
76 .implicit_geometries
77 .insert(LevelOfDetail::Three, g.clone());
78 }
79
80 city_object_geometry_collection
81 }
82
83 pub fn from_thematic_surface(
84 class: CityObjectClass,
85 thematic_surface: &ThematicSurface,
86 ) -> Self {
87 let mut multi_surfaces: HashMap<LevelOfDetail, MultiSurface> = HashMap::new();
88
89 if let Some(g) = &thematic_surface.lod0_multi_surface {
90 multi_surfaces.insert(LevelOfDetail::Zero, g.clone());
91 }
92 if let Some(g) = &thematic_surface.lod1_multi_surface {
93 multi_surfaces.insert(LevelOfDetail::One, g.clone());
94 }
95 if let Some(g) = &thematic_surface.lod2_multi_surface {
96 multi_surfaces.insert(LevelOfDetail::Two, g.clone());
97 }
98 if let Some(g) = &thematic_surface.lod3_multi_surface {
99 multi_surfaces.insert(LevelOfDetail::Three, g.clone());
100 }
101
102 Self {
103 abstract_gml: thematic_surface.city_object.abstract_gml.clone(),
104 class,
105 implicit_geometries: HashMap::new(),
106 multi_surfaces,
107 solids: HashMap::new(),
108 }
109 }
110}
111
112#[derive(Debug, Clone, PartialEq, Default)]
113pub struct GeometryCollector {
114 pub city_objects: HashMap<Id, CityObjectGeometryCollection>,
115}
116
117impl GeometryCollector {
118 pub fn new() -> Self {
119 Self {
120 city_objects: HashMap::new(),
121 }
122 }
123}
124
125impl CityObjectVisitor for GeometryCollector {
126 type Result = ();
127
128 fn visit_city_model(&mut self, v: &CitygmlModel) -> Self::Result {}
129
130 fn visit_city_furniture(&mut self, v: &CityFurniture) -> Self::Result {
131 let city_object_geometry_collection = CityObjectGeometryCollection::from_occupied_space(
132 CityObjectClass::CityFurniture,
133 &v.occupied_space,
134 );
135 self.city_objects.insert(
136 city_object_geometry_collection.abstract_gml.id.clone(),
137 city_object_geometry_collection,
138 );
139 }
140
141 fn visit_building(&mut self, v: &Building) -> Self::Result {}
142
143 fn visit_building_constructive_element(
144 &mut self,
145 v: &BuildingConstructiveElement,
146 ) -> Self::Result {
147 let city_object_geometry_collection = CityObjectGeometryCollection::from_occupied_space(
148 CityObjectClass::BuildingConstructiveElement,
149 &v.occupied_space,
150 );
151 self.city_objects.insert(
152 city_object_geometry_collection.abstract_gml.id.clone(),
153 city_object_geometry_collection,
154 );
155 }
156
157 fn visit_roof_surface(&mut self, v: &RoofSurface) -> Self::Result {
158 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
159 CityObjectClass::RoofSurface,
160 &v.thematic_surface,
161 );
162 self.city_objects.insert(
163 city_object_geometry_collection.abstract_gml.id.clone(),
164 city_object_geometry_collection,
165 );
166 }
167
168 fn visit_ground_surface(&mut self, v: &GroundSurface) -> Self::Result {
169 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
170 CityObjectClass::GroundSurface,
171 &v.thematic_surface,
172 );
173 self.city_objects.insert(
174 city_object_geometry_collection.abstract_gml.id.clone(),
175 city_object_geometry_collection,
176 );
177 }
178
179 fn visit_wall_surface(&mut self, v: &WallSurface) -> Self::Result {
180 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
181 CityObjectClass::WallSurface,
182 &v.thematic_surface,
183 );
184 self.city_objects.insert(
185 city_object_geometry_collection.abstract_gml.id.clone(),
186 city_object_geometry_collection,
187 );
188 }
189
190 fn visit_window_surface(&mut self, v: &WindowSurface) -> Self::Result {
191 let city_object_geometry_collection = CityObjectGeometryCollection::from_occupied_space(
192 CityObjectClass::WindowSurface,
193 &v.occupied_space,
194 );
195 self.city_objects.insert(
196 city_object_geometry_collection.abstract_gml.id.clone(),
197 city_object_geometry_collection,
198 );
199 }
200
201 fn visit_door_surface(&mut self, v: &DoorSurface) -> Self::Result {
202 let city_object_geometry_collection = CityObjectGeometryCollection::from_occupied_space(
203 CityObjectClass::DoorSurface,
204 &v.occupied_space,
205 );
206 self.city_objects.insert(
207 city_object_geometry_collection.abstract_gml.id.clone(),
208 city_object_geometry_collection,
209 );
210 }
211
212 fn visit_solitary_vegetation_object(&mut self, v: &SolitaryVegetationObject) -> Self::Result {
213 let city_object_geometry_collection = CityObjectGeometryCollection::from_occupied_space(
214 CityObjectClass::SolitaryVegetationObject,
215 &v.occupied_space,
216 );
217 self.city_objects.insert(
218 city_object_geometry_collection.abstract_gml.id.clone(),
219 city_object_geometry_collection,
220 );
221 }
222
223 fn visit_road(&mut self, v: &Road) -> Self::Result {}
224
225 fn visit_section(&mut self, v: &Section) -> Self::Result {}
226
227 fn visit_intersection(&mut self, v: &Intersection) -> Self::Result {}
228
229 fn visit_traffic_space(&mut self, v: &TrafficSpace) -> Self::Result {
230 let city_object_geometry_collection =
231 CityObjectGeometryCollection::from_space(CityObjectClass::TrafficSpace, &v.space);
232 self.city_objects.insert(
233 city_object_geometry_collection.abstract_gml.id.clone(),
234 city_object_geometry_collection,
235 );
236 }
237
238 fn visit_auxiliary_traffic_space(&mut self, v: &AuxiliaryTrafficSpace) -> Self::Result {
239 let city_object_geometry_collection = CityObjectGeometryCollection::from_space(
240 CityObjectClass::AuxiliaryTrafficSpace,
241 &v.space,
242 );
243 self.city_objects.insert(
244 city_object_geometry_collection.abstract_gml.id.clone(),
245 city_object_geometry_collection,
246 );
247 }
248
249 fn visit_traffic_area(&mut self, v: &TrafficArea) -> Self::Result {
250 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
251 CityObjectClass::TrafficArea,
252 &v.thematic_surface,
253 );
254 self.city_objects.insert(
255 city_object_geometry_collection.abstract_gml.id.clone(),
256 city_object_geometry_collection,
257 );
258 }
259
260 fn visit_auxiliary_traffic_area(&mut self, v: &AuxiliaryTrafficArea) -> Self::Result {
261 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
262 CityObjectClass::AuxiliaryTrafficArea,
263 &v.thematic_surface,
264 );
265 self.city_objects.insert(
266 city_object_geometry_collection.abstract_gml.id.clone(),
267 city_object_geometry_collection,
268 );
269 }
270}