ecitygml_core/operations/
geometry_collector.rs1use crate::model::building::Building;
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::{Gml, Id};
16use egml::model::geometry::{MultiSurface, Solid};
17use std::collections::HashMap;
18
19#[derive(Debug, Clone, PartialEq)]
20pub struct CityObjectGeometryCollection {
21 pub gml: Gml,
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 gml: space.city_object.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 gml: thematic_surface.city_object.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.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_roof_surface(&mut self, v: &RoofSurface) -> Self::Result {
144 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
145 CityObjectClass::RoofSurface,
146 &v.thematic_surface,
147 );
148 self.city_objects.insert(
149 city_object_geometry_collection.gml.id.clone(),
150 city_object_geometry_collection,
151 );
152 }
153
154 fn visit_ground_surface(&mut self, v: &GroundSurface) -> Self::Result {
155 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
156 CityObjectClass::WallSurface,
157 &v.thematic_surface,
158 );
159 self.city_objects.insert(
160 city_object_geometry_collection.gml.id.clone(),
161 city_object_geometry_collection,
162 );
163 }
164
165 fn visit_wall_surface(&mut self, v: &WallSurface) -> Self::Result {
166 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
167 CityObjectClass::WallSurface,
168 &v.thematic_surface,
169 );
170 self.city_objects.insert(
171 city_object_geometry_collection.gml.id.clone(),
172 city_object_geometry_collection,
173 );
174 }
175
176 fn visit_window_surface(&mut self, v: &WindowSurface) -> Self::Result {
177 let city_object_geometry_collection = CityObjectGeometryCollection::from_occupied_space(
178 CityObjectClass::WindowSurface,
179 &v.occupied_space,
180 );
181 self.city_objects.insert(
182 city_object_geometry_collection.gml.id.clone(),
183 city_object_geometry_collection,
184 );
185 }
186
187 fn visit_door_surface(&mut self, v: &DoorSurface) -> Self::Result {
188 let city_object_geometry_collection = CityObjectGeometryCollection::from_occupied_space(
189 CityObjectClass::DoorSurface,
190 &v.occupied_space,
191 );
192 self.city_objects.insert(
193 city_object_geometry_collection.gml.id.clone(),
194 city_object_geometry_collection,
195 );
196 }
197
198 fn visit_solitary_vegetation_object(&mut self, v: &SolitaryVegetationObject) -> Self::Result {
199 let city_object_geometry_collection = CityObjectGeometryCollection::from_occupied_space(
200 CityObjectClass::SolitaryVegetationObject,
201 &v.occupied_space,
202 );
203 self.city_objects.insert(
204 city_object_geometry_collection.gml.id.clone(),
205 city_object_geometry_collection,
206 );
207 }
208
209 fn visit_road(&mut self, v: &Road) -> Self::Result {}
210
211 fn visit_section(&mut self, v: &Section) -> Self::Result {}
212
213 fn visit_intersection(&mut self, v: &Intersection) -> Self::Result {}
214
215 fn visit_traffic_space(&mut self, v: &TrafficSpace) -> Self::Result {
216 let city_object_geometry_collection =
217 CityObjectGeometryCollection::from_space(CityObjectClass::TrafficSpace, &v.space);
218 self.city_objects.insert(
219 city_object_geometry_collection.gml.id.clone(),
220 city_object_geometry_collection,
221 );
222 }
223
224 fn visit_auxiliary_traffic_space(&mut self, v: &AuxiliaryTrafficSpace) -> Self::Result {
225 let city_object_geometry_collection = CityObjectGeometryCollection::from_space(
226 CityObjectClass::AuxiliaryTrafficSpace,
227 &v.space,
228 );
229 self.city_objects.insert(
230 city_object_geometry_collection.gml.id.clone(),
231 city_object_geometry_collection,
232 );
233 }
234
235 fn visit_traffic_area(&mut self, v: &TrafficArea) -> Self::Result {
236 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
237 CityObjectClass::TrafficArea,
238 &v.thematic_surface,
239 );
240 self.city_objects.insert(
241 city_object_geometry_collection.gml.id.clone(),
242 city_object_geometry_collection,
243 );
244 }
245
246 fn visit_auxiliary_traffic_area(&mut self, v: &AuxiliaryTrafficArea) -> Self::Result {
247 let city_object_geometry_collection = CityObjectGeometryCollection::from_thematic_surface(
248 CityObjectClass::AuxiliaryTrafficArea,
249 &v.thematic_surface,
250 );
251 self.city_objects.insert(
252 city_object_geometry_collection.gml.id.clone(),
253 city_object_geometry_collection,
254 );
255 }
256}