ecitygml_core/model/
transportation.rs

1use crate::model::core::{CityObject, Space, ThematicSurface};
2use crate::operations::{CityObjectVisitor, FeatureWithGeometry, Visitable};
3use egml::model::base;
4use egml::model::base::Gml;
5use egml::model::geometry::Envelope;
6use nalgebra::Isometry3;
7
8#[derive(Debug, Clone, PartialEq)]
9pub struct Road {
10    pub city_object: CityObject, // TODO: space
11    pub section: Vec<Section>,
12    pub intersection: Vec<Intersection>,
13}
14
15impl Road {
16    pub fn new(id: base::Id) -> Self {
17        let gml = Gml::new(id);
18        let city_object = CityObject::new(gml);
19
20        Self {
21            city_object,
22            section: Default::default(),
23            intersection: Default::default(),
24        }
25    }
26}
27
28impl Visitable for Road {
29    fn accept<V: CityObjectVisitor>(&self, visitor: &mut V) {
30        visitor.visit_road(self);
31        self.section.iter().for_each(|x| x.accept(visitor));
32        self.intersection.iter().for_each(|x| x.accept(visitor));
33    }
34}
35
36impl FeatureWithGeometry for Road {
37    fn envelope(&self) -> Option<Envelope> {
38        let mut envelopes: Vec<Option<Envelope>> = vec![];
39        envelopes.extend(self.section.iter().map(|x| x.envelope()));
40        envelopes.extend(self.intersection.iter().map(|x| x.envelope()));
41
42        Envelope::from_optional_envelopes(&envelopes).expect("should work")
43    }
44
45    fn apply_transform(&mut self, m: &Isometry3<f64>) {
46        self.section.iter_mut().for_each(|x| x.apply_transform(m));
47        self.intersection
48            .iter_mut()
49            .for_each(|x| x.apply_transform(m));
50    }
51}
52
53#[derive(Debug, Clone, PartialEq)]
54pub struct Section {
55    pub city_object: CityObject, // TODO: space
56    pub traffic_space: Vec<TrafficSpace>,
57    pub auxiliary_traffic_space: Vec<AuxiliaryTrafficSpace>,
58}
59
60impl Section {
61    pub fn new(id: base::Id) -> Self {
62        let gml = Gml::new(id);
63        let city_object = CityObject::new(gml);
64
65        Self {
66            city_object,
67            traffic_space: Vec::new(),
68            auxiliary_traffic_space: Vec::new(),
69        }
70    }
71}
72
73impl Visitable for Section {
74    fn accept<V: CityObjectVisitor>(&self, visitor: &mut V) {
75        visitor.visit_section(self);
76        self.traffic_space.iter().for_each(|x| x.accept(visitor));
77        self.auxiliary_traffic_space
78            .iter()
79            .for_each(|x| x.accept(visitor));
80    }
81}
82
83impl FeatureWithGeometry for Section {
84    fn envelope(&self) -> Option<Envelope> {
85        let mut envelopes: Vec<Option<Envelope>> = vec![];
86        envelopes.extend(self.traffic_space.iter().map(|x| x.envelope()));
87        envelopes.extend(self.auxiliary_traffic_space.iter().map(|x| x.envelope()));
88
89        Envelope::from_optional_envelopes(&envelopes).expect("should work")
90    }
91
92    fn apply_transform(&mut self, m: &Isometry3<f64>) {
93        self.traffic_space
94            .iter_mut()
95            .for_each(|x| x.apply_transform(m));
96        self.auxiliary_traffic_space
97            .iter_mut()
98            .for_each(|x| x.apply_transform(m));
99    }
100}
101
102#[derive(Debug, Clone, PartialEq)]
103pub struct Intersection {
104    pub city_object: CityObject, // TODO: space
105    pub traffic_space: Vec<TrafficSpace>,
106    pub auxiliary_traffic_space: Vec<AuxiliaryTrafficSpace>,
107}
108
109impl Intersection {
110    pub fn new(id: base::Id) -> Self {
111        let gml = Gml::new(id);
112        let city_object = CityObject::new(gml);
113
114        Self {
115            city_object,
116            traffic_space: Vec::new(),
117            auxiliary_traffic_space: Vec::new(),
118        }
119    }
120}
121
122impl Visitable for Intersection {
123    fn accept<V: CityObjectVisitor>(&self, visitor: &mut V) {
124        visitor.visit_intersection(self);
125        self.traffic_space.iter().for_each(|x| x.accept(visitor));
126        self.auxiliary_traffic_space
127            .iter()
128            .for_each(|x| x.accept(visitor));
129    }
130}
131
132impl FeatureWithGeometry for Intersection {
133    fn envelope(&self) -> Option<Envelope> {
134        let mut envelopes: Vec<Option<Envelope>> = vec![];
135        envelopes.extend(self.traffic_space.iter().map(|x| x.envelope()));
136        envelopes.extend(self.auxiliary_traffic_space.iter().map(|x| x.envelope()));
137
138        Envelope::from_optional_envelopes(&envelopes).expect("should work")
139    }
140
141    fn apply_transform(&mut self, m: &Isometry3<f64>) {
142        self.traffic_space
143            .iter_mut()
144            .for_each(|x| x.apply_transform(m));
145        self.auxiliary_traffic_space
146            .iter_mut()
147            .for_each(|x| x.apply_transform(m));
148    }
149}
150
151#[derive(Debug, Clone, PartialEq)]
152pub struct TrafficSpace {
153    pub space: Space,
154    pub traffic_area: Vec<TrafficArea>, // this should be located in boundaries the space struct
155}
156
157impl TrafficSpace {
158    pub fn new(space: Space) -> Self {
159        Self {
160            space,
161            traffic_area: Vec::new(),
162        }
163    }
164}
165
166impl Visitable for TrafficSpace {
167    fn accept<V: CityObjectVisitor>(&self, visitor: &mut V) {
168        visitor.visit_traffic_space(self);
169        self.traffic_area.iter().for_each(|x| x.accept(visitor));
170    }
171}
172
173impl FeatureWithGeometry for TrafficSpace {
174    fn envelope(&self) -> Option<Envelope> {
175        let mut envelopes: Vec<Option<Envelope>> = vec![self.space.envelope()];
176        envelopes.extend(self.traffic_area.iter().map(|x| x.envelope()));
177
178        Envelope::from_optional_envelopes(&envelopes).expect("should work")
179    }
180
181    fn apply_transform(&mut self, m: &Isometry3<f64>) {
182        self.space.apply_transform(m);
183        self.traffic_area
184            .iter_mut()
185            .for_each(|x| x.apply_transform(m));
186    }
187}
188
189#[derive(Debug, Clone, PartialEq)]
190pub struct AuxiliaryTrafficSpace {
191    pub space: Space,
192    pub auxiliary_traffic_area: Vec<AuxiliaryTrafficArea>, // this should be located in boundaries the space struct
193}
194
195impl AuxiliaryTrafficSpace {
196    pub fn new(space: Space) -> Self {
197        Self {
198            space,
199            auxiliary_traffic_area: Vec::new(),
200        }
201    }
202}
203
204impl Visitable for AuxiliaryTrafficSpace {
205    fn accept<V: CityObjectVisitor>(&self, visitor: &mut V) {
206        visitor.visit_auxiliary_traffic_space(self);
207        self.auxiliary_traffic_area
208            .iter()
209            .for_each(|x| x.accept(visitor));
210    }
211}
212
213impl FeatureWithGeometry for AuxiliaryTrafficSpace {
214    fn envelope(&self) -> Option<Envelope> {
215        let mut envelopes: Vec<Option<Envelope>> = vec![self.space.envelope()];
216        envelopes.extend(self.auxiliary_traffic_area.iter().map(|x| x.envelope()));
217
218        Envelope::from_optional_envelopes(&envelopes).expect("should work")
219    }
220
221    fn apply_transform(&mut self, m: &Isometry3<f64>) {
222        self.space.apply_transform(m);
223        self.auxiliary_traffic_area
224            .iter_mut()
225            .for_each(|x| x.apply_transform(m));
226    }
227}
228
229#[derive(Debug, Clone, PartialEq)]
230pub struct TrafficArea {
231    pub thematic_surface: ThematicSurface,
232}
233
234impl TrafficArea {
235    pub fn new(thematic_surface: ThematicSurface) -> Self {
236        Self { thematic_surface }
237    }
238}
239
240impl Visitable for TrafficArea {
241    fn accept<V: CityObjectVisitor>(&self, visitor: &mut V) {
242        visitor.visit_traffic_area(self);
243    }
244}
245
246impl FeatureWithGeometry for TrafficArea {
247    fn envelope(&self) -> Option<Envelope> {
248        self.thematic_surface.envelope()
249    }
250
251    fn apply_transform(&mut self, m: &Isometry3<f64>) {
252        self.thematic_surface.apply_transform(m);
253    }
254}
255
256#[derive(Debug, Clone, PartialEq)]
257pub struct AuxiliaryTrafficArea {
258    pub thematic_surface: ThematicSurface,
259}
260
261impl AuxiliaryTrafficArea {
262    pub fn new(thematic_surface: ThematicSurface) -> Self {
263        Self { thematic_surface }
264    }
265}
266
267impl Visitable for AuxiliaryTrafficArea {
268    fn accept<V: CityObjectVisitor>(&self, visitor: &mut V) {
269        visitor.visit_auxiliary_traffic_area(self);
270    }
271}
272
273impl FeatureWithGeometry for AuxiliaryTrafficArea {
274    fn envelope(&self) -> Option<Envelope> {
275        self.thematic_surface.envelope()
276    }
277
278    fn apply_transform(&mut self, m: &Isometry3<f64>) {
279        self.thematic_surface.apply_transform(m);
280    }
281}