mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 06:55:40 +03:00
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:
parent
f610c66572
commit
38ba8d55f3
@ -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
|
||||
|
@ -236,6 +236,7 @@ impl State for DebugMode {
|
||||
"krakow_center",
|
||||
"lakeslice",
|
||||
"montlake",
|
||||
"southbank",
|
||||
"udistrict",
|
||||
],
|
||||
}));
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
});
|
||||
}
|
||||
|
@ -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,9 +225,17 @@ pub fn get_lane_specs_ltr(tags: &Tags) -> Vec<LaneSpec> {
|
||||
back_side.push(back(LaneType::Sidewalk));
|
||||
}
|
||||
} else if tags.is(osm::SIDEWALK, "right") {
|
||||
fwd_side.push(fwd(LaneType::Sidewalk));
|
||||
if driving_side == DrivingSide::Right {
|
||||
fwd_side.push(fwd(LaneType::Sidewalk));
|
||||
} else {
|
||||
back_side.push(back(LaneType::Sidewalk));
|
||||
}
|
||||
} else if tags.is(osm::SIDEWALK, "left") {
|
||||
back_side.push(back(LaneType::Sidewalk));
|
||||
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
|
||||
@ -262,10 +268,26 @@ pub fn get_lane_specs_ltr(tags: &Tags) -> Vec<LaneSpec> {
|
||||
back_side.push(back(LaneType::Shoulder));
|
||||
}
|
||||
|
||||
// Assemble left-to-right
|
||||
back_side.reverse();
|
||||
back_side.extend(fwd_side);
|
||||
back_side
|
||||
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))
|
||||
|
@ -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());
|
||||
|
@ -629,4 +629,8 @@ impl Map {
|
||||
}
|
||||
languages
|
||||
}
|
||||
|
||||
pub fn get_config(&self) -> &MapConfig {
|
||||
&self.config
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user