moving psrc->scenario code to popdat crate

This commit is contained in:
Dustin Carlino 2019-08-04 14:51:45 -07:00
parent 27e933fbf8
commit 44cedeefab
6 changed files with 89 additions and 96 deletions

View File

@ -1,6 +1,5 @@
use crate::common::{CommonState, SpeedControls};
use crate::game::{State, Transition};
use crate::mission::trips::{clip_trips, Trip};
use crate::ui::UI;
use abstutil::prettyprint_usize;
use ezgui::{
@ -9,6 +8,7 @@ use ezgui::{
use geom::{Circle, Distance, Duration};
use map_model::{PathRequest, LANE_THICKNESS};
use popdat::psrc::Mode;
use popdat::{clip_trips, Trip};
pub struct TripsVisualizer {
menu: ModalMenu,
@ -27,7 +27,7 @@ enum MaybeTrip {
impl TripsVisualizer {
pub fn new(ctx: &mut EventCtx, ui: &UI) -> TripsVisualizer {
let trips = ctx.loading_screen("load trip data", |_, mut timer| {
let (all_trips, _) = clip_trips(ui, &mut timer);
let (all_trips, _) = clip_trips(&ui.primary.map, &mut timer);
let map = &ui.primary.map;
let maybe_trips =
timer.parallelize("calculate paths with geometry", all_trips, |mut trip| {

View File

@ -1,12 +1,11 @@
use crate::common::CommonState;
use crate::game::{State, Transition};
use crate::helpers::ID;
use crate::mission::trips::{clip_trips, Trip, TripEndpt};
use crate::ui::UI;
use ezgui::{hotkey, Color, EventCtx, GfxCtx, ItemSlider, Key, Text};
use geom::{Circle, Distance, Line, Speed};
use map_model::BuildingID;
use popdat::psrc;
use popdat::{clip_trips, psrc, Trip, TripEndpt};
use std::collections::HashMap;
pub struct TripsVisualizer {
@ -18,7 +17,7 @@ impl TripsVisualizer {
pub fn new(ctx: &mut EventCtx, ui: &UI) -> TripsVisualizer {
let (trips, bldgs) = ctx.loading_screen("load trip data", |_, mut timer| {
// TODO We'll break if there are no matching trips
let (trips, bldgs) = clip_trips(ui, &mut timer);
let (trips, bldgs) = clip_trips(&ui.primary.map, &mut timer);
(
trips
.into_iter()

View File

@ -3,9 +3,7 @@ mod dataviz;
mod individ_trips;
mod neighborhood;
mod scenario;
mod trips;
use self::trips::trips_to_scenario;
use crate::game::{State, Transition};
use crate::sandbox::SandboxMode;
use crate::ui::UI;
@ -13,6 +11,7 @@ use abstutil::Timer;
use ezgui::{hotkey, EventCtx, GfxCtx, Key, ModalMenu, Wizard, WrappedWizard};
use geom::Duration;
use map_model::Map;
use popdat::trips_to_scenario;
use sim::Scenario;
pub struct MissionEditMode {
@ -62,8 +61,13 @@ impl State for MissionEditMode {
} else if self.menu.action("visualize all PSRC trips") {
return Transition::Push(Box::new(all_trips::TripsVisualizer::new(ctx, ui)));
} else if self.menu.action("set up simulation with PSRC trips") {
let scenario = trips_to_scenario(ctx, ui, Duration::ZERO, Duration::END_OF_DAY);
ctx.loading_screen("instantiate scenario", |_, timer| {
ctx.loading_screen("setup PSRC scenario", |_, mut timer| {
let scenario = trips_to_scenario(
&ui.primary.map,
Duration::ZERO,
Duration::END_OF_DAY,
&mut timer,
);
scenario.instantiate(
&mut ui.primary.sim,
&ui.primary.map,
@ -109,7 +113,9 @@ impl State for TripsToScenario {
"Include trips departing AFTER when?",
"Include trips departing BEFORE when?",
) {
trips_to_scenario(ctx, ui, t1, t2).save();
ctx.loading_screen("extract PSRC scenario", |_, mut timer| {
trips_to_scenario(&ui.primary.map, t1, t2, &mut timer).save();
});
return Transition::Pop;
} else if self.wizard.aborted() {
return Transition::Pop;

View File

@ -13,4 +13,5 @@ kml = { path = "../kml" }
map_model = { path = "../map_model" }
serde = "1.0.89"
serde_derive = "1.0.89"
sim = { path = "../sim" }
structopt = "0.2.15"

View File

@ -1,10 +1,12 @@
pub mod psrc;
mod trips;
use abstutil::Timer;
use geom::{GPSBounds, LonLat};
use serde_derive::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt;
pub use trips::{clip_trips, trips_to_scenario, Trip, TripEndpt};
#[derive(Serialize, Deserialize)]
pub struct PopDat {

View File

@ -1,6 +1,6 @@
use crate::ui::UI;
use crate::psrc::{Endpoint, Mode, Parcel, Purpose};
use crate::PopDat;
use abstutil::Timer;
use ezgui::EventCtx;
use geom::{Distance, Duration, LonLat, PolyLine, Polygon, Pt2D};
use map_model::{BuildingID, IntersectionID, LaneType, Map, PathRequest, Position};
use sim::{DrivingGoal, Scenario, SidewalkSpot, SpawnTrip, TripSpec};
@ -11,8 +11,8 @@ pub struct Trip {
pub from: TripEndpt,
pub to: TripEndpt,
pub depart_at: Duration,
pub purpose: (popdat::psrc::Purpose, popdat::psrc::Purpose),
pub mode: popdat::psrc::Mode,
pub purpose: (Purpose, Purpose),
pub mode: Mode,
// These are an upper bound when TripEndpt::Border is involved.
pub trip_time: Duration,
pub trip_dist: Distance,
@ -34,8 +34,6 @@ impl Trip {
}
pub fn path_req(&self, map: &Map) -> PathRequest {
use popdat::psrc::Mode;
match self.mode {
Mode::Walk => PathRequest {
start: self.from.start_sidewalk_spot(map).sidewalk_pos,
@ -87,7 +85,7 @@ impl Trip {
impl TripEndpt {
fn new(
endpt: &popdat::psrc::Endpoint,
endpt: &Endpoint,
map: &Map,
osm_id_to_bldg: &HashMap<i64, BuildingID>,
borders: &Vec<(IntersectionID, LonLat)>,
@ -148,17 +146,10 @@ impl TripEndpt {
}
}
pub fn clip_trips(
ui: &UI,
timer: &mut Timer,
) -> (Vec<Trip>, HashMap<BuildingID, popdat::psrc::Parcel>) {
use popdat::psrc::Mode;
let popdat: popdat::PopDat = abstutil::read_binary("../data/shapes/popdat.bin", timer)
pub fn clip_trips(map: &Map, timer: &mut Timer) -> (Vec<Trip>, HashMap<BuildingID, Parcel>) {
let popdat: PopDat = abstutil::read_binary("../data/shapes/popdat.bin", timer)
.expect("Couldn't load popdat.bin");
let map = &ui.primary.map;
let mut osm_id_to_bldg = HashMap::new();
for b in map.all_buildings() {
osm_id_to_bldg.insert(b.osm_way_id, b.id);
@ -265,92 +256,86 @@ pub fn clip_trips(
(trips, bldgs)
}
pub fn trips_to_scenario(ctx: &mut EventCtx, ui: &UI, t1: Duration, t2: Duration) -> Scenario {
use popdat::psrc::Mode;
let map = &ui.primary.map;
pub fn trips_to_scenario(map: &Map, t1: Duration, t2: Duration, timer: &mut Timer) -> Scenario {
let (trips, _) = clip_trips(map, timer);
let individ_trips = timer
.parallelize("turn PSRC trips into SpawnTrips", trips, |trip| {
if trip.depart_at < t1 || trip.depart_at > t2 {
return None;
}
let individ_trips = ctx.loading_screen("convert PSRC trips to scenario", |_, mut timer| {
let (trips, _) = clip_trips(ui, &mut timer);
timer
.parallelize("turn PSRC trips into SpawnTrips", trips, |trip| {
if trip.depart_at < t1 || trip.depart_at > t2 {
return None;
match trip.mode {
Mode::Drive => {
// TODO Use a parked car, but first have to figure out what cars to seed.
if let Some(start) =
TripSpec::spawn_car_at(trip.from.start_pos_driving(map), map)
{
Some(SpawnTrip::CarAppearing {
depart: trip.depart_at,
start,
goal: trip.to.driving_goal(vec![LaneType::Driving], map),
is_bike: false,
})
} else {
// TODO need to be able to emit warnings from parallelize
//timer.warn(format!("No room for car to appear at {:?}", trip.from));
None
}
}
match trip.mode {
Mode::Drive => {
// TODO Use a parked car, but first have to figure out what cars to seed.
Mode::Bike => match trip.from {
TripEndpt::Building(b) => Some(SpawnTrip::UsingBike(
trip.depart_at,
SidewalkSpot::building(b, map),
trip.to
.driving_goal(vec![LaneType::Biking, LaneType::Driving], map),
)),
TripEndpt::Border(_, _) => {
if let Some(start) =
TripSpec::spawn_car_at(trip.from.start_pos_driving(map), map)
{
Some(SpawnTrip::CarAppearing {
depart: trip.depart_at,
start,
goal: trip.to.driving_goal(vec![LaneType::Driving], map),
is_bike: false,
goal: trip
.to
.driving_goal(vec![LaneType::Biking, LaneType::Driving], map),
is_bike: true,
})
} else {
// TODO need to be able to emit warnings from parallelize
//timer.warn(format!("No room for car to appear at {:?}", trip.from));
//timer.warn(format!("No room for bike to appear at {:?}", trip.from));
None
}
}
Mode::Bike => match trip.from {
TripEndpt::Building(b) => Some(SpawnTrip::UsingBike(
},
Mode::Walk => Some(SpawnTrip::JustWalking(
trip.depart_at,
trip.from.start_sidewalk_spot(map),
trip.to.end_sidewalk_spot(map),
)),
Mode::Transit => {
let start = trip.from.start_sidewalk_spot(map);
let goal = trip.to.end_sidewalk_spot(map);
if let Some((stop1, stop2, route)) =
map.should_use_transit(start.sidewalk_pos, goal.sidewalk_pos)
{
Some(SpawnTrip::UsingTransit(
trip.depart_at,
SidewalkSpot::building(b, map),
trip.to
.driving_goal(vec![LaneType::Biking, LaneType::Driving], map),
)),
TripEndpt::Border(_, _) => {
if let Some(start) =
TripSpec::spawn_car_at(trip.from.start_pos_driving(map), map)
{
Some(SpawnTrip::CarAppearing {
depart: trip.depart_at,
start,
goal: trip.to.driving_goal(
vec![LaneType::Biking, LaneType::Driving],
map,
),
is_bike: true,
})
} else {
//timer.warn(format!("No room for bike to appear at {:?}", trip.from));
None
}
}
},
Mode::Walk => Some(SpawnTrip::JustWalking(
trip.depart_at,
trip.from.start_sidewalk_spot(map),
trip.to.end_sidewalk_spot(map),
)),
Mode::Transit => {
let start = trip.from.start_sidewalk_spot(map);
let goal = trip.to.end_sidewalk_spot(map);
if let Some((stop1, stop2, route)) =
map.should_use_transit(start.sidewalk_pos, goal.sidewalk_pos)
{
Some(SpawnTrip::UsingTransit(
trip.depart_at,
start,
goal,
route,
stop1,
stop2,
))
} else {
//timer.warn(format!("{:?} not actually using transit, because pathfinding didn't find any useful route", trip));
Some(SpawnTrip::JustWalking(trip.depart_at, start, goal))
}
start,
goal,
route,
stop1,
stop2,
))
} else {
//timer.warn(format!("{:?} not actually using transit, because pathfinding didn't find any useful route", trip));
Some(SpawnTrip::JustWalking(trip.depart_at, start, goal))
}
}
})
.into_iter()
.flatten()
.collect()
});
}
})
.into_iter()
.flatten()
.collect();
Scenario {
scenario_name: format!("psrc {} to {}", t1, t2),