Skip to content

Commit

Permalink
Preserve crossing when merging intersections. #246
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Mar 22, 2024
1 parent 6faf454 commit 30fa6b9
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 50 deletions.
20 changes: 15 additions & 5 deletions osm2streets/src/intersection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ pub struct Crossing {
pub has_island: bool,
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum CrossingKind {
/// Controlled by a traffic signal
Signalized,
/// Often a zebra crossing. The semantics of which road user has priority is region-specific.
Marked,
/// No paint markings, but maybe still a de facto crossing due to a nearby curb cut or an
/// island on this crossing.
Unmarked,
/// Often a zebra crossing. The semantics of which road user has priority is region-specific.
Marked,
/// Controlled by a traffic signal
Signalized,
}

/// The path that some group of adjacent lanes of traffic can take through an intersection.
Expand Down Expand Up @@ -395,3 +395,13 @@ fn is_between(num: usize, range: &(usize, usize)) -> bool {
let top = std::cmp::max(range.0, range.1);
return bot < num && num < top;
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_crossing_kind_order() {
assert!(CrossingKind::Signalized > CrossingKind::Marked);
}
}
45 changes: 32 additions & 13 deletions osm2streets/src/operations/collapse_short_road.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use std::collections::BTreeMap;

use anyhow::Result;

use crate::{IntersectionControl, IntersectionKind, RestrictionType, RoadID, StreetNetwork};
use crate::{
Crossing, IntersectionControl, IntersectionKind, RestrictionType, RoadID, StreetNetwork,
};

impl StreetNetwork {
/// Collapses a road, merging the two intersections together. This may also delete other roads
Expand Down Expand Up @@ -62,20 +64,23 @@ impl StreetNetwork {

self.remove_road(short_r);

let destroy_i = self.intersections.remove(&destroy_i).unwrap();
let mut destroy_i = self.intersections.remove(&destroy_i).unwrap();

// If the intersection types differ, upgrade the surviving interesting.
if destroy_i.control == IntersectionControl::Signalled {
self.intersections.get_mut(&keep_i).unwrap().control = IntersectionControl::Signalled;
// TODO Propagate to stop lines
}
{
let keep_intersection = self.intersections.get_mut(&keep_i).unwrap();

// Remember the merge
self.intersections
.get_mut(&keep_i)
.unwrap()
.osm_ids
.extend(destroy_i.osm_ids);
// If the intersection types differ, upgrade the surviving interesting.
if destroy_i.control == IntersectionControl::Signalled {
keep_intersection.control = IntersectionControl::Signalled;
// TODO Propagate to stop lines
}

keep_intersection.crossing =
merge_crossings(keep_intersection.crossing.take(), destroy_i.crossing.take());

// Remember the merge
keep_intersection.osm_ids.extend(destroy_i.osm_ids);
}

// Fix the endpoint of all roads connected to destroy_i.
for r in destroy_i.roads {
Expand Down Expand Up @@ -155,3 +160,17 @@ impl StreetNetwork {
Ok(())
}
}

fn merge_crossings(c1: Option<Crossing>, c2: Option<Crossing>) -> Option<Crossing> {
match (c1, c2) {
(Some(mut c1), Some(c2)) => {
c1.has_island = c1.has_island || c2.has_island;
if c1.kind != c2.kind {
// TODO Log?
c1.kind = c1.kind.max(c2.kind);
}
return Some(c1);
}
(c1, c2) => c1.or(c2),
}
}
5 changes: 4 additions & 1 deletion tests/src/aurora_sausage_link/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -2989,7 +2989,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 18,
"intersection_kind": "Intersection",
"movements": [
Expand Down
15 changes: 12 additions & 3 deletions tests/src/borough_sausage_links/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -6914,7 +6914,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Signalized"
},
"id": 46,
"intersection_kind": "Connection",
"movements": [
Expand Down Expand Up @@ -7482,7 +7485,10 @@
},
"properties": {
"control": "Signalled",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Signalized"
},
"id": 61,
"intersection_kind": "Connection",
"movements": [
Expand Down Expand Up @@ -8070,7 +8076,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Signalized"
},
"id": 79,
"intersection_kind": "Connection",
"movements": [
Expand Down
5 changes: 4 additions & 1 deletion tests/src/cycleway_rejoin_road/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -6212,7 +6212,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 71,
"intersection_kind": "Connection",
"movements": [
Expand Down
10 changes: 8 additions & 2 deletions tests/src/i5_exit_ramp/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -7711,7 +7711,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 17,
"intersection_kind": "Intersection",
"movements": [
Expand Down Expand Up @@ -9839,7 +9842,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Marked"
},
"id": 66,
"intersection_kind": "Intersection",
"movements": [
Expand Down
5 changes: 4 additions & 1 deletion tests/src/kingsway_junction/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -7390,7 +7390,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": true,
"kind": "Signalized"
},
"id": 24,
"intersection_kind": "Fork",
"movements": [
Expand Down
12 changes: 9 additions & 3 deletions tests/src/leeds_cycleway/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -26331,7 +26331,10 @@
},
"properties": {
"control": "Signalled",
"crossing": null,
"crossing": {
"has_island": true,
"kind": "Signalized"
},
"id": 72,
"intersection_kind": "Connection",
"movements": [
Expand Down Expand Up @@ -33731,7 +33734,7 @@
"control": "Signed",
"crossing": {
"has_island": false,
"kind": "Marked"
"kind": "Signalized"
},
"id": 309,
"intersection_kind": "Connection",
Expand Down Expand Up @@ -35926,7 +35929,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Signalized"
},
"id": 358,
"intersection_kind": "Connection",
"movements": [
Expand Down
5 changes: 4 additions & 1 deletion tests/src/montlake_roundabout/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -3345,7 +3345,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 35,
"intersection_kind": "Intersection",
"movements": [
Expand Down
20 changes: 16 additions & 4 deletions tests/src/northgate_dual_carriageway/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -26258,7 +26258,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 217,
"intersection_kind": "Intersection",
"movements": [
Expand Down Expand Up @@ -26505,7 +26508,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 224,
"intersection_kind": "Intersection",
"movements": [
Expand Down Expand Up @@ -27679,7 +27685,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 252,
"intersection_kind": "Intersection",
"movements": [
Expand Down Expand Up @@ -28064,7 +28073,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 262,
"intersection_kind": "Intersection",
"movements": [
Expand Down
10 changes: 8 additions & 2 deletions tests/src/perth_peanut_roundabout/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -4343,7 +4343,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 43,
"intersection_kind": "Fork",
"movements": [
Expand Down Expand Up @@ -4762,7 +4765,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 52,
"intersection_kind": "Connection",
"movements": [
Expand Down
5 changes: 4 additions & 1 deletion tests/src/quad_intersection/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -5812,7 +5812,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 48,
"intersection_kind": "Intersection",
"movements": [
Expand Down
27 changes: 21 additions & 6 deletions tests/src/roosevelt_cycletrack/geometry.json
Original file line number Diff line number Diff line change
Expand Up @@ -18465,7 +18465,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 5,
"intersection_kind": "Fork",
"movements": [
Expand Down Expand Up @@ -20440,7 +20443,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 62,
"intersection_kind": "Connection",
"movements": [],
Expand Down Expand Up @@ -24214,7 +24220,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Signalized"
},
"id": 158,
"intersection_kind": "Intersection",
"movements": [
Expand Down Expand Up @@ -29042,7 +29051,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 265,
"intersection_kind": "Intersection",
"movements": [
Expand Down Expand Up @@ -32312,7 +32324,7 @@
"control": "Signalled",
"crossing": {
"has_island": false,
"kind": "Unmarked"
"kind": "Signalized"
},
"id": 331,
"intersection_kind": "Intersection",
Expand Down Expand Up @@ -33338,7 +33350,10 @@
},
"properties": {
"control": "Signed",
"crossing": null,
"crossing": {
"has_island": false,
"kind": "Unmarked"
},
"id": 359,
"intersection_kind": "Fork",
"movements": [
Expand Down
Loading

0 comments on commit 30fa6b9

Please sign in to comment.