diff --git a/game/src/debug/mod.rs b/game/src/debug/mod.rs index 9c94761f5f..8aa5ee04c8 100644 --- a/game/src/debug/mod.rs +++ b/game/src/debug/mod.rs @@ -23,6 +23,7 @@ mod objects; pub mod path_counter; mod polygons; pub mod shared_row; +pub mod streetmix; pub struct DebugMode { panel: Panel, diff --git a/game/src/debug/shared_row.rs b/game/src/debug/shared_row.rs index 24a0d1b34e..4a59f128f0 100644 --- a/game/src/debug/shared_row.rs +++ b/game/src/debug/shared_row.rs @@ -3,7 +3,7 @@ use geojson::{Feature, FeatureCollection, GeoJson, Geometry, Value}; use map_model::{Direction, Lane, LaneType, Map, RoadID}; -// Exports to https://github.com/d-wasserman/shared-row/, returns the filename +/// Exports to https://github.com/d-wasserman/shared-row/, returns the filename pub fn export(roads: Vec, map: &Map) -> String { let path = format!( "shared_row_export_{}.json", diff --git a/game/src/debug/streetmix.rs b/game/src/debug/streetmix.rs new file mode 100644 index 0000000000..2a58a31868 --- /dev/null +++ b/game/src/debug/streetmix.rs @@ -0,0 +1,63 @@ +use map_model::{Direction, Lane, LaneType, Map, RoadID}; + +/// Exports a single road to Streetmix's format, returns the filename +pub fn export(r: RoadID, map: &Map) -> String { + let path = format!("streetmix_export_{}.json", r.0); + let street = road(r, map); + abstutil::write_json(path.clone(), &street); + path +} + +fn road(id: RoadID, map: &Map) -> serde_json::Map { + let r = map.get_r(id); + let mut street = serde_json::Map::new(); + street.insert("schemaVersion".to_string(), 24.into()); + // TODO Many more fields + + let mut segments = Vec::new(); + for (l, dir, _) in r.lanes_ltr() { + segments.push(serde_json::value::Value::Object(lane(map.get_l(l), dir))); + } + street.insert( + "segments".to_string(), + serde_json::value::Value::Array(segments), + ); + + street +} + +fn lane(lane: &Lane, dir: Direction) -> serde_json::Map { + let mut segment = serde_json::Map::new(); + segment.insert("id".to_string(), lane.id.to_string().into()); + segment.insert("width".to_string(), lane.width.inner_meters().into()); + + // TODO I'm taking wild stabs at these values for now. Once I can visualize the results, will + // iterate on these. + let (segment_type, variant) = match lane.lane_type { + LaneType::Driving => match dir { + Direction::Fwd => ("drive-lane", "inbound|car"), + Direction::Back => ("drive-lane", "outbound|car"), + }, + LaneType::Parking => match dir { + Direction::Fwd => ("parking-lane", "inbound|left"), + Direction::Back => ("parking-lane", "outbound|right"), + }, + LaneType::Sidewalk => ("sidewalk", "dense"), + LaneType::Shoulder => ("sidewalk", "dense"), + LaneType::Biking => match dir { + Direction::Fwd => ("bike-lane", "inbound|green|road"), + Direction::Back => ("bike-lane", "outbound|green|road"), + }, + LaneType::Bus => match dir { + Direction::Fwd => ("bus-lane", "inbound|shared"), + Direction::Back => ("bus-lane", "outbound|shared"), + }, + LaneType::SharedLeftTurn => ("TODO", "TODO"), + LaneType::Construction => ("TODO", "TODO"), + LaneType::LightRail => ("TODO", "TODO"), + }; + segment.insert("type".to_string(), segment_type.into()); + segment.insert("variant".to_string(), variant.into()); + + segment +} diff --git a/game/src/edit/bulk.rs b/game/src/edit/bulk.rs index c5c0493ba1..f603c2c1e3 100644 --- a/game/src/edit/bulk.rs +++ b/game/src/edit/bulk.rs @@ -44,6 +44,7 @@ fn make_select_panel(ctx: &mut EventCtx, selector: &RoadSelector) -> Panel { selector.roads.len() )) .build(ctx, "export roads to shared-row", None), + Btn::text_fg("export one road to Streetmix").build_def(ctx, None), Btn::text_fg("Cancel").build_def(ctx, Key::Escape), ]) .evenly_spaced(), @@ -77,6 +78,21 @@ impl State for BulkSelect { vec![format!("Roads exported to shared-row format at {}", path)], )); } + "export one road to Streetmix" => { + let path = crate::debug::streetmix::export( + *self.selector.roads.iter().next().unwrap(), + &app.primary.map, + ); + return Transition::Push(PopupMsg::new( + ctx, + "One road exported", + vec![format!( + "One arbitrary road from your selection exported to Streetmix format \ + at {}", + path + )], + )); + } x => { if self.selector.event(ctx, app, Some(x)) { self.panel = make_select_panel(ctx, &self.selector);