mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-29 17:34:58 +03:00
slowly reintroduce MapEdits, just with lane type overrides. load and
"apply" them
This commit is contained in:
parent
3ea3ea199a
commit
3f47c00e03
33
map_model/src/edits.rs
Normal file
33
map_model/src/edits.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use crate::{LaneID, LaneType};
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct MapEdits {
|
||||||
|
pub(crate) map_name: String,
|
||||||
|
pub edits_name: String,
|
||||||
|
pub lane_overrides: BTreeMap<LaneID, LaneType>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MapEdits {
|
||||||
|
pub fn new(map_name: String) -> MapEdits {
|
||||||
|
MapEdits {
|
||||||
|
map_name,
|
||||||
|
// Something has to fill this out later
|
||||||
|
edits_name: "no_edits".to_string(),
|
||||||
|
lane_overrides: BTreeMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn describe(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"map edits \"{}\" ({} lanes)",
|
||||||
|
self.edits_name,
|
||||||
|
self.lane_overrides.len(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(&self) {
|
||||||
|
abstutil::save_object("edits", &self.map_name, &self.edits_name, self);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
mod area;
|
mod area;
|
||||||
mod building;
|
mod building;
|
||||||
mod bus_stop;
|
mod bus_stop;
|
||||||
|
mod edits;
|
||||||
mod intersection;
|
mod intersection;
|
||||||
mod lane;
|
mod lane;
|
||||||
mod make;
|
mod make;
|
||||||
@ -18,6 +19,7 @@ mod turn;
|
|||||||
pub use crate::area::{Area, AreaID, AreaType};
|
pub use crate::area::{Area, AreaID, AreaType};
|
||||||
pub use crate::building::{Building, BuildingID, BuildingType, FrontPath};
|
pub use crate::building::{Building, BuildingID, BuildingType, FrontPath};
|
||||||
pub use crate::bus_stop::{BusRoute, BusRouteID, BusStop, BusStopID};
|
pub use crate::bus_stop::{BusRoute, BusRouteID, BusStop, BusStopID};
|
||||||
|
pub use crate::edits::MapEdits;
|
||||||
pub use crate::intersection::{Intersection, IntersectionID, IntersectionType};
|
pub use crate::intersection::{Intersection, IntersectionID, IntersectionType};
|
||||||
pub use crate::lane::{Lane, LaneID, LaneType, PARKING_SPOT_LENGTH};
|
pub use crate::lane::{Lane, LaneID, LaneType, PARKING_SPOT_LENGTH};
|
||||||
pub use crate::make::RoadSpec;
|
pub use crate::make::RoadSpec;
|
||||||
|
@ -2,8 +2,8 @@ use crate::pathfind::Pathfinder;
|
|||||||
use crate::{
|
use crate::{
|
||||||
make, raw_data, Area, AreaID, Building, BuildingID, BusRoute, BusRouteID, BusStop, BusStopID,
|
make, raw_data, Area, AreaID, Building, BuildingID, BusRoute, BusRouteID, BusStop, BusStopID,
|
||||||
ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID, IntersectionType, Lane,
|
ControlStopSign, ControlTrafficSignal, Intersection, IntersectionID, IntersectionType, Lane,
|
||||||
LaneID, LaneType, Parcel, ParcelID, Path, PathRequest, Position, Road, RoadID, Turn, TurnID,
|
LaneID, LaneType, MapEdits, Parcel, ParcelID, Path, PathRequest, Position, Road, RoadID, Turn,
|
||||||
TurnPriority,
|
TurnID, TurnPriority,
|
||||||
};
|
};
|
||||||
use abstutil;
|
use abstutil;
|
||||||
use abstutil::{deserialize_btreemap, serialize_btreemap, Error, Timer};
|
use abstutil::{deserialize_btreemap, serialize_btreemap, Error, Timer};
|
||||||
@ -46,6 +46,7 @@ pub struct Map {
|
|||||||
pathfinder: Option<Pathfinder>,
|
pathfinder: Option<Pathfinder>,
|
||||||
|
|
||||||
name: String,
|
name: String,
|
||||||
|
edits: MapEdits,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Map {
|
impl Map {
|
||||||
@ -92,7 +93,8 @@ impl Map {
|
|||||||
bounds,
|
bounds,
|
||||||
turn_lookup: half_map.turn_lookup,
|
turn_lookup: half_map.turn_lookup,
|
||||||
pathfinder: None,
|
pathfinder: None,
|
||||||
name,
|
name: name.clone(),
|
||||||
|
edits: MapEdits::new(name),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extra setup that's annoying to do as HalfMap, since we want to pass around a Map.
|
// Extra setup that's annoying to do as HalfMap, since we want to pass around a Map.
|
||||||
@ -390,6 +392,7 @@ impl Map {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&self) {
|
pub fn save(&self) {
|
||||||
|
assert_eq!(self.edits.edits_name, "no_edits");
|
||||||
let path = format!("../data/maps/{}.abst", self.name);
|
let path = format!("../data/maps/{}.abst", self.name);
|
||||||
println!("Saving {}...", path);
|
println!("Saving {}...", path);
|
||||||
abstutil::write_binary(&path, self).expect(&format!("Saving {} failed", path));
|
abstutil::write_binary(&path, self).expect(&format!("Saving {} failed", path));
|
||||||
@ -548,3 +551,9 @@ impl Map {
|
|||||||
.should_use_transit(self, start, end)
|
.should_use_transit(self, start, end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Map {
|
||||||
|
pub fn apply_edits(&mut self, edits: MapEdits) {
|
||||||
|
// TODO implement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{Scenario, Sim};
|
use crate::{Scenario, Sim};
|
||||||
use abstutil;
|
use abstutil;
|
||||||
use geom::Duration;
|
use geom::Duration;
|
||||||
use map_model::Map;
|
use map_model::{Map, MapEdits};
|
||||||
use rand::{FromEntropy, SeedableRng};
|
use rand::{FromEntropy, SeedableRng};
|
||||||
use rand_xorshift::XorShiftRng;
|
use rand_xorshift::XorShiftRng;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
@ -34,7 +34,7 @@ impl SimFlags {
|
|||||||
|
|
||||||
pub fn synthetic_test(map: &str, run_name: &str) -> SimFlags {
|
pub fn synthetic_test(map: &str, run_name: &str) -> SimFlags {
|
||||||
SimFlags {
|
SimFlags {
|
||||||
load: format!("../data/maps/{}.abst", map),
|
load: format!("../data/maps/{}_no_edits.abst", map),
|
||||||
rng_seed: Some(42),
|
rng_seed: Some(42),
|
||||||
run_name: run_name.to_string(),
|
run_name: run_name.to_string(),
|
||||||
edits_name: "no_edits".to_string(),
|
edits_name: "no_edits".to_string(),
|
||||||
@ -58,14 +58,17 @@ impl SimFlags {
|
|||||||
let mut rng = self.make_rng();
|
let mut rng = self.make_rng();
|
||||||
|
|
||||||
if self.load.contains("data/save/") {
|
if self.load.contains("data/save/") {
|
||||||
|
assert_eq!(self.edits_name, "no_edits");
|
||||||
timer.note(format!("Resuming from {}", self.load));
|
timer.note(format!("Resuming from {}", self.load));
|
||||||
|
|
||||||
timer.start("read sim savestate");
|
timer.start("read sim savestate");
|
||||||
let sim: Sim = abstutil::read_json(&self.load).expect("loading sim state failed");
|
let sim: Sim = abstutil::read_json(&self.load).expect("loading sim state failed");
|
||||||
timer.stop("read sim savestate");
|
timer.stop("read sim savestate");
|
||||||
|
|
||||||
let map: Map =
|
let mut map: Map =
|
||||||
abstutil::read_binary(&format!("../data/maps/{}.abst", sim.map_name), timer)
|
abstutil::read_binary(&format!("../data/maps/{}.abst", sim.map_name), timer)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
apply_edits(&mut map, &sim.edits_name);
|
||||||
|
|
||||||
(map, sim, rng)
|
(map, sim, rng)
|
||||||
} else if self.load.contains("data/scenarios/") {
|
} else if self.load.contains("data/scenarios/") {
|
||||||
@ -73,12 +76,15 @@ impl SimFlags {
|
|||||||
"Seeding the simulation from scenario {}",
|
"Seeding the simulation from scenario {}",
|
||||||
self.load
|
self.load
|
||||||
));
|
));
|
||||||
|
|
||||||
let scenario: Scenario =
|
let scenario: Scenario =
|
||||||
abstutil::read_json(&self.load).expect("loading scenario failed");
|
abstutil::read_json(&self.load).expect("loading scenario failed");
|
||||||
|
|
||||||
let map: Map =
|
let mut map: Map =
|
||||||
abstutil::read_binary(&format!("../data/maps/{}.abst", scenario.map_name), timer)
|
abstutil::read_binary(&format!("../data/maps/{}.abst", scenario.map_name), timer)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
apply_edits(&mut map, &self.edits_name);
|
||||||
|
|
||||||
let mut sim = Sim::new(
|
let mut sim = Sim::new(
|
||||||
&map,
|
&map,
|
||||||
// TODO or the scenario name if no run name
|
// TODO or the scenario name if no run name
|
||||||
@ -86,26 +92,47 @@ impl SimFlags {
|
|||||||
savestate_every,
|
savestate_every,
|
||||||
);
|
);
|
||||||
scenario.instantiate(&mut sim, &map, &mut rng, timer);
|
scenario.instantiate(&mut sim, &map, &mut rng, timer);
|
||||||
|
|
||||||
(map, sim, rng)
|
(map, sim, rng)
|
||||||
} else if self.load.contains("data/raw_maps/") {
|
} else if self.load.contains("data/raw_maps/") {
|
||||||
// TODO relative dir is brittle; match more cautiously
|
|
||||||
timer.note(format!("Loading map {}", self.load));
|
timer.note(format!("Loading map {}", self.load));
|
||||||
let map = Map::new(&self.load, timer)
|
|
||||||
|
let mut map = Map::new(&self.load, timer)
|
||||||
.expect(&format!("Couldn't load map from {}", self.load));
|
.expect(&format!("Couldn't load map from {}", self.load));
|
||||||
|
apply_edits(&mut map, &self.edits_name);
|
||||||
|
|
||||||
timer.start("create sim");
|
timer.start("create sim");
|
||||||
let sim = Sim::new(&map, self.run_name.clone(), savestate_every);
|
let sim = Sim::new(&map, self.run_name.clone(), savestate_every);
|
||||||
timer.stop("create sim");
|
timer.stop("create sim");
|
||||||
|
|
||||||
(map, sim, rng)
|
(map, sim, rng)
|
||||||
} else if self.load.contains("data/maps/") {
|
} else if self.load.contains("data/maps/") {
|
||||||
timer.note(format!("Loading map {}", self.load));
|
timer.note(format!("Loading map {}", self.load));
|
||||||
let map: Map = abstutil::read_binary(&self.load, timer)
|
|
||||||
|
let mut map: Map = abstutil::read_binary(&self.load, timer)
|
||||||
.expect(&format!("Couldn't load map from {}", self.load));
|
.expect(&format!("Couldn't load map from {}", self.load));
|
||||||
|
apply_edits(&mut map, &self.edits_name);
|
||||||
|
|
||||||
timer.start("create sim");
|
timer.start("create sim");
|
||||||
let sim = Sim::new(&map, self.run_name.clone(), savestate_every);
|
let sim = Sim::new(&map, self.run_name.clone(), savestate_every);
|
||||||
timer.stop("create sim");
|
timer.stop("create sim");
|
||||||
|
|
||||||
(map, sim, rng)
|
(map, sim, rng)
|
||||||
} else {
|
} else {
|
||||||
panic!("Don't know how to load {}", self.load);
|
panic!("Don't know how to load {}", self.load);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_edits(map: &mut Map, edits_name: &str) {
|
||||||
|
if edits_name == "no_edits" {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let edits: MapEdits = abstutil::read_json(&format!(
|
||||||
|
"../data/edits/{}/{}.json",
|
||||||
|
map.get_name(),
|
||||||
|
edits_name
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
map.apply_edits(edits);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user