Produce proper lanes for left-hand driving by intervening at the LaneSpec layer for #311. Since London looks reasonable, opt it into the screenshot tests

This commit is contained in:
Dustin Carlino 2020-09-03 20:16:09 -07:00
parent f610c66572
commit 38ba8d55f3
8 changed files with 85 additions and 27 deletions

View File

@ -30,6 +30,7 @@ data/input/screenshots/downtown.zip,21838ff62b31b2d6d4860a7f3d08f921,https://www
data/input/screenshots/krakow_center.zip,1274855e993e09015c3b00127bf0da97,https://www.dropbox.com/s/azea6v6mnxbe0vc/krakow_center.zip.zip?dl=0
data/input/screenshots/lakeslice.zip,adedabf6ee4e30f8e386762f860176d8,https://www.dropbox.com/s/06mwgdt6orow3rk/lakeslice.zip.zip?dl=0
data/input/screenshots/montlake.zip,158ec5f3913f62519fbbeb5a6f47f9cd,https://www.dropbox.com/s/eblgq5zj3gflhwx/montlake.zip.zip?dl=0
data/input/screenshots/southbank.zip,6abe141b2d2bc5cdb01bff31aaa093ca,https://www.dropbox.com/s/2smj2sw9gq7ajwx/southbank.zip.zip?dl=0
data/input/screenshots/udistrict.zip,8a98fae6bc9d995f9e1ab4c91d0d7a23,https://www.dropbox.com/s/nlyxnfy11qszk50/udistrict.zip.zip?dl=0
data/input/seattle/N47W122.hgt,0db4e23e51f7680538b0bbbc72208e07,https://www.dropbox.com/s/mmb4mgutwotijdw/N47W122.hgt.zip?dl=0
data/input/seattle/blockface.bin,add872bab9040ae911366328a230f8b5,https://www.dropbox.com/s/rxd2care60tbe75/blockface.bin.zip?dl=0
@ -80,7 +81,7 @@ data/system/maps/krakow_center.bin,7e423da356c1671ea09d2527575fce5c,https://www.
data/system/maps/lakeslice.bin,c117a20d21a7c68ceae775c6c1daf318,https://www.dropbox.com/s/sss05ts43u8ghb8/lakeslice.bin.zip?dl=0
data/system/maps/montlake.bin,6ca284783ce83e915282476cf99e04cc,https://www.dropbox.com/s/wyybiw5y7z3gdoc/montlake.bin.zip?dl=0
data/system/maps/south_seattle.bin,286ce475d0d4a93501d7f9af6fff6418,https://www.dropbox.com/s/y505pnkwxyyrw0f/south_seattle.bin.zip?dl=0
data/system/maps/southbank.bin,d7a8606a30927a8b73aa935881e526c2,https://www.dropbox.com/s/7k2gxn3jp2h10l0/southbank.bin.zip?dl=0
data/system/maps/southbank.bin,dc5b1f91ae0e477aea5b4bdcb56e2e2c,https://www.dropbox.com/s/06v1x7enu00pmds/southbank.bin.zip?dl=0
data/system/maps/tel_aviv.bin,b273e64c3e2ded4134f46bce6d9992cf,https://www.dropbox.com/s/7hndvhud5x8xao5/tel_aviv.bin.zip?dl=0
data/system/maps/udistrict.bin,d2773d20a171843b7b6c805f350d4cf5,https://www.dropbox.com/s/y03l06emjmtjp32/udistrict.bin.zip?dl=0
data/system/maps/west_seattle.bin,df580b7566bb9d57a2605cf4affa741d,https://www.dropbox.com/s/a9ws18sar0l5tns/west_seattle.bin.zip?dl=0

View File

@ -236,6 +236,7 @@ impl State for DebugMode {
"krakow_center",
"lakeslice",
"montlake",
"southbank",
"udistrict",
],
}));

View File

