auto detect clusters of signals, seed the UI with that

This commit is contained in:
Dustin Carlino 2020-05-21 10:00:57 -07:00
parent cf2ce9f5dd
commit bcd5d39626
2 changed files with 52 additions and 8 deletions

View File

@ -21,7 +21,12 @@ pub struct UberTurnPicker {
impl UberTurnPicker {
pub fn new(ctx: &mut EventCtx, app: &App, i: IntersectionID) -> Box<dyn State> {
let mut members = BTreeSet::new();
members.insert(i);
if let Some(list) = IntersectionCluster::autodetect(i, &app.primary.map) {
members.extend(list);
} else {
members.insert(i);
}
Box::new(UberTurnPicker {
members,
composite: Composite::new(
@ -35,6 +40,7 @@ impl UberTurnPicker {
.align_right(),
]),
Btn::text_fg("View uber-turns").build_def(ctx, None),
Btn::text_fg("Edit").build_def(ctx, None),
])
.padding(10)
.bg(app.cs.panel_bg),
@ -81,6 +87,19 @@ impl State for UberTurnPicker {
true,
));
}
"Edit" => {
if self.members.len() < 2 {
return Transition::Push(msg(
"Error",
vec!["Select at least two intersections"],
));
}
return Transition::Replace(ClusterTrafficSignalEditor::new(
ctx,
app,
&IntersectionCluster::new(self.members.clone(), &app.primary.map).0,
));
}
_ => unreachable!(),
},
None => {}
@ -177,7 +196,6 @@ impl UberTurnViewer {
Btn::text_fg("X").build_def(ctx, hotkey(Key::Escape)),
]),
Checkbox::text(ctx, "legal / illegal movements", None, legal_turns),
Btn::text_fg("Edit").build_def(ctx, None),
])
.padding(10)
.bg(app.cs.panel_bg),
@ -200,11 +218,6 @@ impl State for UberTurnViewer {
"X" => {
return Transition::Pop;
}
"Edit" => {
return Transition::Replace(ClusterTrafficSignalEditor::new(
ctx, app, &self.ic,
));
}
"previous uber-turn" => {
return Transition::Replace(UberTurnViewer::new(
ctx,

View File

@ -1,5 +1,5 @@
use crate::{DirectedRoadID, IntersectionID, LaneID, Map, TurnID};
use abstutil::MultiMap;
use abstutil::{retain_btreeset, MultiMap};
use geom::{Distance, PolyLine, Pt2D};
use petgraph::graphmap::UnGraphMap;
use serde::{Deserialize, Serialize};
@ -109,6 +109,37 @@ impl IntersectionCluster {
},
)
}
// Find all other traffic signals "close" to one
// TODO I haven't found a case with interior nodes yet
pub fn autodetect(from: IntersectionID, map: &Map) -> Option<BTreeSet<IntersectionID>> {
let threshold = Distance::meters(25.0);
let mut found = BTreeSet::new();
let mut queue = vec![from];
while !queue.is_empty() {
let i = map.get_i(queue.pop().unwrap());
if found.contains(&i.id) {
continue;
}
found.insert(i.id);
for r in &i.roads {
let r = map.get_r(*r);
if r.center_pts.length() > threshold {
continue;
}
let other = if r.src_i == i.id { r.dst_i } else { r.src_i };
queue.push(other);
}
}
retain_btreeset(&mut found, |i| map.get_i(*i).is_traffic_signal());
if found.len() > 1 {
Some(found)
} else {
None
}
}
}
fn flood(start: TurnID, map: &Map, exits: &BTreeSet<TurnID>) -> Vec<UberTurn> {