1 use crate::{LaneID, Map, TurnID};
2 use geom::{Angle, Distance, PolyLine, Pt2D, Speed};
3 use serde::{Deserialize, Serialize};
4 use std::fmt;
5 
6 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
7 pub struct Position {
8     // Don't let callers construct a Position directly, so it's easy to find callers of new().
9     lane: LaneID,
10     dist_along: Distance,
11 }
12 
13 impl fmt::Display for Position {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result14     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15         write!(f, "Position({}, {})", self.lane, self.dist_along)
16     }
17 }
18 
19 impl Position {
new(lane: LaneID, dist_along: Distance) -> Position20     pub fn new(lane: LaneID, dist_along: Distance) -> Position {
21         Position { lane, dist_along }
22     }
23 
start(lane: LaneID) -> Position24     pub fn start(lane: LaneID) -> Position {
25         Position {
26             lane,
27             dist_along: Distance::ZERO,
28         }
29     }
30 
end(lane: LaneID, map: &Map) -> Position31     pub fn end(lane: LaneID, map: &Map) -> Position {
32         Position {
33             lane,
34             dist_along: map.get_l(lane).length(),
35         }
36     }
37 
lane(&self) -> LaneID38     pub fn lane(&self) -> LaneID {
39         self.lane
40     }
41 
dist_along(&self) -> Distance42     pub fn dist_along(&self) -> Distance {
43         self.dist_along
44     }
45 
pt(&self, map: &Map) -> Pt2D46     pub fn pt(&self, map: &Map) -> Pt2D {
47         match map
48             .get_l(self.lane)
49             .lane_center_pts
50             .dist_along(self.dist_along)
51         {
52             Ok((pt, _)) => pt,
53             Err(err) => panic!("{} invalid: {}", self, err),
54         }
55     }
56 
pt_and_angle(&self, map: &Map) -> (Pt2D, Angle)57     pub fn pt_and_angle(&self, map: &Map) -> (Pt2D, Angle) {
58         match map
59             .get_l(self.lane)
60             .lane_center_pts
61             .dist_along(self.dist_along)
62         {
63             Ok(pair) => pair,
64             Err(err) => panic!("{} invalid: {}", self, err),
65         }
66     }
67 
equiv_pos(&self, lane: LaneID, map: &Map) -> Position68     pub fn equiv_pos(&self, lane: LaneID, map: &Map) -> Position {
69         self.equiv_pos_for_long_object(lane, Distance::ZERO, map)
70     }
equiv_pos_for_long_object( &self, lane: LaneID, our_len: Distance, map: &Map, ) -> Position71     pub fn equiv_pos_for_long_object(
72         &self,
73         lane: LaneID,
74         our_len: Distance,
75         map: &Map,
76     ) -> Position {
77         let r = map.get_parent(lane);
78         assert_eq!(map.get_l(self.lane).parent, r.id);
79 
80         // TODO Project perpendicular
81         let len = map.get_l(lane).length();
82         // The two lanes may be on opposite sides of the road; this often happens on one-ways with
83         // sidewalks on both sides.
84         if r.dir(lane) == r.dir(self.lane) {
85             Position::new(lane, self.dist_along.min(len))
86         } else {
87             Position::new(
88                 lane,
89                 // TODO I don't understand what this is doing anymore in the one case, revisit
90                 (len - self.dist_along + our_len)
91                     .max(Distance::ZERO)
92                     .min(len),
93             )
94         }
95     }
min_dist(mut self, dist_along: Distance, map: &Map) -> Option<Position>96     pub fn min_dist(mut self, dist_along: Distance, map: &Map) -> Option<Position> {
97         if self.dist_along >= dist_along {
98             return Some(self);
99         }
100         if map.get_l(self.lane).length() < dist_along {
101             return None;
102         }
103         self.dist_along = dist_along;
104         Some(self)
105     }
buffer_dist(mut self, buffer: Distance, map: &Map) -> Option<Position>106     pub fn buffer_dist(mut self, buffer: Distance, map: &Map) -> Option<Position> {
107         let len = map.get_l(self.lane).length();
108         if len <= buffer * 2.0 {
109             return None;
110         }
111         self.dist_along = self.dist_along.max(buffer).min(len - buffer);
112         Some(self)
113     }
114 }
115 
116 // TODO also building paths?
117 #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
118 pub enum Traversable {
119     Lane(LaneID),
120     Turn(TurnID),
121 }
122 
123 impl fmt::Display for Traversable {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result124     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
125         match self {
126             Traversable::Lane(id) => write!(f, "Traversable::Lane({})", id.0),
127             Traversable::Turn(id) => write!(
128                 f,
129                 "Traversable::Turn({}, {}, {})",
130                 id.src, id.dst, id.parent
131             ),
132         }
133     }
134 }
135 
136 impl Traversable {
as_lane(&self) -> LaneID137     pub fn as_lane(&self) -> LaneID {
138         match *self {
139             Traversable::Lane(id) => id,
140             Traversable::Turn(_) => panic!("not a lane"),
141         }
142     }
143 
as_turn(&self) -> TurnID144     pub fn as_turn(&self) -> TurnID {
145         match *self {
146             Traversable::Turn(id) => id,
147             Traversable::Lane(_) => panic!("not a turn"),
148         }
149     }
150 
maybe_turn(&self) -> Option<TurnID>151     pub fn maybe_turn(&self) -> Option<TurnID> {
152         match *self {
153             Traversable::Turn(id) => Some(id),
154             Traversable::Lane(_) => None,
155         }
156     }
157 
maybe_lane(&self) -> Option<LaneID>158     pub fn maybe_lane(&self) -> Option<LaneID> {
159         match *self {
160             Traversable::Turn(_) => None,
161             Traversable::Lane(id) => Some(id),
162         }
163     }
164 
165     // TODO Just expose the PolyLine instead of all these layers of helpers
length(&self, map: &Map) -> Distance166     pub fn length(&self, map: &Map) -> Distance {
167         match *self {
168             Traversable::Lane(id) => map.get_l(id).length(),
169             Traversable::Turn(id) => map.get_t(id).geom.length(),
170         }
171     }
172 
dist_along(&self, dist: Distance, map: &Map) -> Result<(Pt2D, Angle), String>173     pub fn dist_along(&self, dist: Distance, map: &Map) -> Result<(Pt2D, Angle), String> {
174         match *self {
175             Traversable::Lane(id) => map.get_l(id).lane_center_pts.dist_along(dist),
176             Traversable::Turn(id) => map.get_t(id).geom.dist_along(dist),
177         }
178     }
179 
slice( &self, start: Distance, end: Distance, map: &Map, ) -> Result<(PolyLine, Distance), String>180     pub fn slice(
181         &self,
182         start: Distance,
183         end: Distance,
184         map: &Map,
185     ) -> Result<(PolyLine, Distance), String> {
186         match *self {
187             Traversable::Lane(id) => map.get_l(id).lane_center_pts.slice(start, end),
188             Traversable::Turn(id) => map.get_t(id).geom.slice(start, end),
189         }
190     }
191 
exact_slice(&self, start: Distance, end: Distance, map: &Map) -> PolyLine192     pub fn exact_slice(&self, start: Distance, end: Distance, map: &Map) -> PolyLine {
193         match *self {
194             Traversable::Lane(id) => map.get_l(id).lane_center_pts.exact_slice(start, end),
195             Traversable::Turn(id) => map.get_t(id).geom.exact_slice(start, end),
196         }
197     }
198 
speed_limit(&self, map: &Map) -> Speed199     pub fn speed_limit(&self, map: &Map) -> Speed {
200         match *self {
201             Traversable::Lane(id) => map.get_parent(id).speed_limit,
202             Traversable::Turn(id) => map.get_parent(id.dst).speed_limit,
203         }
204     }
205 
get_zorder(&self, map: &Map) -> isize206     pub fn get_zorder(&self, map: &Map) -> isize {
207         match *self {
208             Traversable::Lane(id) => map.get_parent(id).zorder,
209             Traversable::Turn(id) => map.get_i(id.parent).get_zorder(map),
210         }
211     }
212 }
213