save hints from debug_initialmap, use them when constructing the real

map
This commit is contained in:
Dustin Carlino 2019-06-11 17:25:09 -07:00
parent 290c274661
commit 98e073d8be
9 changed files with 69 additions and 27 deletions

1
.gitignore vendored
View File

@ -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/*

View File

@ -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()
}

View File

@ -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;

View File

@ -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");
} }

View File

@ -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;

View File

@ -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),
} }

View File

@ -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;

View File

@ -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");

View File

@ -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;