gracefully degrade if we cant make TurnGroups for a traffic signal. this

gets SF, Tokyo, and London to import!!!
This commit is contained in:
Dustin Carlino 2020-08-12 11:05:19 -07:00
parent 7a0dbb28b1
commit 3b49353df2
7 changed files with 41 additions and 19 deletions

View File

@ -221,8 +221,12 @@ pub fn snap_bus_stops(
for idx in (0..idx_in_route).rev() {
let (i, pt) = route.all_pts[idx];
if !raw.intersections.contains_key(&i) {
found = Some(pt_to_road[&pt.to_hashable()]);
break;
if let Some(r) = pt_to_road.get(&pt.to_hashable()) {
found = Some(*r);
break;
} else {
return Err(format!("Some point on the route isn't even on a road?!"));
}
}
}
if let Some(r) = found {

View File

@ -9,7 +9,7 @@ pub struct Line(Pt2D, Pt2D);
impl Line {
pub fn new(pt1: Pt2D, pt2: Pt2D) -> Option<Line> {
if pt1.dist_to(pt2) < EPSILON_DIST {
if pt1.dist_to(pt2) <= EPSILON_DIST {
return None;
}
Some(Line(pt1, pt2))

View File

@ -120,7 +120,7 @@ impl Ring {
for pt in pts.iter().cloned() {
current.push(pt);
if intersections.contains(&pt.to_hashable()) && current.len() > 1 {
if current[0] == pt {
if current[0] == pt && current.len() >= 3 {
rings.push(Ring::must_new(current.drain(..).collect()));
} else {
polylines.push(PolyLine::new(current.drain(..).collect())?);

View File

@ -13,7 +13,7 @@ use crate::raw::{OriginalIntersection, OriginalRoad, RawMap};
use crate::{
connectivity, osm, Area, AreaID, ControlStopSign, ControlTrafficSignal, Intersection,
IntersectionID, IntersectionType, Lane, LaneID, Map, MapEdits, PathConstraints, Position, Road,
RoadID, Zone,
RoadID, TurnGroup, Zone,
};
use abstutil::{Parallelism, Timer};
use enumset::EnumSet;
@ -141,7 +141,9 @@ impl Map {
}
// TODO Maybe easier to use the road's "yellow center line" and shift left/right from
// there.
let road_left_pts = map.must_left_shift(road.center_pts.clone(), r.half_width);
let road_left_pts = map
.left_shift(road.center_pts.clone(), r.half_width)
.unwrap_or_else(|_| road.center_pts.clone());
let mut fwd_width_so_far = Distance::ZERO;
let mut back_width_so_far = Distance::ZERO;
@ -306,14 +308,28 @@ impl Map {
IntersectionType::StopSign => {
stop_signs.insert(i.id, ControlStopSign::new(&map, i.id));
}
IntersectionType::TrafficSignal => {
traffic_signals.insert(i.id, ControlTrafficSignal::new(&map, i.id, timer));
}
IntersectionType::TrafficSignal => match TurnGroup::for_i(i.id, &map) {
Ok(_) => {
traffic_signals.insert(i.id, ControlTrafficSignal::new(&map, i.id, timer));
}
Err(err) => {
timer.error(format!(
"Traffic signal at {} downgraded to stop sign because of weird \
problem: {}",
i.orig_id, err
));
stop_signs.insert(i.id, ControlStopSign::new(&map, i.id));
}
},
IntersectionType::Border | IntersectionType::Construction => {}
};
}
map.stop_signs = stop_signs;
map.traffic_signals = traffic_signals;
// Fix up the type for any problematic traffic signals
for i in map.stop_signs.keys() {
map.intersections[i.0].intersection_type = IntersectionType::StopSign;
}
traffic_signals::synchronize(&mut map);

View File

@ -70,7 +70,7 @@ fn new(id: IntersectionID, map: &Map) -> ControlTrafficSignal {
id,
phases: Vec::new(),
offset: Duration::ZERO,
turn_groups: TurnGroup::for_i(id, map),
turn_groups: TurnGroup::for_i(id, map).unwrap(),
}
}
@ -428,6 +428,7 @@ fn make_phases(
pub fn brute_force(map: &Map, i: IntersectionID) {
let turn_groups: Vec<TurnGroup> = TurnGroup::for_i(i, map)
.unwrap()
.into_iter()
.filter_map(|(id, tg)| if id.crosswalk { None } else { Some(tg) })
.collect();

View File

@ -306,7 +306,7 @@ impl ControlTrafficSignal {
id,
phases,
offset: Duration::seconds(raw.offset_seconds as f64),
turn_groups: TurnGroup::for_i(id, map),
turn_groups: TurnGroup::for_i(id, map).unwrap(),
}
.validate()
}

View File

@ -197,7 +197,10 @@ pub struct TurnGroup {
}
impl TurnGroup {
pub(crate) fn for_i(i: IntersectionID, map: &Map) -> BTreeMap<TurnGroupID, TurnGroup> {
pub(crate) fn for_i(
i: IntersectionID,
map: &Map,
) -> Result<BTreeMap<TurnGroupID, TurnGroup>, Box<dyn Error>> {
let mut results = BTreeMap::new();
let mut groups: MultiMap<(DirectedRoadID, DirectedRoadID), TurnID> = MultiMap::new();
for turn in map.get_turns_in_intersection(i) {
@ -233,11 +236,7 @@ impl TurnGroup {
members.iter().map(|t| &map.get_t(*t).geom).collect(),
from,
to,
)
.expect(&format!(
"Weird turn group geometry near {}",
map.get_i(i).orig_id
));
)?;
let turn_types: BTreeSet<TurnType> =
members.iter().map(|t| map.get_t(*t).turn_type).collect();
if turn_types.len() > 1 {
@ -265,9 +264,11 @@ impl TurnGroup {
);
}
if results.is_empty() {
panic!("{} has no TurnGroups!", map.get_i(i).orig_id);
return Err(
format!("No TurnGroups! Does the intersection have at least 2 roads?").into(),
);
}
results
Ok(results)
}
// Polyline points FROM intersection