Skip to content

Commit

Permalink
Make the intersection geometry logic an operation. Keep the transform…
Browse files Browse the repository at this point in the history
… for the moment. #136
  • Loading branch information
dabreegster committed Jan 21, 2023
1 parent 612feef commit 14e6a82
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 56 deletions.
1 change: 1 addition & 0 deletions osm2streets/src/operations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

mod collapse_intersection;
mod collapse_short_road;
mod update_geometry;
66 changes: 66 additions & 0 deletions osm2streets/src/operations/update_geometry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use geom::{Circle, Distance};

use crate::{IntersectionID, Road, StreetNetwork};

impl StreetNetwork {
/// Recalculates trim distances and intersection geometry. This is idempotent; it doesn't use
/// any results from the previous call.
pub fn update_geometry(&mut self, id: IntersectionID) {
let i = &self.intersections[&id];

// Update the polygon and Set trim distances for roads
let input_roads = i
.roads
.iter()
.map(|r| self.roads[r].to_input_road(self.config.driving_side))
.collect::<Vec<_>>();
match crate::intersection_polygon(i.id, input_roads, &i.trim_roads_for_merging) {
Ok(results) => {
self.intersections.get_mut(&id).unwrap().polygon = results.intersection_polygon;

for (r, dist) in results.trim_starts {
self.roads.get_mut(&r).unwrap().trim_start = dist;
}
for (r, dist) in results.trim_ends {
self.roads.get_mut(&r).unwrap().trim_end = dist;
}
for (pt, label) in results.debug {
self.debug_point(pt, label);
}
}
Err(err) => {
error!("Can't make intersection geometry for {}: {}", i.id, err);

let r = i.roads[0];
// Don't trim lines back at all
let road = &self.roads[&r];
let pt = if road.src_i == i.id {
road.center_line.first_pt()
} else {
road.center_line.last_pt()
};
self.intersections.get_mut(&id).unwrap().polygon =
Circle::new(pt, Distance::meters(3.0)).to_polygon();
}
}

// Update road center lines based on the trim. Note update_geometry works on one
// intersection at a time, so it's possible some roads haven't been trimmed yet on the
// other side.
for r in &self.intersections[&id].roads {
let road = self.roads.get_mut(r).unwrap();

let untrimmed = road.get_untrimmed_center_line(self.config.driving_side);
if let Some(pl) =
Road::trim_polyline_both_ends(untrimmed.clone(), road.trim_start, road.trim_end)
{
road.center_line = pl;
} else {
error!("{} got trimmed into oblivion, collapse it later", road.id);
road.center_line = untrimmed;
// Collapse it later
road.internal_junction_road = true;
}
}
}
}
60 changes: 4 additions & 56 deletions osm2streets/src/transform/intersection_geometry.rs
Original file line number Diff line number Diff line change
@@ -1,68 +1,16 @@
use abstutil::Timer;
use geom::{Circle, Distance};

use crate::{Road, StreetNetwork};
use crate::StreetNetwork;

pub fn generate(streets: &mut StreetNetwork, timer: &mut Timer) {
timer.start_iter(
"find each intersection polygon",
streets.intersections.len(),
);
// It'd be nice to mutate in the loop, but the borrow checker won't let us
let mut set_polygons = Vec::new();

// Set trim distances for all roads
for i in streets.intersections.values() {
let ids = streets.intersections.keys().cloned().collect::<Vec<_>>();
for i in ids {
timer.next();
let input_roads = i
.roads
.iter()
.map(|r| streets.roads[r].to_input_road(streets.config.driving_side))
.collect::<Vec<_>>();
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, 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);
}
}
Err(err) => {
error!("Can't make intersection geometry for {}: {}", i.id, err);

let r = i.roads[0];
// Don't trim lines back at all
let road = &streets.roads[&r];
let pt = if road.src_i == i.id {
road.center_line.first_pt()
} else {
road.center_line.last_pt()
};
set_polygons.push((i.id, Circle::new(pt, Distance::meters(3.0)).to_polygon()));
}
}
}

for road in streets.roads.values_mut() {
let untrimmed = road.get_untrimmed_center_line(streets.config.driving_side);
if let Some(pl) =
Road::trim_polyline_both_ends(untrimmed.clone(), road.trim_start, road.trim_end)
{
road.center_line = pl;
} else {
error!("{} got trimmed into oblivion, collapse it later", road.id);
road.center_line = untrimmed;
// Collapse it later
road.internal_junction_road = true;
}
}

for (i, polygon) in set_polygons {
streets.intersections.get_mut(&i).unwrap().polygon = polygon;
streets.update_geometry(i);
}
}

0 comments on commit 14e6a82

Please sign in to comment.