mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +03:00
Ignore spurious changes in pathfinding for the LTN impact tool. #868
This commit is contained in:
parent
1126972fdd
commit
272408002f
@ -143,15 +143,39 @@ impl Impact {
|
||||
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(
|
||||
let pathfinder_after =
|
||||
Pathfinder::new_ch(map, params, constraints.into_iter().collect(), timer);
|
||||
|
||||
// We can't simply use TrafficCounts::from_path_requests. Due to spurious diffs with paths,
|
||||
// we need to skip cases where the path before and after have the same cost. It's easiest
|
||||
// (code-wise) to just repeat some calculation here.
|
||||
let mut counts = TrafficCounts::from_path_requests(
|
||||
map,
|
||||
// Don't bother describing all the trip filtering
|
||||
"after filters".to_string(),
|
||||
&self.filtered_trips,
|
||||
&pathfinder,
|
||||
&vec![],
|
||||
&pathfinder_after,
|
||||
timer,
|
||||
)
|
||||
);
|
||||
|
||||
timer.start_iter("calculate routes", self.filtered_trips.len());
|
||||
for (req, count) in &self.filtered_trips {
|
||||
timer.next();
|
||||
if let (Some(path1), Some(path2)) = (
|
||||
map.get_pathfinder().pathfind_v2(req.clone(), map),
|
||||
pathfinder_after.pathfind_v2(req.clone(), map),
|
||||
) {
|
||||
if path1.get_cost() == path2.get_cost() {
|
||||
// When the path maybe changed but the cost is the same, just count it the same
|
||||
// as the original path
|
||||
counts.update_with_path(path1, *count, map);
|
||||
} else {
|
||||
counts.update_with_path(path2, *count, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
counts
|
||||
}
|
||||
|
||||
/// Returns routes that start or stop crossing the given road. Returns paths (before filters,
|
||||
@ -185,6 +209,11 @@ impl Impact {
|
||||
map.get_pathfinder().pathfind_v2(req.clone(), map),
|
||||
pathfinder_after.pathfind_v2(req.clone(), map),
|
||||
) {
|
||||
// Skip spurious changes where the cost matches.
|
||||
if path1.get_cost() == path2.get_cost() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if path1.crosses_road(r) != path2.crosses_road(r) {
|
||||
if let (Ok(path1), Ok(path2)) = (path1.into_v1(map), path2.into_v1(map)) {
|
||||
changed.push((path1, path2));
|
||||
|
@ -3,7 +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, Pathfinder, RoadID};
|
||||
use map_model::{IntersectionID, Map, PathRequest, PathStepV2, PathV2, 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
|
||||
@ -70,35 +70,39 @@ impl TrafficCounts {
|
||||
for (req, count) in requests {
|
||||
timer.next();
|
||||
if let Some(path) = pathfinder.pathfind_v2(req.clone(), map) {
|
||||
let count = *count;
|
||||
counts.update_with_path(path, *count, map);
|
||||
}
|
||||
}
|
||||
counts
|
||||
}
|
||||
|
||||
pub fn update_with_path(&mut self, path: PathV2, count: usize, map: &Map) {
|
||||
for step in path.get_steps() {
|
||||
match step {
|
||||
PathStepV2::Along(dr) | PathStepV2::Contraflow(dr) => {
|
||||
counts.per_road.add(dr.road, count);
|
||||
self.per_road.add(dr.road, count);
|
||||
}
|
||||
PathStepV2::Movement(m) | PathStepV2::ContraflowMovement(m) => {
|
||||
counts.per_intersection.add(m.parent, count);
|
||||
self.per_intersection.add(m.parent, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're starting or ending at a border, count it
|
||||
let req = path.get_req();
|
||||
if req.start.dist_along() == Distance::ZERO {
|
||||
// TODO src_i and dst_i may not work for pedestrians on contraflow sidewalks
|
||||
let i = map.get_l(req.start.lane()).src_i;
|
||||
if map.get_i(i).is_border() {
|
||||
counts.per_intersection.add(i, count);
|
||||
self.per_intersection.add(i, count);
|
||||
}
|
||||
} else {
|
||||
let i = map.get_l(req.end.lane()).dst_i;
|
||||
if map.get_i(i).is_border() {
|
||||
counts.per_intersection.add(i, count);
|
||||
self.per_intersection.add(i, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
counts
|
||||
}
|
||||
|
||||
/// Print a comparison of counts. Only look at roads/intersections in `self`.
|
||||
pub fn quickly_compare(&self, other: &TrafficCounts) {
|
||||
|
Loading…
Reference in New Issue
Block a user