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
use std::collections::BTreeSet;
use enumset::EnumSet;
use serde::{Deserialize, Serialize};
use crate::{IntersectionID, Map, PathConstraints, RoadID};
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct AccessRestrictions {
pub allow_through_traffic: EnumSet<PathConstraints>,
}
impl AccessRestrictions {
pub fn new() -> AccessRestrictions {
AccessRestrictions {
allow_through_traffic: EnumSet::all(),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Zone {
pub members: BTreeSet<RoadID>,
pub borders: BTreeSet<IntersectionID>,
pub restrictions: AccessRestrictions,
}
impl Zone {
pub fn make_all(map: &Map) -> Vec<Zone> {
let mut queue = Vec::new();
for r in map.all_roads() {
if r.is_private() {
queue.push(r.id);
}
}
let mut zones = Vec::new();
let mut seen = BTreeSet::new();
while !queue.is_empty() {
let start = queue.pop().unwrap();
if seen.contains(&start) {
continue;
}
let zone = floodfill(map, start);
seen.extend(zone.members.clone());
zones.push(zone);
}
zones
}
}
fn floodfill(map: &Map, start: RoadID) -> Zone {
let match_constraints = map.get_r(start).access_restrictions.clone();
let merge_zones = map.get_edits().merge_zones;
let mut queue = vec![start];
let mut members = BTreeSet::new();
let mut borders = BTreeSet::new();
while !queue.is_empty() {
let current = queue.pop().unwrap();
if members.contains(¤t) {
continue;
}
members.insert(current);
for r in map.get_next_roads(current) {
let r = map.get_r(r);
if r.access_restrictions == match_constraints && merge_zones {
queue.push(r.id);
} else {
borders.insert(map.get_r(current).common_endpt(r));
}
}
}
assert!(!members.is_empty());
assert!(!borders.is_empty());
Zone {
members,
borders,
restrictions: match_constraints,
}
}