ecitygml_core/model/
core.rs1use 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 }
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}