plumb errors for shifting polylines through more APIs. mostly no-op for

now, just switched everything to must_* variants, but this paves the way
for handling failures.

... except for rendering pedestrian crowds -- I _think_ I saw a crash
from that, and it's easy to have a fallback there
This commit is contained in:
Dustin Carlino 2020-08-12 08:18:10 -07:00
parent 8568690a7a
commit a27b029ff6
12 changed files with 53 additions and 35 deletions

View File

@ -415,12 +415,12 @@ impl ChangeWay {
let r = map.get_r(*id);
batch.push(
Color::GREEN,
map.right_shift(r.center_pts.clone(), r.get_half_width(map))
map.must_right_shift(r.center_pts.clone(), r.get_half_width(map))
.make_polygons(thickness),
);
batch.push(
Color::BLUE,
map.left_shift(r.center_pts.clone(), r.get_half_width(map))
map.must_left_shift(r.center_pts.clone(), r.get_half_width(map))
.make_polygons(thickness),
);
}

View File

@ -200,11 +200,13 @@ pub fn calculate_corners(i: &Intersection, map: &Map) -> Vec<Polygon> {
let l1 = map.get_l(turn.id.src);
let l2 = map.get_l(turn.id.dst);
let mut pts = map.left_shift(turn.geom.clone(), width / 2.0).into_points();
let mut pts = map
.must_left_shift(turn.geom.clone(), width / 2.0)
.into_points();
pts.push(map.left_shift_line(l2.first_line(), width / 2.0).pt1());
pts.push(map.right_shift_line(l2.first_line(), width / 2.0).pt1());
pts.extend(
map.right_shift(turn.geom.clone(), width / 2.0)
map.must_right_shift(turn.geom.clone(), width / 2.0)
.reversed()
.into_points(),
);

View File

@ -270,7 +270,7 @@ fn calculate_driving_lines(map: &Map, lane: &Lane, parent: &Road) -> Vec<Polygon
if idx == 0 || (dir && !parent.children_forwards[idx - 1].1.is_for_moving_vehicles()) {
return Vec::new();
}
let lane_edge_pts = map.left_shift(lane.lane_center_pts.clone(), lane.width / 2.0);
let lane_edge_pts = map.must_left_shift(lane.lane_center_pts.clone(), lane.width / 2.0);
lane_edge_pts.dashed_lines(
Distance::meters(0.25),
Distance::meters(1.0),

View File

@ -210,6 +210,7 @@ impl DrawPedCrowd {
} else {
map.right_shift(pl_slice, SIDEWALK_THICKNESS / 4.0)
}
.unwrap_or_else(|_| on.exact_slice(input.low, input.high, map))
}
PedCrowdLocation::BldgDriveway(b) => map
.get_b(b)

View File

@ -37,8 +37,8 @@ pub fn intersection_polygon(
} else {
panic!("Incident road {} doesn't have an endpoint at {}", id, i.id);
};
let pl_normal = driving_side.right_shift(pl.clone(), r.half_width);
let pl_reverse = driving_side.left_shift(pl.clone(), r.half_width);
let pl_normal = driving_side.must_right_shift(pl.clone(), r.half_width);
let pl_reverse = driving_side.must_left_shift(pl.clone(), r.half_width);
(*id, pl.last_line(), pl_normal, pl_reverse)
})
.collect();
@ -219,23 +219,23 @@ fn generalized_trim_back(
if r.dst_i == i {
endpoints.push(
driving_side
.right_shift(r.trimmed_center_pts.clone(), r.half_width)
.must_right_shift(r.trimmed_center_pts.clone(), r.half_width)
.last_pt(),
);
endpoints.push(
driving_side
.left_shift(r.trimmed_center_pts.clone(), r.half_width)
.must_left_shift(r.trimmed_center_pts.clone(), r.half_width)
.last_pt(),
);
} else {
endpoints.push(
driving_side
.left_shift(r.trimmed_center_pts.clone(), r.half_width)
.must_left_shift(r.trimmed_center_pts.clone(), r.half_width)
.first_pt(),
);
endpoints.push(
driving_side
.right_shift(r.trimmed_center_pts.clone(), r.half_width)
.must_right_shift(r.trimmed_center_pts.clone(), r.half_width)
.first_pt(),
);
}
@ -333,21 +333,25 @@ fn deadend(
if r.dst_i == i {
endpts.push(
driving_side
.right_shift(trimmed.clone(), r.half_width)
.must_right_shift(trimmed.clone(), r.half_width)
.last_pt(),
);
endpts.push(
driving_side
.left_shift(trimmed.clone(), r.half_width)
.must_left_shift(trimmed.clone(), r.half_width)
.last_pt(),
);
} else {
endpts.push(
driving_side
.left_shift(trimmed.clone(), r.half_width)
.must_left_shift(trimmed.clone(), r.half_width)
.first_pt(),
);
endpts.push(
driving_side
.must_right_shift(trimmed, r.half_width)
.first_pt(),
);
endpts.push(driving_side.right_shift(trimmed, r.half_width).first_pt());
}
endpts.dedup();
@ -549,23 +553,23 @@ fn on_off_ramp(
if r.dst_i == i {
endpoints.push(
driving_side
.right_shift(r.trimmed_center_pts.clone(), r.half_width)
.must_right_shift(r.trimmed_center_pts.clone(), r.half_width)
.last_pt(),
);
endpoints.push(
driving_side
.left_shift(r.trimmed_center_pts.clone(), r.half_width)
.must_left_shift(r.trimmed_center_pts.clone(), r.half_width)
.last_pt(),
);
} else {
endpoints.push(
driving_side
.left_shift(r.trimmed_center_pts.clone(), r.half_width)
.must_left_shift(r.trimmed_center_pts.clone(), r.half_width)
.first_pt(),
);
endpoints.push(
driving_side
.right_shift(r.trimmed_center_pts.clone(), r.half_width)
.must_right_shift(r.trimmed_center_pts.clone(), r.half_width)
.first_pt(),
);
}

View File

@ -141,7 +141,7 @@ impl Map {
}
// TODO Maybe easier to use the road's "yellow center line" and shift left/right from
// there.
let road_left_pts = map.left_shift(road.center_pts.clone(), r.half_width);
let road_left_pts = map.must_left_shift(road.center_pts.clone(), r.half_width);
let mut fwd_width_so_far = Distance::ZERO;
let mut back_width_so_far = Distance::ZERO;
@ -158,14 +158,14 @@ impl Map {
// Careful about order here. lane_specs are all of the forwards from center to
// sidewalk, then all the backwards from center to sidewalk.
let lane_center_pts = if !lane.reverse_pts {
let pl = map.right_shift(
let pl = map.must_right_shift(
road_left_pts.clone(),
total_back_width + fwd_width_so_far + (lane.width / 2.0),
);
fwd_width_so_far += lane.width;
pl
} else {
let pl = map.right_shift(
let pl = map.must_right_shift(
road_left_pts.clone(),
total_back_width - back_width_so_far - (lane.width / 2.0),
);

View File

@ -384,7 +384,7 @@ fn make_shared_sidewalk_corner(
pts_between.extend(
driving_side
.right_shift(PolyLine::must_new(deduped), l1.width.min(l2.width) / 2.0)
.must_right_shift(PolyLine::must_new(deduped), l1.width.min(l2.width) / 2.0)
.points(),
);
}

View File

@ -9,6 +9,7 @@ use abstutil::Timer;
use geom::{Angle, Bounds, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D, Ring, Time};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
use std::error::Error;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MapConfig {
@ -584,12 +585,18 @@ impl Map {
None
}
pub fn right_shift(&self, pl: PolyLine, width: Distance) -> PolyLine {
pub fn right_shift(&self, pl: PolyLine, width: Distance) -> Result<PolyLine, Box<dyn Error>> {
self.config.driving_side.right_shift(pl, width)
}
pub fn left_shift(&self, pl: PolyLine, width: Distance) -> PolyLine {
pub fn must_right_shift(&self, pl: PolyLine, width: Distance) -> PolyLine {
self.right_shift(pl, width).unwrap()
}
pub fn left_shift(&self, pl: PolyLine, width: Distance) -> Result<PolyLine, Box<dyn Error>> {
self.config.driving_side.left_shift(pl, width)
}
pub fn must_left_shift(&self, pl: PolyLine, width: Distance) -> PolyLine {
self.left_shift(pl, width).unwrap()
}
pub fn right_shift_line(&self, line: Line, width: Distance) -> Line {
self.config.driving_side.right_shift_line(line, width)
}

View File

@ -272,7 +272,7 @@ impl Road {
} else {
self.children_backwards[0].0
});
map.left_shift(lane.lane_center_pts.clone(), lane.width / 2.0)
map.must_left_shift(lane.lane_center_pts.clone(), lane.width / 2.0)
}
pub fn any_on_other_side(&self, l: LaneID, lt: LaneType) -> Option<LaneID> {

View File

@ -298,7 +298,7 @@ impl TurnGroup {
left += map.get_l(l).width;
}
let pl = map.right_shift(pl, (leftmost + rightmost) / 2.0);
let pl = map.must_right_shift(pl, (leftmost + rightmost) / 2.0);
// Flip direction, so we point away from the intersection
let pl = if self.id.crosswalk
&& map.get_l(self.members[0].src).src_i == self.members[0].parent

View File

@ -322,7 +322,7 @@ impl UberTurnGroup {
left += map.get_l(l).width;
}
let pl = map.right_shift(pl, (leftmost + rightmost) / 2.0);
let pl = map.must_right_shift(pl, (leftmost + rightmost) / 2.0);
// Flip direction, so we point away from the intersection
(pl.reversed(), rightmost - leftmost)
}

View File

@ -5,6 +5,7 @@ use geom::{Angle, Circle, Distance, GPSBounds, Line, PolyLine, Polygon, Pt2D};
use petgraph::graphmap::DiGraphMap;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
use std::error::Error;
use std::fmt;
#[derive(Debug, Serialize, Deserialize)]
@ -323,10 +324,10 @@ impl RawRoad {
let mut true_center = PolyLine::new(self.center_points.clone()).expect(&id.to_string());
match (sidewalk_right, sidewalk_left) {
(Some(w), None) => {
true_center = driving_side.right_shift(true_center, w / 2.0);
true_center = driving_side.must_right_shift(true_center, w / 2.0);
}
(None, Some(w)) => {
true_center = driving_side.left_shift(true_center, w / 2.0);
true_center = driving_side.must_left_shift(true_center, w / 2.0);
}
_ => {}
}
@ -413,21 +414,24 @@ pub enum DrivingSide {
impl DrivingSide {
// "right" and "left" here are in terms of DrivingSide::Right, what I'm used to reasoning about
// in the USA. They invert appropriately for DrivingSide::Left.
pub fn right_shift(self, pl: PolyLine, width: Distance) -> PolyLine {
// TODO Plumb through the error further
pub fn right_shift(self, pl: PolyLine, width: Distance) -> Result<PolyLine, Box<dyn Error>> {
match self {
DrivingSide::Right => pl.shift_right(width),
DrivingSide::Left => pl.shift_left(width),
}
.unwrap()
}
pub fn must_right_shift(self, pl: PolyLine, width: Distance) -> PolyLine {
self.right_shift(pl, width).unwrap()
}
pub fn left_shift(self, pl: PolyLine, width: Distance) -> PolyLine {
pub fn left_shift(self, pl: PolyLine, width: Distance) -> Result<PolyLine, Box<dyn Error>> {
match self {
DrivingSide::Right => pl.shift_left(width),
DrivingSide::Left => pl.shift_right(width),
}
.unwrap()
}
pub fn must_left_shift(self, pl: PolyLine, width: Distance) -> PolyLine {
self.left_shift(pl, width).unwrap()
}
pub fn right_shift_line(self, line: Line, width: Distance) -> Line {