From 9229ce1be53b6d88c7bf0ba9db1eb1b51ee75278 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Thu, 15 Dec 2022 14:24:59 +0000 Subject: [PATCH] Move the calculation of trim_start and trim_end into the intersection geometry layer. #136 --- osm2streets/src/geometry/mod.rs | 27 ++++++++++++++++--- osm2streets/src/lib.rs | 6 ++++- .../src/transform/intersection_geometry.rs | 18 ++++--------- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/osm2streets/src/geometry/mod.rs b/osm2streets/src/geometry/mod.rs index 5291af48..517027e4 100644 --- a/osm2streets/src/geometry/mod.rs +++ b/osm2streets/src/geometry/mod.rs @@ -84,8 +84,11 @@ pub struct Results { pub intersection_id: IntersectionID, pub intersection_polygon: Polygon, /// The only transformation to `center_line` passed in must be to trim it (reducing the length) - /// or to lengthen the first/last line. - pub trimmed_center_pts: BTreeMap, + /// or to lengthen the first/last line. `trim_starts` and `trim_ends` are calculated from this, + /// and the caller deliberately can't see `trimmed_center_pts`. + trimmed_center_pts: BTreeMap, + pub trim_starts: BTreeMap, + pub trim_ends: BTreeMap, /// Extra points with labels to debug the algorithm pub debug: Vec<(Pt2D, String)>, } @@ -115,9 +118,12 @@ pub fn intersection_polygon( intersection_polygon: Polygon::dummy(), debug: Vec::new(), trimmed_center_pts: BTreeMap::new(), + trim_starts: BTreeMap::new(), + trim_ends: BTreeMap::new(), }; + let mut untrimmed_roads = roads.clone(); - if roads.len() == 1 { + let mut results = if roads.len() == 1 { terminus::terminus(results, roads.into_values().next().unwrap()) } else if roads.len() == 2 { let mut iter = roads.into_values(); @@ -130,7 +136,22 @@ pub fn intersection_polygon( Ok(result) } else { general_case::trim_to_corners(results, roads, sorted_roads) + }?; + + // We've filled out trimmed_center_pts, now calculate trim_starts and trim_ends + for (r, pl) in &results.trimmed_center_pts { + // Normally this'll be positive, indicating trim. If it's negative, the algorithm extended + // the first or last line + let road = untrimmed_roads.remove(r).unwrap(); + let trim = road.center_line.length() - pl.length(); + if road.src_i == intersection_id { + results.trim_starts.insert(*r, trim); + } else { + results.trim_ends.insert(*r, trim); + } } + + Ok(results) } /// After trimming roads back, form the final polygon using the endpoints of each road edge and diff --git a/osm2streets/src/lib.rs b/osm2streets/src/lib.rs index 9e600635..19fe3396 100644 --- a/osm2streets/src/lib.rs +++ b/osm2streets/src/lib.rs @@ -164,7 +164,11 @@ impl StreetNetwork { &BTreeMap::new(), ) .ok()?; - trims.push(untrimmed.length() - results.trimmed_center_pts[&road_id].length()); + trims.push(if i == orig_road.src_i { + results.trim_starts[&road_id] + } else { + results.trim_ends[&road_id] + }); } Road::trim_polyline_both_ends(untrimmed, trims[0], trims[1]) diff --git a/osm2streets/src/transform/intersection_geometry.rs b/osm2streets/src/transform/intersection_geometry.rs index e490a8a1..18ab40b2 100644 --- a/osm2streets/src/transform/intersection_geometry.rs +++ b/osm2streets/src/transform/intersection_geometry.rs @@ -23,19 +23,11 @@ pub fn generate(streets: &mut StreetNetwork, timer: &mut Timer) { match crate::intersection_polygon(i.id, input_roads, &i.trim_roads_for_merging) { Ok(results) => { set_polygons.push((i.id, results.intersection_polygon)); - for (r, pl) in results.trimmed_center_pts { - let road = streets.roads.get_mut(&r).unwrap(); - // Normally this'll be positive, indicating trim. If it's negative, the - // algorithm extended the first or last line - let trim = road - .get_untrimmed_center_line(streets.config.driving_side) - .length() - - pl.length(); - if road.src_i == i.id { - road.trim_start = trim; - } else { - road.trim_end = trim; - } + for (r, dist) in results.trim_starts { + streets.roads.get_mut(&r).unwrap().trim_start = dist; + } + for (r, dist) in results.trim_ends { + streets.roads.get_mut(&r).unwrap().trim_end = dist; } for (pt, label) in results.debug { streets.debug_point(pt, label);