Skip to main content

ecitygml_core/model/transportation/
intersection.rs

1use 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}