mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-10-26 10:09:22 +03:00
Scrape bollards defined as OSM nodes, and plumb through to the LTN tool.
The approach is a bit brittle, but works fine in Bristol. Regenerating everything...
This commit is contained in:
parent
f8d30c411f
commit
7af2c028fc
@ -60,6 +60,13 @@ pub fn transform_existing_filters(ctx: &EventCtx, app: &mut App, timer: &mut Tim
|
||||
.roads
|
||||
.insert(r, app.map.get_r(r).length() / 2.0);
|
||||
}
|
||||
|
||||
// The new, kind of simpler case
|
||||
for r in app.map.all_roads() {
|
||||
for dist in &r.barrier_nodes {
|
||||
app.session.modal_filters.roads.insert(r.id, *dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_filters(map: &Map) -> Vec<&Road> {
|
||||
|
@ -28,6 +28,9 @@ pub struct OsmExtract {
|
||||
pub amenities: Vec<(Pt2D, Amenity)>,
|
||||
/// Crosswalks located at these points, which should be on a RawRoad's center line
|
||||
pub crosswalks: HashSet<HashablePt2D>,
|
||||
/// Some kind of barrier nodes at these points. Only the ones on a RawRoad center line are
|
||||
/// relevant.
|
||||
pub barrier_nodes: HashSet<HashablePt2D>,
|
||||
}
|
||||
|
||||
pub fn extract_osm(
|
||||
@ -66,6 +69,7 @@ pub fn extract_osm(
|
||||
complicated_turn_restrictions: Vec::new(),
|
||||
amenities: Vec::new(),
|
||||
crosswalks: HashSet::new(),
|
||||
barrier_nodes: HashSet::new(),
|
||||
};
|
||||
|
||||
timer.start_iter("processing OSM nodes", doc.nodes.len());
|
||||
@ -84,6 +88,10 @@ pub fn extract_osm(
|
||||
if node.tags.is(osm::HIGHWAY, "crossing") {
|
||||
out.crosswalks.insert(node.pt.to_hashable());
|
||||
}
|
||||
// TODO Any kind of barrier?
|
||||
if node.tags.is("barrier", "bollard") {
|
||||
out.barrier_nodes.insert(node.pt.to_hashable());
|
||||
}
|
||||
for amenity in get_bldg_amenities(&node.tags) {
|
||||
out.amenities.push((node.pt, amenity));
|
||||
}
|
||||
|
@ -132,6 +132,12 @@ pub fn convert(
|
||||
|
||||
parking::apply_parking(&mut map, &opts, timer);
|
||||
|
||||
use_barrier_nodes(
|
||||
&mut map,
|
||||
split_output.barrier_nodes,
|
||||
&split_output.pt_to_road,
|
||||
);
|
||||
|
||||
if opts.elevation {
|
||||
timer.start("add elevation data");
|
||||
if let Err(err) = elevation::add_data(&mut map) {
|
||||
@ -251,6 +257,22 @@ fn filter_crosswalks(
|
||||
}
|
||||
}
|
||||
|
||||
fn use_barrier_nodes(
|
||||
map: &mut RawMap,
|
||||
barrier_nodes: HashSet<HashablePt2D>,
|
||||
pt_to_road: &HashMap<HashablePt2D, OriginalRoad>,
|
||||
) {
|
||||
for pt in barrier_nodes {
|
||||
// Many barriers are on footpaths or roads that we don't retain
|
||||
if let Some(road) = pt_to_road.get(&pt).and_then(|r| map.roads.get_mut(r)) {
|
||||
// Filters on roads that're already car-free are redundant
|
||||
if road.is_driveable() {
|
||||
road.barrier_nodes.push(pt.to_pt2d());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We're using Bristol for a project that requires an unusual LTN neighborhood boundary. Insert a
|
||||
// fake road where a bridge crosses another road, to force blockfinding to trace along there.
|
||||
fn bristol_hack(map: &mut RawMap) {
|
||||
|
@ -11,6 +11,7 @@ use crate::extract::OsmExtract;
|
||||
pub struct Output {
|
||||
pub amenities: Vec<(Pt2D, Amenity)>,
|
||||
pub crosswalks: HashSet<HashablePt2D>,
|
||||
pub barrier_nodes: HashSet<HashablePt2D>,
|
||||
/// A mapping of all points to the split road. Some internal points on roads get removed in
|
||||
/// `split_up_roads`, so this mapping isn't redundant.
|
||||
pub pt_to_road: HashMap<HashablePt2D, OriginalRoad>,
|
||||
@ -222,6 +223,7 @@ pub fn split_up_roads(map: &mut RawMap, mut input: OsmExtract, timer: &mut Timer
|
||||
Output {
|
||||
amenities: input.amenities,
|
||||
crosswalks: input.crosswalks,
|
||||
barrier_nodes: input.barrier_nodes,
|
||||
pt_to_road,
|
||||
}
|
||||
}
|
||||
|
2942
data/MANIFEST.json
2942
data/MANIFEST.json
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,9 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use structopt::StructOpt;
|
||||
|
||||
use abstutil::{MultiMap, Timer};
|
||||
use geom::{Distance, FindClosest, HashablePt2D, Line, Polygon, Speed, EPSILON_DIST};
|
||||
use geom::{
|
||||
Distance, FindClosest, HashablePt2D, Line, PolyLine, Polygon, Pt2D, Speed, EPSILON_DIST,
|
||||
};
|
||||
use raw_map::initial;
|
||||
|
||||
pub use self::parking_lots::snap_driveway;
|
||||
@ -111,6 +113,7 @@ impl Map {
|
||||
let i2 = intersection_id_mapping[&r.dst_i];
|
||||
|
||||
let raw_road = &raw.roads[&r.id];
|
||||
let barrier_nodes = snap_nodes_to_line(&raw_road.barrier_nodes, &r.trimmed_center_pts);
|
||||
let mut road = Road {
|
||||
id: road_id,
|
||||
osm_tags: raw_road.osm_tags.clone(),
|
||||
@ -152,6 +155,7 @@ impl Map {
|
||||
crosswalk_forward: raw_road.crosswalk_forward,
|
||||
crosswalk_backward: raw_road.crosswalk_backward,
|
||||
transit_stops: BTreeSet::new(),
|
||||
barrier_nodes,
|
||||
};
|
||||
road.speed_limit = road.speed_limit_from_osm();
|
||||
road.access_restrictions = road.access_restrictions_from_osm();
|
||||
@ -373,3 +377,15 @@ pub fn trim_path(poly: &Polygon, path: Line) -> Line {
|
||||
// Just give up
|
||||
path
|
||||
}
|
||||
|
||||
fn snap_nodes_to_line(pts: &[Pt2D], pl: &PolyLine) -> Vec<Distance> {
|
||||
let mut results = Vec::new();
|
||||
for pt in pts {
|
||||
let projected = pl.project_pt(*pt);
|
||||
// TODO Check distance isn't too crazy? Not sure why it would be
|
||||
if let Some((dist, _)) = pl.dist_along_of_point(projected) {
|
||||
results.push(dist);
|
||||
}
|
||||
}
|
||||
results
|
||||
}
|
||||
|
@ -189,6 +189,9 @@ pub struct Road {
|
||||
|
||||
/// Meaningless order
|
||||
pub transit_stops: BTreeSet<TransitStopID>,
|
||||
|
||||
/// Some kind of modal filter or barrier this distance along center_pts.
|
||||
pub barrier_nodes: Vec<Distance>,
|
||||
}
|
||||
|
||||
impl Road {
|
||||
|
@ -353,6 +353,11 @@ pub struct RawRoad {
|
||||
/// Is there a tagged crosswalk near each end of the road?
|
||||
pub crosswalk_forward: bool,
|
||||
pub crosswalk_backward: bool,
|
||||
/// Barrier nodes along this road's original center line.
|
||||
// TODO Preserving these across transformations (especially merging dual carriageways!) could
|
||||
// be really hard. It might be better to split the road into two pieces to match the more often
|
||||
// used OSM style.
|
||||
pub barrier_nodes: Vec<Pt2D>,
|
||||
|
||||
/// Derived from osm_tags. Not automatically updated.
|
||||
pub lane_specs_ltr: Vec<LaneSpec>,
|
||||
@ -376,6 +381,7 @@ impl RawRoad {
|
||||
// later
|
||||
crosswalk_forward: true,
|
||||
crosswalk_backward: true,
|
||||
barrier_nodes: Vec::new(),
|
||||
|
||||
lane_specs_ltr,
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user