mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +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 geom::{Circle, Distance, Line, Polygon};
|
||||||
use map_gui::tools::DrawRoadLabels;
|
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::mapspace::ToggleZoomed;
|
||||||
use widgetry::{Color, Drawable, EventCtx, GeomBatch};
|
use widgetry::{Color, Drawable, EventCtx, GeomBatch};
|
||||||
|
|
||||||
@ -41,6 +41,25 @@ pub struct ModalFilters {
|
|||||||
pub intersections: BTreeMap<IntersectionID, DiagonalFilter>,
|
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
|
/// 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
|
/// 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
|
/// 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
|
let mut paths: Vec<Path> = timer
|
||||||
.parallelize(
|
.parallelize(
|
||||||
"calculate paths between entrances and exits",
|
"calculate paths between entrances and exits",
|
||||||
requests,
|
requests,
|
||||||
|req| map.pathfind(req),
|
|req| map.pathfind_with_params(req, ¶ms, cache_custom),
|
||||||
)
|
)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.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
|
// Some paths wind up partly using perimeter roads (or even things outside the neighborhood
|
||||||
// entirely). Sort by "worse" paths that spend more time inside.
|
// entirely). Sort by "worse" paths that spend more time inside.
|
||||||
paths.sort_by_key(|path| {
|
paths.sort_by_key(|path| {
|
||||||
|
@ -87,14 +87,7 @@ impl RoutePlanner {
|
|||||||
// First the route respecting the filters
|
// First the route respecting the filters
|
||||||
let (total_time_after, total_dist_after) = {
|
let (total_time_after, total_dist_after) = {
|
||||||
let mut params = map.routing_params().clone();
|
let mut params = map.routing_params().clone();
|
||||||
params
|
app.session.modal_filters.update_routing_params(&mut 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());
|
|
||||||
}
|
|
||||||
params.main_road_penalty = self.panel.spinner::<RoundedF64>("main road penalty").0;
|
params.main_road_penalty = self.panel.spinner::<RoundedF64>("main road penalty").0;
|
||||||
let cache_custom = true;
|
let cache_custom = true;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user