@ -219,7 +219,7 @@ impl Static {
let edits = app.primary.map.get_edits();
for r in &edits.changed_roads {
let r = app.primary.map.get_r(*r);
let orig = EditRoad::get_orig_from_osm(r);
let orig = EditRoad::get_orig_from_osm(r, app.primary.map.get_config().driving_side);
// What exactly changed?
if r.speed_limit != orig.speed_limit
|| r.access_restrictions != orig.access_restrictions

View File

@ -2,6 +2,7 @@ mod compat;
mod perma;
use crate::make::initial::lane_specs::get_lane_specs_ltr;
use crate::raw::DrivingSide;
use crate::{
connectivity, AccessRestrictions, BusRouteID, ControlStopSign, ControlTrafficSignal, Direction,
IntersectionID, IntersectionType, LaneType, Map, PathConstraints, Pathfinder, Road, RoadID,
@ -46,9 +47,9 @@ pub struct EditRoad {
}
impl EditRoad {
pub fn get_orig_from_osm(r: &Road) -> EditRoad {
pub fn get_orig_from_osm(r: &Road, driving_side: DrivingSide) -> EditRoad {
EditRoad {
lanes_ltr: get_lane_specs_ltr(&r.osm_tags)
lanes_ltr: get_lane_specs_ltr(&r.osm_tags, driving_side)
.into_iter()
.map(|spec| (spec.lt, spec.dir))
.collect(),
@ -144,7 +145,8 @@ impl MapEdits {
}
retain_btreeset(&mut self.changed_roads, |r| {
map.get_r_edit(*r) != EditRoad::get_orig_from_osm(map.get_r(*r))
map.get_r_edit(*r)
!= EditRoad::get_orig_from_osm(map.get_r(*r), map.config.driving_side)
});
retain_btreemap(&mut self.original_intersections, |i, orig| {
map.get_i_edit(*i) != orig.clone()
@ -160,7 +162,7 @@ impl MapEdits {
for r in &self.changed_roads {
self.commands.push(EditCmd::ChangeRoad {
r: *r,
old: EditRoad::get_orig_from_osm(map.get_r(*r)),
old: EditRoad::get_orig_from_osm(map.get_r(*r), map.config.driving_side),
new: map.get_r_edit(*r),
});
}

View File

@ -1,3 +1,4 @@
use crate::raw::DrivingSide;
use crate::{
osm, Direction, LaneType, NORMAL_LANE_THICKNESS, SHOULDER_THICKNESS, SIDEWALK_THICKNESS,
};
@ -36,7 +37,7 @@ fn back(lt: LaneType) -> LaneSpec {
}
}
pub fn get_lane_specs_ltr(tags: &Tags) -> Vec<LaneSpec> {
pub fn get_lane_specs_ltr(tags: &Tags, driving_side: DrivingSide) -> Vec<LaneSpec> {
// Easy special cases first.
if tags.is_any("railway", vec!["light_rail", "rail"]) {
return vec![fwd(LaneType::LightRail)];
@ -123,10 +124,7 @@ pub fn get_lane_specs_ltr(tags: &Tags) -> Vec<LaneSpec> {
}
if driving_lane == LaneType::Construction {
// Assemble left-to-right
back_side.reverse();
back_side.extend(fwd_side);
return back_side;
return assemble_ltr(fwd_side, back_side, driving_side);
}
let fwd_bus_spec = if let Some(s) = tags.get("bus:lanes:forward") {
@ -227,10 +225,18 @@ pub fn get_lane_specs_ltr(tags: &Tags) -> Vec<LaneSpec> {
back_side.push(back(LaneType::Sidewalk));
}
} else if tags.is(osm::SIDEWALK, "right") {
if driving_side == DrivingSide::Right {
fwd_side.push(fwd(LaneType::Sidewalk));
} else if tags.is(osm::SIDEWALK, "left") {
} else {
back_side.push(back(LaneType::Sidewalk));
}
} else if tags.is(osm::SIDEWALK, "left") {
if driving_side == DrivingSide::Right {
back_side.push(back(LaneType::Sidewalk));
} else {
fwd_side.push(fwd(LaneType::Sidewalk));
}
}
let mut need_fwd_shoulder = fwd_side
.last()
@ -262,10 +268,26 @@ pub fn get_lane_specs_ltr(tags: &Tags) -> Vec<LaneSpec> {
back_side.push(back(LaneType::Shoulder));
}
// Assemble left-to-right
assemble_ltr(fwd_side, back_side, driving_side)
}
fn assemble_ltr(
mut fwd_side: Vec<LaneSpec>,
mut back_side: Vec<LaneSpec>,
driving_side: DrivingSide,
) -> Vec<LaneSpec> {
match driving_side {
DrivingSide::Right => {
back_side.reverse();
back_side.extend(fwd_side);
back_side
}
DrivingSide::Left => {
fwd_side.reverse();
fwd_side.extend(back_side);
fwd_side
}
}
}
#[cfg(test)]
@ -298,7 +320,7 @@ mod tests {
#[test]
fn test_osm_to_specs() {
let mut ok = true;
for (url, input, expected_lt, expected_dir) in vec![
for (url, input, driving_side, expected_lt, expected_dir) in vec![
(
"https://www.openstreetmap.org/way/428294122",
vec![
@ -307,6 +329,7 @@ mod tests {
"sidewalk=both",
"cycleway:left=lane",
],
DrivingSide::Right,
"sbdds",
"v^^^^",
),
@ -319,6 +342,7 @@ mod tests {
"cycleway:left=track",
"oneway:bicycle=no",
],
DrivingSide::Right,
"sbbds",
"vv^^^",
),
@ -331,6 +355,7 @@ mod tests {
"cycleway:right=track",
"cycleway:right:oneway=no",
],
DrivingSide::Right,
"spddddbbps",
"vvvv^^v^^^",
),
@ -345,6 +370,7 @@ mod tests {
"cycleway:right=track",
"cycleway:right:oneway=no",
],
DrivingSide::Right,
"spdCdbbs",
"vvv^^v^^",
),
@ -358,6 +384,7 @@ mod tests {
"cycleway:left=opposite_track",
"oneway:bicycle=no",
],
DrivingSide::Right,
"sbbdps",
"vv^^^^",
),
@ -371,11 +398,26 @@ mod tests {
"cycleway:right:oneway=no",
"oneway:bicycle=no",
],
DrivingSide::Right,
"sddbbs",
"v^^v^^",
),
(
"https://www.openstreetmap.org/way/777565028",
vec!["highway=residential", "oneway=no", "sidewalk=both"],
DrivingSide::Left,
"sdds",
"^^vv",
),
(
"https://www.openstreetmap.org/way/224637155",
vec!["lanes=2", "oneway=yes", "sidewalk=left"],
DrivingSide::Left,
"sdd",
"^^^",
),
] {
let actual = get_lane_specs_ltr(&tags(input.clone()));
let actual = get_lane_specs_ltr(&tags(input.clone()), driving_side);
let actual_lt = actual
.iter()
.map(|s| lt_to_char(s.lt))

View File

@ -2,7 +2,7 @@ mod geometry;
pub mod lane_specs;
pub use self::geometry::intersection_polygon;
use crate::raw::{OriginalRoad, RawMap, RawRoad};
use crate::raw::{DrivingSide, OriginalRoad, RawMap, RawRoad};
use crate::{osm, IntersectionType};
use abstutil::{Tags, Timer};
use geom::{Bounds, Circle, Distance, PolyLine, Polygon, Pt2D};
@ -29,9 +29,9 @@ pub struct Road {
}
impl Road {
pub fn new(id: OriginalRoad, r: &RawRoad) -> Road {
let lane_specs_ltr = lane_specs::get_lane_specs_ltr(&r.osm_tags);
let (trimmed_center_pts, total_width) = r.get_geometry(id);
pub fn new(id: OriginalRoad, r: &RawRoad, driving_side: DrivingSide) -> Road {
let lane_specs_ltr = lane_specs::get_lane_specs_ltr(&r.osm_tags, driving_side);
let (trimmed_center_pts, total_width) = r.get_geometry(id, driving_side);
Road {
id,
@ -89,7 +89,8 @@ impl InitialMap {
m.intersections.get_mut(&id.i1).unwrap().roads.insert(*id);
m.intersections.get_mut(&id.i2).unwrap().roads.insert(*id);
m.roads.insert(*id, Road::new(*id, r));
m.roads
.insert(*id, Road::new(*id, r, raw.config.driving_side));
}
timer.start_iter("find each intersection polygon", m.intersections.len());

View File

@ -629,4 +629,8 @@ impl Map {
}
languages
}
pub fn get_config(&self) -> &MapConfig {
&self.config
}
}

View File

@ -153,7 +153,10 @@ impl RawMap {
};
let mut roads = BTreeMap::new();
for r in &i.roads {
roads.insert(*r, initial::Road::new(*r, &self.roads[r]));
roads.insert(
*r,
initial::Road::new(*r, &self.roads[r], self.config.driving_side),
);
}
let (poly, debug) = initial::intersection_polygon(&i, &mut roads, timer).unwrap();
@ -242,8 +245,12 @@ pub struct RawRoad {
impl RawRoad {
// Returns the corrected center and half width
pub fn get_geometry(&self, id: OriginalRoad) -> (PolyLine, Distance) {
let lane_specs = get_lane_specs_ltr(&self.osm_tags);
pub fn get_geometry(
&self,
id: OriginalRoad,
driving_side: DrivingSide,
) -> (PolyLine, Distance) {
let lane_specs = get_lane_specs_ltr(&self.osm_tags, driving_side);
let mut total_width = Distance::ZERO;
let mut sidewalk_right = None;
let mut sidewalk_left = None;