ecitygml_core/operations/
geometry_index.rs1use crate::model::common::{CityObjectClass, LevelOfDetail};
2use crate::model::core::{
3 AbstractCityObject, AbstractOccupiedSpace, AbstractSpace, AbstractThematicSurface,
4 AsAbstractCityObject, AsAbstractFeature, AsAbstractOccupiedSpace, AsAbstractSpace,
5 CityObjectRef, ImplicitGeometry,
6};
7use crate::model::core::{AsAbstractThematicSurface, CityModel};
8use egml::model::base::Id;
9use egml::model::geometry::Envelope;
10use egml::model::geometry::aggregates::{MultiCurve, MultiSurface};
11use egml::model::geometry::primitives::Solid;
12use std::collections::HashMap;
13
14#[derive(Debug, Clone, PartialEq, Default)]
15pub struct CityModelGeometryIndex {
16 pub objects: HashMap<Id, CityObjectGeometry>,
17}
18
19impl CityModelGeometryIndex {
20 pub fn from_city_model(mut city_model: CityModel) -> Self {
21 city_model.refresh_bounded_by_recursive();
22
23 let city_objects: HashMap<Id, CityObjectGeometry> = city_model
24 .iter_city_object()
25 .map(|x| (x.id().clone(), CityObjectGeometry::from_city_object(x)))
26 .collect();
27
28 Self {
29 objects: city_objects,
30 }
31 }
32
33 pub fn objects_len(&self) -> usize {
34 self.objects.len()
35 }
36
37 pub fn object_ids(&self) -> Vec<String> {
38 self.objects.keys().map(|x| x.to_string()).collect()
39 }
40
41 pub fn get(&self, id: &Id) -> Option<&CityObjectGeometry> {
42 self.objects.get(id)
43 }
44}
45
46#[derive(Debug, Clone, PartialEq)]
47pub struct CityObjectGeometry {
48 pub base: AbstractCityObject,
49 pub class: CityObjectClass,
50 pub implicit_geometries: HashMap<LevelOfDetail, ImplicitGeometry>,
51 pub multi_surfaces: HashMap<LevelOfDetail, MultiSurface>,
52 pub multi_curves: HashMap<LevelOfDetail, MultiCurve>,
53 pub solids: HashMap<LevelOfDetail, Solid>,
54}
55
56impl CityObjectGeometry {
57 pub fn new(abstract_space: AbstractCityObject, class: CityObjectClass) -> Self {
58 Self {
59 base: abstract_space,
60 class,
61 implicit_geometries: HashMap::new(),
62 multi_surfaces: HashMap::new(),
63 multi_curves: HashMap::new(),
64 solids: HashMap::new(),
65 }
66 }
67
68 pub fn from_city_object(city_object: CityObjectRef) -> Self {
69 let city_object_class = city_object.city_object_class();
70
71 match city_object {
72 CityObjectRef::AuxiliaryTrafficArea(x) => Self::from_abstract_thematic_surface(
73 city_object_class,
74 x.abstract_thematic_surface(),
75 ),
76 CityObjectRef::AuxiliaryTrafficSpace(x) => {
77 Self::from_abstract_space(city_object_class, x.abstract_space())
78 }
79 CityObjectRef::Building(x) => {
80 Self::from_abstract_space(city_object_class, x.abstract_space())
81 }
82 CityObjectRef::BuildingConstructiveElement(x) => {
83 Self::from_abstract_occupied_space(city_object_class, x.abstract_occupied_space())
84 }
85 CityObjectRef::BuildingInstallation(x) => {
86 Self::from_abstract_occupied_space(city_object_class, x.abstract_occupied_space())
87 }
88 CityObjectRef::BuildingRoom(x) => {
89 Self::from_abstract_space(city_object_class, x.abstract_space())
90 }
91 CityObjectRef::CityFurniture(x) => {
92 Self::from_abstract_occupied_space(city_object_class, x.abstract_occupied_space())
93 }
94 CityObjectRef::DoorSurface(x) => Self::from_abstract_thematic_surface(
95 city_object_class,
96 x.abstract_thematic_surface(),
97 ),
98 CityObjectRef::GroundSurface(x) => Self::from_abstract_thematic_surface(
99 city_object_class,
100 x.abstract_thematic_surface(),
101 ),
102 CityObjectRef::Intersection(x) => {
103 Self::from_abstract_space(city_object_class, x.abstract_space())
104 }
105 CityObjectRef::ReliefFeature(x) => {
106 CityObjectGeometry::new(x.abstract_city_object().clone(), city_object_class)
107 }
108 CityObjectRef::Road(x) => {
109 Self::from_abstract_space(city_object_class, x.abstract_space())
110 }
111 CityObjectRef::RoofSurface(x) => Self::from_abstract_thematic_surface(
112 city_object_class,
113 x.abstract_thematic_surface(),
114 ),
115 CityObjectRef::Section(x) => {
116 Self::from_abstract_space(city_object_class, x.abstract_space())
117 }
118 CityObjectRef::SolitaryVegetationObject(x) => {
119 Self::from_abstract_occupied_space(city_object_class, x.abstract_occupied_space())
120 }
121 CityObjectRef::Storey(x) => {
122 Self::from_abstract_space(city_object_class, x.abstract_space())
123 }
124 CityObjectRef::TinRelief(x) => {
125 CityObjectGeometry::new(x.abstract_city_object().clone(), city_object_class)
126 }
127 CityObjectRef::TrafficArea(x) => Self::from_abstract_thematic_surface(
128 city_object_class,
129 x.abstract_thematic_surface(),
130 ),
131 CityObjectRef::TrafficSpace(x) => {
132 Self::from_abstract_space(city_object_class, x.abstract_space())
133 }
134 CityObjectRef::WallSurface(x) => Self::from_abstract_thematic_surface(
135 city_object_class,
136 x.abstract_thematic_surface(),
137 ),
138 CityObjectRef::WindowSurface(x) => Self::from_abstract_thematic_surface(
139 city_object_class,
140 x.abstract_thematic_surface(),
141 ),
142 }
143 }
144
145 pub fn from_abstract_space(class: CityObjectClass, space: &AbstractSpace) -> Self {
146 let solids: HashMap<LevelOfDetail, Solid> = space
147 .solids_by_lod()
148 .into_iter()
149 .map(|(lod, x)| (lod, x.clone()))
150 .collect();
151
152 let multi_surfaces: HashMap<LevelOfDetail, MultiSurface> = space
153 .multi_surfaces_by_lod()
154 .into_iter()
155 .map(|(lod, x)| (lod, x.clone()))
156 .collect();
157
158 let multi_curves: HashMap<LevelOfDetail, MultiCurve> = space
159 .multi_curves_by_lod()
160 .into_iter()
161 .map(|(lod, x)| (lod, x.clone()))
162 .collect();
163
164 Self {
165 base: space.abstract_city_object().clone(),
166 class,
167 implicit_geometries: HashMap::new(),
168 multi_surfaces,
169 multi_curves,
170 solids,
171 }
172 }
173
174 pub fn from_abstract_occupied_space(
175 class: CityObjectClass,
176 occupied_space: &AbstractOccupiedSpace,
177 ) -> Self {
178 let mut city_object_geometry = CityObjectGeometry::from_abstract_space(
179 class,
180 &occupied_space.abstract_physical_space.abstract_space,
181 );
182
183 let implicit_representations: HashMap<LevelOfDetail, ImplicitGeometry> = occupied_space
184 .implicit_representations_by_lod()
185 .into_iter()
186 .map(|(lod, x)| (lod, x.clone()))
187 .collect();
188
189 city_object_geometry.implicit_geometries = implicit_representations;
190 city_object_geometry
191 }
192
193 pub fn from_abstract_thematic_surface(
194 class: CityObjectClass,
195 thematic_surface: &AbstractThematicSurface,
196 ) -> Self {
197 let multi_surfaces: HashMap<LevelOfDetail, MultiSurface> = thematic_surface
198 .multi_surfaces_by_lod()
199 .into_iter()
200 .map(|(lod, x)| (lod, x.clone()))
201 .collect();
202
203 Self {
204 base: thematic_surface.abstract_city_object().clone(),
205 class,
206 implicit_geometries: HashMap::new(),
207 multi_surfaces,
208 solids: HashMap::new(),
209 multi_curves: HashMap::new(),
210 }
211 }
212
213 pub fn id(&self) -> &Id {
214 self.base.id()
215 }
216
217 pub fn envelope(&self) -> Option<&Envelope> {
218 self.base.bounded_by()
219 }
220}