pub struct Perimeter {
pub roads: Vec<RoadSideID>,
pub interior: BTreeSet<RoadID>,
}
Expand description
A sequence of roads in order, beginning and ending at the same place. No “crossings” – tracing along this sequence should geometrically yield a simple polygon.
Fields
roads: Vec<RoadSideID>
interior: BTreeSet<RoadID>
These roads exist entirely within the perimeter
Implementations
sourceimpl Perimeter
impl Perimeter
sourcepub fn single_block(
map: &Map,
start: LaneID,
skip: &HashSet<RoadID>
) -> Result<Perimeter>
pub fn single_block(
map: &Map,
start: LaneID,
skip: &HashSet<RoadID>
) -> Result<Perimeter>
Starting at any lane, snap to the nearest side of that road, then begin tracing a single
block, with no interior roads. This will fail if a map boundary is reached. The results are
unusual when crossing the entrance to a tunnel or bridge, and so skip
is used to avoid
tracing there.
sourcepub fn find_all_single_blocks(map: &Map) -> Vec<Perimeter>ⓘNotable traits for Vec<u8, A>impl<A> Write for Vec<u8, A> where
A: Allocator,
pub fn find_all_single_blocks(map: &Map) -> Vec<Perimeter>ⓘNotable traits for Vec<u8, A>impl<A> Write for Vec<u8, A> where
A: Allocator,
A: Allocator,
This calculates all single block perimeters for the entire map. The resulting list does not cover roads near the map boundary.
sourcepub fn find_roads_to_skip_tracing(map: &Map) -> HashSet<RoadID>
pub fn find_roads_to_skip_tracing(map: &Map) -> HashSet<RoadID>
Blockfinding is specialized for the LTN tool, so non-driveable roads (cycleways and light rail) are considered invisible and can’t be on a perimeter. Previously, there were also some heuristics here to try to skip certain bridges/tunnels that break the planarity of blocks.
sourcefn undo_invariant(&mut self)
fn undo_invariant(&mut self)
A perimeter has the first and last road matching up, but that’s confusing to work with. Temporarily undo that.
sourcefn restore_invariant(&mut self)
fn restore_invariant(&mut self)
Restore the first=last invariant. Methods may temporarily break this, but must restore it before returning.
sourcefn try_to_merge(
&mut self,
map: &Map,
other: &mut Perimeter,
debug_failures: bool,
use_expensive_blockfinding: bool
) -> bool
fn try_to_merge(
&mut self,
map: &Map,
other: &mut Perimeter,
debug_failures: bool,
use_expensive_blockfinding: bool
) -> bool
Try to merge two blocks. Returns true if this is successful, which will only be when the blocks are adjacent, but the merge wouldn’t create an interior “hole”.
Note this may modify both perimeters and still return false
. The modification is just to
rotate the order of the road loop; this doesn’t logically change the perimeter.
TODO Due to https://github.com/a-b-street/abstreet/issues/841, it seems like rotation
sometimes breaks to_block
, so for now, always revert to the original upon failure.
fn check_continuity(&self, map: &Map) -> Result<()>
sourcefn reverse_to_fix_winding_order(&self, map: &Map, other: &Perimeter) -> bool
fn reverse_to_fix_winding_order(&self, map: &Map, other: &Perimeter) -> bool
Should we reverse one perimeter to match the winding order?
This is only meant to be called in the middle of try_to_merge. It assumes both perimeters have already been rotated so the common roads are at the end. The invariant of first=last is not true.
sourcepub fn merge_all(
map: &Map,
input: Vec<Perimeter>,
stepwise_debug: bool,
use_expensive_blockfinding: bool
) -> Vec<Perimeter>ⓘNotable traits for Vec<u8, A>impl<A> Write for Vec<u8, A> where
A: Allocator,
pub fn merge_all(
map: &Map,
input: Vec<Perimeter>,
stepwise_debug: bool,
use_expensive_blockfinding: bool
) -> Vec<Perimeter>ⓘNotable traits for Vec<u8, A>impl<A> Write for Vec<u8, A> where
A: Allocator,
A: Allocator,
Try to merge all given perimeters. If successful, only one perimeter will be returned.
Perimeters are never “destroyed” – if not merged, they’ll appear in the results. If
stepwise_debug
is true, returns after performing just one merge.
sourcepub fn collapse_deadends(&mut self)
pub fn collapse_deadends(&mut self)
If the perimeter follows any dead-end roads, “collapse” them and instead make the perimeter contain the dead-end.
sourcepub fn partition_by_predicate<F: Fn(RoadID) -> bool>(
input: Vec<Perimeter>,
predicate: F
) -> Vec<Vec<Perimeter>>ⓘNotable traits for Vec<u8, A>impl<A> Write for Vec<u8, A> where
A: Allocator,
pub fn partition_by_predicate<F: Fn(RoadID) -> bool>(
input: Vec<Perimeter>,
predicate: F
) -> Vec<Vec<Perimeter>>ⓘNotable traits for Vec<u8, A>impl<A> Write for Vec<u8, A> where
A: Allocator,
A: Allocator,
Consider the perimeters as a graph, with adjacency determined by sharing any road in common.
Partition adjacent perimeters, subject to the predicate. Each partition should produce a
single result with merge_all
.
sourcepub fn calculate_coloring(
input: &[Perimeter],
num_colors: usize
) -> Option<Vec<usize>>
pub fn calculate_coloring(
input: &[Perimeter],
num_colors: usize
) -> Option<Vec<usize>>
Assign each perimeter one of num_colors
, such that no two adjacent perimeters share the
same color. May fail. The resulting colors are expressed as [0, num_colors)
.
pub fn to_block(self, map: &Map) -> Result<Block>
sourcepub fn contains(&self, other: &Perimeter) -> bool
pub fn contains(&self, other: &Perimeter) -> bool
Does this perimeter completely enclose the other?
sourcepub fn flip_side_of_road(self) -> Self
pub fn flip_side_of_road(self) -> Self
Shrinks or expands the perimeter by tracing the opposite side of the road.
Trait Implementations
sourceimpl<'de> Deserialize<'de> for Perimeter
impl<'de> Deserialize<'de> for Perimeter
sourcefn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error> where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
Auto Trait Implementations
impl RefUnwindSafe for Perimeter
impl Send for Perimeter
impl Sync for Perimeter
impl Unpin for Perimeter
impl UnwindSafe for Perimeter
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> Instrument for T
impl<T> Instrument for T
sourcefn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Instruments this type with the provided Span
, returning an
Instrumented
wrapper. Read more
sourcefn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
impl<T> Same<T> for T
impl<T> Same<T> for T
type Output = T
type Output = T
Should always be Self
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more