mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
adding a new hint for extra turn restrictions
This commit is contained in:
parent
bf5c45cd72
commit
574e30b3d8
@ -331,6 +331,30 @@
|
||||
"latitude": 47.6447682
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"BanTurnsBetween": [
|
||||
{
|
||||
"pt1": {
|
||||
"longitude": -122.2961948,
|
||||
"latitude": 47.6234769
|
||||
},
|
||||
"pt2": {
|
||||
"longitude": -122.296451,
|
||||
"latitude": 47.6236649
|
||||
}
|
||||
},
|
||||
{
|
||||
"pt1": {
|
||||
"longitude": -122.2965799,
|
||||
"latitude": 47.6236045
|
||||
},
|
||||
"pt2": {
|
||||
"longitude": -122.2964149,
|
||||
"latitude": 47.6233284
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"parking_overrides": [
|
||||
@ -341,7 +365,7 @@
|
||||
"latitude": 47.647500000184834
|
||||
},
|
||||
"pt2": {
|
||||
"longitude": -122.30462539972673,
|
||||
"longitude": -122.30462539972672,
|
||||
"latitude": 47.6469044999953
|
||||
}
|
||||
},
|
||||
|
@ -6,7 +6,7 @@ become the complex maps in A/B Street. As always,
|
||||
process generalizes to most cities in OpenStreetMap. Some extra data specific to
|
||||
Seattle is used, but could be ommitted.
|
||||
|
||||
Everything here should be up-to-date as of July 2019.
|
||||
Everything here should be up-to-date as of August 2019.
|
||||
|
||||
<!--ts-->
|
||||
|
||||
@ -176,6 +176,9 @@ before the final Map: InitialMap and HalfMap.
|
||||
lanes, speed limit, or some other reason to preserve the intersection.
|
||||
- The hint to override parking on a road: the blockface dataset is inaccurate
|
||||
sometimes, so manually toggle parking on a road.
|
||||
- The ban turns hint: don't allow turns from one road to another. In areas
|
||||
with many close intersections, there are some U-turns that may be valid in
|
||||
reality, but quickly cause gridlock in the simulation.
|
||||
|
||||
## InitialMap to HalfMap
|
||||
|
||||
|
@ -28,6 +28,11 @@ enum State {
|
||||
osd: Text,
|
||||
},
|
||||
BrowsingHints(WarpingItemSlider<Hint>),
|
||||
BanTurnsBetween {
|
||||
from: StableRoadID,
|
||||
selected: Option<ID>,
|
||||
osd: Text,
|
||||
},
|
||||
}
|
||||
|
||||
impl State {
|
||||
@ -95,13 +100,6 @@ impl GUI for UI {
|
||||
len,
|
||||
self.hints.parking_overrides.len()
|
||||
));
|
||||
for i in (1..=5).rev() {
|
||||
if len >= i {
|
||||
txt.add_line(describe(&self.hints.hints[len - i]));
|
||||
} else {
|
||||
txt.add_line("...".to_string());
|
||||
}
|
||||
}
|
||||
if let Some(ID::Road(r)) = selected {
|
||||
txt.push(format!(
|
||||
"[red:{}] is {} long",
|
||||
@ -169,7 +167,9 @@ impl GUI for UI {
|
||||
.iter()
|
||||
.filter_map(|h| {
|
||||
let gps_pt = match h {
|
||||
Hint::MergeRoad(r) | Hint::DeleteRoad(r) => {
|
||||
Hint::MergeRoad(r)
|
||||
| Hint::DeleteRoad(r)
|
||||
| Hint::BanTurnsBetween(r, _) => {
|
||||
self.raw.roads[&self.raw.find_r(*r)?].points[0]
|
||||
}
|
||||
Hint::MergeDegenerateIntersection(i) => {
|
||||
@ -240,6 +240,16 @@ impl GUI for UI {
|
||||
&mut Timer::new("override parking"),
|
||||
);
|
||||
self.world = initial_map_to_world(&self.data, ctx);
|
||||
} else if ctx
|
||||
.input
|
||||
.key_pressed(Key::T, "ban turns between this road and another")
|
||||
{
|
||||
self.state = State::BanTurnsBetween {
|
||||
from: *r,
|
||||
selected: *selected,
|
||||
osd: Text::new(),
|
||||
};
|
||||
return EventLoopMode::InputOnly;
|
||||
}
|
||||
}
|
||||
if let Some(ID::Intersection(i)) = selected {
|
||||
@ -271,6 +281,43 @@ impl GUI for UI {
|
||||
EventLoopMode::InputOnly
|
||||
}
|
||||
}
|
||||
State::BanTurnsBetween {
|
||||
from,
|
||||
ref mut selected,
|
||||
ref mut osd,
|
||||
} => {
|
||||
ctx.canvas.handle_event(ctx.input);
|
||||
|
||||
if ctx.redo_mouseover() {
|
||||
*selected = self.world.mouseover_something(ctx, &HashSet::new());
|
||||
}
|
||||
|
||||
if ctx.input.key_pressed(Key::Escape, "cancel") {
|
||||
self.state = State::main(ctx);
|
||||
return EventLoopMode::InputOnly;
|
||||
} else if let Some(ID::Road(r)) = selected {
|
||||
// TODO Why do we use data and not raw here?
|
||||
let (i1, i2) = (self.data.roads[&from].src_i, self.data.roads[&from].dst_i);
|
||||
let (i3, i4) = (self.data.roads[r].src_i, self.data.roads[r].dst_i);
|
||||
|
||||
if from != *r
|
||||
&& (i1 == i3 || i1 == i4 || i2 == i3 || i2 == i4)
|
||||
&& ctx.input.key_pressed(Key::T, "ban turns to this road")
|
||||
{
|
||||
self.hints.hints.push(Hint::BanTurnsBetween(
|
||||
self.raw.roads[&from].orig_id(),
|
||||
self.raw.roads[r].orig_id(),
|
||||
));
|
||||
// There's nothing to change about our model here.
|
||||
self.state = State::main(ctx);
|
||||
return EventLoopMode::InputOnly;
|
||||
}
|
||||
}
|
||||
|
||||
*osd = Text::new();
|
||||
ctx.input.populate_osd(osd);
|
||||
EventLoopMode::InputOnly
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,7 +342,7 @@ impl GUI for UI {
|
||||
State::BrowsingHints(ref slider) => {
|
||||
let poly =
|
||||
match slider.get().1 {
|
||||
Hint::MergeRoad(r) | Hint::DeleteRoad(r) => {
|
||||
Hint::MergeRoad(r) | Hint::DeleteRoad(r) | Hint::BanTurnsBetween(r, _) => {
|
||||
PolyLine::new(self.raw.gps_bounds.must_convert(
|
||||
&self.raw.roads[&self.raw.find_r(*r).unwrap()].points,
|
||||
))
|
||||
@ -316,6 +363,17 @@ impl GUI for UI {
|
||||
|
||||
slider.draw(g);
|
||||
}
|
||||
State::BanTurnsBetween {
|
||||
ref selected,
|
||||
ref osd,
|
||||
..
|
||||
} => {
|
||||
if let Some(id) = selected {
|
||||
self.world.draw_selected(g, *id);
|
||||
}
|
||||
|
||||
g.draw_blocking_text(osd, ezgui::BOTTOM_LEFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -392,5 +450,6 @@ fn describe(hint: &Hint) -> String {
|
||||
Hint::MergeRoad(_) => "MergeRoad(...)".to_string(),
|
||||
Hint::DeleteRoad(_) => "DeleteRoad(...)".to_string(),
|
||||
Hint::MergeDegenerateIntersection(_) => "MergeDegenerateIntersection(...)".to_string(),
|
||||
Hint::BanTurnsBetween(_, _) => "BanTurnsBetween(...)".to_string(),
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,11 @@
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$1" != "" ]; then
|
||||
~/npm/node_modules/prettier/bin-prettier.js --write --prose-wrap=always $1;
|
||||
exit
|
||||
fi
|
||||
|
||||
# Ignore notes; they're not important
|
||||
for x in `find | grep '.md$' | grep -v design/notes | grep -v TODO_ | grep -v CHANGELOG.md`; do
|
||||
~/npm/node_modules/prettier/bin-prettier.js --write --prose-wrap=always $x;
|
||||
|
@ -87,6 +87,10 @@ pub fn make_half_map(
|
||||
parking_lane_fwd: r.parking_lane_fwd,
|
||||
parking_lane_back: r.parking_lane_back,
|
||||
};
|
||||
for stable_id in &r.override_turn_restrictions_to {
|
||||
road.turn_restrictions
|
||||
.push(("no_anything".to_string(), road_id_mapping[stable_id]));
|
||||
}
|
||||
|
||||
for lane in &r.lane_specs {
|
||||
let id = LaneID(half_map.lanes.len());
|
||||
|
@ -32,6 +32,7 @@ pub struct Road {
|
||||
pub osm_tags: BTreeMap<String, String>,
|
||||
pub parking_lane_fwd: bool,
|
||||
pub parking_lane_back: bool,
|
||||
pub override_turn_restrictions_to: Vec<StableRoadID>,
|
||||
}
|
||||
|
||||
impl Road {
|
||||
@ -165,6 +166,7 @@ impl InitialMap {
|
||||
osm_tags: r.osm_tags.clone(),
|
||||
parking_lane_fwd: r.parking_lane_fwd,
|
||||
parking_lane_back: r.parking_lane_back,
|
||||
override_turn_restrictions_to: Vec::new(),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -345,6 +347,18 @@ impl InitialMap {
|
||||
self.merge_degenerate_intersection(i, timer);
|
||||
}
|
||||
}
|
||||
Hint::BanTurnsBetween(orig1, orig2) => {
|
||||
if let Some(r1) = raw.find_r(*orig1) {
|
||||
if let Some(r2) = raw.find_r(*orig2) {
|
||||
self.roads
|
||||
.get_mut(&r1)
|
||||
.unwrap()
|
||||
.override_turn_restrictions_to
|
||||
.push(r2);
|
||||
cnt += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
timer.note(format!("Applied {} of {} hints", cnt, hints.hints.len()));
|
||||
@ -395,6 +409,7 @@ pub enum Hint {
|
||||
MergeRoad(raw_data::OriginalRoad),
|
||||
DeleteRoad(raw_data::OriginalRoad),
|
||||
MergeDegenerateIntersection(raw_data::OriginalIntersection),
|
||||
BanTurnsBetween(raw_data::OriginalRoad, raw_data::OriginalRoad),
|
||||
}
|
||||
|
||||
pub struct LaneSpec {
|
||||
|
@ -526,7 +526,7 @@ fn does_turn_pass_restrictions(
|
||||
//
|
||||
// Strip off time restrictions (like " @ (Mo-Fr 06:00-09:00, 15:00-18:30)")
|
||||
match restriction.split(" @ ").next().unwrap() {
|
||||
"no_left_turn" | "no_right_turn" | "no_straight_on" | "no_u_turn" => {
|
||||
"no_left_turn" | "no_right_turn" | "no_straight_on" | "no_u_turn" | "no_anything" => {
|
||||
if dst == *to {
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user