mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-27 15:03:20 +03:00
Dramatically speed up editing roads by re-snapping buildings and parking
lots in one big batch, instead of after every single command. A batch of 300 edited road segments in huge_seattle went from over 70 seconds to apply down to... 0.6 seconds. Embarrassing.
This commit is contained in:
parent
309db511c2
commit
9803558885
@ -199,6 +199,7 @@ pub struct EditEffects {
|
|||||||
pub added_turns: BTreeSet<TurnID>,
|
pub added_turns: BTreeSet<TurnID>,
|
||||||
pub deleted_turns: BTreeSet<TurnID>,
|
pub deleted_turns: BTreeSet<TurnID>,
|
||||||
pub changed_parking_lots: BTreeSet<ParkingLotID>,
|
pub changed_parking_lots: BTreeSet<ParkingLotID>,
|
||||||
|
modified_lanes: BTreeSet<LaneID>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MapEdits {
|
impl MapEdits {
|
||||||
@ -554,40 +555,16 @@ fn modify_lanes(map: &mut Map, r: RoadID, lanes_ltr: Vec<LaneSpec>, effects: &mu
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We might've affected the geometry of other nearby roads.
|
// We might've affected the geometry of other nearby roads.
|
||||||
let mut modified_lanes = BTreeSet::new();
|
|
||||||
for r in road_geom_changed {
|
for r in road_geom_changed {
|
||||||
effects.changed_roads.insert(r);
|
effects.changed_roads.insert(r);
|
||||||
let lane_specs = map.get_r(r).lane_specs();
|
let lane_specs = map.get_r(r).lane_specs();
|
||||||
let road = &mut map.roads[r.0];
|
let road = &mut map.roads[r.0];
|
||||||
road.recreate_lanes(lane_specs);
|
road.recreate_lanes(lane_specs);
|
||||||
for lane in &road.lanes {
|
for lane in &road.lanes {
|
||||||
modified_lanes.insert(lane.id);
|
effects.modified_lanes.insert(lane.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
modified_lanes.extend(effects.deleted_lanes.clone());
|
effects.modified_lanes.extend(effects.deleted_lanes.clone());
|
||||||
|
|
||||||
// Find all buildings connected to modified/deleted sidewalks
|
|
||||||
let mut recalc_buildings = Vec::new();
|
|
||||||
for b in map.all_buildings() {
|
|
||||||
if modified_lanes.contains(&b.sidewalk()) {
|
|
||||||
recalc_buildings.push(b.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fix_building_driveways(map, recalc_buildings, effects);
|
|
||||||
|
|
||||||
// Same for parking lots
|
|
||||||
let mut recalc_parking_lots = Vec::new();
|
|
||||||
for pl in map.all_parking_lots() {
|
|
||||||
if modified_lanes.contains(&pl.driving_pos.lane())
|
|
||||||
|| modified_lanes.contains(&pl.sidewalk_pos.lane())
|
|
||||||
{
|
|
||||||
recalc_parking_lots.push(pl.id);
|
|
||||||
effects.changed_parking_lots.insert(pl.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fix_parking_lot_driveways(map, recalc_parking_lots);
|
|
||||||
|
|
||||||
// TODO We need to update bus stops -- they may refer to an old ID.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the other roads affected by this change, not counting changed_road.
|
// Returns the other roads affected by this change, not counting changed_road.
|
||||||
@ -840,6 +817,7 @@ impl Map {
|
|||||||
added_turns: BTreeSet::new(),
|
added_turns: BTreeSet::new(),
|
||||||
deleted_turns: BTreeSet::new(),
|
deleted_turns: BTreeSet::new(),
|
||||||
changed_parking_lots: BTreeSet::new(),
|
changed_parking_lots: BTreeSet::new(),
|
||||||
|
modified_lanes: BTreeSet::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Short-circuit to avoid marking pathfinder_dirty
|
// Short-circuit to avoid marking pathfinder_dirty
|
||||||
@ -877,6 +855,29 @@ impl Map {
|
|||||||
cmd.apply(&mut effects, self);
|
cmd.apply(&mut effects, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timer.start("re-snap buildings");
|
||||||
|
let mut recalc_buildings = Vec::new();
|
||||||
|
for b in self.all_buildings() {
|
||||||
|
if effects.modified_lanes.contains(&b.sidewalk()) {
|
||||||
|
recalc_buildings.push(b.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fix_building_driveways(self, recalc_buildings, &mut effects);
|
||||||
|
timer.stop("re-snap buildings");
|
||||||
|
|
||||||
|
timer.start("re-snap parking lots");
|
||||||
|
let mut recalc_parking_lots = Vec::new();
|
||||||
|
for pl in self.all_parking_lots() {
|
||||||
|
if effects.modified_lanes.contains(&pl.driving_pos.lane())
|
||||||
|
|| effects.modified_lanes.contains(&pl.sidewalk_pos.lane())
|
||||||
|
{
|
||||||
|
recalc_parking_lots.push(pl.id);
|
||||||
|
effects.changed_parking_lots.insert(pl.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fix_parking_lot_driveways(self, recalc_parking_lots);
|
||||||
|
timer.stop("re-snap parking lots");
|
||||||
|
|
||||||
// Might need to update bus stops.
|
// Might need to update bus stops.
|
||||||
if enforce_valid {
|
if enforce_valid {
|
||||||
for id in &effects.changed_roads {
|
for id in &effects.changed_roads {
|
||||||
|
Loading…
Reference in New Issue
Block a user