mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 06:55:40 +03:00
Make the rat-run detector respect modal filters.
Overall results still not right, but getting closer. Some "rat-runs" retained will only be in the neighborhood out of "necessity" -- they should maybe be totally filtered out for the heatmap counts.
This commit is contained in:
parent
83bf6953d1
commit
fd852795c2
@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use geom::{Circle, Distance, Line, Polygon};
|
||||
use map_gui::tools::DrawRoadLabels;
|
||||
use map_model::{IntersectionID, Map, Perimeter, RoadID};
|
||||
use map_model::{IntersectionID, Map, Perimeter, RoadID, RoutingParams, TurnID};
|
||||
use widgetry::mapspace::ToggleZoomed;
|
||||
use widgetry::{Color, Drawable, EventCtx, GeomBatch};
|
||||
|
||||
@ -41,6 +41,25 @@ pub struct ModalFilters {
|
||||
pub intersections: BTreeMap<IntersectionID, DiagonalFilter>,
|
||||
}
|
||||
|
||||
impl ModalFilters {
|
||||
/// Modify RoutingParams to respect these modal filters
|
||||
pub fn update_routing_params(&self, params: &mut RoutingParams) {
|
||||
params.avoid_roads.extend(self.roads.keys().cloned());
|
||||
for filter in self.intersections.values() {
|
||||
params
|
||||
.avoid_movements_between
|
||||
.extend(filter.avoid_movements_between_roads());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allows_turn(&self, t: TurnID) -> bool {
|
||||
if let Some(filter) = self.intersections.get(&t.parent) {
|
||||
return filter.allows_turn(t.src.road, t.dst.road);
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// A diagonal filter exists in an intersection. It's defined by two roads (the order is
|
||||
/// arbitrary). When all of the intersection's roads are sorted in clockwise order, this pair of
|
||||
/// roads splits the ordering into two groups. Turns in each group are still possible, but not
|
||||
|
@ -38,16 +38,30 @@ pub fn find_rat_runs(
|
||||
}
|
||||
}
|
||||
|
||||
let mut params = map.routing_params().clone();
|
||||
modal_filters.update_routing_params(&mut params);
|
||||
let cache_custom = true;
|
||||
let mut paths: Vec<Path> = timer
|
||||
.parallelize(
|
||||
"calculate paths between entrances and exits",
|
||||
requests,
|
||||
|req| map.pathfind(req),
|
||||
|req| map.pathfind_with_params(req, ¶ms, cache_custom),
|
||||
)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
// update_routing_params heavily penalizes crossing modal filters, but it doesn't prevent it
|
||||
// completely! So strip out paths that were forced to cross a filter.
|
||||
paths.retain(|path| {
|
||||
!path.get_steps().iter().any(|step| match step {
|
||||
PathStep::Lane(l) => modal_filters.roads.contains_key(&l.road),
|
||||
PathStep::Turn(t) => !modal_filters.allows_turn(*t),
|
||||
// Car paths don't make contraflow movements
|
||||
_ => unreachable!(),
|
||||
})
|
||||
});
|
||||
|
||||
// Some paths wind up partly using perimeter roads (or even things outside the neighborhood
|
||||
// entirely). Sort by "worse" paths that spend more time inside.
|
||||
paths.sort_by_key(|path| {
|
||||
|
@ -87,14 +87,7 @@ impl RoutePlanner {
|
||||
// First the route respecting the filters
|
||||
let (total_time_after, total_dist_after) = {
|
||||
let mut params = map.routing_params().clone();
|
||||
params
|
||||
.avoid_roads
|
||||
.extend(app.session.modal_filters.roads.keys().cloned());
|
||||
for filter in app.session.modal_filters.intersections.values() {
|
||||
params
|
||||
.avoid_movements_between
|
||||
.extend(filter.avoid_movements_between_roads());
|
||||
}
|
||||
app.session.modal_filters.update_routing_params(&mut params);
|
||||
params.main_road_penalty = self.panel.spinner::<RoundedF64>("main road penalty").0;
|
||||
let cache_custom = true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user