mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +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/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/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/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/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/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
|
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/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/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/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/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/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
|
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",
|
"krakow_center",
|
||||||
"lakeslice",
|
"lakeslice",
|
||||||
"montlake",
|
"montlake",
|
||||||
|
"southbank",
|
||||||
"udistrict",
|
"udistrict",
|
||||||
],
|
],
|
||||||
}));
|
}));
|
||||||
|
@ -219,7 +219,7 @@ impl Static {
|
|||||||
let edits = app.primary.map.get_edits();
|
let edits = app.primary.map.get_edits();
|
||||||
for r in &edits.changed_roads {
|
for r in &edits.changed_roads {
|
||||||
let r = app.primary.map.get_r(*r);
|
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?
|
// What exactly changed?
|
||||||
if r.speed_limit != orig.speed_limit
|
if r.speed_limit != orig.speed_limit
|
||||||
|| r.access_restrictions != orig.access_restrictions
|
|| r.access_restrictions != orig.access_restrictions
|
||||||
|
@ -2,6 +2,7 @@ mod compat;
|
|||||||
mod perma;
|
mod perma;
|
||||||
|
|
||||||
use crate::make::initial::lane_specs::get_lane_specs_ltr;
|
use crate::make::initial::lane_specs::get_lane_specs_ltr;
|
||||||
|
use crate::raw::DrivingSide;
|
||||||
use crate::{
|
use crate::{
|
||||||
connectivity, AccessRestrictions, BusRouteID, ControlStopSign, ControlTrafficSignal, Direction,
|
connectivity, AccessRestrictions, BusRouteID, ControlStopSign, ControlTrafficSignal, Direction,
|
||||||
IntersectionID, IntersectionType, LaneType, Map, PathConstraints, Pathfinder, Road, RoadID,
|
IntersectionID, IntersectionType, LaneType, Map, PathConstraints, Pathfinder, Road, RoadID,
|
||||||
@ -46,9 +47,9 @@ pub struct EditRoad {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
EditRoad {
|
||||||
lanes_ltr: get_lane_specs_ltr(&r.osm_tags)
|
lanes_ltr: get_lane_specs_ltr(&r.osm_tags, driving_side)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|spec| (spec.lt, spec.dir))
|
.map(|spec| (spec.lt, spec.dir))
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -144,7 +145,8 @@ impl MapEdits {
|
|||||||
}
|
}
|
||||||
|
|
||||||
retain_btreeset(&mut self.changed_roads, |r| {
|
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| {
|
retain_btreemap(&mut self.original_intersections, |i, orig| {
|
||||||
map.get_i_edit(*i) != orig.clone()
|
map.get_i_edit(*i) != orig.clone()
|
||||||
@ -160,7 +162,7 @@ impl MapEdits {
|
|||||||
for r in &self.changed_roads {
|
for r in &self.changed_roads {
|
||||||
self.commands.push(EditCmd::ChangeRoad {
|
self.commands.push(EditCmd::ChangeRoad {
|
||||||
r: *r,
|
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),
|
new: map.get_r_edit(*r),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::raw::DrivingSide;
|
||||||
use crate::{
|
use crate::{
|
||||||
osm, Direction, LaneType, NORMAL_LANE_THICKNESS, SHOULDER_THICKNESS, SIDEWALK_THICKNESS,
|
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.
|
// Easy special cases first.
|
||||||
if tags.is_any("railway", vec!["light_rail", "rail"]) {
|
if tags.is_any("railway", vec!["light_rail", "rail"]) {
|
||||||
return vec![fwd(LaneType::LightRail)];
|
return vec![fwd(LaneType::LightRail)];
|
||||||
@ -123,10 +124,7 @@ pub fn get_lane_specs_ltr(tags: &Tags) -> Vec<LaneSpec> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if driving_lane == LaneType::Construction {
|
if driving_lane == LaneType::Construction {
|
||||||
// Assemble left-to-right
|
return assemble_ltr(fwd_side, back_side, driving_side);
|
||||||
back_side.reverse();
|
|
||||||
back_side.extend(fwd_side);
|
|
||||||
return back_side;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let fwd_bus_spec = if let Some(s) = tags.get("bus:lanes:forward") {
|
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));
|
back_side.push(back(LaneType::Sidewalk));
|
||||||
}
|
}
|
||||||
} else if tags.is(osm::SIDEWALK, "right") {
|
} 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") {
|
} 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
|
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));
|
back_side.push(back(LaneType::Shoulder));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assemble left-to-right
|
assemble_ltr(fwd_side, back_side, driving_side)
|
||||||
back_side.reverse();
|
}
|
||||||
back_side.extend(fwd_side);
|
|
||||||
back_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)]
|
#[cfg(test)]
|
||||||
@ -298,7 +320,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_osm_to_specs() {
|
fn test_osm_to_specs() {
|
||||||
let mut ok = true;
|
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",
|
"https://www.openstreetmap.org/way/428294122",
|
||||||
vec![
|
vec![
|
||||||
@ -307,6 +329,7 @@ mod tests {
|
|||||||
"sidewalk=both",
|
"sidewalk=both",
|
||||||
"cycleway:left=lane",
|
"cycleway:left=lane",
|
||||||
],
|
],
|
||||||
|
DrivingSide::Right,
|
||||||
"sbdds",
|
"sbdds",
|
||||||
"v^^^^",
|
"v^^^^",
|
||||||
),
|
),
|
||||||
@ -319,6 +342,7 @@ mod tests {
|
|||||||
"cycleway:left=track",
|
"cycleway:left=track",
|
||||||
"oneway:bicycle=no",
|
"oneway:bicycle=no",
|
||||||
],
|
],
|
||||||
|
DrivingSide::Right,
|
||||||
"sbbds",
|
"sbbds",
|
||||||
"vv^^^",
|
"vv^^^",
|
||||||
),
|
),
|
||||||
@ -331,6 +355,7 @@ mod tests {
|
|||||||
"cycleway:right=track",
|
"cycleway:right=track",
|
||||||
"cycleway:right:oneway=no",
|
"cycleway:right:oneway=no",
|
||||||
],
|
],
|
||||||
|
DrivingSide::Right,
|
||||||
"spddddbbps",
|
"spddddbbps",
|
||||||
"vvvv^^v^^^",
|
"vvvv^^v^^^",
|
||||||
),
|
),
|
||||||
@ -345,6 +370,7 @@ mod tests {
|
|||||||
"cycleway:right=track",
|
"cycleway:right=track",
|
||||||
"cycleway:right:oneway=no",
|
"cycleway:right:oneway=no",
|
||||||
],
|
],
|
||||||
|
DrivingSide::Right,
|
||||||
"spdCdbbs",
|
"spdCdbbs",
|
||||||
"vvv^^v^^",
|
"vvv^^v^^",
|
||||||
),
|
),
|
||||||
@ -358,6 +384,7 @@ mod tests {
|
|||||||
"cycleway:left=opposite_track",
|
"cycleway:left=opposite_track",
|
||||||
"oneway:bicycle=no",
|
"oneway:bicycle=no",
|
||||||
],
|
],
|
||||||
|
DrivingSide::Right,
|
||||||
"sbbdps",
|
"sbbdps",
|
||||||
"vv^^^^",
|
"vv^^^^",
|
||||||
),
|
),
|
||||||
@ -371,11 +398,26 @@ mod tests {
|
|||||||
"cycleway:right:oneway=no",
|
"cycleway:right:oneway=no",
|
||||||
"oneway:bicycle=no",
|
"oneway:bicycle=no",
|
||||||
],
|
],
|
||||||
|
DrivingSide::Right,
|
||||||
"sddbbs",
|
"sddbbs",
|
||||||
"v^^v^^",
|
"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
|
let actual_lt = actual
|
||||||
.iter()
|
.iter()
|
||||||
.map(|s| lt_to_char(s.lt))
|
.map(|s| lt_to_char(s.lt))
|
||||||
|
@ -2,7 +2,7 @@ mod geometry;
|
|||||||
pub mod lane_specs;
|
pub mod lane_specs;
|
||||||
|
|
||||||
pub use self::geometry::intersection_polygon;
|
pub use self::geometry::intersection_polygon;
|
||||||
use crate::raw::{OriginalRoad, RawMap, RawRoad};
|
use crate::raw::{DrivingSide, OriginalRoad, RawMap, RawRoad};
|
||||||
use crate::{osm, IntersectionType};
|
use crate::{osm, IntersectionType};
|
||||||
use abstutil::{Tags, Timer};
|
use abstutil::{Tags, Timer};
|
||||||
use geom::{Bounds, Circle, Distance, PolyLine, Polygon, Pt2D};
|
use geom::{Bounds, Circle, Distance, PolyLine, Polygon, Pt2D};
|
||||||
@ -29,9 +29,9 @@ pub struct Road {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Road {
|
impl Road {
|
||||||
pub fn new(id: OriginalRoad, r: &RawRoad) -> Road {
|
pub fn new(id: OriginalRoad, r: &RawRoad, driving_side: DrivingSide) -> Road {
|
||||||
let lane_specs_ltr = lane_specs::get_lane_specs_ltr(&r.osm_tags);
|
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);
|
let (trimmed_center_pts, total_width) = r.get_geometry(id, driving_side);
|
||||||
|
|
||||||
Road {
|
Road {
|
||||||
id,
|
id,
|
||||||
@ -89,7 +89,8 @@ impl InitialMap {
|
|||||||
m.intersections.get_mut(&id.i1).unwrap().roads.insert(*id);
|
m.intersections.get_mut(&id.i1).unwrap().roads.insert(*id);
|
||||||
m.intersections.get_mut(&id.i2).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());
|
timer.start_iter("find each intersection polygon", m.intersections.len());
|
||||||
|
@ -629,4 +629,8 @@ impl Map {
|
|||||||
}
|
}
|
||||||
languages
|
languages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_config(&self) -> &MapConfig {
|
||||||
|
&self.config
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,10 @@ impl RawMap {
|
|||||||
};
|
};
|
||||||
let mut roads = BTreeMap::new();
|
let mut roads = BTreeMap::new();
|
||||||
for r in &i.roads {
|
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();
|
let (poly, debug) = initial::intersection_polygon(&i, &mut roads, timer).unwrap();
|
||||||
@ -242,8 +245,12 @@ pub struct RawRoad {
|
|||||||
|
|
||||||
impl RawRoad {
|
impl RawRoad {
|
||||||
// Returns the corrected center and half width
|
// Returns the corrected center and half width
|
||||||
pub fn get_geometry(&self, id: OriginalRoad) -> (PolyLine, Distance) {
|
pub fn get_geometry(
|
||||||
let lane_specs = get_lane_specs_ltr(&self.osm_tags);
|
&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 total_width = Distance::ZERO;
|
||||||
let mut sidewalk_right = None;
|
let mut sidewalk_right = None;
|
||||||
let mut sidewalk_left = None;
|
let mut sidewalk_left = None;
|
||||||
|
Loading…
Reference in New Issue
Block a user