From 966d7bb03de5c06be71d2c0f33c80695ca2c2f4e Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sun, 16 Sep 2018 09:07:36 -0700 Subject: [PATCH] adding Areas to map and UI; not instantiating them yet --- docs/design.md | 5 ++++- map_model/src/area.rs | 42 +++++++++++++++++++++++++++++++++++++++ map_model/src/lib.rs | 2 ++ map_model/src/map.rs | 28 ++++++++++++++++++++++++-- map_model/src/raw_data.rs | 17 ++++++++++++++++ 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 map_model/src/area.rs diff --git a/docs/design.md b/docs/design.md index 4942c22224..4d8ff4b1fe 100644 --- a/docs/design.md +++ b/docs/design.md @@ -997,8 +997,11 @@ Alright, replan yet again. = plugin trait, color(id) -> Option. parallel list of box plugins (or, a fxn that takes the idx) = refactor to one color_blah method = handle the two color things... just buildings? += and see how much boilerplate a new type would need, by adding bus stops and water/parks + +- load water/parks and stuff - deal with overlapping keys that still kinda happen (sim ctrl, escape game) - bug: do need to recalculate current_selection whenever anything potentially changes camera, like follow -= and see how much boilerplate a new type would need, by adding bus stops and water/parks - consider merging control map into map - see how hard it is to render textures onto cars or something +- refactor debug and tooltip lines for objects diff --git a/map_model/src/area.rs b/map_model/src/area.rs new file mode 100644 index 0000000000..75a45acb99 --- /dev/null +++ b/map_model/src/area.rs @@ -0,0 +1,42 @@ +use abstutil; +use geom::{PolyLine, Pt2D}; +use std::collections::BTreeMap; +use std::fmt; + +// TODO reconsider pub usize. maybe outside world shouldnt know. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct AreaID(pub usize); + +impl fmt::Display for AreaID { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "AreaID({0})", self.0) + } +} + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] +pub enum AreaType { + Park, + Water, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Area { + pub id: AreaID, + pub area_type: AreaType, + pub points: Vec, + pub osm_tags: BTreeMap, + pub osm_way_id: i64, +} + +impl PartialEq for Area { + fn eq(&self, other: &Area) -> bool { + self.id == other.id + } +} + +impl Area { + pub fn dump_debug(&self) { + println!("{}", abstutil::to_json(self)); + println!("{}", PolyLine::new(self.points.clone())); + } +} diff --git a/map_model/src/lib.rs b/map_model/src/lib.rs index e8df4be096..b4eb31d648 100644 --- a/map_model/src/lib.rs +++ b/map_model/src/lib.rs @@ -13,6 +13,7 @@ extern crate serde; #[macro_use] extern crate serde_derive; +mod area; mod building; mod bus_stop; mod edits; @@ -27,6 +28,7 @@ pub mod raw_data; mod road; mod turn; +pub use area::{Area, AreaID, AreaType}; pub use building::{Building, BuildingID, FrontPath}; pub use bus_stop::{BusRoute, BusStop, BusStopID}; pub use edits::{EditReason, Edits}; diff --git a/map_model/src/map.rs b/map_model/src/map.rs index 571cc75f68..b096e22f3d 100644 --- a/map_model/src/map.rs +++ b/map_model/src/map.rs @@ -11,8 +11,8 @@ use std::collections::{BTreeMap, BTreeSet, HashMap}; use std::io::Error; use std::path; use { - Building, BuildingID, BusRoute, BusStop, BusStopID, Intersection, IntersectionID, Lane, LaneID, - LaneType, Parcel, ParcelID, Road, RoadID, Turn, TurnID, + Area, AreaID, Building, BuildingID, BusRoute, BusStop, BusStopID, Intersection, IntersectionID, + Lane, LaneID, LaneType, Parcel, ParcelID, Road, RoadID, Turn, TurnID, }; #[derive(Serialize, Deserialize, Debug)] @@ -25,6 +25,7 @@ pub struct Map { parcels: Vec, bus_stops: BTreeMap, bus_routes: Vec, + areas: Vec, // TODO maybe dont need to retain GPS stuff later bounds: Bounds, @@ -65,6 +66,7 @@ impl Map { parcels: Vec::new(), bus_stops: BTreeMap::new(), bus_routes: Vec::new(), + areas: Vec::new(), }; let mut pt_to_intersection: HashMap = HashMap::new(); @@ -195,6 +197,20 @@ impl Map { }); } + for (idx, a) in data.areas.iter().enumerate() { + m.areas.push(Area { + id: AreaID(idx), + area_type: a.area_type, + points: a + .points + .iter() + .map(|coord| Pt2D::from_gps(coord, &bounds)) + .collect(), + osm_tags: a.osm_tags.clone(), + osm_way_id: a.osm_way_id, + }); + } + m } @@ -243,6 +259,10 @@ impl Map { &self.parcels } + pub fn all_areas(&self) -> &Vec { + &self.areas + } + pub fn maybe_get_r(&self, id: RoadID) -> Option<&Road> { self.roads.get(id.0) } @@ -291,6 +311,10 @@ impl Map { &self.parcels[id.0] } + pub fn get_a(&self, id: AreaID) -> &Area { + &self.areas[id.0] + } + // All these helpers should take IDs and return objects. pub fn get_source_intersection(&self, l: LaneID) -> &Intersection { diff --git a/map_model/src/raw_data.rs b/map_model/src/raw_data.rs index 6425d793b4..812f3f1643 100644 --- a/map_model/src/raw_data.rs +++ b/map_model/src/raw_data.rs @@ -2,6 +2,7 @@ use dimensioned::si; use geom::{Bounds, HashablePt2D, LonLat}; use gtfs::Route; use std::collections::BTreeMap; +use AreaType; #[derive(PartialEq, Debug, Serialize, Deserialize)] pub struct Map { @@ -10,6 +11,7 @@ pub struct Map { pub buildings: Vec, pub parcels: Vec, pub bus_routes: Vec, + pub areas: Vec, pub coordinates_in_world_space: bool, } @@ -22,6 +24,7 @@ impl Map { buildings: Vec::new(), parcels: Vec::new(), bus_routes: Vec::new(), + areas: Vec::new(), coordinates_in_world_space: false, } } @@ -42,6 +45,11 @@ impl Map { bounds.update_coord(pt); } } + for a in &self.areas { + for pt in &a.points { + bounds.update_coord(pt); + } + } for p in &self.parcels { for pt in &p.points { bounds.update_coord(pt); @@ -86,6 +94,15 @@ pub struct Building { pub osm_way_id: i64, } +#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] +pub struct Area { + pub area_type: AreaType, + // last point is always the same as the first + pub points: Vec, + pub osm_tags: BTreeMap, + pub osm_way_id: i64, +} + #[derive(PartialEq, Debug, Serialize, Deserialize)] pub struct Parcel { // last point never the first?