From 2e41b2284e953301aa26b24601d7fbe3e004c667 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Thu, 4 Jul 2019 18:55:55 -0500 Subject: [PATCH] use the turn restriction data to filter more turns --- data/screenshots/montlake/MANIFEST | 10 +++--- editor/src/debug/objects.rs | 6 ++++ map_model/src/make/half_map.rs | 23 ++++++++++++++ map_model/src/make/turns.rs | 49 ++++++++++++++++++++++++++++-- map_model/src/map.rs | 24 --------------- map_model/src/road.rs | 2 ++ 6 files changed, 83 insertions(+), 31 deletions(-) diff --git a/data/screenshots/montlake/MANIFEST b/data/screenshots/montlake/MANIFEST index 4e22fd1cfe..a3918ca351 100644 --- a/data/screenshots/montlake/MANIFEST +++ b/data/screenshots/montlake/MANIFEST @@ -1,21 +1,21 @@ 3f52c25aa91b0f59a2e89f0a77cd650b ../data/screenshots/pending_montlake/01x01_i63.png 1c0914c0325afa86300e1ae099b7318b ../data/screenshots/pending_montlake/02x01_i6.png -f6dec828838f2e0d1e68f9fd5c7bda77 ../data/screenshots/pending_montlake/03x01_i4.png +75f0d752358e3be545f02cf7d3d5ef8b ../data/screenshots/pending_montlake/03x01_i4.png 2a4b431b1e4ca26c9d57bef23484703f ../data/screenshots/pending_montlake/01x02_i14.png 0f590ee6c6f030ba6d03bcaf033ade3e ../data/screenshots/pending_montlake/02x02_i142.png -4d11d4c860340189dbd82fbd721e7447 ../data/screenshots/pending_montlake/03x02_i43.png +f51c42108c832e689d4483d3127b536c ../data/screenshots/pending_montlake/03x02_i43.png 5eb6a8833532b1fbd2cc1a3c5e4f9005 ../data/screenshots/pending_montlake/01x03_i109.png ee918e6b57ac2ce07df175f228dda316 ../data/screenshots/pending_montlake/02x03_i10.png -ec8dfea00318efff1590f7ca837015ba ../data/screenshots/pending_montlake/03x03_i21.png +dc28ff4fe186e2c54b6f7cfa2af1aff4 ../data/screenshots/pending_montlake/03x03_i21.png 477ab2de1f55ed3f16e71c034f2783ee ../data/screenshots/pending_montlake/01x04_i8.png -af0fe85afcade470782e1843def22081 ../data/screenshots/pending_montlake/02x04_i0.png +f1cee50c0585b9dec1f1c366a22dd8d1 ../data/screenshots/pending_montlake/02x04_i0.png 91efe051fbc190f4da79bc48560bfa4b ../data/screenshots/pending_montlake/03x04_i20.png 389124ee2a87a2566d141622a7e73311 ../data/screenshots/pending_montlake/01x05_i53.png 48306f1c0424ae23fd505a02bbf879eb ../data/screenshots/pending_montlake/02x05_i51.png 9cd2082dcb1a5085b0c4b0ceadd569d9 ../data/screenshots/pending_montlake/03x05_i29.png fb5bebac24bd173c80475027dfea358a ../data/screenshots/pending_montlake/01x06_i18.png 44421735e045b5608d363c65973c4bf0 ../data/screenshots/pending_montlake/02x06_i16.png -cfe42a449b6fd5a7fbb8284fef7fc27c ../data/screenshots/pending_montlake/03x06_i1.png +6e884150f8ad30bae05e17adaa6a91a5 ../data/screenshots/pending_montlake/03x06_i1.png 47653ef12e3755353b6742c3858ac983 ../data/screenshots/pending_montlake/01x07_i119.png d5f14bb92e76aac680046b1de4610b2a ../data/screenshots/pending_montlake/02x07_i27.png ab473f663181bd57f42702ad210613bf ../data/screenshots/pending_montlake/03x07_i59.png diff --git a/editor/src/debug/objects.rs b/editor/src/debug/objects.rs index 9d82d7fadf..02400b2308 100644 --- a/editor/src/debug/objects.rs +++ b/editor/src/debug/objects.rs @@ -158,6 +158,12 @@ fn tooltip_lines(id: ID, g: &mut GfxCtx, ctx: &PerMapUI) -> Text { if let Some(types) = l.get_turn_restrictions(r) { txt.add_line(format!("Turn restriction for this lane: {:?}", types)); } + for (restriction, to) in &r.turn_restrictions { + txt.add_line(format!( + "Restriction from this road to {}: {}", + to, restriction + )); + } } ID::Intersection(id) => { txt.add_line(id.to_string()); diff --git a/map_model/src/make/half_map.rs b/map_model/src/make/half_map.rs index fa7a9feea9..61adc6434e 100644 --- a/map_model/src/make/half_map.rs +++ b/map_model/src/make/half_map.rs @@ -75,6 +75,7 @@ pub fn make_half_map( let mut road = Road { id: road_id, osm_tags: r.osm_tags.clone(), + turn_restrictions: Vec::new(), osm_way_id, stable_id: r.id, children_forwards: Vec::new(), @@ -132,6 +133,28 @@ pub fn make_half_map( half_map.roads.push(road); } + let mut filtered_restrictions = Vec::new(); + for r in &half_map.roads { + if let Some(restrictions) = data.turn_restrictions.get(&r.osm_way_id) { + for (restriction, to) in restrictions { + // Make sure the restriction actually applies to this road. + if let Some(to_road) = half_map.intersections[r.src_i.0] + .roads + .iter() + .chain(half_map.intersections[r.dst_i.0].roads.iter()) + .find(|r| half_map.roads[r.0].osm_way_id == *to) + { + filtered_restrictions.push((r.id, restriction, to_road)); + } + } + } + } + for (from, restriction, to) in filtered_restrictions { + half_map.roads[from.0] + .turn_restrictions + .push((restriction.to_string(), *to)); + } + for i in half_map.intersections.iter_mut() { if is_border(i, &half_map.lanes) { i.intersection_type = IntersectionType::Border; diff --git a/map_model/src/make/turns.rs b/map_model/src/make/turns.rs index 86a0978a5e..a0a9aa5a24 100644 --- a/map_model/src/make/turns.rs +++ b/map_model/src/make/turns.rs @@ -1,6 +1,6 @@ use crate::{ - Intersection, IntersectionID, IntersectionType, Lane, LaneID, LaneType, Road, Turn, TurnID, - TurnType, LANE_THICKNESS, + Intersection, IntersectionID, IntersectionType, Lane, LaneID, LaneType, Road, RoadID, Turn, + TurnID, TurnType, LANE_THICKNESS, }; use abstutil::{Timer, Warn}; use geom::{Distance, Line, PolyLine, Pt2D}; @@ -25,6 +25,10 @@ pub fn make_all_turns( let mut final_turns: Vec = Vec::new(); let mut filtered_turns: HashMap> = HashMap::new(); for turn in unique_turns { + if !does_turn_pass_restrictions(&turn, &i.roads, roads, lanes) { + continue; + } + if is_turn_allowed(&turn, roads, lanes) { final_turns.push(turn); } else { @@ -497,3 +501,44 @@ fn is_turn_allowed(turn: &Turn, roads: &Vec, lanes: &Vec) -> bool { true } } + +fn does_turn_pass_restrictions( + turn: &Turn, + intersection_roads: &BTreeSet, + roads: &Vec, + lanes: &Vec, +) -> bool { + if turn.between_sidewalks() { + return true; + } + + let src = lanes[turn.id.src.0].parent; + let dst = lanes[turn.id.dst.0].parent; + + for (restriction, to) in &roads[src.0].turn_restrictions { + // The restriction only applies to one direction of the road. + if !intersection_roads.contains(to) { + continue; + } + + // Ignore the TurnType. Between two roads, there's only one category of TurnType (treating + // Straight/LaneChangeLeft/LaneChangeRight as the same). + // + // Strip off time restrictions (like " @ (Mo-Fr 06:00-09:00, 15:00-18:30)") + match restriction.split(" @ ").next().unwrap() { + "no_left_turn" | "no_right_turn" | "no_straight_on" | "no_u_turn" => { + if dst == *to { + return false; + } + } + "only_left_turn" | "only_right_turn" | "only_straight_on" => { + if dst != *to { + return false; + } + } + _ => panic!("Unknown restriction {}", restriction), + } + } + + true +} diff --git a/map_model/src/map.rs b/map_model/src/map.rs index 5ff7dfcede..24855f91d7 100644 --- a/map_model/src/map.rs +++ b/map_model/src/map.rs @@ -119,30 +119,6 @@ impl Map { edits: MapEdits::new(name), }; - // TODO Temporary to debug turn restrictions. - let mut filtered_restrictions = Vec::new(); - for r in &m.roads { - if let Some(restrictions) = data.turn_restrictions.get(&r.osm_way_id) { - for (restriction, to) in restrictions { - // Make sure the restriction actually applies to this road. - if let Some(to_road) = m.intersections[r.src_i.0] - .roads - .iter() - .chain(m.intersections[r.dst_i.0].roads.iter()) - .find(|r| m.roads[r.0].osm_way_id == *to) - { - filtered_restrictions.push((r.id, restriction, to_road)); - } - } - } - } - for (idx, (from, restriction, to)) in filtered_restrictions.into_iter().enumerate() { - m.roads[from.0].osm_tags.insert( - format!("turn_restriction_{}", idx), - format!("{} to {}", restriction, to), - ); - } - // Extra setup that's annoying to do as HalfMap, since we want to pass around a Map. { let mut stop_signs: BTreeMap = BTreeMap::new(); diff --git a/map_model/src/road.rs b/map_model/src/road.rs index 5f57784726..4fe33c3e3a 100644 --- a/map_model/src/road.rs +++ b/map_model/src/road.rs @@ -57,6 +57,8 @@ impl fmt::Display for DirectedRoadID { pub struct Road { pub id: RoadID, pub osm_tags: BTreeMap, + // self is 'from' + pub turn_restrictions: Vec<(String, RoadID)>, pub osm_way_id: i64, pub stable_id: raw_data::StableRoadID,