mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-27 15:03:20 +03:00
Change how non-driveable roads (cycleways) work in the LTN tool and
blockfinding. Stop using them as parts of block boundaries, and stop drawing special "car-free" cells around them. Motivation in the PR description.
This commit is contained in:
parent
a60104762e
commit
a56f47bfaf
@ -30,7 +30,6 @@ lazy_static::lazy_static! {
|
|||||||
pub static ref PLAN_ROUTE_WALK: Color = Color::BLUE;
|
pub static ref PLAN_ROUTE_WALK: Color = Color::BLUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CAR_FREE_CELL: Color = Color::GREEN.alpha(0.5);
|
|
||||||
pub const DISCONNECTED_CELL: Color = Color::RED.alpha(0.5);
|
pub const DISCONNECTED_CELL: Color = Color::RED.alpha(0.5);
|
||||||
|
|
||||||
pub const OUTLINE: Color = Color::BLACK;
|
pub const OUTLINE: Color = Color::BLACK;
|
||||||
|
@ -138,11 +138,9 @@ impl RenderCellsBuilder {
|
|||||||
let adjacencies = diffusion(&mut grid, boundary_marker);
|
let adjacencies = diffusion(&mut grid, boundary_marker);
|
||||||
let mut cell_colors = color_cells(neighborhood.cells.len(), adjacencies);
|
let mut cell_colors = color_cells(neighborhood.cells.len(), adjacencies);
|
||||||
|
|
||||||
// Color car-free cells in a special way
|
// Color some special cells
|
||||||
for (idx, cell) in neighborhood.cells.iter().enumerate() {
|
for (idx, cell) in neighborhood.cells.iter().enumerate() {
|
||||||
if cell.car_free {
|
if cell.is_disconnected() {
|
||||||
cell_colors[idx] = colors::CAR_FREE_CELL;
|
|
||||||
} else if cell.is_disconnected() {
|
|
||||||
cell_colors[idx] = colors::DISCONNECTED_CELL;
|
cell_colors[idx] = colors::DISCONNECTED_CELL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,15 +34,12 @@ pub struct Cell {
|
|||||||
pub roads: BTreeMap<RoadID, DistanceInterval>,
|
pub roads: BTreeMap<RoadID, DistanceInterval>,
|
||||||
/// Intersections where this cell touches the boundary of the neighborhood.
|
/// Intersections where this cell touches the boundary of the neighborhood.
|
||||||
pub borders: BTreeSet<IntersectionID>,
|
pub borders: BTreeSet<IntersectionID>,
|
||||||
/// This cell only contains roads that ban cars.
|
|
||||||
pub car_free: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cell {
|
impl Cell {
|
||||||
/// A cell is disconnected if it's not connected to a perimeter road. (The exception is cells
|
/// A cell is disconnected if it's not connected to a perimeter road.
|
||||||
/// containing roads that by their OSM classification already ban cars.)
|
|
||||||
pub fn is_disconnected(&self) -> bool {
|
pub fn is_disconnected(&self) -> bool {
|
||||||
self.borders.is_empty() && !self.car_free
|
self.borders.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,14 +138,13 @@ fn find_cells(
|
|||||||
let mut cells = Vec::new();
|
let mut cells = Vec::new();
|
||||||
let mut visited = BTreeSet::new();
|
let mut visited = BTreeSet::new();
|
||||||
|
|
||||||
let mut no_car_roads = Vec::new();
|
|
||||||
for start in &perimeter.interior {
|
for start in &perimeter.interior {
|
||||||
if visited.contains(start) || modal_filters.roads.contains_key(start) {
|
if visited.contains(start) || modal_filters.roads.contains_key(start) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let start = *start;
|
let start = *start;
|
||||||
|
// Just skip entirely; they're invisible for the purpose of dividing into cells
|
||||||
if !PathConstraints::Car.can_use_road(map.get_r(start), map) {
|
if !PathConstraints::Car.can_use_road(map.get_r(start), map) {
|
||||||
no_car_roads.push(start);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let cell = floodfill(map, start, borders, &modal_filters);
|
let cell = floodfill(map, start, borders, &modal_filters);
|
||||||
@ -163,7 +159,6 @@ fn find_cells(
|
|||||||
let mut cell = Cell {
|
let mut cell = Cell {
|
||||||
roads: BTreeMap::new(),
|
roads: BTreeMap::new(),
|
||||||
borders: btreeset! { road.src_i },
|
borders: btreeset! { road.src_i },
|
||||||
car_free: false,
|
|
||||||
};
|
};
|
||||||
cell.roads.insert(
|
cell.roads.insert(
|
||||||
road.id,
|
road.id,
|
||||||
@ -178,7 +173,6 @@ fn find_cells(
|
|||||||
let mut cell = Cell {
|
let mut cell = Cell {
|
||||||
roads: BTreeMap::new(),
|
roads: BTreeMap::new(),
|
||||||
borders: btreeset! { road.dst_i },
|
borders: btreeset! { road.dst_i },
|
||||||
car_free: false,
|
|
||||||
};
|
};
|
||||||
cell.roads.insert(
|
cell.roads.insert(
|
||||||
road.id,
|
road.id,
|
||||||
@ -191,34 +185,6 @@ fn find_cells(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Roads already banning cars should still contribute a cell, so the cell coloring can still
|
|
||||||
// account for them
|
|
||||||
//
|
|
||||||
// TODO Should we attempt to merge adjacent cells like this? If we have lots of tiny pieces of
|
|
||||||
// bike-only roads, they'll each get their own cell
|
|
||||||
for r in no_car_roads {
|
|
||||||
let mut cell = Cell {
|
|
||||||
roads: BTreeMap::new(),
|
|
||||||
borders: BTreeSet::new(),
|
|
||||||
car_free: true,
|
|
||||||
};
|
|
||||||
let road = map.get_r(r);
|
|
||||||
if borders.contains(&road.src_i) {
|
|
||||||
cell.borders.insert(road.src_i);
|
|
||||||
}
|
|
||||||
if borders.contains(&road.dst_i) {
|
|
||||||
cell.borders.insert(road.dst_i);
|
|
||||||
}
|
|
||||||
cell.roads.insert(
|
|
||||||
road.id,
|
|
||||||
DistanceInterval {
|
|
||||||
start: Distance::ZERO,
|
|
||||||
end: road.length(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
cells.push(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
cells
|
cells
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,6 +276,5 @@ fn floodfill(
|
|||||||
Cell {
|
Cell {
|
||||||
roads: visited_roads,
|
roads: visited_roads,
|
||||||
borders: cell_borders,
|
borders: cell_borders,
|
||||||
car_free: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use abstutil::wraparound_get;
|
use abstutil::wraparound_get;
|
||||||
use geom::{Polygon, Pt2D, Ring};
|
use geom::{Polygon, Pt2D, Ring};
|
||||||
|
|
||||||
use crate::{CommonEndpoint, Direction, LaneID, Map, RoadID, RoadSideID, SideOfRoad};
|
use crate::{
|
||||||
|
CommonEndpoint, Direction, LaneID, Map, PathConstraints, RoadID, RoadSideID, SideOfRoad,
|
||||||
|
};
|
||||||
|
|
||||||
/// A block is defined by a perimeter that traces along the sides of roads. Inside the perimeter,
|
/// A block is defined by a perimeter that traces along the sides of roads. Inside the perimeter,
|
||||||
/// the block may contain buildings and interior roads. In the simple case, a block represents a
|
/// the block may contain buildings and interior roads. In the simple case, a block represents a
|
||||||
@ -120,15 +122,16 @@ impl Perimeter {
|
|||||||
perimeters
|
perimeters
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trying to form blocks near railways or cycleways that involve bridges/tunnels often causes
|
/// Blockfinding is specialized for the LTN tool, so non-driveable roads (cycleways and light
|
||||||
/// overlapping geometry or blocks that're way too large. These are extremely imperfect
|
/// rail) are considered invisible and can't be on a perimeter. Previously, there were also
|
||||||
/// heuristics to avoid the worst problems.
|
/// some heuristics here to try to skip certain bridges/tunnels that break the planarity of
|
||||||
|
/// blocks.
|
||||||
pub fn find_roads_to_skip_tracing(map: &Map) -> HashSet<RoadID> {
|
pub fn find_roads_to_skip_tracing(map: &Map) -> HashSet<RoadID> {
|
||||||
let mut skip = HashSet::new();
|
let mut skip = HashSet::new();
|
||||||
for r in map.all_roads() {
|
for r in map.all_roads() {
|
||||||
if r.is_light_rail() {
|
if r.is_light_rail() {
|
||||||
skip.insert(r.id);
|
skip.insert(r.id);
|
||||||
} else if r.is_cycleway() && r.zorder != 0 {
|
} else if !PathConstraints::Car.can_use_road(r, map) {
|
||||||
skip.insert(r.id);
|
skip.insert(r.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
data/system/us/seattle/maps/montlake.bin
|
data/system/us/seattle/maps/montlake.bin
|
||||||
177 single blocks (0 failures to blockify), 1 partial merges, 0 failures to blockify partitions
|
160 single blocks (0 failures to blockify), 0 partial merges, 0 failures to blockify partitions
|
||||||
data/system/us/seattle/maps/downtown.bin
|
data/system/us/seattle/maps/downtown.bin
|
||||||
1526 single blocks (0 failures to blockify), 10 partial merges, 0 failures to blockify partitions
|
1309 single blocks (0 failures to blockify), 1 partial merges, 0 failures to blockify partitions
|
||||||
data/system/us/seattle/maps/lakeslice.bin
|
data/system/us/seattle/maps/lakeslice.bin
|
||||||
1063 single blocks (0 failures to blockify), 1 partial merges, 0 failures to blockify partitions
|
1009 single blocks (0 failures to blockify), 1 partial merges, 0 failures to blockify partitions
|
||||||
data/system/us/phoenix/maps/tempe.bin
|
data/system/us/phoenix/maps/tempe.bin
|
||||||
425 single blocks (1 failures to blockify), 0 partial merges, 0 failures to blockify partitions
|
419 single blocks (1 failures to blockify), 0 partial merges, 0 failures to blockify partitions
|
||||||
data/system/gb/bristol/maps/east.bin
|
data/system/gb/bristol/maps/east.bin
|
||||||
1059 single blocks (3 failures to blockify), 6 partial merges, 0 failures to blockify partitions
|
822 single blocks (3 failures to blockify), 2 partial merges, 0 failures to blockify partitions
|
||||||
data/system/gb/leeds/maps/north.bin
|
data/system/gb/leeds/maps/north.bin
|
||||||
2597 single blocks (5 failures to blockify), 17 partial merges, 1 failures to blockify partitions
|
1936 single blocks (1 failures to blockify), 6 partial merges, 1 failures to blockify partitions
|
||||||
data/system/gb/london/maps/camden.bin
|
data/system/gb/london/maps/camden.bin
|
||||||
1565 single blocks (1 failures to blockify), 5 partial merges, 0 failures to blockify partitions
|
1046 single blocks (2 failures to blockify), 3 partial merges, 0 failures to blockify partitions
|
||||||
data/system/gb/london/maps/southwark.bin
|
data/system/gb/london/maps/southwark.bin
|
||||||
2195 single blocks (3 failures to blockify), 11 partial merges, 1 failures to blockify partitions
|
1326 single blocks (1 failures to blockify), 5 partial merges, 1 failures to blockify partitions
|
||||||
data/system/gb/manchester/maps/levenshulme.bin
|
data/system/gb/manchester/maps/levenshulme.bin
|
||||||
1353 single blocks (1 failures to blockify), 0 partial merges, 0 failures to blockify partitions
|
1244 single blocks (1 failures to blockify), 0 partial merges, 0 failures to blockify partitions
|
||||||
data/system/fr/lyon/maps/center.bin
|
data/system/fr/lyon/maps/center.bin
|
||||||
5216 single blocks (5 failures to blockify), 26 partial merges, 1 failures to blockify partitions
|
3818 single blocks (3 failures to blockify), 12 partial merges, 0 failures to blockify partitions
|
||||||
data/system/us/seattle/maps/north_seattle.bin
|
data/system/us/seattle/maps/north_seattle.bin
|
||||||
3418 single blocks (1 failures to blockify), 6 partial merges, 1 failures to blockify partitions
|
3286 single blocks (1 failures to blockify), 7 partial merges, 0 failures to blockify partitions
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user