mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
Get rid of the now redundant lanes_ltr
This commit is contained in:
parent
4c46510342
commit
112bc38e0c
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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(),
|
||||
|
@ -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));
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user