synthpop/
lib.rs

1//! This crate describes a synthetic population that exist in a map. Currently each person's travel
2//! behavior is modelled, but in the future, demographic and health attributes may be added.
3//! There's a variety of ways to create these populations, scattered in other crates.
4//!
5//! Note that "scenario" is the term currently used to describe the population. This will be
6//! renamed "soon."
7
8#[macro_use]
9extern crate anyhow;
10#[macro_use]
11extern crate log;
12
13use serde::{Deserialize, Serialize};
14
15use abstutil::{deserialize_usize, serialize_usize};
16use map_model::PathConstraints;
17
18pub use self::borders::{MapBorder, MapBorders};
19pub use self::counts::TrafficCounts;
20pub use self::endpoint::TripEndpoint;
21pub use self::external::{ExternalPerson, ExternalTrip, ExternalTripEndpoint};
22pub use self::modifier::ScenarioModifier;
23pub use self::scenario::{IndividTrip, PersonSpec, Scenario, TripPurpose};
24
25mod borders;
26mod counts;
27mod endpoint;
28mod external;
29pub mod make;
30mod modifier;
31mod scenario;
32
33/// How does a trip primarily happen?
34///
35/// Note most trips are "multi-modal" -- somebody has to walk a bit before and after parking their
36/// car.
37#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)]
38pub enum TripMode {
39    Walk,
40    Bike,
41    Transit,
42    Drive,
43}
44
45impl TripMode {
46    pub fn all() -> Vec<TripMode> {
47        vec![
48            TripMode::Walk,
49            TripMode::Bike,
50            TripMode::Transit,
51            TripMode::Drive,
52        ]
53    }
54
55    pub fn verb(self) -> &'static str {
56        match self {
57            TripMode::Walk => "walk",
58            TripMode::Bike => "bike",
59            TripMode::Transit => "use transit",
60            TripMode::Drive => "drive",
61        }
62    }
63
64    // If I used "present participle" in a method name, I'd never live it down.
65    pub fn ongoing_verb(self) -> &'static str {
66        match self {
67            TripMode::Walk => "walking",
68            TripMode::Bike => "biking",
69            TripMode::Transit => "using transit",
70            TripMode::Drive => "driving",
71        }
72    }
73
74    pub fn noun(self) -> &'static str {
75        match self {
76            TripMode::Walk => "Pedestrian",
77            TripMode::Bike => "Bike",
78            TripMode::Transit => "Bus",
79            TripMode::Drive => "Car",
80        }
81    }
82
83    pub fn to_constraints(self) -> PathConstraints {
84        match self {
85            TripMode::Walk => PathConstraints::Pedestrian,
86            TripMode::Bike => PathConstraints::Bike,
87            // TODO WRONG
88            TripMode::Transit => PathConstraints::Bus,
89            TripMode::Drive => PathConstraints::Car,
90        }
91    }
92
93    pub fn from_constraints(c: PathConstraints) -> TripMode {
94        match c {
95            PathConstraints::Pedestrian => TripMode::Walk,
96            PathConstraints::Bike => TripMode::Bike,
97            // TODO The bijection breaks down... transit rider vs train vs bus...
98            PathConstraints::Bus | PathConstraints::Train => TripMode::Transit,
99            PathConstraints::Car => TripMode::Drive,
100        }
101    }
102}
103
104/// This is an ID used by Seattle soundcast. Originally it was preserved for debugging, but that
105/// hasn't happened in a long time. Also the format is tied to Soundcast. Consider deleting /
106/// changing.
107#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
108pub struct OrigPersonID(
109    #[serde(
110        serialize_with = "serialize_usize",
111        deserialize_with = "deserialize_usize"
112    )]
113    pub usize,
114    #[serde(
115        serialize_with = "serialize_usize",
116        deserialize_with = "deserialize_usize"
117    )]
118    pub usize,
119);