mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 23:43:25 +03:00
moving psrc->scenario code to popdat crate
This commit is contained in:
parent
27e933fbf8
commit
44cedeefab
@ -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| {
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
Loading…
Reference in New Issue
Block a user