ecitygml_core/operations/
geometry_collector.rs

1use 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}