use crate::Reachable;
use crate::transition::candidate::*;
use geo::LineString;
use routers_network::Edge;
use routers_network::Network;
use routers_network::{Entry, Metadata};
pub struct CollapsedPath<E>
where
E: Entry,
{
pub cost: u32,
pub route: Vec<CandidateId>,
pub interpolated: Vec<Reachable<E>>,
pub candidates: Candidates<E>,
}
impl<E> CollapsedPath<E>
where
E: Entry,
{
pub(crate) fn new(
cost: u32,
interpolated: Vec<Reachable<E>>,
route: Vec<CandidateId>,
candidates: Candidates<E>,
) -> Self {
Self {
cost,
interpolated,
route,
candidates,
}
}
pub fn matched(&self) -> Vec<Candidate<E>> {
self.route
.iter()
.filter_map(|node| self.candidates.lookup.get(node))
.map(|can| *can)
.collect::<Vec<_>>()
}
pub fn interpolated<M: Metadata>(&self, map: &impl Network<E, M>) -> LineString {
self.interpolated
.iter()
.enumerate()
.flat_map(|(index, reachable)| {
let source = self.candidates.candidate(&reachable.source).unwrap();
let target = self.candidates.candidate(&reachable.target).unwrap();
let path = reachable.path_nodes().filter_map(|node| map.point(&node));
core::iter::repeat_n(source.position, if index == 0 { 1 } else { 0 })
.chain(path)
.chain(core::iter::once(target.position))
})
.collect::<LineString>()
}
pub fn edges(self) -> impl Iterator<Item = Edge<E>> {
self.interpolated
.into_iter()
.flat_map(|reachable| reachable.path)
}
}