Get rid of the now redundant lanes_ltr

This commit is contained in:
Dustin Carlino 2021-09-05 17:41:18 -07:00
parent 4c46510342
commit 112bc38e0c
29 changed files with 143 additions and 153 deletions

View File

@ -93,10 +93,9 @@ impl Isochrone {
let mut onstreet_parking_spots = 0;
for r in all_roads {
let r = app.map.get_r(r);
for (l, _, lt) in r.lanes_ltr() {
if lt == LaneType::Parking {
onstreet_parking_spots +=
app.map.get_l(l).number_parking_spots(app.map.get_config());
for l in &r.lanes {
if l.lane_type == LaneType::Parking {
onstreet_parking_spots += l.number_parking_spots(app.map.get_config());
}
}
}

View File

@ -579,8 +579,10 @@ pub fn draw_unwalkable_roads(ctx: &mut EventCtx, app: &App, opts: &Options) -> D
if road.is_light_rail() {
continue;
}
for (_, _, lt) in road.lanes_ltr() {
if lt == LaneType::Sidewalk || (lt == LaneType::Shoulder && allow_shoulders) {
for l in &road.lanes {
if l.lane_type == LaneType::Sidewalk
|| (l.lane_type == LaneType::Shoulder && allow_shoulders)
{
continue 'ROADS;
}
}

View File

@ -183,7 +183,7 @@ fn inner_warp_to_id(ctx: &mut EventCtx, app: &mut App, line: &str) -> Option<Tra
Ok(idx) => match line.chars().next().unwrap() {
'r' => {
let r = app.primary.map.maybe_get_r(RoadID(idx))?;
ID::Lane(r.lanes_ltr()[0].0)
ID::Lane(r.lanes[0].id)
}
'R' => {
let r = BusRouteID(idx);

View File

@ -784,8 +784,8 @@ impl ContextualActions for Actions {
if let Some((dist, _)) = pl.dist_along_of_point(pl.project_pt(pt)) {
let base_pos = Position::new(l, dist);
let mut batch = GeomBatch::new();
for (l, _, _) in map.get_parent(l).lanes_ltr() {
let pt = base_pos.equiv_pos(l, map).pt(map);
for l in &map.get_parent(l).lanes {
let pt = base_pos.equiv_pos(l.id, map).pt(map);
batch.push(
Color::RED,
Circle::new(pt, Distance::meters(1.0)).to_polygon(),
@ -891,14 +891,14 @@ fn find_degenerate_roads(app: &App) {
continue;
}
if r1
.lanes_ltr()
.into_iter()
.map(|(_, dir, lt)| (dir, lt))
.lanes
.iter()
.map(|l| (l.dir, l.lane_type))
.collect::<Vec<_>>()
!= r2
.lanes_ltr()
.into_iter()
.map(|(_, dir, lt)| (dir, lt))
.lanes
.iter()
.map(|l| (l.dir, l.lane_type))
.collect::<Vec<_>>()
{
continue;

View File

@ -35,11 +35,11 @@ fn road(id: RoadID, map: &Map) -> Feature {
properties.insert("sharedstreetid".to_string(), id.0.into());
let mut slices = Vec::new();
for (l, dir, _) in r.lanes_ltr() {
if let Some(mut slice) = lane(map.get_l(l)) {
for l in &r.lanes {
if let Some(mut slice) = lane(l) {
slice
.entry("direction".to_string())
.or_insert(if dir == Direction::Fwd {
.or_insert(if l.dir == Direction::Fwd {
"forward".into()
} else {
"reverse".into()

View File

@ -15,8 +15,8 @@ fn road(id: RoadID, map: &Map) -> serde_json::Map<String, serde_json::value::Val
// TODO Many more fields
let mut segments = Vec::new();
for (l, dir, _) in r.lanes_ltr() {
segments.push(serde_json::value::Value::Object(lane(map.get_l(l), dir)));
for l in &r.lanes {
segments.push(serde_json::value::Value::Object(lane(l, l.dir)));
}
street.insert(
"segments".to_string(),

View File

@ -80,7 +80,7 @@ impl RoadEditor {
}
fn lane_for_idx(&self, app: &App, idx: usize) -> LaneID {
app.primary.map.get_r(self.r).lanes_ltr()[idx].0
app.primary.map.get_r(self.r).lanes[idx].id
}
fn modify_current_lane<F: Fn(&mut EditRoad, usize)>(
@ -316,9 +316,9 @@ impl State<App> for RoadEditor {
.primary
.map
.get_r(self.r)
.lanes_ltr()
.into_iter()
.all(|(_, _, lt)| lt != LaneType::Driving)
.lanes
.iter()
.all(|l| l.lane_type != LaneType::Driving)
{
return Transition::Push(PopupMsg::new_state(ctx, "Error", vec!["Add a driving lane first. Parking can't exist without a way to access it."]));
}
@ -553,7 +553,7 @@ fn make_main_panel(
let current_lt = selected_lane.map(|l| map.get_l(l).lane_type);
let current_lts: Vec<LaneType> = road.lanes_ltr().into_iter().map(|(_, _, lt)| lt).collect();
let current_lts: Vec<LaneType> = road.lanes.iter().map(|l| l.lane_type).collect();
let lane_types = [
(LaneType::Driving, Some(Key::D)),
@ -628,10 +628,13 @@ fn make_main_panel(
let mut drag_drop = DragDrop::new(ctx, "lane cards", StackAxis::Horizontal);
let road_width = road.get_width();
let lanes_ltr = road.lanes_ltr();
let lanes_len = lanes_ltr.len();
for (idx, (id, dir, lt)) in lanes_ltr.into_iter().enumerate() {
for l in &road.lanes {
let idx = l.id.offset;
let id = l.id;
let dir = l.dir;
let lt = l.lane_type;
let mut icon_stack = GeomBatchStack::vertical(vec![
Image::from_path(lane_type_to_icon(lt).unwrap())
.dims((60.0, 50.0))
@ -664,7 +667,7 @@ fn make_main_panel(
if idx == 0 {
rounding.top_left = DEFAULT_CORNER_RADIUS;
}
if idx == lanes_len - 1 {
if idx == road.lanes.len() - 1 {
rounding.top_right = DEFAULT_CORNER_RADIUS;
}
@ -786,7 +789,7 @@ fn make_main_panel(
ctx.style()
.btn_solid_destructive
.icon("system/assets/tools/trash.svg")
.disabled(road.lanes_ltr().len() == 1)
.disabled(road.lanes.len() == 1)
.hotkey(Key::Backspace)
.build_widget(ctx, "delete lane")
.centered_vert(),
@ -1010,8 +1013,8 @@ fn draw_drop_position(app: &App, r: RoadID, from: usize, to: usize) -> GeomBatch
let map = &app.primary.map;
let road = map.get_r(r);
let take_num = if from < to { to + 1 } else { to };
for (l, _, _) in road.lanes_ltr().into_iter().take(take_num) {
width += map.get_l(l).width;
for l in road.lanes.iter().take(take_num) {
width += l.width;
}
if let Ok(pl) = road.get_left_side().shift_right(width) {
batch.push(app.cs.selected, pl.make_polygons(OUTLINE_THICKNESS));

View File

@ -226,14 +226,14 @@ impl Snapper {
let mut incoming_pts = Vec::new();
let mut outgoing_pts = Vec::new();
for (l, dir, lt) in r.lanes_ltr() {
if lt.is_walkable() {
for l in &r.lanes {
if l.lane_type.is_walkable() {
continue;
}
if dir == incoming_id.dir {
incoming_pts.push(map.get_l(l).lane_center_pts.last_pt());
if l.dir == incoming_id.dir {
incoming_pts.push(l.lane_center_pts.last_pt());
} else {
outgoing_pts.push(map.get_l(l).lane_center_pts.first_pt());
outgoing_pts.push(l.lane_center_pts.first_pt());
}
}

View File

@ -94,9 +94,9 @@ impl BikeActivity {
.primary
.map
.get_r(*r)
.lanes_ltr()
.into_iter()
.any(|(_, _, lt)| lt == LaneType::Biking)
.lanes
.iter()
.any(|l| l.lane_type == LaneType::Biking)
{
on_bike_lanes.add(*r, *count);
} else {

View File

@ -1062,16 +1062,16 @@ impl TutorialState {
))
.unwrap(),
);
assert_eq!(r.lanes_ltr().len(), 6);
r.lanes_ltr()[2].0
assert_eq!(r.lanes.len(), 6);
r.lanes[2].id
};
let lane_near_bldg = {
let r = map.get_r(
map.find_r_by_osm_id(OriginalRoad::new(6484869, (53163501, 53069236)))
.unwrap(),
);
assert_eq!(r.lanes_ltr().len(), 6);
r.lanes_ltr()[3].0
assert_eq!(r.lanes.len(), 6);
r.lanes[3].id
};
let mut scenario = Scenario::empty(map, "prank");

View File

@ -61,10 +61,10 @@ impl DrawNetworkLayer {
for r in map.all_roads() {
let mut bike_lane = false;
let mut buffer = false;
for (_, _, lt) in r.lanes_ltr() {
if lt == LaneType::Biking {
for l in &r.lanes {
if l.lane_type == LaneType::Biking {
bike_lane = true;
} else if matches!(lt, LaneType::Buffer(_)) {
} else if matches!(l.lane_type, LaneType::Buffer(_)) {
buffer = true;
}
}

View File

@ -356,10 +356,10 @@ impl Layers {
let rank = r.get_rank();
let mut bike_lane = false;
let mut buffer = false;
for (_, _, lt) in r.lanes_ltr() {
if lt == LaneType::Biking {
for l in &r.lanes {
if l.lane_type == LaneType::Biking {
bike_lane = true;
} else if matches!(lt, LaneType::Buffer(_)) {
} else if matches!(l.lane_type, LaneType::Buffer(_)) {
buffer = true;
}
}

View File

@ -396,11 +396,11 @@ fn calculate_border_arrows(i: &Intersection, r: &Road, map: &Map) -> Vec<Polygon
let mut width_fwd = Distance::ZERO;
let mut width_back = Distance::ZERO;
for (l, dir, _) in r.lanes_ltr() {
if dir == Direction::Fwd {
width_fwd += map.get_l(l).width;
for l in &r.lanes {
if l.dir == Direction::Fwd {
width_fwd += l.width;
} else {
width_back += map.get_l(l).width;
width_back += l.width;
}
}
let center = r.get_dir_change_pl(map);

View File

@ -281,17 +281,19 @@ fn calculate_parking_lines(lane: &Lane, map: &Map) -> Vec<Polygon> {
// Because the stripe straddles two lanes, it'll be partly hidden on one side. There are a bunch of
// ways to work around this z-order issue. The current approach is to rely on the fact that
// quadtrees return LaneIDs in order, and lanes are always created from left->right.
fn calculate_driving_lines(lane: &Lane, parent: &Road) -> Vec<Polygon> {
let lanes = parent.lanes_ltr();
let idx = parent.offset(lane.id);
fn calculate_driving_lines(lane: &Lane, road: &Road) -> Vec<Polygon> {
let idx = road.offset(lane.id);
// If the lane to the left of us isn't in the same direction or isn't the same type, don't
// need dashed lines.
if idx == 0 || lanes[idx].1 != lanes[idx - 1].1 || lanes[idx].2 != lanes[idx - 1].2 {
if idx == 0
|| lane.dir != road.lanes[idx - 1].dir
|| lane.lane_type != road.lanes[idx - 1].lane_type
{
return Vec::new();
}
let lane_edge_pts = if lanes[idx].1 == Direction::Fwd {
let lane_edge_pts = if lane.dir == Direction::Fwd {
lane.lane_center_pts.must_shift_left(lane.width / 2.0)
} else {
lane.lane_center_pts.must_shift_right(lane.width / 2.0)
@ -359,12 +361,12 @@ fn calculate_turn_markings(map: &Map, lane: &Lane) -> Vec<Polygon> {
results
}
fn calculate_one_way_markings(lane: &Lane, parent: &Road) -> Vec<Polygon> {
fn calculate_one_way_markings(lane: &Lane, road: &Road) -> Vec<Polygon> {
let mut results = Vec::new();
let lanes = parent.lanes_ltr();
if lanes
.into_iter()
.any(|(_, d, lt)| lane.dir != d && lt == LaneType::Driving)
if road
.lanes
.iter()
.any(|l| l.dir != lane.dir && l.lane_type == LaneType::Driving)
{
// Not a one-way
return results;

View File

@ -38,10 +38,12 @@ impl DrawRoad {
// Draw a center line every time two driving/bike/bus lanes of opposite direction are
// adjacent.
let mut width = Distance::ZERO;
for pair in r.lanes_ltr().windows(2) {
let ((l1, dir1, lt1), (_, dir2, lt2)) = (pair[0], pair[1]);
width += app.map().get_l(l1).width;
if dir1 != dir2 && lt1.is_for_moving_vehicles() && lt2.is_for_moving_vehicles() {
for pair in r.lanes.windows(2) {
width += pair[0].width;
if pair[0].dir != pair[1].dir
&& pair[0].lane_type.is_for_moving_vehicles()
&& pair[1].lane_type.is_for_moving_vehicles()
{
let pl = r.get_left_side().must_shift_right(width);
batch.extend(
center_line_color,

View File

@ -119,9 +119,8 @@ pub fn all_walking_costs_from(
let mut shoulder_endpoint = Vec::new();
for q in &queue {
if let WalkingNode::SidewalkEndpoint(dir_r, _) = q.node {
let lanes = &map.get_r(dir_r.id).lanes_ltr;
for (_, _, lane_type) in lanes {
shoulder_endpoint.push(lane_type == &LaneType::Shoulder)
for lane in &map.get_r(dir_r.id).lanes {
shoulder_endpoint.push(lane.lane_type == LaneType::Shoulder);
}
}
}

View File

@ -392,7 +392,7 @@ fn fix_lane_widths(value: &mut Value, map: &Map) -> Result<()> {
dir,
// Before this commit, lane widths weren't modifiable, so this lookup works
// for both "old" and "new".
width: map.get_l(road.lanes_ltr()[idx].0).width,
width: road.lanes[idx].width,
});
}
cmd[key]["lanes_ltr"] = serde_json::to_value(lanes_ltr).unwrap();

View File

@ -326,15 +326,14 @@ impl MapEdits {
{
roads.insert(r.id);
} else {
let lanes_ltr = r.lanes_ltr();
if lanes_ltr.len() != orig.lanes_ltr.len() {
if r.lanes.len() != orig.lanes_ltr.len() {
// If a lane was added or deleted, figuring out if any were modified is kind of
// unclear -- just mark the entire road.
roads.insert(r.id);
} else {
for ((l, dir, lt), spec) in lanes_ltr.into_iter().zip(orig.lanes_ltr.iter()) {
if dir != spec.dir || lt != spec.lt || map.get_l(l).width != spec.width {
lanes.insert(l);
for (l, spec) in r.lanes.iter().zip(orig.lanes_ltr.iter()) {
if l.dir != spec.dir || l.lane_type != spec.lt || l.width != spec.width {
lanes.insert(l.id);
}
}
}

View File

@ -93,7 +93,7 @@ impl PermanentEditCmd {
match self {
PermanentEditCmd::ChangeRoad { r, new, old } => {
let id = map.find_r_by_osm_id(r)?;
let num_current = map.get_r(id).lanes_ltr().len();
let num_current = map.get_r(id).lanes.len();
// The basemap changed -- it'd be pretty hard to understand the original
// intent of the edit.
if num_current != old.lanes_ltr.len() {

View File

@ -15,8 +15,7 @@ pub fn find_medians(map: &Map) -> Vec<Polygon> {
for r in map.all_roads() {
if r.osm_tags.is("dual_carriageway", "yes") {
// TODO Always to the left? Maybe driving side matters; test in southbank too
let lanes_ltr = r.lanes_ltr();
candidates.push(lanes_ltr[0].0);
candidates.push(r.lanes[0].id);
}
}

View File

@ -150,7 +150,6 @@ impl Map {
.collect(),
orig_id: r.id,
lanes: Vec::new(),
lanes_ltr: Vec::new(),
center_pts: r.trimmed_center_pts,
untrimmed_center_pts: raw_road.get_geometry(r.id, map.get_config()).unwrap().0,
src_i: i1,

View File

@ -209,15 +209,15 @@ fn make_walking_turns_v2(map: &Map, i: &Intersection) -> Vec<Turn> {
}
for r in sorted_roads {
let r = map.get_r(r);
let road = map.get_r(r);
let mut fwd = None;
let mut back = None;
for (l, dir, lt) in r.lanes_ltr() {
if lt.is_walkable() {
if dir == Direction::Fwd {
fwd = Some(map.get_l(l));
for l in &road.lanes {
if l.lane_type.is_walkable() {
if l.dir == Direction::Fwd {
fwd = Some(l);
} else {
back = Some(map.get_l(l));
back = Some(l);
}
}
}
@ -227,7 +227,7 @@ fn make_walking_turns_v2(map: &Map, i: &Intersection) -> Vec<Turn> {
if back.is_some() {
num_sidewalks += 1;
}
let (in_lane, out_lane) = if r.src_i == i.id {
let (in_lane, out_lane) = if road.src_i == i.id {
(back, fwd)
} else {
(fwd, back)

View File

@ -23,8 +23,8 @@ const SHOULDER_THICKNESS: Distance = Distance::const_meters(0.5);
/// A lane is identified by its parent road and its position, ordered from the left.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct LaneID {
pub(crate) road: RoadID,
pub(crate) offset: usize,
pub road: RoadID,
pub offset: usize,
}
impl fmt::Display for LaneID {
@ -445,7 +445,7 @@ impl Lane {
let start = self.id;
let mut pts = Vec::new();
let mut current = start;
let mut fwd = map.get_parent(start).lanes_ltr()[0].0 == start;
let mut fwd = map.get_parent(start).lanes[0].id == start;
let mut visited = BTreeSet::new();
loop {
let l = map.get_l(current);
@ -484,9 +484,9 @@ impl Lane {
// Depending on if this road points to or from the intersection, get the left- or
// right-most lane.
let next_lane = if next_road.src_i == i {
next_road.lanes_ltr()[0].0
next_road.lanes[0].id
} else {
next_road.lanes_ltr().last().unwrap().0
next_road.lanes.last().unwrap().id
};
if next_lane == start {
break;

View File

@ -147,10 +147,9 @@ pub struct Road {
/// positive is uphill from src_i -> dst_i, negative is downhill.
pub percent_incline: f64,
/// Invariant: A road must contain at least one child. These are ordered from left-to-right.
/// Invariant: A road must contain at least one child. These are ordered from the left side of
/// the road to the right, with that orientation determined by the direction of `center_pts`.
pub lanes: Vec<Lane>,
// TODO Remove -- this becomes redundant
pub(crate) lanes_ltr: Vec<(LaneID, Direction, LaneType)>,
/// The physical center of the road, including sidewalks, after trimming to account for the
/// intersection geometry. The order implies road orientation.
@ -163,13 +162,6 @@ pub struct Road {
}
impl Road {
/// Returns all lanes from the left side of the road to right. Left/right is determined by the
/// orientation of center_pts.
pub fn lanes_ltr(&self) -> Vec<(LaneID, Direction, LaneType)> {
// TODO Change this to return &Vec
self.lanes_ltr.clone()
}
pub(crate) fn lane_specs(&self) -> Vec<LaneSpec> {
self.lanes
.iter()
@ -188,13 +180,11 @@ impl Road {
/// Counting from the left side of the road
pub fn offset(&self, lane: LaneID) -> usize {
for (idx, (l, _, _)) in self.lanes_ltr().into_iter().enumerate() {
if lane == l {
return idx;
match self.lanes.iter().position(|l| l.id == lane) {
Some(x) => x,
None => panic!("{} doesn't contain {}", self.id, lane),
}
}
panic!("{} doesn't contain {}", self.id, lane);
}
/// lane must belong to this road. Offset 0 is the centermost lane on each side of a road, then
/// it counts up from there. Note this is a different offset than `offset`!
@ -409,11 +399,11 @@ impl Road {
}
pub fn is_light_rail(&self) -> bool {
self.lanes_ltr().len() == 1 && self.lanes_ltr()[0].2 == LaneType::LightRail
self.lanes.len() == 1 && self.lanes[0].lane_type == LaneType::LightRail
}
pub fn is_footway(&self) -> bool {
self.lanes_ltr().len() == 1 && self.lanes_ltr()[0].2 == LaneType::Sidewalk
self.lanes.len() == 1 && self.lanes[0].lane_type == LaneType::Sidewalk
}
pub fn is_service(&self) -> bool {
@ -422,10 +412,10 @@ impl Road {
pub fn is_cycleway(&self) -> bool {
let mut bike = false;
for (_, _, lt) in self.lanes_ltr() {
if lt == LaneType::Biking {
for lane in &self.lanes {
if lane.lane_type == LaneType::Biking {
bike = true;
} else if lt != LaneType::Shoulder {
} else if lane.lane_type != LaneType::Shoulder {
return false;
}
}
@ -509,7 +499,6 @@ impl Road {
pub(crate) fn recreate_lanes(&mut self, lane_specs_ltr: Vec<LaneSpec>) {
self.lanes.clear();
self.lanes_ltr.clear();
let mut total_width = Distance::ZERO;
for lane in &lane_specs_ltr {
@ -548,8 +537,6 @@ impl Road {
};
width_so_far += lane.width;
// TODO Revisit
self.lanes_ltr.push((id, lane.dir, lane.lt));
self.lanes.push(Lane {
id,
lane_center_pts,
@ -570,13 +557,13 @@ impl Road {
pub fn get_lanes_between(&self, l1: LaneID, l2: LaneID) -> Vec<LaneID> {
let mut results = Vec::new();
let mut found_start = false;
for (l, _, _) in self.lanes_ltr() {
for l in &self.lanes {
if found_start {
if l == l1 || l == l2 {
if l.id == l1 || l.id == l2 {
return results;
}
results.push(l);
} else if l == l1 || l == l2 {
results.push(l.id);
} else if l.id == l1 || l.id == l2 {
found_start = true;
}
}
@ -594,11 +581,11 @@ impl Road {
let mut bike_lanes = false;
let mut can_use = false;
// Can a bike even use it, or is it a highway?
for (l, _, lt) in self.lanes_ltr() {
if lt == LaneType::Biking {
for l in &self.lanes {
if l.lane_type == LaneType::Biking {
bike_lanes = true;
}
if PathConstraints::Bike.can_use(map.get_l(l), map) {
if PathConstraints::Bike.can_use(l, map) {
can_use = true;
}
}
@ -609,26 +596,26 @@ impl Road {
}
}
// TODO All of this is kind of deprecated? During the transiton towards lanes_ltr, some pieces
// seemed to really need to still handle lanes going outward from the "center" line. Should keep
// whittling this down, probably. These very much don't handle multiple direction changes.
// TODO All of this is kind of deprecated? Some callers seem to really need to still handle lanes
// going outward from the "center" line. Should keep whittling this down, probably. These very much
// don't handle multiple direction changes.
impl Road {
/// These are ordered from closest to center lane (left-most when driving on the right) to
/// farthest (sidewalk)
pub(crate) fn children_forwards(&self) -> Vec<(LaneID, LaneType)> {
let mut result = Vec::new();
for (l, dir, lt) in self.lanes_ltr() {
if dir == Direction::Fwd {
result.push((l, lt));
for l in &self.lanes {
if l.dir == Direction::Fwd {
result.push((l.id, l.lane_type));
}
}
result
}
pub(crate) fn children_backwards(&self) -> Vec<(LaneID, LaneType)> {
let mut result = Vec::new();
for (l, dir, lt) in self.lanes_ltr() {
if dir == Direction::Back {
result.push((l, lt));
for l in &self.lanes {
if l.dir == Direction::Back {
result.push((l.id, l.lane_type));
}
}
result.reverse();

View File

@ -65,11 +65,11 @@ impl ControlStopSign {
Direction::Back
};
let travel_lanes: Vec<LaneID> = r
.lanes_ltr()
.into_iter()
.filter_map(|(id, dir, lt)| {
if dir == want_dir && lt.is_for_moving_vehicles() {
Some(id)
.lanes
.iter()
.filter_map(|l| {
if l.dir == want_dir && l.lane_type.is_for_moving_vehicles() {
Some(l.id)
} else {
None
}

View File

@ -364,10 +364,10 @@ impl Movement {
let mut rightmost = Distance::ZERO;
let mut left = Distance::ZERO;
for (l, _, _) in r.lanes_ltr() {
let right = left + map.get_l(l).width;
for l in &r.lanes {
let right = left + l.width;
if self.members.iter().any(|t| t.src == l) {
if self.members.iter().any(|t| t.src == l.id) {
leftmost = leftmost.min(left);
rightmost = rightmost.max(right);
}

View File

@ -205,8 +205,8 @@ impl Player {
On::Intersection(i) => app.map.get_i(i).roads.iter().cloned().collect(),
};
for r in roads {
for (_, _, lt) in app.map.get_r(r).lanes_ltr() {
if lt == LaneType::Biking || lt == LaneType::Bus {
for l in &app.map.get_r(r).lanes {
if l.lane_type == LaneType::Biking || l.lane_type == LaneType::Bus {
return true;
}
}

View File

@ -1083,14 +1083,13 @@ impl DrivingSimState {
let current_lane = map.get_l(car.router.head().maybe_lane()?);
let road = map.get_r(current_lane.parent);
let idx = road.offset(current_lane.id);
let lanes_ltr = road.lanes_ltr();
let mut candidates = Vec::new();
if idx != 0 {
candidates.push(lanes_ltr[idx - 1].0);
candidates.push(road.lanes[idx - 1].id);
}
if idx != lanes_ltr.len() - 1 {
candidates.push(lanes_ltr[idx + 1].0);
if idx != road.lanes.len() - 1 {
candidates.push(road.lanes[idx + 1].id);
}
if map.get_config().driving_side == DrivingSide::Left {
candidates.reverse();

View File

@ -399,27 +399,27 @@ impl Router {
let mut original_cost = None;
let dir = map.get_l(orig_target_lane).dir;
let best = parent
.lanes_ltr()
.into_iter()
.filter(|(l, d, _)| dir == *d && constraints.can_use(map.get_l(*l), map))
.filter_map(|(l, _, _)| {
.lanes
.iter()
.filter(|l| l.dir == dir && constraints.can_use(l, map))
.filter_map(|l| {
// Make sure we can go from this lane to next_lane.
let t1 = TurnID {
parent: current_turn.parent,
src: current_turn.src,
dst: l,
dst: l.id,
};
let turn1 = map.maybe_get_t(t1)?;
let t2 = TurnID {
parent: next_parent,
src: l,
src: l.id,
dst: next_lane,
};
let turn2 = map.maybe_get_t(t2)?;
Some((turn1, l, turn2))
Some((turn1, l.id, turn2))
})
.map(|(turn1, l, turn2)| {
let cost = compute_cost(turn1, l);