mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
finding paths between buildings and nearest sidewalk
This commit is contained in:
parent
03df50c96e
commit
c2473828a6
14
TODO.md
14
TODO.md
@ -45,17 +45,20 @@
|
||||
- https://gis-kingcounty.opendata.arcgis.com/datasets/traffic-signs--sign-point/
|
||||
|
||||
- multiple lanes
|
||||
- model cars parking
|
||||
- maybe render numbers on the cars to distinguish them
|
||||
- document the FSM (on lane driving, waiting, turning, parking, etc)
|
||||
- always draw building to sidewalk paths
|
||||
- move colors to config, have interactive picker
|
||||
|
||||
- model bikes in driving lanes (as slow cars)
|
||||
- add random bike lanes, figure out how turns would work
|
||||
- be able to convert between parking and bike lanes, recompute the turns
|
||||
|
||||
- model cars parking
|
||||
- maybe render numbers on the cars to distinguish them
|
||||
- document the FSM (on lane driving, waiting, turning, parking, etc)
|
||||
|
||||
- model pdestrians
|
||||
- maybe draw crosswalks?
|
||||
|
||||
- when rendering sidewalks, have an option for a grass buffer
|
||||
|
||||
- regression testing
|
||||
- goldenfile approach for map_model, geom, and render layer from a small OSM chunk
|
||||
- or maybe a visual demo approach with a list of things to manually check
|
||||
@ -63,6 +66,7 @@
|
||||
|
||||
## Code cleanup
|
||||
|
||||
- where does 'extern crate' belong? only in main / mod?
|
||||
- clean up code
|
||||
- master Map struct
|
||||
- line type / ditch vec2d / settle on types
|
||||
|
@ -6,6 +6,7 @@ authors = ["Dustin Carlino <dabreegster@gmail.com>"]
|
||||
[dependencies]
|
||||
aabb-quadtree = "0.1.0"
|
||||
control = { path = "../control" }
|
||||
geo = "0.9.1"
|
||||
geom = { path = "../geom" }
|
||||
ezgui = { path = "../ezgui" }
|
||||
map_model = { path = "../map_model" }
|
||||
|
@ -3,6 +3,7 @@
|
||||
extern crate aabb_quadtree;
|
||||
extern crate control;
|
||||
extern crate ezgui;
|
||||
extern crate geo;
|
||||
extern crate geom;
|
||||
extern crate glutin_window;
|
||||
extern crate graphics;
|
||||
|
@ -182,6 +182,7 @@ impl SelectionState {
|
||||
}
|
||||
SelectionState::SelectedBuilding(id) => {
|
||||
canvas.draw_mouse_tooltip(g, &draw_map.get_b(id).tooltip_lines(map));
|
||||
draw_map.get_b(id).draw_sidewalk_path(g, map, geom_map);
|
||||
}
|
||||
SelectionState::SelectedCar(id) => {
|
||||
canvas.draw_mouse_tooltip(g, &sim.car_tooltip(id));
|
||||
|
@ -1,15 +1,19 @@
|
||||
// Copyright 2018 Google LLC, licensed under http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
extern crate aabb_quadtree;
|
||||
extern crate geo;
|
||||
extern crate map_model;
|
||||
|
||||
use aabb_quadtree::geom::Rect;
|
||||
use ezgui::canvas::GfxCtx;
|
||||
use geom::GeomMap;
|
||||
use geom::geometry;
|
||||
use graphics;
|
||||
use graphics::math::Vec2d;
|
||||
use graphics::types::Color;
|
||||
use map_model::{Bounds, BuildingID};
|
||||
use ordered_float::NotNaN;
|
||||
use render;
|
||||
use std::f64;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -54,4 +58,78 @@ impl DrawBuilding {
|
||||
pub fn get_bbox(&self) -> Rect {
|
||||
geometry::get_bbox_for_polygons(&[self.polygon.clone()])
|
||||
}
|
||||
|
||||
// TODO compute these once, and draw them always
|
||||
// TODO ideally start the path on a side of the building
|
||||
pub fn draw_sidewalk_path(&self, g: &mut GfxCtx, map: &map_model::Map, geom_map: &GeomMap) {
|
||||
use geo::prelude::{ClosestPoint, EuclideanDistance};
|
||||
|
||||
if let Some(tag) = map.get_b(self.id)
|
||||
.osm_tags
|
||||
.iter()
|
||||
.find(|kv| kv.starts_with("addr:street="))
|
||||
{
|
||||
let (_, street_name) = tag.split_at("addr:street=".len());
|
||||
|
||||
let bldg_center = self.center();
|
||||
let center_pt = geo::Point::new(bldg_center[0], bldg_center[1]);
|
||||
|
||||
// Find all matching sidewalks with that street name, then find the closest point on
|
||||
// that sidewalk
|
||||
let candidates: Vec<(map_model::RoadID, geo::Point<f64>)> = map.all_roads()
|
||||
.iter()
|
||||
.filter_map(|r| {
|
||||
if r.lane_type == map_model::LaneType::Sidewalk
|
||||
&& map_model::has_osm_tag(&r.osm_tags, "name", street_name)
|
||||
{
|
||||
if let geo::Closest::SinglePoint(pt) =
|
||||
road_to_line_string(r.id, geom_map).closest_point(¢er_pt)
|
||||
{
|
||||
return Some((r.id, pt));
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect();
|
||||
|
||||
if let Some(closest) = candidates
|
||||
.iter()
|
||||
.min_by_key(|pair| NotNaN::new(pair.1.euclidean_distance(¢er_pt)).unwrap())
|
||||
{
|
||||
let path = graphics::Line::new_round(render::DEBUG_COLOR, 1.0);
|
||||
path.draw(
|
||||
[center_pt.x(), center_pt.y(), closest.1.x(), closest.1.y()],
|
||||
&g.ctx.draw_state,
|
||||
g.ctx.transform,
|
||||
g.gfx,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn center(&self) -> Vec2d {
|
||||
let mut x = 0.0;
|
||||
let mut y = 0.0;
|
||||
for pt in &self.polygon {
|
||||
x += pt[0];
|
||||
y += pt[1];
|
||||
}
|
||||
let len = self.polygon.len() as f64;
|
||||
[x / len, y / len]
|
||||
}
|
||||
}
|
||||
|
||||
fn road_to_line_string(r: map_model::RoadID, geom_map: &GeomMap) -> geo::LineString<f64> {
|
||||
let pts: Vec<geo::Point<f64>> = geom_map
|
||||
.get_r(r)
|
||||
.lane_center_lines
|
||||
.iter()
|
||||
.flat_map(|pair| {
|
||||
vec![
|
||||
geo::Point::new(pair.0.x(), pair.0.y()),
|
||||
geo::Point::new(pair.1.x(), pair.1.y()),
|
||||
]
|
||||
})
|
||||
.collect();
|
||||
pts.into()
|
||||
}
|
||||
|
@ -35,18 +35,18 @@ impl DrawParcel {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw(&self, g: &mut GfxCtx, (boundary_color, fill_color): (Color, Color)) {
|
||||
pub fn draw(&self, g: &mut GfxCtx, (boundary_color, _fill_color): (Color, Color)) {
|
||||
let boundary_poly = graphics::Polygon::new(boundary_color);
|
||||
for p in &self.boundary_polygons {
|
||||
boundary_poly.draw(p, &g.ctx.draw_state, g.ctx.transform, g.gfx);
|
||||
}
|
||||
let fill_poly = graphics::Polygon::new(fill_color);
|
||||
/*let fill_poly = graphics::Polygon::new(fill_color);
|
||||
fill_poly.draw(
|
||||
&self.fill_polygon,
|
||||
&g.ctx.draw_state,
|
||||
g.ctx.transform,
|
||||
g.gfx,
|
||||
);
|
||||
);*/
|
||||
}
|
||||
|
||||
//pub fn contains_pt(&self, x: f64, y: f64) -> bool {}
|
||||
|
@ -505,3 +505,7 @@ impl Map {
|
||||
b
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_osm_tag(tags: &Vec<String>, key: &str, value: &str) -> bool {
|
||||
tags.contains(&format!("{}={}", key, value))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user