ecitygml_core/operations/
geometry_collector.rs

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