being able to find sibling lanes

This commit is contained in:
Dustin Carlino 2018-07-09 12:04:55 -07:00
parent d3bcbe1da2
commit 0e6111e86a
4 changed files with 87 additions and 27 deletions

View File

@ -1,5 +1,18 @@
# TODO for Phase 1 (Basemap)
- road with many lanes
- maybe also the time to split into different lane types? what's similar/not between them?
- graph querying?
- rendering (and other UI/editor interactions)?
- sim state?
- split structs, IDs, getters, etc
- osm tags belong to road
- this will clean up other_side and siblings
- figure out what to do about yellow center lines
- yellow and white lines intersect cars and turn icons and such
- who should own drawing them?
- trim them back too (maybe to avoid hitting the intersection?)
- model bike lanes
- more data
@ -25,7 +38,6 @@
building layer before sidewalk layer
- code cleanup
- rename Road to Lane
- make final Map serializable too
- useful to precompute sidewalk paths
- waiting on https://github.com/paholg/dimensioned/issues/31 to release
@ -33,12 +45,6 @@
- also a polygon struct? for parcels and buildings. maybe have a form that's pre-triangulated?
- isolate vec2d
- figure out what to do about yellow center lines
- yellow and white lines intersect cars and turn icons and such
- who should own drawing them?
- trim them back too (maybe to avoid hitting the intersection?)
- osm tags and such would ideally be part of a master road
- draw detailed turns better, like https://i.ytimg.com/vi/NH6R3RH_ZDY/maxresdefault.jpg
## Intersection geometry brainstorm

View File

@ -59,6 +59,7 @@ pub(crate) struct LaneSpec {
pub offset: u8,
pub reverse_pts: bool,
pub offset_for_other_id: Option<isize>,
pub offsets_for_siblings: Vec<isize>,
}
impl LaneSpec {
@ -67,12 +68,14 @@ impl LaneSpec {
offset: u8,
reverse_pts: bool,
offset_for_other_id: Option<isize>,
offsets_for_siblings: Vec<isize>,
) -> LaneSpec {
LaneSpec {
lane_type,
offset,
reverse_pts,
offset_for_other_id,
offsets_for_siblings,
}
}
}
@ -107,6 +110,7 @@ fn lane_specs_for((side1_types, side2_types): (Vec<LaneType>, Vec<LaneType>)) ->
idx as u8,
false,
offset_for_other_id,
make_offsets(idx as isize, side1_types.len() as isize),
));
}
for (idx, lane_type) in side2_types.iter().enumerate() {
@ -122,19 +126,50 @@ fn lane_specs_for((side1_types, side2_types): (Vec<LaneType>, Vec<LaneType>)) ->
idx as u8,
true,
offset_for_other_id,
make_offsets(idx as isize, side2_types.len() as isize),
));
}
specs
}
fn make_offsets(idx: isize, len: isize) -> Vec<isize> {
let mut offsets = Vec::new();
for i in 0 .. len {
if i != idx {
offsets.push(i - idx);
}
}
offsets
}
#[test]
fn offsets() {
let no_offsets: Vec<isize> = Vec::new();
assert_eq!(
make_offsets(0, 1),
no_offsets);
assert_eq!(
make_offsets(0, 3),
vec![1, 2]);
assert_eq!(
make_offsets(1, 3),
vec![-1, 1]);
assert_eq!(
make_offsets(2, 3),
vec![-2, -1]);
}
#[test]
fn junction() {
let d = LaneType::Driving;
assert_eq!(
lane_specs_for((vec![d], vec![])),
vec![LaneSpec::new(d, 0, false, None)]
vec![LaneSpec::new(d, 0, false, None, vec![])]
);
}
@ -147,10 +182,10 @@ fn oneway() {
assert_eq!(
lane_specs_for((vec![d, p, s], vec![s])),
vec![
LaneSpec::new(d, 0, false, None),
LaneSpec::new(p, 1, false, None),
LaneSpec::new(s, 2, false, Some(1)),
LaneSpec::new(s, 0, true, Some(-1)),
LaneSpec::new(d, 0, false, None, vec![1, 2]),
LaneSpec::new(p, 1, false, None, vec![-1, 1]),
LaneSpec::new(s, 2, false, Some(1), vec![-2, -1]),
LaneSpec::new(s, 0, true, Some(-1), vec![]),
]
);
}
@ -164,12 +199,12 @@ fn twoway() {
assert_eq!(
lane_specs_for((vec![d, p, s], vec![d, p, s])),
vec![
LaneSpec::new(d, 0, false, Some(3)),
LaneSpec::new(p, 1, false, None),
LaneSpec::new(s, 2, false, Some(3)),
LaneSpec::new(d, 0, true, Some(-3)),
LaneSpec::new(p, 1, true, None),
LaneSpec::new(s, 2, true, Some(-3)),
LaneSpec::new(d, 0, false, Some(3), vec![1, 2]),
LaneSpec::new(p, 1, false, None, vec![-1, 1]),
LaneSpec::new(s, 2, false, Some(3), vec![-2, -1]),
LaneSpec::new(d, 0, true, Some(-3), vec![1, 2]),
LaneSpec::new(p, 1, true, None, vec![-1, 1]),
LaneSpec::new(s, 2, true, Some(-3), vec![-2, -1]),
]
);
}
@ -183,14 +218,14 @@ fn big_twoway() {
assert_eq!(
lane_specs_for((vec![d, d, p, s], vec![d, d, p, s])),
vec![
LaneSpec::new(d, 0, false, Some(4)),
LaneSpec::new(d, 1, false, Some(4)),
LaneSpec::new(p, 2, false, None),
LaneSpec::new(s, 3, false, Some(4)),
LaneSpec::new(d, 0, true, Some(-4)),
LaneSpec::new(d, 1, true, Some(-4)),
LaneSpec::new(p, 2, true, None),
LaneSpec::new(s, 3, true, Some(-4)),
LaneSpec::new(d, 0, false, Some(4), vec![1, 2, 3]),
LaneSpec::new(d, 1, false, Some(4), vec![-1, 1, 2]),
LaneSpec::new(p, 2, false, None, vec![-2, -1, 1]),
LaneSpec::new(s, 3, false, Some(4), vec![-3, -2, -1]),
LaneSpec::new(d, 0, true, Some(-4), vec![1, 2, 3]),
LaneSpec::new(d, 1, true, Some(-4), vec![-1, 1, 2]),
LaneSpec::new(p, 2, true, None, vec![-2, -1, 1]),
LaneSpec::new(s, 3, true, Some(-4), vec![-3, -2, -1]),
]
);
}

