Skip to main content

ecitygml_core/model/transportation/
traffic_space.rs

1use crate::model::core::{
2    AbstractUnoccupiedSpace, AsAbstractFeature, AsAbstractFeatureMut, AsAbstractSpace,
3    AsAbstractSpaceMut, AsAbstractThematicSurfaceMut, AsAbstractUnoccupiedSpace,
4    AsAbstractUnoccupiedSpaceMut, CityObjectKind, CityObjectRef,
5};
6use crate::model::transportation::granularity_value::GranularityValue;
7use crate::model::transportation::{TrafficArea, TrafficDirectionValue};
8use crate::operations::{Visitable, Visitor};
9use egml::model::basic::Code;
10use egml::model::geometry::Envelope;
11use nalgebra::Isometry3;
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct TrafficSpace {
15    pub(crate) abstract_unoccupied_space: AbstractUnoccupiedSpace,
16    pub traffic_area: Vec<TrafficArea>, // this should be located in boundaries the space struct
17    pub(crate) class: Option<Code>,
18    pub(crate) functions: Vec<Code>,
19    pub(crate) usages: Vec<Code>,
20    pub(crate) granularity: GranularityValue,
21    pub(crate) traffic_direction: Option<TrafficDirectionValue>,
22}
23
24impl TrafficSpace {
25    pub fn new(
26        abstract_unoccupied_space: AbstractUnoccupiedSpace,
27        granularity: GranularityValue,
28    ) -> Self {
29        Self {
30            abstract_unoccupied_space,
31            traffic_area: Vec::new(),
32            class: None,
33            functions: Vec::new(),
34            usages: Vec::new(),
35            granularity,
36            traffic_direction: None,
37        }
38    }
39
40    pub fn iter_city_object<'a>(&'a self) -> impl Iterator<Item = CityObjectRef<'a>> + 'a {
41        std::iter::once(CityObjectRef::TrafficSpace(self))
42            .chain(self.traffic_area.iter().flat_map(|x| x.iter_city_object()))
43    }
44
45    pub fn refresh_bounded_by_recursive(&mut self) {
46        self.traffic_area
47            .iter_mut()
48            .for_each(|x| x.refresh_bounded_by());
49
50        let own_envelope = self.compute_envelope();
51        let envelopes: Vec<Envelope> = own_envelope
52            .as_ref()
53            .into_iter()
54            .chain(self.traffic_area.iter().filter_map(|x| x.bounded_by()))
55            .cloned()
56            .collect();
57
58        self.set_bounded_by(Envelope::from_envelopes(&envelopes));
59    }
60
61    pub fn apply_transform_recursive(&mut self, m: &Isometry3<f64>) {
62        self.abstract_unoccupied_space.apply_transform(m);
63
64        self.traffic_area
65            .iter_mut()
66            .for_each(|x| x.apply_transform(m));
67    }
68
69    pub fn class(&self) -> &Option<Code> {
70        &self.class
71    }
72
73    pub fn set_class(&mut self, class: Option<Code>) {
74        self.class = class;
75    }
76
77    pub fn functions(&self) -> &Vec<Code> {
78        &self.functions
79    }
80
81    pub fn set_functions(&mut self, functions: Vec<Code>) {
82        self.functions = functions;
83    }
84
85    pub fn usages(&self) -> &Vec<Code> {
86        &self.usages
87    }
88
89    pub fn set_usages(&mut self, usages: Vec<Code>) {
90        self.usages = usages;
91    }
92
93    pub fn granularity(&self) -> &GranularityValue {
94        &self.granularity
95    }
96
97    pub fn set_granularity(&mut self, granularity: GranularityValue) {
98        self.granularity = granularity;
99    }
100
101    pub fn traffic_direction(&self) -> &Option<TrafficDirectionValue> {
102        &self.traffic_direction
103    }
104
105    pub fn set_traffic_direction(&mut self, traffic_direction: Option<TrafficDirectionValue>) {
106        self.traffic_direction = traffic_direction;
107    }
108}
109
110impl AsAbstractUnoccupiedSpace for TrafficSpace {
111    fn abstract_unoccupied_space(&self) -> &AbstractUnoccupiedSpace {
112        &self.abstract_unoccupied_space
113    }
114}
115
116impl AsAbstractUnoccupiedSpaceMut for TrafficSpace {
117    fn abstract_unoccupied_space_mut(&mut self) -> &mut AbstractUnoccupiedSpace {
118        &mut self.abstract_unoccupied_space
119    }
120}
121
122crate::impl_abstract_unoccupied_space_traits!(TrafficSpace);
123
124impl From<TrafficSpace> for CityObjectKind {
125    fn from(item: TrafficSpace) -> Self {
126        CityObjectKind::TrafficSpace(item)
127    }
128}
129
130impl Visitable for TrafficSpace {
131    fn accept<V: Visitor>(&self, visitor: &mut V) {
132        visitor.visit_traffic_space(self);
133        self.traffic_area.iter().for_each(|x| x.accept(visitor));
134    }
135}