moved the route reconstruction into the Route struct
This commit is contained in:
parent
32a81b3561
commit
367fc0ef3e
2 changed files with 40 additions and 56 deletions
41
src/astar.rs
41
src/astar.rs
|
|
@ -8,11 +8,17 @@ pub struct AStar<'a> {
|
||||||
pub graph: &'a GridGraph,
|
pub graph: &'a GridGraph,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An element on the Heap for A*.
|
||||||
|
/// The Ord and PartialOrd Traits are inverted so that the MaxHeap works as a
|
||||||
|
/// MinHeap.
|
||||||
|
/// index is the index of the Node, cost is the cost which the heap sorts after.
|
||||||
|
/// path_cost is the actual cost of the path to that node.
|
||||||
#[derive(Eq, PartialEq)]
|
#[derive(Eq, PartialEq)]
|
||||||
struct HeapElement {
|
struct HeapElement {
|
||||||
index: u32,
|
index: u32,
|
||||||
cost: EdgeCost, // the cost so far plus the estimated cost until we reach the
|
|
||||||
// destination
|
// the cost so far plus the estimated cost until we reach the destination
|
||||||
|
cost: EdgeCost,
|
||||||
path_cost: EdgeCost, // the cost to reach this node from the start node
|
path_cost: EdgeCost, // the cost to reach this node from the start node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,10 +70,7 @@ impl AStar<'_> {
|
||||||
let mut popcount = 0;
|
let mut popcount = 0;
|
||||||
|
|
||||||
while let Some(HeapElement {
|
while let Some(HeapElement {
|
||||||
index,
|
index, path_cost, ..
|
||||||
cost, // the cost value, no longer needed, because it is only important for the
|
|
||||||
// distance estimate
|
|
||||||
path_cost,
|
|
||||||
}) = heap.pop()
|
}) = heap.pop()
|
||||||
{
|
{
|
||||||
//println!("working on node {} with cost {} and path cost {}", index, cost, path_cost);
|
//println!("working on node {} with cost {} and path cost {}", index, cost, path_cost);
|
||||||
|
|
@ -113,30 +116,6 @@ impl AStar<'_> {
|
||||||
|
|
||||||
println!("popped {} elements from the heap", popcount);
|
println!("popped {} elements from the heap", popcount);
|
||||||
|
|
||||||
// now the route calculation is done. If a route exist we can construct
|
Route::construct(self.graph, &ancestor, &distance, start, end)
|
||||||
// it from the ancestors.
|
|
||||||
if ancestor[end.index as usize].is_some() {
|
|
||||||
let mut route = Route {
|
|
||||||
cost: distance[end.index as usize],
|
|
||||||
nodes: Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut current = end.index;
|
|
||||||
while current != start.index {
|
|
||||||
route
|
|
||||||
.nodes
|
|
||||||
.push(self.graph.nodes[current as usize].position);
|
|
||||||
current = ancestor[current as usize].unwrap();
|
|
||||||
}
|
|
||||||
route
|
|
||||||
.nodes
|
|
||||||
.push(self.graph.nodes[current as usize].position);
|
|
||||||
|
|
||||||
route.nodes.reverse();
|
|
||||||
|
|
||||||
return Some(route);
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,34 @@ impl LookupGrid {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Route {
|
impl Route {
|
||||||
|
|
||||||
|
/// Constructs a route from the start to the end node on the graph
|
||||||
|
/// based on the ancestor and distance lists of a routing algorithm.
|
||||||
|
pub fn construct(graph: &GridGraph, ancestors: &Vec<Option<u32>>, distance: &Vec<EdgeCost>, start: &GraphNode, end: &GraphNode) -> Option<Self>{
|
||||||
|
if ancestors[end.index as usize].is_some() {
|
||||||
|
let mut route = Route {
|
||||||
|
cost: distance[end.index as usize],
|
||||||
|
nodes: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut current = end.index;
|
||||||
|
while current != start.index {
|
||||||
|
route
|
||||||
|
.nodes
|
||||||
|
.push(graph.nodes[current as usize].position);
|
||||||
|
current = ancestors[current as usize].unwrap();
|
||||||
|
}
|
||||||
|
route
|
||||||
|
.nodes
|
||||||
|
.push(graph.nodes[current as usize].position);
|
||||||
|
|
||||||
|
route.nodes.reverse();
|
||||||
|
|
||||||
|
return Some(route);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_geojson(&self) -> Box<FeatureCollection> {
|
pub fn to_geojson(&self) -> Box<FeatureCollection> {
|
||||||
let mut features: Box<FeatureCollection> = Box::new(FeatureCollection {
|
let mut features: Box<FeatureCollection> = Box::new(FeatureCollection {
|
||||||
bbox: None,
|
bbox: None,
|
||||||
|
|
@ -205,10 +233,7 @@ impl GridGraph {
|
||||||
|
|
||||||
//println!("working on node {} with cost {}", index, cost);
|
//println!("working on node {} with cost {}", index, cost);
|
||||||
|
|
||||||
let edge_start = self.edge_offsets[index as usize] as usize;
|
for edge in self.get_edges(index as usize).iter() {
|
||||||
let edge_end = self.edge_offsets[(index + 1) as usize] as usize;
|
|
||||||
|
|
||||||
for edge in self.edges[edge_start..edge_end].iter() {
|
|
||||||
let new_cost = cost + edge.cost;
|
let new_cost = cost + edge.cost;
|
||||||
|
|
||||||
if new_cost < distance[edge.neighbor as usize] {
|
if new_cost < distance[edge.neighbor as usize] {
|
||||||
|
|
@ -228,27 +253,7 @@ impl GridGraph {
|
||||||
|
|
||||||
println!("popped {} elements from the heap", popcount);
|
println!("popped {} elements from the heap", popcount);
|
||||||
|
|
||||||
// now the route calculation is done. If a route exist we can construct
|
Route::construct(self, &ancestor, &distance, start, end)
|
||||||
// it from the ancestors.
|
|
||||||
if ancestor[end.index as usize].is_some() {
|
|
||||||
let mut route = Route {
|
|
||||||
cost: distance[end.index as usize],
|
|
||||||
nodes: Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut current = end.index;
|
|
||||||
while current != start.index {
|
|
||||||
route.nodes.push(self.nodes[current as usize].position);
|
|
||||||
current = ancestor[current as usize].unwrap();
|
|
||||||
}
|
|
||||||
route.nodes.push(self.nodes[current as usize].position);
|
|
||||||
|
|
||||||
route.nodes.reverse();
|
|
||||||
|
|
||||||
return Some(route);
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// returns the GraphNode nearest to that positon.
|
/// returns the GraphNode nearest to that positon.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue