Cache the custom pathfinders in the LTN impact tool. I had trouble with this previously, because it was exposing the RoutingParams bug just fixed. #852

This commit is contained in:
Dustin Carlino 2022-03-25 11:24:18 +00:00
parent b89e716d0c
commit d0f0fcf611
5 changed files with 48 additions and 44 deletions

View File

@ -6,7 +6,7 @@ use abstio::MapName;
use abstutil::Timer;
use geom::{Duration, Time};
use map_gui::tools::compare_counts::CompareCounts;
use map_model::{PathConstraints, PathRequest, PathfinderCaching};
use map_model::{PathConstraints, PathRequest, Pathfinder};
use synthpop::{Scenario, TrafficCounts, TripEndpoint, TripMode};
use widgetry::EventCtx;
@ -107,26 +107,11 @@ impl Impact {
// Don't bother describing all the trip filtering
"before filters".to_string(),
&self.filtered_trips,
map.routing_params().clone(),
PathfinderCaching::NoCache,
map.get_pathfinder(),
timer,
);
let counts_b = {
let mut params = map.routing_params().clone();
app.session.modal_filters.update_routing_params(&mut params);
// Since we're making so many requests, it's worth it to rebuild a contraction
// hierarchy. And since we're single-threaded, no complications there.
TrafficCounts::from_path_requests(
map,
// Don't bother describing all the trip filtering
"after filters".to_string(),
&self.filtered_trips,
params,
PathfinderCaching::CacheCH,
timer,
)
};
let counts_b = self.counts_b(app, timer);
self.compare_counts =
CompareCounts::new(ctx, app, counts_a, counts_b, self.compare_counts.layer);
@ -134,25 +119,33 @@ impl Impact {
fn map_edits_changed(&mut self, ctx: &mut EventCtx, app: &App, timer: &mut Timer) {
self.change_key = app.session.modal_filters.get_change_key();
let map = &app.map;
let counts_b = {
let mut params = map.routing_params().clone();
app.session.modal_filters.update_routing_params(&mut params);
// Since we're making so many requests, it's worth it to rebuild a contraction
// hierarchy. And since we're single-threaded, no complications there.
TrafficCounts::from_path_requests(
map,
// Don't bother describing all the trip filtering
"after filters".to_string(),
&self.filtered_trips,
params,
PathfinderCaching::CacheCH,
timer,
)
};
let counts_b = self.counts_b(app, timer);
self.compare_counts.recalculate_b(ctx, app, counts_b);
}
fn counts_b(&self, app: &App, timer: &mut Timer) -> TrafficCounts {
let constraints: BTreeSet<PathConstraints> = self
.filters
.modes
.iter()
.map(|m| m.to_constraints())
.collect();
let map = &app.map;
let mut params = map.routing_params().clone();
app.session.modal_filters.update_routing_params(&mut params);
// Since we're making so many requests, it's worth it to rebuild a contraction hierarchy.
// This depends on the current map edits, so no need to cache
let pathfinder = Pathfinder::new_ch(map, params, constraints.into_iter().collect(), timer);
TrafficCounts::from_path_requests(
map,
// Don't bother describing all the trip filtering
"after filters".to_string(),
&self.filtered_trips,
&pathfinder,
timer,
)
}
}
// TODO Fixed, and sadly not const

View File

@ -217,7 +217,7 @@ fn load_study_area(map: &Map) -> Result<Polygon> {
}
fn check_sensor_data(map: &Map, scenario: &Scenario, sensor_path: &str, timer: &mut Timer) {
use map_model::{PathRequest, PathfinderCaching};
use map_model::PathRequest;
let requests = scenario
.all_trips()
@ -234,8 +234,7 @@ fn check_sensor_data(map: &Map, scenario: &Scenario, sensor_path: &str, timer: &
map,
"the generated scenario".to_string(),
&deduped,
map.routing_params().clone(),
PathfinderCaching::NoCache,
map.get_pathfinder(),
timer,
);

View File

@ -543,6 +543,10 @@ impl Map {
&self.boundary_polygon
}
pub fn get_pathfinder(&self) -> &Pathfinder {
&self.pathfinder
}
pub fn pathfind(&self, req: PathRequest) -> Result<Path> {
self.pathfind_v2(req)?.into_v1(self)
}

View File

@ -145,6 +145,17 @@ impl Pathfinder {
Self::new_limited(map, params, CreateEngine::Dijkstra, modes, timer)
}
/// Create a new Pathfinder with custom routing params that can only serve some modes. Slow to
/// create, fast to use. Doesn't re-use the node ordering when building the CH.
pub fn new_ch(
map: &Map,
params: RoutingParams,
modes: Vec<PathConstraints>,
timer: &mut Timer,
) -> Self {
Self::new_limited(map, params, CreateEngine::CH, modes, timer)
}
/// Create a new Pathfinder with custom routing params that can only serve some modes.
pub(crate) fn new_limited(
map: &Map,

View File

@ -3,9 +3,7 @@ use serde::{Deserialize, Serialize};
use abstio::MapName;
use abstutil::{prettyprint_usize, Counter, Timer};
use geom::Distance;
use map_model::{
IntersectionID, Map, PathRequest, PathStepV2, PathfinderCaching, RoadID, RoutingParams,
};
use map_model::{IntersectionID, Map, PathRequest, PathStepV2, Pathfinder, RoadID};
/// This represents the number of vehicles (or trips, or something else) crossing roads and
/// intersections over some span of time. The data could represent real observations or something
@ -42,8 +40,7 @@ impl TrafficCounts {
map: &Map,
description: String,
requests: &[(PathRequest, usize)],
params: RoutingParams,
cache_custom: PathfinderCaching,
pathfinder: &Pathfinder,
timer: &mut Timer,
) -> Self {
let mut counts = Self {
@ -72,7 +69,7 @@ impl TrafficCounts {
timer.start_iter("calculate routes", requests.len());
for (req, count) in requests {
timer.next();
if let Ok(path) = map.pathfind_v2_with_params(req.clone(), &params, cache_custom) {
if let Some(path) = pathfinder.pathfind_v2(req.clone(), map) {
let count = *count;
for step in path.get_steps() {
match step {