1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use std::fmt;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use abstutil::{deserialize_usize, serialize_usize};
use geom::Time;
use crate::{LaneID, Map, Path, PathConstraints, PathRequest, Position, RoadID};
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct TransitStopID {
pub road: RoadID,
pub(crate) idx: usize,
}
impl fmt::Display for TransitStopID {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TransitStopID({0}, {1})", self.road, self.idx)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct TransitRouteID(
#[serde(
serialize_with = "serialize_usize",
deserialize_with = "deserialize_usize"
)]
pub usize,
);
impl fmt::Display for TransitRouteID {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "TransitRoute #{}", self.0)
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct TransitStop {
pub id: TransitStopID,
pub name: String,
pub gtfs_id: String,
pub driving_pos: Position,
pub sidewalk_pos: Position,
pub is_train_stop: bool,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct TransitRoute {
pub id: TransitRouteID,
pub long_name: String,
pub short_name: String,
pub gtfs_id: String,
pub stops: Vec<TransitStopID>,
pub start: LaneID,
pub end_border: Option<LaneID>,
pub route_type: PathConstraints,
pub spawn_times: Vec<Time>,
pub orig_spawn_times: Vec<Time>,
}
impl TransitRoute {
fn all_path_requests(&self, map: &Map) -> Vec<PathRequest> {
let mut steps = vec![PathRequest::vehicle(
Position::start(self.start),
map.get_ts(self.stops[0]).driving_pos,
self.route_type,
)];
for pair in self.stops.windows(2) {
steps.push(PathRequest::vehicle(
map.get_ts(pair[0]).driving_pos,
map.get_ts(pair[1]).driving_pos,
self.route_type,
));
}
let last_stop_pos = map.get_ts(*self.stops.last().unwrap()).driving_pos;
if let Some(end) = self.end_border {
steps.push(PathRequest::vehicle(
last_stop_pos,
Position::end(end, map),
self.route_type,
));
} else {
steps.push(PathRequest::vehicle(
last_stop_pos,
Position::end(last_stop_pos.lane(), map),
self.route_type,
));
}
steps
}
pub fn all_paths(&self, map: &Map) -> Result<Vec<Path>> {
let mut paths = Vec::new();
for req in self.all_path_requests(map) {
if req.start.lane().road == req.end.lane().road
&& req.start.dist_along() > req.end.dist_along()
{
bail!(
"Two consecutive stops are on the same road, but they travel backwards: {}",
req
);
}
let path = map.pathfind(req)?;
if path.is_empty() {
bail!("Empty path between stops: {}", path.get_req());
}
paths.push(path);
}
for pair in paths.windows(2) {
if pair[0].get_req().end != pair[1].get_req().start {
bail!(
"Transit route will warp from {} to {}",
pair[0].get_req().end,
pair[1].get_req().start
);
}
}
Ok(paths)
}
pub fn plural_noun(&self) -> &'static str {
if self.route_type == PathConstraints::Bus {
"buses"
} else {
"trains"
}
}
}