ecitygml_core/model/transportation/
intersection.rs1use crate::model::core::{
2 AbstractSpace, AsAbstractFeature, AsAbstractFeatureMut, AsAbstractSpace, AsAbstractSpaceMut,
3 CityObjectKind, CityObjectRef,
4};
5use crate::model::transportation::{AuxiliaryTrafficSpace, TrafficSpace};
6use crate::operations::{Visitable, Visitor};
7use egml::model::geometry::Envelope;
8use nalgebra::Isometry3;
9
10#[derive(Debug, Clone, PartialEq)]
11pub struct Intersection {
12 pub(crate) abstract_space: AbstractSpace,
13 pub traffic_space: Vec<TrafficSpace>,
14 pub auxiliary_traffic_space: Vec<AuxiliaryTrafficSpace>,
15}
16
17impl Intersection {
18 pub fn new(abstract_space: AbstractSpace) -> Self {
19 Self {
20 abstract_space,
21 traffic_space: Vec::new(),
22 auxiliary_traffic_space: Vec::new(),
23 }
24 }
25
26 pub fn iter_city_object<'a>(&'a self) -> impl Iterator<Item = CityObjectRef<'a>> + 'a {
27 std::iter::once(CityObjectRef::Intersection(self))
28 .chain(self.traffic_space.iter().flat_map(|x| x.iter_city_object()))
29 .chain(
30 self.auxiliary_traffic_space
31 .iter()
32 .flat_map(|x| x.iter_city_object()),
33 )
34 }
35
36 pub fn refresh_bounded_by_recursive(&mut self) {
37 self.traffic_space
38 .iter_mut()
39 .for_each(|x| x.refresh_bounded_by_recursive());
40 self.auxiliary_traffic_space
41 .iter_mut()
42 .for_each(|x| x.refresh_bounded_by_recursive());
43
44 let own_envelope = self.compute_envelope();
45 let envelopes: Vec<Envelope> = own_envelope
46 .as_ref()
47 .into_iter()
48 .chain(self.traffic_space.iter().filter_map(|x| x.bounded_by()))
49 .chain(
50 self.auxiliary_traffic_space
51 .iter()
52 .filter_map(|x| x.bounded_by()),
53 )
54 .cloned()
55 .collect();
56
57 self.set_bounded_by(Envelope::from_envelopes(&envelopes));
58 }
59
60 pub fn apply_transform_recursive(&mut self, m: &Isometry3<f64>) {
61 self.abstract_space.apply_transform(m);
62
63 self.traffic_space
64 .iter_mut()
65 .for_each(|x| x.apply_transform_recursive(m));
66 self.auxiliary_traffic_space
67 .iter_mut()
68 .for_each(|x| x.apply_transform_recursive(m));
69 }
70}
71
72impl AsAbstractSpace for Intersection {
73 fn abstract_space(&self) -> &AbstractSpace {
74 &self.abstract_space
75 }
76}
77
78impl AsAbstractSpaceMut for Intersection {
79 fn abstract_space_mut(&mut self) -> &mut AbstractSpace {
80 &mut self.abstract_space
81 }
82}
83
84crate::impl_abstract_space_traits!(Intersection);
85
86impl From<Intersection> for CityObjectKind {
87 fn from(item: Intersection) -> Self {
88 CityObjectKind::Intersection(item)
89 }
90}
91
92impl Visitable for Intersection {
93 fn accept<V: Visitor>(&self, visitor: &mut V) {
94 visitor.visit_intersection(self);
95 self.traffic_space.iter().for_each(|x| x.accept(visitor));
96 self.auxiliary_traffic_space
97 .iter()
98 .for_each(|x| x.accept(visitor));
99 }
100}