diff --git a/data/screenshots/montlake/MANIFEST b/data/screenshots/montlake/MANIFEST index 63b15283ff..556f7c3502 100644 --- a/data/screenshots/montlake/MANIFEST +++ b/data/screenshots/montlake/MANIFEST @@ -3,10 +3,10 @@ e1a6e14f3b585a99d70f4d3d9afc97ea ../data/screenshots/pending_montlake/01x01_i52 b3cf25e0c4382a7c91f8a12c5abfc023 ../data/screenshots/pending_montlake/03x01_i0.png f2c7083a2e0e2a6039f0ce3fc75823b0 ../data/screenshots/pending_montlake/01x02_i7.png 1af3029a2c2c64af9568760ada59c9f5 ../data/screenshots/pending_montlake/02x02_i125.png -c4b0cf4d2389d9f1d4dbad1a3f95adce ../data/screenshots/pending_montlake/03x02_i30.png +7a2f0c56b2dbb2997da807b90dab3566 ../data/screenshots/pending_montlake/03x02_i30.png 75c7bba069f59f245d05c79588891538 ../data/screenshots/pending_montlake/01x03_i96.png 96a8b52e299032c187ff395bf96e3a54 ../data/screenshots/pending_montlake/02x03_i5.png -c25dd6296e4b034fa971909b028116eb ../data/screenshots/pending_montlake/03x03_i13.png +392f6158d97402eb7eb8d349591cc384 ../data/screenshots/pending_montlake/03x03_i13.png 615e04c96503dc3a0eec27ae1b9e953e ../data/screenshots/pending_montlake/01x04_i3.png 515cbe5b6ad4545f5771dd7f9cee297e ../data/screenshots/pending_montlake/02x04_i26.png 24cfe9e237b59ba7ef61d7348bd6a683 ../data/screenshots/pending_montlake/03x04_i12.png @@ -15,7 +15,7 @@ bb7b19d3ec9435ded8a5f00a2c4ad04d ../data/screenshots/pending_montlake/01x05_i41 20744688172dfca19683a621438b6825 ../data/screenshots/pending_montlake/03x05_i20.png 96108b40fb32b44ab64cf569941e5faf ../data/screenshots/pending_montlake/01x06_i11.png d66a4f0e23bd6662201ddad433476e73 ../data/screenshots/pending_montlake/02x06_i9.png -75bb186a8bee1eae263a6085ee20a7ba ../data/screenshots/pending_montlake/03x06_i16.png +9641d727daf589de64923cd4296e0a13 ../data/screenshots/pending_montlake/03x06_i16.png 228d874db835c89248966a4eda679465 ../data/screenshots/pending_montlake/01x07_i103.png ddbd185ea6e662c014be4b35b101a29c ../data/screenshots/pending_montlake/02x07_i18.png -50e1b4fb5206edbeed33c44a9c3f7765 ../data/screenshots/pending_montlake/03x07_i17.png +fc0041b2f79218a9bb9d7e879564886c ../data/screenshots/pending_montlake/03x07_i17.png diff --git a/map_model/src/make/turns.rs b/map_model/src/make/turns.rs index b206b59ba3..eb81c8e977 100644 --- a/map_model/src/make/turns.rs +++ b/map_model/src/make/turns.rs @@ -3,7 +3,7 @@ use crate::{ Intersection, IntersectionID, Lane, LaneID, LaneType, Road, RoadID, Turn, TurnID, TurnType, LANE_THICKNESS, }; -use abstutil::{Timer, Warn}; +use abstutil::{wraparound_get, Timer, Warn}; use geom::{Distance, Line, PolyLine, Pt2D}; use nbez::{Bez3o, BezCurve, Point2d}; use std::collections::{BTreeSet, HashMap, HashSet}; @@ -107,9 +107,13 @@ fn make_vehicle_turns( lanes: &Vec, timer: &mut Timer, ) -> Vec { - let roads: Vec<&Road> = i.roads.iter().map(|r| &all_roads[r.0]).collect(); + let sorted_roads: Vec<&Road> = i + .get_roads_sorted_by_incoming_angle(all_roads) + .iter() + .map(|r| &all_roads[r.0]) + .collect(); let mut lane_types: BTreeSet = BTreeSet::new(); - for r in &roads { + for r in &sorted_roads { let (t1, t2) = r.get_lane_types(); for lt in t1.into_iter().chain(t2.into_iter()) { lane_types.insert(lt); @@ -128,7 +132,7 @@ fn make_vehicle_turns( continue; } - for r1 in &roads { + for (idx1, r1) in sorted_roads.iter().enumerate() { // We can't filter incoming just on the preferred type, because we might be forced to // make a turn from a driving lane to a bike/bus lane. let incoming = filter_vehicle_lanes(r1.incoming_lanes(i.id), lane_type); @@ -139,7 +143,7 @@ fn make_vehicle_turns( let mut maybe_add_turns = Vec::new(); let mut all_incoming_lanes_covered = false; - for r2 in &roads { + for r2 in &sorted_roads { if r1.id == r2.id { continue; } @@ -160,7 +164,22 @@ fn make_vehicle_turns( let angle1 = lanes[incoming[0].0].last_line().angle(); let angle2 = lanes[outgoing[0].0].first_line().angle(); - match TurnType::from_angles(angle1, angle2) { + let type_from_angle = TurnType::from_angles(angle1, angle2); + let tt = if type_from_angle == TurnType::Right { + // This one's fragile, based on angles. Really we care that there aren't roads + // between the two. + if wraparound_get(&sorted_roads, (idx1 as isize) - 1).id == r2.id + || wraparound_get(&sorted_roads, (idx1 as isize) + 1).id == r2.id + { + TurnType::Right + } else { + TurnType::Straight + } + } else { + type_from_angle + }; + + match tt { TurnType::Straight => { // Cartesian product. Additionally detect where the lane-changing movements // happen. But we have to use the indices assuming all travel lanes, not @@ -193,7 +212,7 @@ fn make_vehicle_turns( if !incoming.contains(&l1) || !outgoing.contains(l2) { continue; } - if let Some(mut t) = make_vehicle_turn(lanes, i.id, l1, *l2) { + if let Some(mut t) = make_vehicle_turn(lanes, i.id, l1, *l2, tt) { if idx1 < idx2 { t.turn_type = TurnType::LaneChangeRight; } else if idx1 > idx2 { @@ -208,7 +227,7 @@ fn make_vehicle_turns( TurnType::Right => { for (idx, l1) in incoming.iter().enumerate() { for l2 in &outgoing { - let turn = make_vehicle_turn(lanes, i.id, *l1, *l2); + let turn = make_vehicle_turn(lanes, i.id, *l1, *l2, tt); if idx == incoming.len() - 1 { result.push(turn); } else { @@ -220,7 +239,7 @@ fn make_vehicle_turns( TurnType::Left => { for (idx, l1) in incoming.iter().enumerate() { for l2 in &outgoing { - let turn = make_vehicle_turn(lanes, i.id, *l1, *l2); + let turn = make_vehicle_turn(lanes, i.id, *l1, *l2, tt); if idx == 0 { result.push(turn); } else { @@ -258,7 +277,16 @@ fn make_vehicle_turns_for_dead_end( let mut result = Vec::new(); for l1 in incoming { for l2 in &outgoing { - result.push(make_vehicle_turn(lanes, i.id, l1, *l2)); + result.push(make_vehicle_turn( + lanes, + i.id, + l1, + *l2, + TurnType::from_angles( + lanes[l1.0].last_line().angle(), + lanes[l2.0].first_line().angle(), + ), + )); } } @@ -521,10 +549,15 @@ fn filter_lanes(lanes: &Vec<(LaneID, LaneType)>, filter: LaneType) -> Vec, i: IntersectionID, l1: LaneID, l2: LaneID) -> Option { +fn make_vehicle_turn( + lanes: &Vec, + i: IntersectionID, + l1: LaneID, + l2: LaneID, + turn_type: TurnType, +) -> Option { let src = &lanes[l1.0]; let dst = &lanes[l2.0]; - let turn_type = TurnType::from_angles(src.last_line().angle(), dst.first_line().angle()); if src.last_pt().epsilon_eq(dst.first_pt()) { return None;