ecitygml_core/model/
core.rs

1use crate::operations::FeatureWithGeometry;
2use egml::model::base::Gml;
3use egml::model::geometry;
4use egml::model::geometry::{DirectPosition, Envelope};
5use egml::operations::geometry::Geometry;
6use nalgebra::Isometry3;
7
8#[derive(Debug, Clone, PartialEq)]
9pub struct CityObject {
10    pub gml: Gml,
11    // TODO: generic_attributes: Vec<String>,
12}
13
14impl CityObject {
15    pub fn new(gml: Gml) -> Self {
16        Self { gml }
17    }
18}
19
20#[derive(Debug, Clone, PartialEq, Default)]
21pub struct ImplicitGeometry {
22    pub reference_point: geometry::DirectPosition,
23}
24
25impl ImplicitGeometry {
26    pub fn new(reference_point: geometry::DirectPosition) -> Self {
27        Self { reference_point }
28    }
29}
30
31impl Geometry for ImplicitGeometry {
32    fn points(&self) -> Vec<&DirectPosition> {
33        vec![&self.reference_point]
34    }
35
36    fn apply_transform(&mut self, m: &Isometry3<f64>) {
37        self.reference_point.apply_transform(m);
38    }
39}
40
41#[derive(Debug, Clone, PartialEq)]
42pub struct Space {
43    pub city_object: CityObject,
44
45    pub lod1_solid: Option<geometry::Solid>,
46    pub lod2_solid: Option<geometry::Solid>,
47    pub lod3_solid: Option<geometry::Solid>,
48
49    pub lod0_multi_surface: Option<geometry::MultiSurface>,
50    pub lod2_multi_surface: Option<geometry::MultiSurface>,
51    pub lod3_multi_surface: Option<geometry::MultiSurface>,
52}
53
54impl Space {
55    pub fn new(city_object: CityObject) -> Self {
56        Self {
57            city_object,
58            lod1_solid: None,
59            lod2_solid: None,
60            lod3_solid: None,
61            lod0_multi_surface: None,
62            lod2_multi_surface: None,
63            lod3_multi_surface: None,
64        }
65    }
66}
67
68impl FeatureWithGeometry for Space {
69    fn envelope(&self) -> Option<Envelope> {
70        let envelopes: Vec<Option<Envelope>> = vec![
71            self.lod1_solid.as_ref().map(|x| x.envelope()),
72            self.lod2_solid.as_ref().map(|x| x.envelope()),
73            self.lod3_solid.as_ref().map(|x| x.envelope()),
74            self.lod0_multi_surface.as_ref().map(|x| x.envelope()),
75            self.lod2_multi_surface.as_ref().map(|x| x.envelope()),
76            self.lod3_multi_surface.as_ref().map(|x| x.envelope()),
77        ];
78
79        Envelope::from_optional_envelopes(&envelopes).expect("should work")
80    }
81
82    fn apply_transform(&mut self, m: &Isometry3<f64>) {
83        if let Some(g) = &mut self.lod0_multi_surface {
84            g.apply_transform(m);
85        }
86        if let Some(g) = &mut self.lod1_solid {
87            g.apply_transform(m);
88        }
89        if let Some(g) = &mut self.lod2_solid {
90            g.apply_transform(m);
91        }
92        if let Some(g) = &mut self.lod3_solid {
93            g.apply_transform(m);
94        }
95
96        if let Some(g) = &mut self.lod0_multi_surface {
97            g.apply_transform(m);
98        }
99        if let Some(g) = &mut self.lod2_multi_surface {
100            g.apply_transform(m);
101        }
102        if let Some(g) = &mut self.lod3_multi_surface {
103            g.apply_transform(m);
104        }
105    }
106}
107
108#[derive(Debug, Clone, PartialEq)]
109pub struct OccupiedSpace {
110    pub space: Space,
111    pub lod1_implicit_representation: Option<ImplicitGeometry>,
112    pub lod2_implicit_representation: Option<ImplicitGeometry>,
113    pub lod3_implicit_representation: Option<ImplicitGeometry>,
114}
115
116impl OccupiedSpace {
117    pub fn new(space: Space) -> Self {
118        Self {
119            space,
120            lod1_implicit_representation: None,
121            lod2_implicit_representation: None,
122            lod3_implicit_representation: None,
123        }
124    }
125}
126
127impl FeatureWithGeometry for OccupiedSpace {
128    fn envelope(&self) -> Option<Envelope> {
129        let envelopes: Vec<Option<Envelope>> = vec![
130            self.space.envelope(),
131            self.lod1_implicit_representation
132                .as_ref()
133                .map(|x| x.envelope()),
134            self.lod2_implicit_representation
135                .as_ref()
136                .map(|x| x.envelope()),
137            self.lod3_implicit_representation
138                .as_ref()
139                .map(|x| x.envelope()),
140        ];
141
142        Envelope::from_optional_envelopes(&envelopes).expect("should work")
143    }
144
145    fn apply_transform(&mut self, m: &Isometry3<f64>) {
146        self.space.apply_transform(m);
147
148        if let Some(g) = &mut self.lod1_implicit_representation {
149            g.apply_transform(m);
150        }
151        if let Some(g) = &mut self.lod2_implicit_representation {
152            g.apply_transform(m);
153        }
154        if let Some(g) = &mut self.lod3_implicit_representation {
155            g.apply_transform(m);
156        }
157    }
158}
159
160#[derive(Debug, Clone, PartialEq)]
161pub struct ThematicSurface {
162    pub city_object: CityObject,
163    pub lod0_multi_surface: Option<geometry::MultiSurface>,
164    pub lod1_multi_surface: Option<geometry::MultiSurface>,
165    pub lod2_multi_surface: Option<geometry::MultiSurface>,
166    pub lod3_multi_surface: Option<geometry::MultiSurface>,
167}
168
169impl ThematicSurface {
170    pub fn new(city_object: CityObject) -> Self {
171        Self {
172            city_object,
173            lod0_multi_surface: None,
174            lod1_multi_surface: None,
175            lod2_multi_surface: None,
176            lod3_multi_surface: None,
177        }
178    }
179}
180
181impl FeatureWithGeometry for ThematicSurface {
182    fn envelope(&self) -> Option<Envelope> {
183        let envelopes: Vec<Option<Envelope>> = vec![
184            self.lod0_multi_surface.as_ref().map(|x| x.envelope()),
185            self.lod1_multi_surface.as_ref().map(|x| x.envelope()),
186            self.lod2_multi_surface.as_ref().map(|x| x.envelope()),
187            self.lod3_multi_surface.as_ref().map(|x| x.envelope()),
188        ];
189
190        Envelope::from_optional_envelopes(&envelopes).expect("should work")
191    }
192
193    fn apply_transform(&mut self, m: &Isometry3<f64>) {
194        if let Some(g) = &mut self.lod0_multi_surface {
195            g.apply_transform(m);
196        }
197        if let Some(g) = &mut self.lod1_multi_surface {
198            g.apply_transform(m);
199        }
200        if let Some(g) = &mut self.lod2_multi_surface {
201            g.apply_transform(m);
202        }
203        if let Some(g) = &mut self.lod3_multi_surface {
204            g.apply_transform(m);
205        }
206    }
207}