dont panic when generating osc

This commit is contained in:
Dustin Carlino 2020-05-12 10:00:49 -07:00
parent 4a7ea37ee9
commit e61cf5f8c3
3 changed files with 25 additions and 20 deletions

View File

@ -13,7 +13,7 @@ regenerate the maps!
5. Select what kind of on-street parking the road has 5. Select what kind of on-street parking the road has
6. Repeat 6. Repeat
7. Click **Generate OsmChange file** 7. Click **Generate OsmChange file**
8. Upload the game/diff.osc file by adding a layer in JOSM 8. Upload the diff.osc file by adding a layer in JOSM
Like all edits to OSM, to figure out ground-truth, you can survey in-person or Like all edits to OSM, to figure out ground-truth, you can survey in-person or
use use

View File

@ -11,6 +11,7 @@ use geom::Distance;
use map_model::{osm, RoadID}; use map_model::{osm, RoadID};
use sim::DontDrawAgents; use sim::DontDrawAgents;
use std::collections::{BTreeMap, HashSet}; use std::collections::{BTreeMap, HashSet};
use std::error::Error;
use std::fs::File; use std::fs::File;
use std::io::Write; use std::io::Write;
@ -281,13 +282,15 @@ impl State for ParkingMapper {
vec!["Map some parking first"], vec!["Map some parking first"],
)); ));
} }
ctx.loading_screen("generate OsmChange file", |_, timer| { return match ctx.loading_screen("generate OsmChange file", |_, timer| {
generate_osmc(&self.data, timer) generate_osmc(&self.data, timer)
}); }) {
return Transition::Push(msg( Ok(()) => Transition::Push(msg(
"Diff generated", "Diff generated",
vec!["diff.osc created. Load it in JOSM, verify, and upload!"], vec!["diff.osc created. Load it in JOSM, verify, and upload!"],
)); )),
Err(err) => Transition::Push(msg("Error", vec![format!("{}", err)])),
};
} }
"change map" => { "change map" => {
return Transition::Push(WizardState::new(Box::new(load_map))); return Transition::Push(WizardState::new(Box::new(load_map)));
@ -320,10 +323,12 @@ impl State for ParkingMapper {
} }
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
fn generate_osmc(data: &BTreeMap<i64, Value>, timer: &mut Timer) {} fn generate_osmc(data: &BTreeMap<i64, Value>, timer: &mut Timer) -> Result<(), Box<dyn Error>> {
Err("Woops, mapping mode isn't supported on the web yet".to_string())
}
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
fn generate_osmc(data: &BTreeMap<i64, Value>, timer: &mut Timer) { fn generate_osmc(data: &BTreeMap<i64, Value>, timer: &mut Timer) -> Result<(), Box<dyn Error>> {
let mut modified_ways = Vec::new(); let mut modified_ways = Vec::new();
timer.start_iter("fetch latest OSM data per modified way", data.len()); timer.start_iter("fetch latest OSM data per modified way", data.len());
for (way, value) in data { for (way, value) in data {
@ -334,9 +339,8 @@ fn generate_osmc(data: &BTreeMap<i64, Value>, timer: &mut Timer) {
let url = format!("https://api.openstreetmap.org/api/0.6/way/{}", way); let url = format!("https://api.openstreetmap.org/api/0.6/way/{}", way);
timer.note(format!("Fetching {}", url)); timer.note(format!("Fetching {}", url));
let resp = reqwest::blocking::get(&url).unwrap().text().unwrap(); let resp = reqwest::blocking::get(&url)?.text()?;
let mut tree = xmltree::Element::parse(resp.as_bytes()) let mut tree = xmltree::Element::parse(resp.as_bytes())?
.unwrap()
.take_child("way") .take_child("way")
.unwrap(); .unwrap();
let mut osm_tags = BTreeMap::new(); let mut osm_tags = BTreeMap::new();
@ -388,20 +392,21 @@ fn generate_osmc(data: &BTreeMap<i64, Value>, timer: &mut Timer) {
tree.attributes.remove("visible"); tree.attributes.remove("visible");
let mut bytes: Vec<u8> = Vec::new(); let mut bytes: Vec<u8> = Vec::new();
tree.write(&mut bytes).unwrap(); tree.write(&mut bytes)?;
let out = String::from_utf8(bytes).unwrap(); let out = String::from_utf8(bytes)?;
let stripped = out.trim_start_matches("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); let stripped = out.trim_start_matches("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
modified_ways.push(stripped.to_string()); modified_ways.push(stripped.to_string());
} }
let path = "diff.osc"; let path = "../diff.osc";
let mut f = File::create(path).unwrap(); let mut f = File::create(path)?;
writeln!(f, "<osmChange version=\"0.6\" generator=\"abst\"><modify>").unwrap(); writeln!(f, "<osmChange version=\"0.6\" generator=\"abst\"><modify>")?;
for w in modified_ways { for w in modified_ways {
writeln!(f, " {}", w).unwrap(); writeln!(f, " {}", w)?;
} }
writeln!(f, "</modify></osmChange>").unwrap(); writeln!(f, "</modify></osmChange>")?;
timer.note(format!("Wrote {}", path)); timer.note(format!("Wrote {}", path));
Ok(())
} }
fn load_map(wiz: &mut Wizard, ctx: &mut EventCtx, app: &mut App) -> Option<Transition> { fn load_map(wiz: &mut Wizard, ctx: &mut EventCtx, app: &mut App) -> Option<Transition> {

View File

@ -133,7 +133,7 @@ pub fn main_menu(ctx: &mut EventCtx, app: &App) -> Box<dyn State> {
}) })
.build_def(ctx, hotkey(Key::M)), .build_def(ctx, hotkey(Key::M)),
if app.opts.dev { if app.opts.dev {
Btn::text_bg2("Internal Dev Tools").build_def(ctx, hotkey(Key::M)) Btn::text_bg2("Internal Dev Tools").build_def(ctx, hotkey(Key::D))
} else { } else {
Widget::nothing() Widget::nothing()
}, },