1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::collections::BTreeSet;
use map_gui::tools::{ColorDiscrete, PopupMsg};
use map_model::{connectivity, EditCmd, PathConstraints};
use widgetry::{Color, EventCtx, State};
use crate::app::App;
pub fn check_sidewalk_connectivity(
ctx: &mut EventCtx,
app: &mut App,
cmd: EditCmd,
) -> Option<Box<dyn State<App>>> {
let orig_edits = app.primary.map.get_edits().clone();
let (_, disconnected_before) =
connectivity::find_scc(&app.primary.map, PathConstraints::Pedestrian);
let mut edits = orig_edits.clone();
edits.commands.push(cmd);
app.primary.map.try_apply_edits(edits);
let (_, disconnected_after) =
connectivity::find_scc(&app.primary.map, PathConstraints::Pedestrian);
app.primary.map.must_apply_edits(orig_edits);
let newly_disconnected = disconnected_after
.difference(&disconnected_before)
.collect::<Vec<_>>();
if newly_disconnected.is_empty() {
return None;
}
let mut c = ColorDiscrete::new(app, vec![("disconnected", Color::RED)]);
let num = newly_disconnected.len();
for l in newly_disconnected {
c.add_l(*l, "disconnected");
}
let (unzoomed, zoomed, _) = c.build(ctx);
Some(PopupMsg::also_draw(
ctx,
"Error",
vec![format!(
"Can't close this intersection; {} sidewalks disconnected",
num
)],
unzoomed,
zoomed,
))
}
#[allow(unused)]
pub fn check_blackholes(
ctx: &mut EventCtx,
app: &mut App,
cmd: EditCmd,
) -> Option<Box<dyn State<App>>> {
let orig_edits = app.primary.map.get_edits().clone();
let mut driving_ok_originally = BTreeSet::new();
let mut biking_ok_originally = BTreeSet::new();
for l in app.primary.map.all_lanes().values() {
if !l.driving_blackhole {
driving_ok_originally.insert(l.id);
}
if !l.biking_blackhole {
biking_ok_originally.insert(l.id);
}
}
let mut edits = orig_edits.clone();
edits.commands.push(cmd);
app.primary.map.try_apply_edits(edits);
let mut newly_disconnected = BTreeSet::new();
for l in connectivity::find_scc(&app.primary.map, PathConstraints::Car).1 {
if driving_ok_originally.contains(&l) {
newly_disconnected.insert(l);
}
}
for l in connectivity::find_scc(&app.primary.map, PathConstraints::Bike).1 {
if biking_ok_originally.contains(&l) {
newly_disconnected.insert(l);
}
}
app.primary.map.must_apply_edits(orig_edits);
if newly_disconnected.is_empty() {
return None;
}
let mut c = ColorDiscrete::new(app, vec![("disconnected", Color::RED)]);
let num = newly_disconnected.len();
for l in newly_disconnected {
c.add_l(l, "disconnected");
}
let (unzoomed, zoomed, _) = c.build(ctx);
Some(PopupMsg::also_draw(
ctx,
"Error",
vec![format!("{} lanes have been disconnected", num)],
unzoomed,
zoomed,
))
}