Optionally skip importing external trips that don't match an endpoint, for the Grid2Demand integration.

This commit is contained in:
Dustin Carlino 2021-02-06 14:59:45 -08:00
parent 1704d93050
commit fc213d1d38
2 changed files with 38 additions and 6 deletions

View File

@ -1,6 +1,6 @@
use serde::Deserialize;
use abstutil::{CmdArgs, Timer};
use abstutil::{prettyprint_usize, CmdArgs, Timer};
use map_model::Map;
use sim::{ExternalPerson, Scenario};
@ -8,6 +8,7 @@ fn main() {
let mut args = CmdArgs::new();
let map = args.required("--map");
let input = args.required("--input");
let skip_problems = args.enabled("--skip_problems");
args.done();
let mut timer = Timer::new("import traffic demand data");
@ -17,7 +18,13 @@ fn main() {
let mut s = Scenario::empty(&map, &input.scenario_name);
// Include all buses/trains
s.only_seed_buses = None;
s.people = ExternalPerson::import(&map, input.people).unwrap();
let orig_num = input.people.len();
s.people = ExternalPerson::import(&map, input.people, skip_problems).unwrap();
println!(
"Imported {}/{} people",
prettyprint_usize(s.people.len()),
prettyprint_usize(orig_num)
);
s.save();
}

View File

@ -33,8 +33,13 @@ impl ExternalPerson {
/// `PersonSpec` is a way to specify endpoints by a `LonLat`. This is snapped to the nearest
/// building. If the point is outside of the map boundary, it's snapped to the nearest border
/// (by Euclidean distance -- the network outside the given map isn't known). Failure happens
/// if a point is within the map, but not close enough to any buildings.
pub fn import(map: &Map, input: Vec<ExternalPerson>) -> Result<Vec<PersonSpec>> {
/// if a point is within the map, but not close enough to any buildings. If `skip_problems` is
/// true, then those failures are logged; otherwise this panics at the first problem.
pub fn import(
map: &Map,
input: Vec<ExternalPerson>,
skip_problems: bool,
) -> Result<Vec<PersonSpec>> {
let mut closest: FindClosest<TripEndpoint> = FindClosest::new(map.get_bounds());
for b in map.all_buildings() {
closest.add(TripEndpoint::Bldg(b.id), b.polygon.points());
@ -68,7 +73,17 @@ impl ExternalPerson {
for person in input {
let mut spec = PersonSpec {
orig_id: None,
origin: lookup_pt(person.origin, true, person.trips[0].mode)?,
origin: match lookup_pt(person.origin, true, person.trips[0].mode) {
Ok(endpt) => endpt,
Err(err) => {
if skip_problems {
warn!("Skipping person: {}", err);
continue;
} else {
return Err(err);
}
}
},
trips: Vec::new(),
};
for trip in person.trips {
@ -78,7 +93,17 @@ impl ExternalPerson {
TripPurpose::Shopping,
// TODO Do we handle somebody going off-map via one one-way bridge, and
// re-entering using the other?
lookup_pt(trip.destination, false, trip.mode)?,
match lookup_pt(trip.destination, false, trip.mode) {
Ok(endpt) => endpt,
Err(err) => {
if skip_problems {
warn!("Skipping person: {}", err);
continue;
} else {
return Err(err);
}
}
},
trip.mode,
));
}