mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 12:12:00 +03:00
Explicitly model U-turns. Sometimes they're legal, often they get
generated incorrectly, but regardless, calling them TurnType::Left is just confusing. For the moment, always filter out U-turns from merged intersections. When connections across merged one-ways are handled properly, we won't need this, but in the meantime, it moves forward. #114 Not regenerating just yet, but will bundle it with the next commit.
This commit is contained in:
parent
de4b026920
commit
9bc761f98e
@ -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));
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<NodeID> {
|
||||
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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -93,6 +93,20 @@ pub fn make_all_turns(map: &Map, i: &Intersection, timer: &mut Timer) -> Vec<Tur
|
||||
final_turns = remove_merging_turns(map, final_turns, TurnType::Right);
|
||||
final_turns = remove_merging_turns(map, final_turns, TurnType::Left);
|
||||
|
||||
if i.merged {
|
||||
final_turns.retain(|turn| {
|
||||
if turn.turn_type == TurnType::UTurn {
|
||||
timer.warn(format!(
|
||||
"Removing u-turn from merged intersection: {}",
|
||||
turn.id
|
||||
));
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let mut outgoing_missing: HashSet<LaneID> = 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
|
||||
|
@ -54,6 +54,9 @@ pub struct Intersection {
|
||||
|
||||
// TODO Maybe DirectedRoadIDs
|
||||
pub roads: BTreeSet<RoadID>,
|
||||
|
||||
/// Was a short road adjacent to this intersection merged?
|
||||
pub merged: bool,
|
||||
}
|
||||
|
||||
impl Intersection {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user