diff --git a/map_gui/src/render/car.rs b/map_gui/src/render/car.rs index 258f89cca8..d1ee94f48f 100644 --- a/map_gui/src/render/car.rs +++ b/map_gui/src/render/car.rs @@ -110,7 +110,7 @@ impl DrawCar { if let Some(t) = input.waiting_for_turn { match map.get_t(t).turn_type { - TurnType::Left => { + TurnType::Left | TurnType::UTurn => { let (pos, angle) = input .body .must_dist_along(input.body.length() - Distance::meters(2.5)); diff --git a/map_gui/src/tools/turn_explorer.rs b/map_gui/src/tools/turn_explorer.rs index aa4172b215..32cedb69a5 100644 --- a/map_gui/src/tools/turn_explorer.rs +++ b/map_gui/src/tools/turn_explorer.rs @@ -162,6 +162,11 @@ impl TurnExplorer { TurnExplorer::color_turn_type(TurnType::Left), "left turn", )); + col.push(ColorLegend::row( + ctx, + TurnExplorer::color_turn_type(TurnType::UTurn), + "U-turn", + )); } } else { let (lt, lc, slow_lane) = turns[idx - 1].penalty(app.map()); @@ -194,6 +199,7 @@ impl TurnExplorer { TurnType::Straight => Color::BLUE, TurnType::Right => Color::GREEN, TurnType::Left => Color::RED, + TurnType::UTurn => Color::PURPLE, } } } diff --git a/map_model/src/make/merge_intersections.rs b/map_model/src/make/merge_intersections.rs index 1376a17383..bcecd631bb 100644 --- a/map_model/src/make/merge_intersections.rs +++ b/map_model/src/make/merge_intersections.rs @@ -1,8 +1,13 @@ -use crate::raw::{OriginalRoad, RawMap}; +use std::collections::BTreeSet; + +use crate::osm::NodeID; +use crate::raw::RawMap; + +/// Merge tiny "roads" that're actually just part of a complicated intersection. Returns all +/// surviving intersections adjacent to one of these merged roads. +pub fn merge_short_roads(map: &mut RawMap) -> BTreeSet { + let mut merged = BTreeSet::new(); -/// Experimentally try to merge tiny "roads" that're actually just part of a complicated -/// intersection. -pub fn merge_short_roads(map: &mut RawMap) { // An expensive fixed-point approach. When we merge one road, the IDs of some other roads might // change, so it's simplest just to start over. // TODO But since merge_short_road tells us what road IDs were deleted and created, it wouldn't @@ -11,13 +16,9 @@ pub fn merge_short_roads(map: &mut RawMap) { let mut changes = false; for (id, road) in &map.roads { // See https://wiki.openstreetmap.org/wiki/Proposed_features/junction%3Dintersection - // Hardcoding some Montlake intersections to test - if road.osm_tags.is("junction", "intersection") - || *id == OriginalRoad::new(459084309, (4550007325, 4550007326)) - || *id == OriginalRoad::new(332060258, (3391701875, 1635790583)) - { + if road.osm_tags.is("junction", "intersection") { let id = *id; - map.merge_short_road(id).unwrap(); + merged.insert(map.merge_short_road(id).unwrap().0); changes = true; break; } @@ -26,4 +27,6 @@ pub fn merge_short_roads(map: &mut RawMap) { break; } } + + merged } diff --git a/map_model/src/make/mod.rs b/map_model/src/make/mod.rs index 631a00ca6c..93587772a1 100644 --- a/map_model/src/make/mod.rs +++ b/map_model/src/make/mod.rs @@ -36,7 +36,7 @@ impl Map { // Better to defer this and see RawMaps with more debug info in map_editor remove_disconnected::remove_disconnected_roads(&mut raw, timer); - merge_intersections::merge_short_roads(&mut raw); + let merged_intersections = merge_intersections::merge_short_roads(&mut raw); timer.start("raw_map to InitialMap"); let gps_bounds = raw.gps_bounds.clone(); @@ -88,6 +88,7 @@ impl Map { incoming_lanes: Vec::new(), outgoing_lanes: Vec::new(), roads: i.roads.iter().map(|id| road_id_mapping[id]).collect(), + merged: merged_intersections.contains(&i.id), }); intersection_id_mapping.insert(i.id, id); } diff --git a/map_model/src/make/turns.rs b/map_model/src/make/turns.rs index 7d8d7bcbb0..c15bca438a 100644 --- a/map_model/src/make/turns.rs +++ b/map_model/src/make/turns.rs @@ -93,6 +93,20 @@ pub fn make_all_turns(map: &Map, i: &Intersection, timer: &mut Timer) -> Vec = HashSet::new(); for l in &i.outgoing_lanes { if map.get_l(*l).lane_type.supports_any_movement() { @@ -373,6 +387,8 @@ fn turn_type_from_angles(from: Angle, to: Angle) -> TurnType { // some observed cases. if diff.abs() < 30.0 { TurnType::Straight + } else if diff.abs() > 135.0 { + TurnType::UTurn } else if diff < 0.0 { // Clockwise rotation TurnType::Right diff --git a/map_model/src/objects/intersection.rs b/map_model/src/objects/intersection.rs index 6d73f03226..779b46bdbe 100644 --- a/map_model/src/objects/intersection.rs +++ b/map_model/src/objects/intersection.rs @@ -54,6 +54,9 @@ pub struct Intersection { // TODO Maybe DirectedRoadIDs pub roads: BTreeSet, + + /// Was a short road adjacent to this intersection merged? + pub merged: bool, } impl Intersection { diff --git a/map_model/src/objects/turn.rs b/map_model/src/objects/turn.rs index 0634863258..be3548704b 100644 --- a/map_model/src/objects/turn.rs +++ b/map_model/src/objects/turn.rs @@ -33,6 +33,7 @@ pub enum TurnType { Straight, Right, Left, + UTurn, } // TODO This concept may be dated, now that Movements exist. Within a movement, the lane-changing