Change the to/from permanent map edits APIs to be a little more ergonomic

This commit is contained in:
Dustin Carlino 2020-11-12 10:13:32 -08:00
parent c0e2401414
commit 7854823c28
6 changed files with 37 additions and 40 deletions

View File

@ -6,7 +6,7 @@ use rand::seq::SliceRandom;
use abstutil::{MapName, Timer};
use geom::{Bounds, Circle, Distance, Duration, Pt2D, Time};
use map_model::{IntersectionID, Map, PermanentMapEdits, Traversable};
use map_model::{IntersectionID, Map, Traversable};
use sim::{Analytics, Scenario, Sim, SimCallback, SimFlags};
use widgetry::{Canvas, EventCtx, GfxCtx, Prerender, SharedAppState};
@ -747,7 +747,7 @@ impl SharedAppState for App {
} else {
abstutil::write_json(
"edits_during_crash.json".to_string(),
&PermanentMapEdits::to_permanent(self.primary.map.get_edits(), &self.primary.map),
&self.primary.map.get_edits().to_permanent(&self.primary.map),
);
println!("Please include edits_during_crash.json in your bug report.");
}

View File

@ -421,7 +421,7 @@ impl State<App> for Proposals {
Box::new(move |ctx, app| {
// Apply edits before setting up the sandbox, for simplicity
let maybe_err = ctx.loading_screen("apply edits", |ctx, mut timer| {
match PermanentMapEdits::from_permanent(edits, &app.primary.map) {
match edits.to_edits(&app.primary.map) {
Ok(edits) => {
apply_map_edits(ctx, app, edits);
app.primary

View File

@ -316,9 +316,7 @@ fn handle_command(
let mut edits = map.get_edits().clone();
edits.commands.clear();
edits.compress(map);
Ok(abstutil::to_json(&PermanentMapEdits::to_permanent(
&edits, map,
)))
Ok(abstutil::to_json(&edits.to_permanent(map)))
}
"/map/get-edit-road-command" => {
let r = RoadID(params["id"].parse::<usize>()?);
@ -415,7 +413,7 @@ impl LoadSim {
let mut map = Map::new(scenario.map_name.path(), timer);
if let Some(perma) = self.edits.clone() {
let edits = PermanentMapEdits::from_permanent(perma, &map).unwrap();
let edits = perma.to_edits(&map).unwrap();
map.must_apply_edits(edits, timer);
map.recalculate_pathfinding_after_edits(timer);
}

View File

@ -147,15 +147,15 @@ impl MapEdits {
}
pub fn load(map: &Map, path: String, timer: &mut Timer) -> Result<MapEdits, String> {
match abstutil::maybe_read_json(path.clone(), timer) {
Ok(perma) => PermanentMapEdits::from_permanent(perma, map),
match abstutil::maybe_read_json::<PermanentMapEdits>(path.clone(), timer) {
Ok(perma) => perma.to_edits(map),
Err(_) => {
// The JSON format may have changed, so attempt backwards compatibility.
let bytes = abstutil::slurp_file(&path).map_err(|err| err.to_string())?;
let contents = std::str::from_utf8(&bytes).map_err(|err| err.to_string())?;
let value = serde_json::from_str(contents).map_err(|err| err.to_string())?;
let perma = compat::upgrade(value, map)?;
PermanentMapEdits::from_permanent(perma, map)
perma.to_edits(map)
}
}
}
@ -168,7 +168,7 @@ impl MapEdits {
abstutil::write_json(
abstutil::path_edits(map.get_name(), &self.edits_name),
&PermanentMapEdits::to_permanent(self, map),
&self.to_permanent(map),
);
}

View File

@ -129,33 +129,36 @@ impl PermanentEditCmd {
}
}
impl PermanentMapEdits {
pub fn to_permanent(edits: &MapEdits, map: &Map) -> PermanentMapEdits {
impl MapEdits {
/// Encode the edits in a permanent format, referring to more-stable OSM IDs.
pub fn to_permanent(&self, map: &Map) -> PermanentMapEdits {
PermanentMapEdits {
map_name: map.get_name().clone(),
edits_name: edits.edits_name.clone(),
edits_name: self.edits_name.clone(),
// Increase this every time there's a schema change
version: 4,
proposal_description: edits.proposal_description.clone(),
proposal_link: edits.proposal_link.clone(),
commands: edits.commands.iter().map(|cmd| cmd.to_perma(map)).collect(),
merge_zones: edits.merge_zones,
proposal_description: self.proposal_description.clone(),
proposal_link: self.proposal_link.clone(),
commands: self.commands.iter().map(|cmd| cmd.to_perma(map)).collect(),
merge_zones: self.merge_zones,
}
}
}
/// Load edits from the permanent form, looking up the map IDs by the hopefully stabler OSM IDs.
/// Validate that the basemap hasn't changed in important ways.
pub fn from_permanent(perma: PermanentMapEdits, map: &Map) -> Result<MapEdits, String> {
impl PermanentMapEdits {
/// Transform permanent edits to MapEdits, looking up the map IDs by the hopefully stabler OSM
/// IDs. Validate that the basemap hasn't changed in important ways.
pub fn to_edits(self, map: &Map) -> Result<MapEdits, String> {
let mut edits = MapEdits {
edits_name: perma.edits_name,
proposal_description: perma.proposal_description,
proposal_link: perma.proposal_link,
commands: perma
edits_name: self.edits_name,
proposal_description: self.proposal_description,
proposal_link: self.proposal_link,
commands: self
.commands
.into_iter()
.map(|cmd| cmd.to_cmd(map))
.collect::<Result<Vec<EditCmd>, String>>()?,
merge_zones: perma.merge_zones,
merge_zones: self.merge_zones,
changed_roads: BTreeSet::new(),
original_intersections: BTreeMap::new(),
@ -165,19 +168,19 @@ impl PermanentMapEdits {
Ok(edits)
}
/// Load edits from the permanent form, looking up the map IDs by the hopefully stabler OSM IDs.
/// Strip out commands that're broken.
pub fn from_permanent_permissive(perma: PermanentMapEdits, map: &Map) -> MapEdits {
/// Transform permanent edits to MapEdits, looking up the map IDs by the hopefully stabler OSM
/// IDs. Strip out commands that're broken.
pub fn to_edits_permissive(self, map: &Map) -> MapEdits {
let mut edits = MapEdits {
edits_name: perma.edits_name,
proposal_description: perma.proposal_description,
proposal_link: perma.proposal_link,
commands: perma
edits_name: self.edits_name,
proposal_description: self.proposal_description,
proposal_link: self.proposal_link,
commands: self
.commands
.into_iter()
.filter_map(|cmd| cmd.to_cmd(map).ok())
.collect(),
merge_zones: perma.merge_zones,
merge_zones: self.merge_zones,
changed_roads: BTreeSet::new(),
original_intersections: BTreeMap::new(),

View File

@ -138,14 +138,10 @@ fn check_proposals() -> Result<(), String> {
) {
Ok(perma) => {
let map = map_model::Map::new(perma.map_name.path(), &mut timer);
if let Err(err) = map_model::PermanentMapEdits::from_permanent(perma.clone(), &map)
{
if let Err(err) = perma.clone().to_edits(&map) {
abstutil::write_json(
"repair_attempt.json".to_string(),
&map_model::PermanentMapEdits::to_permanent(
&map_model::PermanentMapEdits::from_permanent_permissive(perma, &map),
&map,
),
&perma.to_edits_permissive(&map).to_permanent(&map),
);
return Err(format!("{} is out-of-date: {}", name, err));
}