mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-28 03:35:51 +03:00
clean up some crosswalks generated near roads with sidewalks only on one side
This commit is contained in:
parent
c0eeb8848a
commit
03d599775f
@ -3,12 +3,12 @@
|
||||
8c1227160b6a8244bbdb7c8b504d69aa ../data/screenshots/pending_montlake/03x01_i0.png
|
||||
abad174a1a96560ae30c2db15ab6c2cb ../data/screenshots/pending_montlake/01x02_i5.png
|
||||
5e0e26848557b3386a8aa1839ad58560 ../data/screenshots/pending_montlake/02x02_i9.png
|
||||
0a109c274e02027fe355611dc354b74e ../data/screenshots/pending_montlake/03x02_i8.png
|
||||
ff1f5a0a4efd4d6048de5a3703082695 ../data/screenshots/pending_montlake/01x03_i20.png
|
||||
b8e121a435731b3c105c9bd7052775dc ../data/screenshots/pending_montlake/03x02_i8.png
|
||||
a128166f4fc8c404c1043032ce426b40 ../data/screenshots/pending_montlake/01x03_i20.png
|
||||
9162c2429dace890c01b9f1106af7bfe ../data/screenshots/pending_montlake/02x03_i71.png
|
||||
6b7de9c100ca476a4aa2fe12830dd44a ../data/screenshots/pending_montlake/03x03_i77.png
|
||||
e62c06cbcc8b82714009fcc3360d5377 ../data/screenshots/pending_montlake/01x04_i4.png
|
||||
2d0ad4590f8ceeaf33f0d785bbcc4cd2 ../data/screenshots/pending_montlake/02x04_i1.png
|
||||
5c633da7efc5540631743241e00a1220 ../data/screenshots/pending_montlake/02x04_i1.png
|
||||
4a7d05e039eea28b7009d1e78203a3da ../data/screenshots/pending_montlake/03x04_i58.png
|
||||
a9eb423970fc9ec9029ce839b6d45913 ../data/screenshots/pending_montlake/01x05_i31.png
|
||||
bdc20ec3835d5ea97dfe876c7e91b409 ../data/screenshots/pending_montlake/02x05_i25.png
|
||||
|
@ -25,6 +25,9 @@
|
||||
- slowly hone away at problems currently with errors printed (like bad pl shift angles)
|
||||
- eventually: every intersection has at least a turn, minimum lengths enforced, etc
|
||||
|
||||
- useful unit tests
|
||||
- for a given intersection with lanes, check all the turns generated
|
||||
|
||||
## Code to release
|
||||
|
||||
- (from before august 2019) tmp_gfx as a 2D-with-camera glium sample
|
||||
|
26
docs/assumptions.md
Normal file
26
docs/assumptions.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Modeling assumptions
|
||||
|
||||
This is pretty disorganized right now, just need to start something.
|
||||
|
||||
## Sidewalk connectivity
|
||||
|
||||
Should it be possible to close sidewalks for construction? Right now, this
|
||||
breaks too many assumptions that're hard to recompute. Building front paths and
|
||||
bus stops are associated with a sidewalk, so that makes applying the edit way
|
||||
more unclear. Closing intersections is still useful -- remove all of the vehicle
|
||||
turns, but allow the walking turns.
|
||||
|
||||
## Graph connectivity
|
||||
|
||||
For now, no map edits should be able to impact any of the trips possible in the
|
||||
baseline -- so no impacting graph connectivity, no killing bus stops, etc.
|
||||
|
||||
## Over-taking
|
||||
|
||||
Unsupported right now, but it should happen.
|
||||
|
||||
## Left turns in the middle of a road
|
||||
|
||||
Into a driveway, or using the shared left turn lanes. This should be supported.
|
||||
Parking and unparking already have the ability to block one queue -- extend
|
||||
that.
|
@ -102,7 +102,7 @@ impl Line {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn shift_either_direction(&self, width: Distance) -> Line {
|
||||
pub fn shift_either_direction(&self, width: Distance) -> Line {
|
||||
if width >= Distance::ZERO {
|
||||
self.shift_right(width)
|
||||
} else {
|
||||
|
@ -301,20 +301,15 @@ fn make_walking_turns(
|
||||
.into_iter()
|
||||
.map(|id| &all_roads[id.0])
|
||||
.collect();
|
||||
|
||||
let mut result: Vec<Turn> = Vec::new();
|
||||
for idx1 in 0..roads.len() {
|
||||
if let Some(l1) = get_sidewalk(lanes, roads[idx1].incoming_lanes(i.id)) {
|
||||
// Make the crosswalk to the other side
|
||||
if let Some(l2) = get_sidewalk(lanes, roads[idx1].outgoing_lanes(i.id)) {
|
||||
if roads.len() > 2 {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
}
|
||||
}
|
||||
|
||||
// Find the shared corner
|
||||
if roads.len() > 1 {
|
||||
// TODO -1 and not +1 is brittle... must be the angle sorting
|
||||
if roads.len() == 2 {
|
||||
if let Some(turns) = make_degenerate_crosswalks(i.id, lanes, roads[0], roads[1]) {
|
||||
result.extend(turns);
|
||||
}
|
||||
// TODO Argh, duplicate logic for SharedSidewalkCorners
|
||||
for idx1 in 0..roads.len() {
|
||||
if let Some(l1) = get_sidewalk(lanes, roads[idx1].incoming_lanes(i.id)) {
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 1).outgoing_lanes(i.id),
|
||||
@ -336,35 +331,10 @@ fn make_walking_turns(
|
||||
lookup_idx: 0,
|
||||
});
|
||||
}
|
||||
} else if roads.len() > 2 {
|
||||
// See if we need to add a crosswalk over this adjacent road.
|
||||
// TODO This is brittle; I could imagine having to cross two adjacent highway
|
||||
// ramps to get to the next sidewalk.
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 2).outgoing_lanes(i.id),
|
||||
) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
}
|
||||
// TODO Yup, the hack has come to pass.
|
||||
if roads.len() > 3 {
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 3)
|
||||
.outgoing_lanes(i.id),
|
||||
) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if roads.len() == 2 {
|
||||
if let Some(turns) = make_degenerate_crosswalks(i.id, lanes, roads[0], roads[1]) {
|
||||
result.extend(turns);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if roads.len() == 1 {
|
||||
if let Some(l1) = get_sidewalk(lanes, roads[0].incoming_lanes(i.id)) {
|
||||
@ -386,19 +356,90 @@ fn make_walking_turns(
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
for idx1 in 0..roads.len() {
|
||||
if let Some(l1) = get_sidewalk(lanes, roads[idx1].incoming_lanes(i.id)) {
|
||||
// Make the crosswalk to the other side
|
||||
if let Some(l2) = get_sidewalk(lanes, roads[idx1].outgoing_lanes(i.id)) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
}
|
||||
|
||||
// Find the shared corner
|
||||
// TODO -1 and not +1 is brittle... must be the angle sorting
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 1).outgoing_lanes(i.id),
|
||||
) {
|
||||
if l1.last_pt() != l2.first_pt() {
|
||||
let geom = make_shared_sidewalk_corner(i, l1, l2, timer);
|
||||
result.push(Turn {
|
||||
id: turn_id(i.id, l1.id, l2.id),
|
||||
turn_type: TurnType::SharedSidewalkCorner,
|
||||
other_crosswalk_ids: BTreeSet::new(),
|
||||
geom: geom.clone(),
|
||||
lookup_idx: 0,
|
||||
});
|
||||
result.push(Turn {
|
||||
id: turn_id(i.id, l2.id, l1.id),
|
||||
turn_type: TurnType::SharedSidewalkCorner,
|
||||
other_crosswalk_ids: BTreeSet::new(),
|
||||
geom: geom.reversed(),
|
||||
lookup_idx: 0,
|
||||
});
|
||||
}
|
||||
} else if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 1).incoming_lanes(i.id),
|
||||
) {
|
||||
// Adjacent road is missing a sidewalk on the near side, but has one on the far
|
||||
// side
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
} else {
|
||||
// We may need to add a crosswalk over this intermediate road that has no
|
||||
// sidewalks at all. There might be a few in the way -- think highway onramps.
|
||||
// TODO Refactor and loop until we find something to connect it to?
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 2).outgoing_lanes(i.id),
|
||||
) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
} else if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 2).incoming_lanes(i.id),
|
||||
) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
} else if roads.len() > 3 {
|
||||
if let Some(l2) = get_sidewalk(
|
||||
lanes,
|
||||
abstutil::wraparound_get(&roads, (idx1 as isize) - 3).outgoing_lanes(i.id),
|
||||
) {
|
||||
result.extend(make_crosswalks(i.id, l1, l2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn make_crosswalks(i: IntersectionID, l1: &Lane, l2: &Lane) -> Vec<Turn> {
|
||||
if l1.last_pt() == l2.first_pt() {
|
||||
let l1_pt = l1.endpoint(i);
|
||||
let l2_pt = l2.endpoint(i);
|
||||
if l1_pt == l2_pt {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
// TODO Not sure this is always right.
|
||||
let direction = if (l1.dst_i == i) == (l2.dst_i == i) {
|
||||
-1.0
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
// Jut out a bit into the intersection, cross over, then jut back in.
|
||||
let line = Line::new(l1.last_pt(), l2.first_pt()).shift_right(LANE_THICKNESS / 2.0);
|
||||
let geom_fwds = PolyLine::new(vec![l1.last_pt(), line.pt1(), line.pt2(), l2.first_pt()]);
|
||||
let line = Line::new(l1_pt, l2_pt).shift_either_direction(direction * LANE_THICKNESS / 2.0);
|
||||
let geom_fwds = PolyLine::new(vec![l1_pt, line.pt1(), line.pt2(), l2_pt]);
|
||||
|
||||
vec![
|
||||
Turn {
|
||||
|
Loading…
Reference in New Issue
Block a user