mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
save hints from debug_initialmap, use them when constructing the real
map
This commit is contained in:
parent
290c274661
commit
98e073d8be
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@ editor_state.json
|
|||||||
|
|
||||||
data/ab_tests/*
|
data/ab_tests/*
|
||||||
data/edits/*
|
data/edits/*
|
||||||
|
data/hints/*
|
||||||
data/input/*
|
data/input/*
|
||||||
data/maps/*
|
data/maps/*
|
||||||
data/neighborhoods/*
|
data/neighborhoods/*
|
||||||
|
@ -317,3 +317,12 @@ fn list_dir(dir: &std::path::Path) -> Vec<String> {
|
|||||||
files.sort();
|
files.sort();
|
||||||
files
|
files
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn basename(path: &str) -> String {
|
||||||
|
Path::new(path)
|
||||||
|
.file_stem()
|
||||||
|
.unwrap()
|
||||||
|
.to_os_string()
|
||||||
|
.into_string()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
@ -11,9 +11,10 @@ pub use crate::clone::Cloneable;
|
|||||||
pub use crate::collections::{contains_duplicates, retain_btreemap, wraparound_get, MultiMap};
|
pub use crate::collections::{contains_duplicates, retain_btreemap, wraparound_get, MultiMap};
|
||||||
pub use crate::error::Error;
|
pub use crate::error::Error;
|
||||||
pub use crate::io::{
|
pub use crate::io::{
|
||||||
deserialize_btreemap, deserialize_multimap, find_next_file, find_prev_file, list_all_objects,
|
basename, deserialize_btreemap, deserialize_multimap, find_next_file, find_prev_file,
|
||||||
load_all_objects, read_binary, read_json, save_binary_object, save_json_object,
|
list_all_objects, load_all_objects, read_binary, read_json, save_binary_object,
|
||||||
serialize_btreemap, serialize_multimap, to_json, write_binary, write_json, FileWithProgress,
|
save_json_object, serialize_btreemap, serialize_multimap, to_json, write_binary, write_json,
|
||||||
|
FileWithProgress,
|
||||||
};
|
};
|
||||||
pub use crate::logs::Warn;
|
pub use crate::logs::Warn;
|
||||||
pub use crate::notes::note;
|
pub use crate::notes::note;
|
||||||
|
@ -12,7 +12,6 @@ use kml::ExtraShapes;
|
|||||||
use map_model::{raw_data, IntersectionType, LANE_THICKNESS};
|
use map_model::{raw_data, IntersectionType, LANE_THICKNESS};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::path::Path;
|
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
const MAX_DIST_BTWN_INTERSECTION_AND_SIGNAL: Distance = Distance::const_meters(50.0);
|
const MAX_DIST_BTWN_INTERSECTION_AND_SIGNAL: Distance = Distance::const_meters(50.0);
|
||||||
@ -94,12 +93,7 @@ pub fn convert(flags: &Flags, timer: &mut abstutil::Timer) -> raw_data::Map {
|
|||||||
|
|
||||||
if !flags.neighborhoods.is_empty() {
|
if !flags.neighborhoods.is_empty() {
|
||||||
timer.start("convert neighborhood polygons");
|
timer.start("convert neighborhood polygons");
|
||||||
let map_name = Path::new(&flags.output)
|
let map_name = abstutil::basename(&flags.output);
|
||||||
.file_stem()
|
|
||||||
.unwrap()
|
|
||||||
.to_os_string()
|
|
||||||
.into_string()
|
|
||||||
.unwrap();
|
|
||||||
neighborhoods::convert(&flags.neighborhoods, map_name, &gps_bounds);
|
neighborhoods::convert(&flags.neighborhoods, map_name, &gps_bounds);
|
||||||
timer.stop("convert neighborhood polygons");
|
timer.stop("convert neighborhood polygons");
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
use ezgui::{Color, EventCtx, EventLoopMode, GfxCtx, Key, Text, GUI};
|
use ezgui::{Color, EventCtx, EventLoopMode, GfxCtx, Key, Text, GUI};
|
||||||
use geom::{Distance, Polygon};
|
use geom::{Distance, Polygon};
|
||||||
use map_model::raw_data::{InitialMap, StableIntersectionID, StableRoadID};
|
use map_model::raw_data::{Hint, Hints, InitialMap, StableIntersectionID, StableRoadID};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::{env, process};
|
use std::{env, process};
|
||||||
use viewer::World;
|
use viewer::World;
|
||||||
@ -12,6 +12,7 @@ const MIN_ROAD_LENGTH: Distance = Distance::const_meters(13.0);
|
|||||||
struct UI {
|
struct UI {
|
||||||
world: World<ID>,
|
world: World<ID>,
|
||||||
data: InitialMap,
|
data: InitialMap,
|
||||||
|
hints: Hints,
|
||||||
// TODO Or, if these are common things, the World could also hold this state.
|
// TODO Or, if these are common things, the World could also hold this state.
|
||||||
selected: Option<ID>,
|
selected: Option<ID>,
|
||||||
hide: HashSet<ID>,
|
hide: HashSet<ID>,
|
||||||
@ -22,18 +23,25 @@ impl UI {
|
|||||||
fn new(filename: &str, ctx: &mut EventCtx) -> UI {
|
fn new(filename: &str, ctx: &mut EventCtx) -> UI {
|
||||||
let mut timer = Timer::new(&format!("load {}", filename));
|
let mut timer = Timer::new(&format!("load {}", filename));
|
||||||
let raw: map_model::raw_data::Map = abstutil::read_binary(filename, &mut timer).unwrap();
|
let raw: map_model::raw_data::Map = abstutil::read_binary(filename, &mut timer).unwrap();
|
||||||
|
let map_name = abstutil::basename(filename);
|
||||||
let gps_bounds = raw.get_gps_bounds();
|
let gps_bounds = raw.get_gps_bounds();
|
||||||
let data = InitialMap::new(
|
let mut data = InitialMap::new(
|
||||||
filename.to_string(),
|
map_name,
|
||||||
&raw,
|
&raw,
|
||||||
&gps_bounds,
|
&gps_bounds,
|
||||||
&gps_bounds.to_bounds(),
|
&gps_bounds.to_bounds(),
|
||||||
&mut timer,
|
&mut timer,
|
||||||
);
|
);
|
||||||
|
let hints: Hints = abstutil::read_json(&format!("../data/hints/{}.json", data.name))
|
||||||
|
.unwrap_or(Hints { hints: Vec::new() });
|
||||||
|
data.apply_hints(&hints);
|
||||||
|
|
||||||
let world = initial_map_to_world(&data, ctx);
|
let world = initial_map_to_world(&data, ctx);
|
||||||
|
|
||||||
UI {
|
UI {
|
||||||
world,
|
world,
|
||||||
data,
|
data,
|
||||||
|
hints,
|
||||||
selected: None,
|
selected: None,
|
||||||
hide: HashSet::new(),
|
hide: HashSet::new(),
|
||||||
osd: Text::new(),
|
osd: Text::new(),
|
||||||
@ -52,6 +60,16 @@ impl GUI for UI {
|
|||||||
if ctx.input.unimportant_key_pressed(Key::Escape, "quit") {
|
if ctx.input.unimportant_key_pressed(Key::Escape, "quit") {
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
|
if ctx
|
||||||
|
.input
|
||||||
|
.key_pressed(Key::S, &format!("save {} hints", self.hints.hints.len()))
|
||||||
|
{
|
||||||
|
abstutil::write_json(
|
||||||
|
&format!("../data/hints/{}.json", self.data.name),
|
||||||
|
&self.hints,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(id) = self.selected {
|
if let Some(id) = self.selected {
|
||||||
if ctx.input.key_pressed(Key::H, "hide this") {
|
if ctx.input.key_pressed(Key::H, "hide this") {
|
||||||
@ -61,6 +79,7 @@ impl GUI for UI {
|
|||||||
}
|
}
|
||||||
if let Some(ID::HalfRoad(r, _)) = self.selected {
|
if let Some(ID::HalfRoad(r, _)) = self.selected {
|
||||||
if ctx.input.key_pressed(Key::M, "merge") {
|
if ctx.input.key_pressed(Key::M, "merge") {
|
||||||
|
self.hints.hints.push(Hint::MergeRoad(r));
|
||||||
self.data.merge_road(r);
|
self.data.merge_road(r);
|
||||||
self.world = initial_map_to_world(&self.data, ctx);
|
self.world = initial_map_to_world(&self.data, ctx);
|
||||||
self.selected = None;
|
self.selected = None;
|
||||||
|
@ -7,6 +7,7 @@ use crate::raw_data::{StableIntersectionID, StableRoadID};
|
|||||||
use crate::{raw_data, LANE_THICKNESS};
|
use crate::{raw_data, LANE_THICKNESS};
|
||||||
use abstutil::Timer;
|
use abstutil::Timer;
|
||||||
use geom::{Bounds, Distance, GPSBounds, PolyLine, Pt2D};
|
use geom::{Bounds, Distance, GPSBounds, PolyLine, Pt2D};
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
|
|
||||||
pub struct InitialMap {
|
pub struct InitialMap {
|
||||||
@ -148,4 +149,24 @@ impl InitialMap {
|
|||||||
pub fn merge_road(&mut self, r: StableRoadID) {
|
pub fn merge_road(&mut self, r: StableRoadID) {
|
||||||
merge::merge(self, r, &mut Timer::throwaway());
|
merge::merge(self, r, &mut Timer::throwaway());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn apply_hints(&mut self, hints: &Hints) {
|
||||||
|
for h in &hints.hints {
|
||||||
|
match h {
|
||||||
|
Hint::MergeRoad(r) => {
|
||||||
|
self.merge_road(*r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Hints {
|
||||||
|
pub hints: Vec<Hint>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub enum Hint {
|
||||||
|
MergeRoad(StableRoadID),
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,5 @@ pub use self::buildings::make_all_buildings;
|
|||||||
pub use self::bus_stops::{make_bus_stops, verify_bus_routes};
|
pub use self::bus_stops::{make_bus_stops, verify_bus_routes};
|
||||||
pub use self::half_map::make_half_map;
|
pub use self::half_map::make_half_map;
|
||||||
pub use self::initial::lane_specs::{get_lane_types, RoadSpec};
|
pub use self::initial::lane_specs::{get_lane_types, RoadSpec};
|
||||||
pub use self::initial::InitialMap;
|
pub use self::initial::{Hint, Hints, InitialMap};
|
||||||
pub use self::turns::make_all_turns;
|
pub use self::turns::make_all_turns;
|
||||||
|
@ -12,7 +12,6 @@ use geom::{Bounds, GPSBounds, Polygon};
|
|||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
|
use std::collections::{BTreeMap, BTreeSet, HashSet, VecDeque};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct Map {
|
pub struct Map {
|
||||||
@ -52,23 +51,21 @@ pub struct Map {
|
|||||||
impl Map {
|
impl Map {
|
||||||
pub fn new(path: &str, timer: &mut Timer) -> Result<Map, io::Error> {
|
pub fn new(path: &str, timer: &mut Timer) -> Result<Map, io::Error> {
|
||||||
let data: raw_data::Map = abstutil::read_binary(path, timer)?;
|
let data: raw_data::Map = abstutil::read_binary(path, timer)?;
|
||||||
Ok(Map::create_from_raw(
|
Ok(Map::create_from_raw(abstutil::basename(path), data, timer))
|
||||||
path::Path::new(path)
|
|
||||||
.file_stem()
|
|
||||||
.unwrap()
|
|
||||||
.to_os_string()
|
|
||||||
.into_string()
|
|
||||||
.unwrap(),
|
|
||||||
data,
|
|
||||||
timer,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_from_raw(name: String, data: raw_data::Map, timer: &mut Timer) -> Map {
|
pub fn create_from_raw(name: String, data: raw_data::Map, timer: &mut Timer) -> Map {
|
||||||
timer.start("raw_map to InitialMap");
|
timer.start("raw_map to InitialMap");
|
||||||
let gps_bounds = data.get_gps_bounds();
|
let gps_bounds = data.get_gps_bounds();
|
||||||
let bounds = gps_bounds.to_bounds();
|
let bounds = gps_bounds.to_bounds();
|
||||||
let initial_map = make::InitialMap::new(name.clone(), &data, &gps_bounds, &bounds, timer);
|
let mut initial_map =
|
||||||
|
make::InitialMap::new(name.clone(), &data, &gps_bounds, &bounds, timer);
|
||||||
|
if let Ok(hints) =
|
||||||
|
abstutil::read_json::<raw_data::Hints>(&format!("../data/hints/{}.json", name))
|
||||||
|
{
|
||||||
|
timer.note(format!("Applying {} hints", hints.hints.len()));
|
||||||
|
initial_map.apply_hints(&hints);
|
||||||
|
}
|
||||||
timer.stop("raw_map to InitialMap");
|
timer.stop("raw_map to InitialMap");
|
||||||
|
|
||||||
timer.start("InitialMap to HalfMap");
|
timer.start("InitialMap to HalfMap");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::make::get_lane_types;
|
use crate::make::get_lane_types;
|
||||||
pub use crate::make::InitialMap;
|
pub use crate::make::{Hint, Hints, InitialMap};
|
||||||
use crate::{AreaType, IntersectionType, RoadSpec};
|
use crate::{AreaType, IntersectionType, RoadSpec};
|
||||||
use geom::{Distance, GPSBounds, LonLat};
|
use geom::{Distance, GPSBounds, LonLat};
|
||||||
use gtfs::Route;
|
use gtfs::Route;
|
||||||
|
Loading…
Reference in New Issue
Block a user