store Area as a Polygon natively in Map

This commit is contained in:
Dustin Carlino 2019-02-14 17:31:19 -08:00
parent cfe9a8d662
commit 7fb9f721e1
5 changed files with 19 additions and 31 deletions

View File

@ -101,7 +101,7 @@ impl ID {
ID::ExtraShape(id) => Some(draw_map.get_es(id).center()), ID::ExtraShape(id) => Some(draw_map.get_es(id).center()),
ID::Parcel(id) => map.maybe_get_p(id).map(|p| Pt2D::center(&p.points)), ID::Parcel(id) => map.maybe_get_p(id).map(|p| Pt2D::center(&p.points)),
ID::BusStop(id) => map.maybe_get_bs(id).map(|bs| bs.sidewalk_pos.pt(map)), ID::BusStop(id) => map.maybe_get_bs(id).map(|bs| bs.sidewalk_pos.pt(map)),
ID::Area(id) => map.maybe_get_a(id).map(|a| Pt2D::center(&a.points)), ID::Area(id) => map.maybe_get_a(id).map(|a| a.polygon.center()),
ID::Trip(id) => sim.get_canonical_pt_per_trip(id, map), ID::Trip(id) => sim.get_canonical_pt_per_trip(id, map),
} }
} }

View File

@ -80,7 +80,7 @@ impl DebugPolygon {
} }
Some(ID::Area(id)) => { Some(ID::Area(id)) => {
if ctx.input.contextual_action(Key::X, "debug area geometry") { if ctx.input.contextual_action(Key::X, "debug area geometry") {
let pts = &ctx.primary.map.get_a(id).points; let pts = &ctx.primary.map.get_a(id).polygon.points();
let center = if pts[0] == *pts.last().unwrap() { let center = if pts[0] == *pts.last().unwrap() {
// TODO The center looks really wrong for Volunteer Park and others, but I // TODO The center looks really wrong for Volunteer Park and others, but I
// think it's because they have many points along some edges. // think it's because they have many points along some edges.

View File

@ -7,25 +7,16 @@ use map_model::{Area, AreaID, AreaType, Map};
pub struct DrawArea { pub struct DrawArea {
pub id: AreaID, pub id: AreaID,
fill_polygon: Polygon,
} }
impl DrawArea { impl DrawArea {
pub fn new(area: &Area, cs: &ColorScheme) -> (DrawArea, Color, Polygon) { pub fn new(area: &Area, cs: &ColorScheme) -> (DrawArea, Color, Polygon) {
let fill_polygon = area.get_polygon();
let color = match area.area_type { let color = match area.area_type {
AreaType::Park => cs.get_def("park area", Color::rgb(200, 250, 204)), AreaType::Park => cs.get_def("park area", Color::rgb(200, 250, 204)),
AreaType::Water => cs.get_def("water area", Color::rgb(170, 211, 223)), AreaType::Water => cs.get_def("water area", Color::rgb(170, 211, 223)),
}; };
( (DrawArea { id: area.id }, color, area.polygon.clone())
DrawArea {
id: area.id,
fill_polygon: fill_polygon.clone(),
},
color,
fill_polygon,
)
} }
} }
@ -34,17 +25,17 @@ impl Renderable for DrawArea {
ID::Area(self.id) ID::Area(self.id)
} }
fn draw(&self, g: &mut GfxCtx, opts: RenderOptions, _ctx: &DrawCtx) { fn draw(&self, g: &mut GfxCtx, opts: RenderOptions, ctx: &DrawCtx) {
if let Some(color) = opts.color { if let Some(color) = opts.color {
g.draw_polygon(color, &self.fill_polygon); g.draw_polygon(color, &ctx.map.get_a(self.id).polygon);
} }
} }
fn get_bounds(&self, _: &Map) -> Bounds { fn get_bounds(&self, map: &Map) -> Bounds {
self.fill_polygon.get_bounds() map.get_a(self.id).polygon.get_bounds()
} }
fn contains_pt(&self, pt: Pt2D, _: &Map) -> bool { fn contains_pt(&self, pt: Pt2D, map: &Map) -> bool {
self.fill_polygon.contains_pt(pt) map.get_a(self.id).polygon.contains_pt(pt)
} }
} }

View File

@ -1,6 +1,5 @@
use crate::LANE_THICKNESS;
use abstutil; use abstutil;
use geom::{PolyLine, Polygon, Pt2D}; use geom::Polygon;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt; use std::fmt;
@ -25,8 +24,7 @@ pub enum AreaType {
pub struct Area { pub struct Area {
pub id: AreaID, pub id: AreaID,
pub area_type: AreaType, pub area_type: AreaType,
// Might be a closed loop or not -- waterways can be linear. pub polygon: Polygon,
pub points: Vec<Pt2D>,
pub osm_tags: BTreeMap<String, String>, pub osm_tags: BTreeMap<String, String>,
pub osm_id: i64, pub osm_id: i64,
} }
@ -34,13 +32,5 @@ pub struct Area {
impl Area { impl Area {
pub fn dump_debug(&self) { pub fn dump_debug(&self) {
println!("{}", abstutil::to_json(self)); println!("{}", abstutil::to_json(self));
println!("{}", PolyLine::new(self.points.clone()));
}
pub fn get_polygon(&self) -> Polygon {
if self.points[0] == *self.points.last().unwrap() {
return Polygon::new(&self.points);
}
PolyLine::new(self.points.clone()).make_polygons(LANE_THICKNESS)
} }
} }

View File

@ -181,10 +181,17 @@ pub fn make_half_map(
); );
for (idx, a) in data.areas.iter().enumerate() { for (idx, a) in data.areas.iter().enumerate() {
let pts = gps_bounds.must_convert(&a.points);
if pts[0] != *pts.last().unwrap() {
panic!(
"Unclosed Area from OSM {} with tags {:?}",
a.osm_id, a.osm_tags
);
}
half_map.areas.push(Area { half_map.areas.push(Area {
id: AreaID(idx), id: AreaID(idx),
area_type: a.area_type, area_type: a.area_type,
points: gps_bounds.must_convert(&a.points), polygon: Polygon::new(&pts),
osm_tags: a.osm_tags.clone(), osm_tags: a.osm_tags.clone(),
osm_id: a.osm_id, osm_id: a.osm_id,
}); });