hrdf_routing_engine/routing/
models.rs

1use chrono::NaiveDateTime;
2use hrdf_parser::{Coordinates, DataStorage, Journey};
3use rustc_hash::FxHashSet;
4use serde::Serialize;
5
6#[derive(Debug, Clone)]
7pub struct RouteSection {
8    journey_id: Option<i32>,
9    departure_stop_id: i32,
10    arrival_stop_id: i32,
11    arrival_at: NaiveDateTime,
12    duration: Option<i16>,
13}
14
15impl RouteSection {
16    pub fn new(
17        journey_id: Option<i32>,
18        departure_stop_id: i32,
19        arrival_stop_id: i32,
20        arrival_at: NaiveDateTime,
21        duration: Option<i16>,
22    ) -> Self {
23        Self {
24            journey_id,
25            departure_stop_id,
26            arrival_stop_id,
27            arrival_at,
28            duration,
29        }
30    }
31
32    // Getters/Setters
33
34    pub fn journey_id(&self) -> Option<i32> {
35        self.journey_id
36    }
37
38    pub fn departure_stop_id(&self) -> i32 {
39        self.departure_stop_id
40    }
41
42    pub fn arrival_stop_id(&self) -> i32 {
43        self.arrival_stop_id
44    }
45
46    pub fn set_arrival_stop_id(&mut self, value: i32) {
47        self.arrival_stop_id = value;
48    }
49
50    pub fn arrival_at(&self) -> NaiveDateTime {
51        self.arrival_at
52    }
53
54    pub fn set_arrival_at(&mut self, value: NaiveDateTime) {
55        self.arrival_at = value;
56    }
57
58    pub fn duration(&self) -> Option<i16> {
59        self.duration
60    }
61
62    // Functions
63
64    pub fn journey<'a>(&'a self, data_storage: &'a DataStorage) -> Option<&'a Journey> {
65        self.journey_id.map(|id| {
66            data_storage
67                .journeys()
68                .find(id)
69                .unwrap_or_else(|| panic!("Journey {:?} not found.", id))
70        })
71    }
72}
73
74#[derive(Debug, Clone)]
75pub struct Route {
76    sections: Vec<RouteSection>,
77    visited_stops: FxHashSet<i32>,
78}
79
80impl Route {
81    pub fn new(sections: Vec<RouteSection>, visited_stops: FxHashSet<i32>) -> Self {
82        Self {
83            sections,
84            visited_stops,
85        }
86    }
87
88    // Getters/Setters
89
90    pub fn sections(&self) -> &Vec<RouteSection> {
91        &self.sections
92    }
93
94    pub fn visited_stops(&self) -> &FxHashSet<i32> {
95        &self.visited_stops
96    }
97
98    // Functions
99
100    pub fn last_section(&self) -> &RouteSection {
101        // A route always contains at least one section.
102        self.sections.last().unwrap()
103    }
104
105    pub fn last_section_mut(&mut self) -> &mut RouteSection {
106        // A route always contains at least one section.
107        self.sections.last_mut().unwrap()
108    }
109
110    pub fn arrival_stop_id(&self) -> i32 {
111        self.last_section().arrival_stop_id()
112    }
113
114    pub fn arrival_at(&self) -> NaiveDateTime {
115        self.last_section().arrival_at()
116    }
117
118    pub fn has_visited_any_stops(&self, stops: &FxHashSet<i32>) -> bool {
119        !self.visited_stops.is_disjoint(stops)
120    }
121
122    pub fn sections_having_journey(&self) -> Vec<&RouteSection> {
123        self.sections
124            .iter()
125            .filter(|section| section.journey_id().is_some())
126            .collect()
127    }
128
129    pub fn count_connections(&self) -> usize {
130        self.sections_having_journey().len()
131    }
132}
133
134#[derive(Copy, Clone, Eq, PartialEq)]
135pub enum RoutingAlgorithmMode {
136    SolveFromDepartureStopToArrivalStop,
137    SolveFromDepartureStopToReachableArrivalStops,
138}
139
140pub struct RoutingAlgorithmArgs {
141    mode: RoutingAlgorithmMode,
142    arrival_stop_id: Option<i32>,
143    time_limit: Option<NaiveDateTime>,
144}
145
146impl RoutingAlgorithmArgs {
147    pub fn new(
148        mode: RoutingAlgorithmMode,
149        arrival_stop_id: Option<i32>,
150        time_limit: Option<NaiveDateTime>,
151    ) -> Self {
152        Self {
153            mode,
154            arrival_stop_id,
155            time_limit,
156        }
157    }
158
159    pub fn solve_from_departure_stop_to_arrival_stop(arrival_stop_id: i32) -> Self {
160        Self::new(
161            RoutingAlgorithmMode::SolveFromDepartureStopToArrivalStop,
162            Some(arrival_stop_id),
163            None,
164        )
165    }
166
167    pub fn solve_from_departure_stop_to_reachable_arrival_stops(time_limit: NaiveDateTime) -> Self {
168        Self::new(
169            RoutingAlgorithmMode::SolveFromDepartureStopToReachableArrivalStops,
170            None,
171            Some(time_limit),
172        )
173    }
174
175    // Getters/Setters
176
177    pub fn mode(&self) -> RoutingAlgorithmMode {
178        self.mode
179    }
180
181    /// Do not call this function if you are not sure that arrival_stop_id is not None.
182    pub fn arrival_stop_id(&self) -> i32 {
183        self.arrival_stop_id.unwrap()
184    }
185
186    /// Do not call this function if you are not sure that time_limit is not None.
187    pub fn time_limit(&self) -> NaiveDateTime {
188        self.time_limit.unwrap()
189    }
190}
191
192#[derive(Debug, Serialize)]
193pub struct RouteResult {
194    departure_at: NaiveDateTime,
195    arrival_at: NaiveDateTime,
196    sections: Vec<RouteSectionResult>,
197}
198
199impl Clone for RouteResult {
200    fn clone(&self) -> Self {
201        RouteResult {
202            departure_at: self.departure_at,
203            arrival_at: self.arrival_at,
204            sections: self.sections.clone(),
205        }
206    }
207}
208
209impl RouteResult {
210    pub fn new(
211        departure_at: NaiveDateTime,
212        arrival_at: NaiveDateTime,
213        sections: Vec<RouteSectionResult>,
214    ) -> Self {
215        Self {
216            departure_at,
217            arrival_at,
218            sections,
219        }
220    }
221
222    // Getters/Setters
223
224    pub fn arrival_at(&self) -> NaiveDateTime {
225        self.arrival_at
226    }
227
228    pub fn sections(&self) -> &Vec<RouteSectionResult> {
229        &self.sections
230    }
231
232    //pub fn merge(&self, other: &RouteResult) -> RouteResult {}
233}
234
235#[derive(Debug, Serialize, Copy, Clone)]
236pub struct RouteSectionResult {
237    journey_id: Option<i32>,
238    departure_stop_id: i32,
239    departure_stop_lv95_coordinates: Option<Coordinates>,
240    departure_stop_wgs84_coordinates: Option<Coordinates>,
241    arrival_stop_id: i32,
242    arrival_stop_lv95_coordinates: Option<Coordinates>,
243    arrival_stop_wgs84_coordinates: Option<Coordinates>,
244    departure_at: Option<NaiveDateTime>,
245    arrival_at: Option<NaiveDateTime>,
246    duration: Option<i16>,
247}
248
249impl RouteSectionResult {
250    #[allow(clippy::too_many_arguments)]
251    pub fn new(
252        journey_id: Option<i32>,
253        departure_stop_id: i32,
254        departure_stop_lv95_coordinates: Option<Coordinates>,
255        departure_stop_wgs84_coordinates: Option<Coordinates>,
256        arrival_stop_id: i32,
257        arrival_stop_lv95_coordinates: Option<Coordinates>,
258        arrival_stop_wgs84_coordinates: Option<Coordinates>,
259        departure_at: Option<NaiveDateTime>,
260        arrival_at: Option<NaiveDateTime>,
261        duration: Option<i16>,
262    ) -> Self {
263        Self {
264            journey_id,
265            departure_stop_id,
266            departure_stop_lv95_coordinates,
267            departure_stop_wgs84_coordinates,
268            arrival_stop_id,
269            arrival_stop_lv95_coordinates,
270            arrival_stop_wgs84_coordinates,
271            departure_at,
272            arrival_at,
273            duration,
274        }
275    }
276
277    // Getters/Setters
278
279    pub fn departure_stop_id(&self) -> i32 {
280        self.departure_stop_id
281    }
282
283    pub fn departure_at(&self) -> Option<NaiveDateTime> {
284        self.departure_at
285    }
286
287    pub fn arrival_stop_id(&self) -> i32 {
288        self.arrival_stop_id
289    }
290
291    pub fn arrival_stop_lv95_coordinates(&self) -> Option<Coordinates> {
292        self.arrival_stop_lv95_coordinates
293    }
294
295    // pub fn arrival_stop_wgs84_coordinates(&self) -> Option<Coordinates> {
296    //     self.arrival_stop_wgs84_coordinates
297    // }
298
299    pub fn arrival_at(&self) -> Option<NaiveDateTime> {
300        self.arrival_at
301    }
302
303    pub fn duration(&self) -> Option<i16> {
304        self.duration
305    }
306
307    // Functions
308
309    pub fn journey<'a>(&'a self, data_storage: &'a DataStorage) -> Option<&'a Journey> {
310        self.journey_id.map(|id| {
311            data_storage
312                .journeys()
313                .find(id)
314                .unwrap_or_else(|| panic!("Journey {:?} not found.", id))
315        })
316    }
317
318    pub fn is_walking_trip(&self) -> bool {
319        self.journey_id.is_none()
320    }
321}