some right (by angle) turns cross roads; those should be straight turns

This commit is contained in:
Dustin Carlino 2019-10-23 14:37:00 -07:00
parent 5784a389c1
commit d8b11ca10e
2 changed files with 49 additions and 16 deletions

View File

@ -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

View File

@ -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<Lane>,
timer: &mut Timer,
) -> Vec<Turn> {
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<LaneType> = 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<LaneID
.collect()
}
fn make_vehicle_turn(lanes: &Vec<Lane>, i: IntersectionID, l1: LaneID, l2: LaneID) -> Option<Turn> {
fn make_vehicle_turn(
lanes: &Vec<Lane>,
i: IntersectionID,
l1: LaneID,
l2: LaneID,
turn_type: TurnType,
) -> Option<Turn> {
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;