View File

@ -9,7 +9,7 @@ use intersection::{Intersection, IntersectionID};
use make;
use parcel::{Parcel, ParcelID};
use raw_data;
use road::{Road, RoadID};
use road::{Road, RoadID, LaneType};
use std::collections::HashMap;
use std::io::Error;
use turn::{Turn, TurnID};
@ -66,6 +66,8 @@ impl Map {
counter += 1;
let other_side = lane.offset_for_other_id
.map(|offset| RoadID(((id.0 as isize) + offset) as usize));
let siblings = lane.offsets_for_siblings.iter()
.map(|offset| RoadID(((id.0 as isize) + offset) as usize)).collect();
let mut unshifted_pts = PolyLine::new(
r.points
@ -102,6 +104,7 @@ impl Map {
m.roads.push(Road {
id,
other_side,
siblings,
use_yellow_center_lines,
lane_center_pts,
probably_broken,
@ -226,4 +229,17 @@ impl Map {
pub fn get_gps_bounds(&self) -> Bounds {
self.bounds.clone()
}
pub fn find_driving_lane(&self, parking: RoadID) -> Option<RoadID> {
let r = self.get_r(parking);
assert_eq!(r.lane_type, LaneType::Parking);
// TODO find the closest one to the parking lane, if there are multiple
r.siblings.iter().find(|&&id| self.get_r(id).lane_type == LaneType::Driving).map(|id| *id)
}
pub fn find_parking_lane(&self, driving: RoadID) -> Option<RoadID> {
let r = self.get_r(driving);
assert_eq!(r.lane_type, LaneType::Driving);
r.siblings.iter().find(|&&id| self.get_r(id).lane_type == LaneType::Parking).map(|id| *id)
}
}

View File

@ -50,9 +50,12 @@ pub struct Road {
// Should this lane own the drawing of the yellow center lines? For two-way roads, this is
// arbitrarily grouped with one of the lanes. Ideally it would be owned by something else.
pub use_yellow_center_lines: bool,
// Need to remember this just for detecting U-turns here. Also for finding sidewalks to connect
// with a crosswalk.
pub other_side: Option<RoadID>,
// TODO alright, we might need a Road-vs-Lanes distinction
pub siblings: Vec<RoadID>,
/// GeomRoad stuff
pub lane_center_pts: PolyLine,