Place filters where the user draws on a road when resolving one-ways, just like for bus gates

This commit is contained in:
Dustin Carlino 2022-11-12 18:51:52 +00:00
parent be04631d88
commit f3c2687dfc
3 changed files with 35 additions and 36 deletions

View File

@ -60,30 +60,30 @@ pub fn handle_world_outcome(
WorldOutcome::ClickedObject(Obj::InteriorRoad(r)) => {
let road = map.get_r(r);
// The world doesn't contain non-driveable roads, so no need to check for that error
if road.oneway_for_driving().is_some() {
if app.session.layers.autofix_one_ways {
super::fix_oneway_and_add_filter(ctx, app, &[r]);
return EditOutcome::Transition(Transition::Recreate);
}
return EditOutcome::Transition(Transition::Push(
super::ResolveOneWayAndFilter::new_state(ctx, vec![r]),
));
}
if road.is_deadend_for_driving(&app.per_map.map) {
return EditOutcome::error(ctx, "You can't filter a dead-end");
}
// Place the filter on the part of the road that was clicked
// These calls shouldn't fail -- since we clicked a road, the cursor must be in
// map-space. And project_pt returns a point that's guaranteed to be on the polyline.
let cursor_pt = ctx.canvas.get_cursor_in_map_space().unwrap();
let pt_on_line = road.center_pts.project_pt(cursor_pt);
let (distance, _) = road.center_pts.dist_along_of_point(pt_on_line).unwrap();
if road.oneway_for_driving().is_some() {
if app.session.layers.autofix_one_ways {
super::fix_oneway_and_add_filter(ctx, app, &[(r, distance)]);
return EditOutcome::Transition(Transition::Recreate);
}
return EditOutcome::Transition(Transition::Push(
super::ResolveOneWayAndFilter::new_state(ctx, vec![(r, distance)]),
));
}
app.per_map.proposals.before_edit();
if mut_edits!(app).roads.remove(&r).is_none() {
// Place the filter on the part of the road that was clicked
// These calls shouldn't fail -- since we clicked a road, the cursor must be in
// map-space. And project_pt returns a point that's guaranteed to be on the
// polyline.
let cursor_pt = ctx.canvas.get_cursor_in_map_space().unwrap();
let pt_on_line = road.center_pts.project_pt(cursor_pt);
let (distance, _) = road.center_pts.dist_along_of_point(pt_on_line).unwrap();
let mut filter_type = app.session.filter_type;
if filter_type != FilterType::BusGate

View File

@ -42,21 +42,21 @@ fn make_filters_along_path(
continue;
}
if let Some((pt, _)) = road.center_pts.intersection(&path) {
if road.oneway_for_driving().is_some() {
if app.session.layers.autofix_one_ways {
super::fix_oneway_and_add_filter(ctx, app, &[*r]);
} else {
oneways.push(*r);
}
continue;
}
let dist = road
.center_pts
.dist_along_of_point(pt)
.map(|pair| pair.0)
.unwrap_or(road.center_pts.length() / 2.0);
if road.oneway_for_driving().is_some() {
if app.session.layers.autofix_one_ways {
super::fix_oneway_and_add_filter(ctx, app, &[(*r, dist)]);
} else {
oneways.push((*r, dist));
}
continue;
}
let mut filter_type = app.session.filter_type;
if filter_type != FilterType::BusGate
&& !app.per_map.map.get_bus_routes_on_road(*r).is_empty()

View File

@ -186,11 +186,11 @@ fn road_name(app: &App, road: &Road) -> String {
struct ResolveOneWayAndFilter {
panel: Panel,
roads: Vec<RoadID>,
roads: Vec<(RoadID, Distance)>,
}
impl ResolveOneWayAndFilter {
fn new_state(ctx: &mut EventCtx, roads: Vec<RoadID>) -> Box<dyn State<App>> {
fn new_state(ctx: &mut EventCtx, roads: Vec<(RoadID, Distance)>) -> Box<dyn State<App>> {
let mut txt = Text::new();
txt.add_line(Line("Warning").small_heading());
txt.add_line("A modal filter cannot be placed on a one-way street.");
@ -232,10 +232,10 @@ impl State<App> for ResolveOneWayAndFilter {
}
}
fn fix_oneway_and_add_filter(ctx: &mut EventCtx, app: &mut App, roads: &[RoadID]) {
fn fix_oneway_and_add_filter(ctx: &mut EventCtx, app: &mut App, roads: &[(RoadID, Distance)]) {
let driving_side = app.per_map.map.get_config().driving_side;
let mut edits = app.per_map.map.get_edits().clone();
for r in roads {
for (r, _) in roads {
edits
.commands
.push(app.per_map.map.edit_road_cmd(*r, |new| {
@ -253,7 +253,7 @@ fn fix_oneway_and_add_filter(ctx: &mut EventCtx, app: &mut App, roads: &[RoadID]
app.per_map.proposals.before_edit();
for r in roads {
for (r, dist) in roads {
let r = *r;
let road = app.per_map.map.get_r(r);
let r_edit = app.per_map.map.get_r_edit(r);
@ -263,10 +263,9 @@ fn fix_oneway_and_add_filter(ctx: &mut EventCtx, app: &mut App, roads: &[RoadID]
mut_edits!(app).one_ways.insert(r, r_edit);
}
mut_edits!(app).roads.insert(
r,
RoadFilter::new_by_user(road.length() / 2.0, app.session.filter_type),
);
mut_edits!(app)
.roads
.insert(r, RoadFilter::new_by_user(*dist, app.session.filter_type));
}
redraw_all_filters(ctx, app);