show sidewalks disconnected in edit impact. prerequisite to preventing this.

This commit is contained in:
Dustin Carlino 2019-11-12 16:08:39 -08:00
parent 03d599775f
commit 628111b421
4 changed files with 57 additions and 4 deletions

View File

@ -1,5 +1,6 @@
use crate::ui::UI;
use abstutil::{prettyprint_usize, Timer};
use map_model::connectivity;
use sim::Scenario;
// Edits have been applied.
@ -23,5 +24,11 @@ pub fn edit_impacts(scenario: Option<Scenario>, ui: &mut UI, timer: &mut Timer)
lines.push("No scenario, so no trips impacted".to_string());
}
let (_, disconnected) = connectivity::find_sidewalk_scc(&ui.primary.map);
// TODO Display them
if !disconnected.is_empty() {
lines.push(format!("{} sidewalks disconnected", disconnected.len()));
}
lines
}

View File

@ -0,0 +1,37 @@
use crate::{LaneID, Map};
use petgraph::graphmap::DiGraphMap;
use std::collections::HashSet;
// SCC = strongly connected component
// TODO Move make/parking_blackholes.rs logic here.
// TODO Move debug/floodfill.rs logic here.
// Returns (sidewalks in main component, disconnected sidewalks)
pub fn find_sidewalk_scc(map: &Map) -> (HashSet<LaneID>, HashSet<LaneID>) {
let mut graph = DiGraphMap::new();
for turn in map.all_turns().values() {
if map.is_turn_allowed(turn.id) && turn.between_sidewalks() {
graph.add_edge(turn.id.src, turn.id.dst, 1);
}
}
let components = petgraph::algo::kosaraju_scc(&graph);
let largest_group: HashSet<LaneID> = components
.into_iter()
.max_by_key(|c| c.len())
.unwrap()
.into_iter()
.collect();
let disconnected = map
.all_lanes()
.iter()
.filter_map(|l| {
if l.is_sidewalk() && !largest_group.contains(&l.id) {
Some(l.id)
} else {
None
}
})
.collect();
(largest_group, disconnected)
}

View File

@ -1,6 +1,7 @@
mod area;
mod building;
mod bus_stop;
pub mod connectivity;
mod edits;
mod intersection;
mod lane;

View File

@ -1,10 +1,10 @@
use crate::pathfind::Pathfinder;
use crate::raw::{OriginalIntersection, OriginalRoad, RawMap};
use crate::{
make, osm, Area, AreaID, Building, BuildingID, BusRoute, BusRouteID, BusStop, BusStopID,
ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID, IntersectionType, Lane,
LaneID, LaneType, MapEdits, Path, PathRequest, Position, Road, RoadID, Turn, TurnID,
TurnPriority, LANE_THICKNESS,
connectivity, make, osm, Area, AreaID, Building, BuildingID, BusRoute, BusRouteID, BusStop,
BusStopID, ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID,
IntersectionType, Lane, LaneID, LaneType, MapEdits, Path, PathRequest, Position, Road, RoadID,
Turn, TurnID, TurnPriority, LANE_THICKNESS,
};
use abstutil;
use abstutil::{deserialize_btreemap, serialize_btreemap, Error, Timer};
@ -178,6 +178,14 @@ impl Map {
}
timer.stop("find parking blackholes");
let (_, disconnected) = connectivity::find_sidewalk_scc(&m);
if !disconnected.is_empty() {
timer.warn(format!(
"{} sidewalks are disconnected!",
disconnected.len()
));
}
timer.stop("finalize Map");
m
}