From cd01d898a8e8148103db4a25f59a2fef0a81fd71 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Mon, 5 Dec 2022 14:08:03 +0000 Subject: [PATCH] Move RoadEdge logic out of sidewalk rendering. It'll be useful for intersection geometry refactors. #136 --- osm2streets/src/render.rs | 47 +++++++-------------------------------- osm2streets/src/road.rs | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/osm2streets/src/render.rs b/osm2streets/src/render.rs index 3a6b681b..7a77a26b 100644 --- a/osm2streets/src/render.rs +++ b/osm2streets/src/render.rs @@ -6,9 +6,8 @@ use std::path::Path; use anyhow::Result; use geom::{ArrowCap, Distance, Line, PolyLine, Polygon, Ring}; -use crate::{ - DebugStreets, Direction, DrivingSide, Intersection, LaneSpec, LaneType, RoadID, StreetNetwork, -}; +use crate::road::RoadEdge; +use crate::{DebugStreets, Direction, DrivingSide, Intersection, LaneType, StreetNetwork}; impl StreetNetwork { /// Saves the plain GeoJSON rendering to a file. @@ -398,43 +397,13 @@ fn make_props(list: &[(&str, serde_json::Value)]) -> serde_json::Map Vec { - #[derive(Clone)] - struct Edge { - road: RoadID, - // Pointed into the intersection - pl: PolyLine, - lane: LaneSpec, - } - - // Get the left and right edge of each road, pointed into the intersection. All sorted - // clockwise - // TODO Use the road view idea instead. Or just refactor this. - let mut edges = Vec::new(); - for road in streets.roads_per_intersection(intersection.id) { - let mut left = Edge { - road: road.id, - pl: road.center_line.must_shift_left(road.total_width() / 2.0), - lane: road.lane_specs_ltr[0].clone(), - }; - let mut right = Edge { - road: road.id, - pl: road.center_line.must_shift_right(road.total_width() / 2.0), - lane: road.lane_specs_ltr.last().unwrap().clone(), - }; - if road.dst_i == intersection.id { - edges.push(right); - edges.push(left); - } else { - left.pl = left.pl.reversed(); - right.pl = right.pl.reversed(); - edges.push(left); - edges.push(right); - } - } - - // Look at every adjacent pair - let mut results = Vec::new(); + // Look at every adjacent pair of edges + let mut edges = RoadEdge::calculate( + streets.roads_per_intersection(intersection.id), + intersection.id, + ); edges.push(edges[0].clone()); + let mut results = Vec::new(); for pair in edges.windows(2) { let one = &pair[0]; let two = &pair[1]; diff --git a/osm2streets/src/road.rs b/osm2streets/src/road.rs index 28bf05b1..6739eb26 100644 --- a/osm2streets/src/road.rs +++ b/osm2streets/src/road.rs @@ -449,3 +449,44 @@ impl StreetNetwork { id } } + +/// The edge of a road, pointed into some intersection +#[derive(Clone)] +pub(crate) struct RoadEdge { + pub road: RoadID, + /// Pointed into the intersection + pub pl: PolyLine, + pub lane: LaneSpec, +} + +impl RoadEdge { + /// Get the left and right edge of each road, pointed into the intersection. All sorted + /// clockwise. No repetitions -- to iterate over all adjacent pairs, the caller must repeat the + /// first edge + // TODO Maybe returning an iterator over pairs of these is more useful + pub fn calculate(sorted_roads: Vec<&Road>, i: IntersectionID) -> Vec { + let mut edges = Vec::new(); + for road in sorted_roads { + let mut left = RoadEdge { + road: road.id, + pl: road.center_line.must_shift_left(road.total_width() / 2.0), + lane: road.lane_specs_ltr[0].clone(), + }; + let mut right = RoadEdge { + road: road.id, + pl: road.center_line.must_shift_right(road.total_width() / 2.0), + lane: road.lane_specs_ltr.last().unwrap().clone(), + }; + if road.dst_i == i { + edges.push(right); + edges.push(left); + } else { + left.pl = left.pl.reversed(); + right.pl = right.pl.reversed(); + edges.push(left); + edges.push(right); + } + } + edges + } +}