Generate turns much more simply for intersections of footpaths. #161

Also gets rid of some annoying warnings about roads with missing names.
I could continue to skip the warning for more situations, but I think
this sort of data quality check could be done better in the OSM viewer.
This commit is contained in:
Dustin Carlino 2020-11-01 18:20:32 -08:00
parent c210b0a1bd
commit 6e417340e4
5 changed files with 51 additions and 24 deletions

View File

@ -41,7 +41,7 @@
"dropbox_url": "https://www.dropbox.com/s/sbk48ubt9jt3tn6/footways.bin.gz?dl=0"
},
"data/input/krakow/krakow_center_separate_cycleways.bin": {
"checksum": "4a3a56819a46c320248bb967d19d0e9f",
"checksum": "f9ada6cd71de616b558983ed26847577",
"dropbox_url": "https://www.dropbox.com/s/vljil5rin981uwz/krakow_center_separate_cycleways.bin.gz?dl=0"
},
"data/input/krakow/krakow_center_snapped_cycleways.bin": {
@ -141,7 +141,7 @@
"dropbox_url": "https://www.dropbox.com/s/k1y8tqbgcyvaffd/downtown.zip.gz?dl=0"
},
"data/input/screenshots/krakow_center.zip": {
"checksum": "86485a7b1e81cd7d8efdf87f54d62703",
"checksum": "838f7b365e66fa732feeb7a15558efc4",
"dropbox_url": "https://www.dropbox.com/s/lq5313pjaj66904/krakow_center.zip.gz?dl=0"
},
"data/input/screenshots/lakeslice.zip": {
@ -413,7 +413,7 @@
"dropbox_url": "https://www.dropbox.com/s/fff3h6g06g9mirm/huge_seattle.bin.gz?dl=0"
},
"data/system/maps/krakow_center.bin": {
"checksum": "c5222753fd657a970bc5401be8279784",
"checksum": "fbc1de44d8b089011e1989d2d5b812e5",
"dropbox_url": "https://www.dropbox.com/s/6l3iubvqz7uhmv5/krakow_center.bin.gz?dl=0"
},
"data/system/maps/lakeslice.bin": {

View File

@ -205,6 +205,10 @@ impl Renderable for DrawIntersection {
// TODO Temporarily public for debugging.
pub fn calculate_corners(i: &Intersection, map: &Map) -> Vec<Polygon> {
if i.is_footway(map) {
return Vec::new();
}
let mut corners = Vec::new();
for turn in map.get_turns_in_intersection(i.id) {

View File

@ -196,24 +196,6 @@ impl Map {
biking_blackhole: false,
});
}
if road.get_name(None) == "???" {
// Suppress the warning in some cases.
if !(road.osm_tags.is("noname", "yes")
|| road
.osm_tags
.get(osm::HIGHWAY)
.map(|x| x.ends_with("_link"))
.unwrap_or(false)
|| road.osm_tags.is_any("railway", vec!["rail", "light_rail"])
|| road.osm_tags.is("junction", "roundabout")
|| road.osm_tags.is("highway", "service"))
{
timer.warn(format!(
"{} has no name. Tags: {:?}",
road.orig_id, road.osm_tags
));
}
}
map.roads.push(road);
}
@ -249,7 +231,7 @@ impl Map {
if i.is_border() || i.is_closed() {
continue;
}
if i.incoming_lanes.is_empty() || i.outgoing_lanes.is_empty() {
if !i.is_footway(&map) && (i.incoming_lanes.is_empty() || i.outgoing_lanes.is_empty()) {
timer.warn(format!("{} is orphaned!", i.orig_id));
continue;
}

View File

@ -10,8 +10,6 @@ use crate::{Intersection, Lane, LaneID, Map, RoadID, Turn, TurnID, TurnType};
/// Generate all driving and walking turns at an intersection, accounting for OSM turn restrictions.
pub fn make_all_turns(map: &Map, i: &Intersection, timer: &mut Timer) -> Vec<Turn> {
assert!(!i.is_border());
let mut raw_turns: Vec<Turn> = Vec::new();
raw_turns.extend(make_vehicle_turns(i, map, timer));
raw_turns.extend(crate::make::walking_turns::make_walking_turns(

View File

@ -10,6 +10,10 @@ use crate::{
/// Generate Crosswalk and SharedSidewalkCorner (places where two sidewalks directly meet) turns
pub fn make_walking_turns(map: &Map, i: &Intersection, timer: &mut Timer) -> Vec<Turn> {
if i.is_footway(map) {
return make_footway_turns(map, i);
}
let driving_side = map.config.driving_side;
let all_roads = map.all_roads();
let lanes = map.all_lanes();
@ -253,6 +257,45 @@ pub fn _make_walking_turns_v2(map: &Map, i: &Intersection, timer: &mut Timer) ->
result
}
/// At an intersection of footpaths only, just generate a turn between every pair of lanes.
fn make_footway_turns(map: &Map, i: &Intersection) -> Vec<Turn> {
let lanes = i
.incoming_lanes
.iter()
.chain(&i.outgoing_lanes)
.filter_map(|l| {
let l = map.get_l(*l);
if l.is_walkable() {
Some(l)
} else {
None
}
})
.collect::<Vec<&Lane>>();
let mut results = Vec::new();
for l1 in &lanes {
for l2 in &lanes {
if l1.id == l2.id {
continue;
}
let maybe_geom = PolyLine::new(vec![l1.endpoint(i.id), l2.endpoint(i.id)]);
let geom = maybe_geom.unwrap_or_else(|_| {
// TODO Gross! After improving intersection geometry where these cases are
// happening, if this still happens, maybe it's time to make turn geometry be
// optional.
PolyLine::must_new(vec![l1.endpoint(i.id), l1.endpoint(i.id).offset(0.1, 0.1)])
});
results.push(Turn {
id: turn_id(i.id, l1.id, l2.id),
turn_type: TurnType::SharedSidewalkCorner,
other_crosswalk_ids: BTreeSet::new(),
geom,
});
}
}
results
}
fn make_crosswalks(i: IntersectionID, l1: &Lane, l2: &Lane) -> Option<Vec<Turn>> {
let l1_pt = l1.endpoint(i);
let l2_pt = l2.endpoint(i);