Skip to content

Commit

Permalink
Work on cycleway snapping for St George:
Browse files Browse the repository at this point in the history
- the cycleway itself may be short, ignore it
- the short road between the main road and intersection may have been merged
- Remove connector segments immediately
- Remember to regenerate intersection geometry
  • Loading branch information
dabreegster committed Mar 10, 2023
1 parent 6c10dcb commit 01cd3ab
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
4 changes: 2 additions & 2 deletions osm2streets-js/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ impl JsStreetNetwork {
}
if input.sidepath_zipping_experiment {
transformations.push(Transformation::ZipSidepaths);
transformations.push(Transformation::TrimDeadendCycleways);
transformations.push(Transformation::CollapseDegenerateIntersections);
//transformations.push(Transformation::TrimDeadendCycleways);
//transformations.push(Transformation::CollapseDegenerateIntersections);
}
if input.debug_each_step {
street_network.apply_transformations_stepwise_debugging(transformations, &mut timer);
Expand Down
12 changes: 8 additions & 4 deletions osm2streets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,19 @@ impl StreetNetwork {

pub(crate) fn debug_intersection<I: Into<String>>(&mut self, i: IntersectionID, label: I) {
if let Some(step) = self.debug_steps.last_mut() {
step.points
.push((self.intersections[&i].polygon.center(), label.into()));
if let Some(intersection) = self.intersections.get(&i) {
step.points
.push((intersection.polygon.center(), label.into()));
}
}
}

pub(crate) fn debug_road<I: Into<String>>(&mut self, r: RoadID, label: I) {
if let Some(step) = self.debug_steps.last_mut() {
step.polylines
.push((self.roads[&r].center_line.clone(), label.into()));
if let Some(road) = self.roads.get(&r) {
step.polylines
.push((road.center_line.clone(), label.into()));
}
}
}

Expand Down
56 changes: 51 additions & 5 deletions osm2streets/src/operations/zip_sidepath.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::BTreeSet;

use geom::{Distance, PolyLine};

use crate::{BufferType, Direction, IntersectionID, LaneSpec, LaneType, RoadID, StreetNetwork};
Expand All @@ -22,6 +24,8 @@ pub struct Sidepath {
main_road_src_i: IntersectionID,
main_road_dst_i: IntersectionID,
main_roads: Vec<RoadID>,
connector_src_i: Option<RoadID>,
connector_dst_i: Option<RoadID>,
}

impl Sidepath {
Expand All @@ -35,12 +39,17 @@ impl Sidepath {
for i in sidepath_road.endpoints() {
let mut connector_candidates = Vec::new();
for road in streets.roads_per_intersection(i) {
if road.untrimmed_length() < SHORT_ROAD_THRESHOLD {
if road.id != sidepath_road.id && road.center_line.length() < SHORT_ROAD_THRESHOLD {
connector_candidates.push(road.id);
}
}
if connector_candidates.len() == 1 {
main_road_endpoints.push(streets.roads[&connector_candidates[0]].other_side(i));
let connector = connector_candidates[0];
main_road_endpoints
.push((streets.roads[&connector].other_side(i), Some(connector)));
} else if connector_candidates.is_empty() {
// Maybe this intersection has been merged already. Use it directly.
main_road_endpoints.push((i, None));
}
}

Expand All @@ -50,8 +59,12 @@ impl Sidepath {

// Often the main road parallel to this sidepath segment is just one road, but it might
// be more.
let main_road_src_i = main_road_endpoints[0];
let main_road_dst_i = main_road_endpoints[1];
let (main_road_src_i, connector_src_i) = main_road_endpoints[0];
let (main_road_dst_i, connector_dst_i) = main_road_endpoints[1];
// It may be none at all, when the main road intersection gets merged
if main_road_src_i == main_road_dst_i {
return None;
}

// Find all main road segments "parallel to" this sidepath, by pathfinding between the
// main road intersections. We don't care about the order, but simple_path does. In
Expand All @@ -66,6 +79,8 @@ impl Sidepath {
main_road_src_i,
main_road_dst_i,
main_roads: path.into_iter().map(|(r, _)| r).collect(),
connector_src_i,
connector_dst_i,
});
}

Expand All @@ -79,10 +94,20 @@ impl Sidepath {
for x in &self.main_roads {
streets.debug_road(*x, format!("main road along {label}"));
}
if let Some(r) = self.connector_src_i {
streets.debug_road(r, format!("src_i connector of {label}"));
}
if let Some(r) = self.connector_dst_i {
streets.debug_road(r, format!("dst_i connector of {label}"));
}
}

pub fn zip(self, streets: &mut StreetNetwork) {
assert!(streets.roads.contains_key(&self.sidepath));
// The caller may find a bunch of these and zip, which sometimes could delete one of the
// located pieces
if !streets.roads.contains_key(&self.sidepath) {
return;
}

// Remove the sidepath, but remember the lanes it contained
let mut sidepath_lanes = streets.remove_road(self.sidepath).lane_specs_ltr;
Expand Down Expand Up @@ -117,6 +142,7 @@ impl Sidepath {
// - Fixing the direction of the lanes
// - Appending them on the left or right side (and "inside" the inferred sidewalk on the road)
// - Inserting the buffer
let mut intersections = BTreeSet::new();
for r in self.main_roads {
let main_road = &streets.roads[&r];
// Which side is closer to the sidepath?
Expand Down Expand Up @@ -186,11 +212,31 @@ impl Sidepath {

let main_road = streets.roads.get_mut(&r).unwrap();
splice_in(&mut main_road.lane_specs_ltr, insert_idx, insert_lanes);

intersections.extend(main_road.endpoints());
}

// Recalculate geometry along all of the main roads we just thickened
for i in intersections {
streets.update_i(i);
}

// After this transformation, we should run CollapseDegenerateIntersections to handle the
// intersection where the side road originally crossed the sidepath, and TrimDeadendCycleways
// to clean up any small cycle connection roads.
//
// ALTERNATIVELY, remove the connector segments immediately.
if let Some(r) = self.connector_src_i {
if streets.roads.contains_key(&r) {
// Ignore errors
let _ = streets.collapse_short_road(r);
}
}
if let Some(r) = self.connector_dst_i {
if streets.roads.contains_key(&r) {
let _ = streets.collapse_short_road(r);
}
}
}
}

Expand Down

0 comments on commit 01cd3ab

Please sign in to comment.