Port OSRM, Engine and Datafacades to be algorithm aware
This commit is contained in:
committed by
Patrick Niklaus
parent
71e95c92b6
commit
2fa8d0f534
@@ -7,9 +7,9 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
void AlternativeRouting::operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const PhantomNodes &phantom_node_pair,
|
||||
InternalRouteResult &raw_route_data)
|
||||
void AlternativeRouting<algorithm::CH>::operator()(const FacadeT &facade,
|
||||
const PhantomNodes &phantom_node_pair,
|
||||
InternalRouteResult &raw_route_data)
|
||||
{
|
||||
std::vector<NodeID> alternative_path;
|
||||
std::vector<NodeID> via_node_candidate_list;
|
||||
@@ -17,9 +17,9 @@ void AlternativeRouting::operator()(const std::shared_ptr<const datafacade::Base
|
||||
std::vector<SearchSpaceEdge> reverse_search_space;
|
||||
|
||||
// Init queues, semi-expensive because access to TSS invokes a sys-call
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearThirdThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearThirdThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &forward_heap1 = *(engine_working_data.forward_heap_1);
|
||||
QueryHeap &reverse_heap1 = *(engine_working_data.reverse_heap_1);
|
||||
@@ -320,13 +320,14 @@ void AlternativeRouting::operator()(const std::shared_ptr<const datafacade::Base
|
||||
}
|
||||
}
|
||||
|
||||
void AlternativeRouting::RetrievePackedAlternatePath(const QueryHeap &forward_heap1,
|
||||
const QueryHeap &reverse_heap1,
|
||||
const QueryHeap &forward_heap2,
|
||||
const QueryHeap &reverse_heap2,
|
||||
const NodeID s_v_middle,
|
||||
const NodeID v_t_middle,
|
||||
std::vector<NodeID> &packed_path) const
|
||||
void AlternativeRouting<algorithm::CH>::RetrievePackedAlternatePath(
|
||||
const QueryHeap &forward_heap1,
|
||||
const QueryHeap &reverse_heap1,
|
||||
const QueryHeap &forward_heap2,
|
||||
const QueryHeap &reverse_heap2,
|
||||
const NodeID s_v_middle,
|
||||
const NodeID v_t_middle,
|
||||
std::vector<NodeID> &packed_path) const
|
||||
{
|
||||
// fetch packed path [s,v)
|
||||
std::vector<NodeID> packed_v_t_path;
|
||||
@@ -343,15 +344,15 @@ void AlternativeRouting::RetrievePackedAlternatePath(const QueryHeap &forward_he
|
||||
// compute and unpack <s,..,v> and <v,..,t> by exploring search spaces
|
||||
// from v and intersecting against queues. only half-searches have to be
|
||||
// done at this stage
|
||||
void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void AlternativeRouting<algorithm::CH>::ComputeLengthAndSharingOfViaPath(
|
||||
const FacadeT &facade,
|
||||
const NodeID via_node,
|
||||
int *real_length_of_via_path,
|
||||
int *sharing_of_via_path,
|
||||
const std::vector<NodeID> &packed_shortest_path,
|
||||
const EdgeWeight min_edge_offset)
|
||||
{
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &existing_forward_heap = *engine_working_data.forward_heap_1;
|
||||
QueryHeap &existing_reverse_heap = *engine_working_data.reverse_heap_1;
|
||||
@@ -422,9 +423,9 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
if (packed_s_v_path[current_node] == packed_shortest_path[current_node] &&
|
||||
packed_s_v_path[current_node + 1] == packed_shortest_path[current_node + 1])
|
||||
{
|
||||
EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_s_v_path[current_node],
|
||||
packed_s_v_path[current_node + 1]);
|
||||
*sharing_of_via_path += facade->GetEdgeData(edgeID).weight;
|
||||
EdgeID edgeID = facade.FindEdgeInEitherDirection(packed_s_v_path[current_node],
|
||||
packed_s_v_path[current_node + 1]);
|
||||
*sharing_of_via_path += facade.GetEdgeData(edgeID).weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -455,9 +456,9 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
++current_node)
|
||||
{
|
||||
EdgeID selected_edge =
|
||||
facade->FindEdgeInEitherDirection(partially_unpacked_via_path[current_node],
|
||||
partially_unpacked_via_path[current_node + 1]);
|
||||
*sharing_of_via_path += facade->GetEdgeData(selected_edge).weight;
|
||||
facade.FindEdgeInEitherDirection(partially_unpacked_via_path[current_node],
|
||||
partially_unpacked_via_path[current_node + 1]);
|
||||
*sharing_of_via_path += facade.GetEdgeData(selected_edge).weight;
|
||||
}
|
||||
|
||||
// Second, partially unpack v-->t in reverse order until paths deviate and note lengths
|
||||
@@ -468,9 +469,9 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
if (packed_v_t_path[via_path_index - 1] == packed_shortest_path[shortest_path_index - 1] &&
|
||||
packed_v_t_path[via_path_index] == packed_shortest_path[shortest_path_index])
|
||||
{
|
||||
EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_v_t_path[via_path_index - 1],
|
||||
packed_v_t_path[via_path_index]);
|
||||
*sharing_of_via_path += facade->GetEdgeData(edgeID).weight;
|
||||
EdgeID edgeID = facade.FindEdgeInEitherDirection(packed_v_t_path[via_path_index - 1],
|
||||
packed_v_t_path[via_path_index]);
|
||||
*sharing_of_via_path += facade.GetEdgeData(edgeID).weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -499,9 +500,9 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
partially_unpacked_shortest_path[shortest_path_index])
|
||||
{
|
||||
EdgeID edgeID =
|
||||
facade->FindEdgeInEitherDirection(partially_unpacked_via_path[via_path_index - 1],
|
||||
partially_unpacked_via_path[via_path_index]);
|
||||
*sharing_of_via_path += facade->GetEdgeData(edgeID).weight;
|
||||
facade.FindEdgeInEitherDirection(partially_unpacked_via_path[via_path_index - 1],
|
||||
partially_unpacked_via_path[via_path_index]);
|
||||
*sharing_of_via_path += facade.GetEdgeData(edgeID).weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -513,8 +514,8 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
}
|
||||
|
||||
// conduct T-Test
|
||||
bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
bool AlternativeRouting<algorithm::CH>::ViaNodeCandidatePassesTTest(
|
||||
const FacadeT &facade,
|
||||
QueryHeap &existing_forward_heap,
|
||||
QueryHeap &existing_reverse_heap,
|
||||
QueryHeap &new_forward_heap,
|
||||
@@ -606,8 +607,8 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
for (std::size_t i = packed_s_v_path.size() - 1; (i > 0) && unpack_stack.empty(); --i)
|
||||
{
|
||||
const EdgeID current_edge_id =
|
||||
facade->FindEdgeInEitherDirection(packed_s_v_path[i - 1], packed_s_v_path[i]);
|
||||
const EdgeWeight length_of_current_edge = facade->GetEdgeData(current_edge_id).weight;
|
||||
facade.FindEdgeInEitherDirection(packed_s_v_path[i - 1], packed_s_v_path[i]);
|
||||
const EdgeWeight length_of_current_edge = facade.GetEdgeData(current_edge_id).weight;
|
||||
if ((length_of_current_edge + unpacked_until_weight) >= T_threshold)
|
||||
{
|
||||
unpack_stack.emplace(packed_s_v_path[i - 1], packed_s_v_path[i]);
|
||||
@@ -624,21 +625,21 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
const SearchSpaceEdge via_path_edge = unpack_stack.top();
|
||||
unpack_stack.pop();
|
||||
EdgeID edge_in_via_path_id =
|
||||
facade->FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
|
||||
facade.FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
|
||||
|
||||
if (SPECIAL_EDGEID == edge_in_via_path_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const EdgeData ¤t_edge_data = facade->GetEdgeData(edge_in_via_path_id);
|
||||
const EdgeData ¤t_edge_data = facade.GetEdgeData(edge_in_via_path_id);
|
||||
const bool current_edge_is_shortcut = current_edge_data.shortcut;
|
||||
if (current_edge_is_shortcut)
|
||||
{
|
||||
const NodeID via_path_middle_node_id = current_edge_data.id;
|
||||
const EdgeID second_segment_edge_id =
|
||||
facade->FindEdgeInEitherDirection(via_path_middle_node_id, via_path_edge.second);
|
||||
const int second_segment_length = facade->GetEdgeData(second_segment_edge_id).weight;
|
||||
facade.FindEdgeInEitherDirection(via_path_middle_node_id, via_path_edge.second);
|
||||
const int second_segment_length = facade.GetEdgeData(second_segment_edge_id).weight;
|
||||
// attention: !unpacking in reverse!
|
||||
// Check if second segment is the one to go over treshold? if yes add second segment
|
||||
// to stack, else push first segment to stack and add weight of second one.
|
||||
@@ -669,8 +670,8 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
++i)
|
||||
{
|
||||
const EdgeID edgeID =
|
||||
facade->FindEdgeInEitherDirection(packed_v_t_path[i], packed_v_t_path[i + 1]);
|
||||
int length_of_current_edge = facade->GetEdgeData(edgeID).weight;
|
||||
facade.FindEdgeInEitherDirection(packed_v_t_path[i], packed_v_t_path[i + 1]);
|
||||
int length_of_current_edge = facade.GetEdgeData(edgeID).weight;
|
||||
if (length_of_current_edge + unpacked_until_weight >= T_threshold)
|
||||
{
|
||||
unpack_stack.emplace(packed_v_t_path[i], packed_v_t_path[i + 1]);
|
||||
@@ -687,20 +688,20 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
const SearchSpaceEdge via_path_edge = unpack_stack.top();
|
||||
unpack_stack.pop();
|
||||
EdgeID edge_in_via_path_id =
|
||||
facade->FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
|
||||
facade.FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
|
||||
if (SPECIAL_EDGEID == edge_in_via_path_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const EdgeData ¤t_edge_data = facade->GetEdgeData(edge_in_via_path_id);
|
||||
const EdgeData ¤t_edge_data = facade.GetEdgeData(edge_in_via_path_id);
|
||||
const bool IsViaEdgeShortCut = current_edge_data.shortcut;
|
||||
if (IsViaEdgeShortCut)
|
||||
{
|
||||
const NodeID middleOfViaPath = current_edge_data.id;
|
||||
EdgeID edgeIDOfFirstSegment =
|
||||
facade->FindEdgeInEitherDirection(via_path_edge.first, middleOfViaPath);
|
||||
int lengthOfFirstSegment = facade->GetEdgeData(edgeIDOfFirstSegment).weight;
|
||||
facade.FindEdgeInEitherDirection(via_path_edge.first, middleOfViaPath);
|
||||
int lengthOfFirstSegment = facade.GetEdgeData(edgeIDOfFirstSegment).weight;
|
||||
// Check if first segment is the one to go over treshold? if yes first segment to
|
||||
// stack, else push second segment to stack and add weight of first one.
|
||||
if (unpacked_until_weight + lengthOfFirstSegment >= T_threshold)
|
||||
@@ -723,7 +724,7 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
|
||||
t_test_path_length += unpacked_until_weight;
|
||||
// Run actual T-Test query and compare if weight equal.
|
||||
engine_working_data.InitializeOrClearThirdThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearThirdThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &forward_heap3 = *engine_working_data.forward_heap_3;
|
||||
QueryHeap &reverse_heap3 = *engine_working_data.reverse_heap_3;
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace routing_algorithms
|
||||
/// by the previous route.
|
||||
/// This variation is only an optimazation for graphs with slow queries, for example
|
||||
/// not fully contracted graphs.
|
||||
void DirectShortestPathRouting::
|
||||
operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void DirectShortestPathRouting<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
InternalRouteResult &raw_route_data) const
|
||||
{
|
||||
@@ -26,7 +26,7 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const auto &source_phantom = phantom_node_pair.source_phantom;
|
||||
const auto &target_phantom = phantom_node_pair.target_phantom;
|
||||
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
QueryHeap &forward_heap = *(engine_working_data.forward_heap_1);
|
||||
QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1);
|
||||
forward_heap.Clear();
|
||||
@@ -68,9 +68,9 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const bool constexpr DO_NOT_FORCE_LOOPS =
|
||||
false; // prevents forcing of loops, since offsets are set correctly
|
||||
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
QueryHeap &forward_core_heap = *(engine_working_data.forward_heap_2);
|
||||
QueryHeap &reverse_core_heap = *(engine_working_data.reverse_heap_2);
|
||||
forward_core_heap.Clear();
|
||||
|
||||
@@ -7,8 +7,8 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
std::vector<EdgeWeight> ManyToManyRouting::
|
||||
operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
std::vector<EdgeWeight> ManyToManyRouting<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const
|
||||
@@ -22,7 +22,7 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
std::vector<EdgeWeight> weights_table(number_of_entries, INVALID_EDGE_WEIGHT);
|
||||
std::vector<EdgeWeight> durations_table(number_of_entries, MAXIMAL_EDGE_DURATION);
|
||||
|
||||
engine_working_data.InitializeOrClearManyToManyThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearManyToManyThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &query_heap = *(engine_working_data.many_to_many_heap);
|
||||
|
||||
@@ -122,8 +122,8 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
return durations_table;
|
||||
}
|
||||
|
||||
void ManyToManyRouting::ForwardRoutingStep(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ManyToManyRouting<algorithm::CH>::ForwardRoutingStep(
|
||||
const FacadeT &facade,
|
||||
const unsigned row_idx,
|
||||
const unsigned number_of_targets,
|
||||
QueryHeap &query_heap,
|
||||
@@ -179,8 +179,8 @@ void ManyToManyRouting::ForwardRoutingStep(
|
||||
RelaxOutgoingEdges<true>(facade, node, source_weight, source_duration, query_heap);
|
||||
}
|
||||
|
||||
void ManyToManyRouting::BackwardRoutingStep(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ManyToManyRouting<algorithm::CH>::BackwardRoutingStep(
|
||||
const FacadeT &facade,
|
||||
const unsigned column_idx,
|
||||
QueryHeap &query_heap,
|
||||
SearchSpaceWithBuckets &search_space_with_buckets) const
|
||||
|
||||
@@ -7,7 +7,8 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
unsigned MapMatching::GetMedianSampleTime(const std::vector<unsigned> ×tamps) const
|
||||
unsigned
|
||||
MapMatching<algorithm::CH>::GetMedianSampleTime(const std::vector<unsigned> ×tamps) const
|
||||
{
|
||||
BOOST_ASSERT(timestamps.size() > 1);
|
||||
|
||||
@@ -22,8 +23,8 @@ unsigned MapMatching::GetMedianSampleTime(const std::vector<unsigned> ×tamp
|
||||
return *median;
|
||||
}
|
||||
|
||||
SubMatchingList MapMatching::
|
||||
operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
SubMatchingList MapMatching<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const CandidateLists &candidates_list,
|
||||
const std::vector<util::Coordinate> &trace_coordinates,
|
||||
const std::vector<unsigned> &trace_timestamps,
|
||||
@@ -50,7 +51,7 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const auto max_distance_delta = [&] {
|
||||
if (use_timestamps)
|
||||
{
|
||||
return median_sample_time * facade->GetMapMatchingMaxSpeed();
|
||||
return median_sample_time * facade.GetMapMatchingMaxSpeed();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -109,8 +110,8 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
return sub_matchings;
|
||||
}
|
||||
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &forward_heap = *(engine_working_data.forward_heap_1);
|
||||
QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1);
|
||||
@@ -182,7 +183,7 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
reverse_heap.Clear();
|
||||
|
||||
double network_distance;
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
|
||||
@@ -7,17 +7,16 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
void BasicRoutingInterface::RoutingStep(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
NodeID &middle_node_id,
|
||||
EdgeWeight &upper_bound,
|
||||
EdgeWeight min_edge_offset,
|
||||
const bool forward_direction,
|
||||
const bool stalling,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse) const
|
||||
void BasicRouting<algorithm::CH>::RoutingStep(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
NodeID &middle_node_id,
|
||||
EdgeWeight &upper_bound,
|
||||
EdgeWeight min_edge_offset,
|
||||
const bool forward_direction,
|
||||
const bool stalling,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse) const
|
||||
{
|
||||
const NodeID node = forward_heap.DeleteMin();
|
||||
const EdgeWeight weight = forward_heap.GetKey(node);
|
||||
@@ -35,13 +34,13 @@ void BasicRoutingInterface::RoutingStep(
|
||||
new_weight < 0)
|
||||
{
|
||||
// check whether there is a loop present at the node
|
||||
for (const auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (const auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const EdgeData &data = facade.GetEdgeData(edge);
|
||||
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
|
||||
if (forward_directionFlag)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
if (to == node)
|
||||
{
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
@@ -77,13 +76,13 @@ void BasicRoutingInterface::RoutingStep(
|
||||
// Stalling
|
||||
if (stalling)
|
||||
{
|
||||
for (const auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (const auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const EdgeData &data = facade.GetEdgeData(edge);
|
||||
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
|
||||
if (reverse_flag)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
|
||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
||||
@@ -99,13 +98,13 @@ void BasicRoutingInterface::RoutingStep(
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (const auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const EdgeData &data = facade.GetEdgeData(edge);
|
||||
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
|
||||
if (forward_directionFlag)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
|
||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
||||
@@ -134,15 +133,14 @@ void BasicRoutingInterface::RoutingStep(
|
||||
* @param to the node the CH edge finishes at
|
||||
* @param unpacked_path the sequence of original NodeIDs that make up the expanded CH edge
|
||||
*/
|
||||
void BasicRoutingInterface::UnpackEdge(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const NodeID from,
|
||||
const NodeID to,
|
||||
std::vector<NodeID> &unpacked_path) const
|
||||
void BasicRouting<algorithm::CH>::UnpackEdge(const FacadeT &facade,
|
||||
const NodeID from,
|
||||
const NodeID to,
|
||||
std::vector<NodeID> &unpacked_path) const
|
||||
{
|
||||
std::array<NodeID, 2> path{{from, to}};
|
||||
UnpackCHPath(
|
||||
*facade,
|
||||
facade,
|
||||
path.begin(),
|
||||
path.end(),
|
||||
[&unpacked_path](const std::pair<NodeID, NodeID> &edge, const EdgeData & /* data */) {
|
||||
@@ -151,7 +149,7 @@ void BasicRoutingInterface::UnpackEdge(
|
||||
unpacked_path.emplace_back(to);
|
||||
}
|
||||
|
||||
void BasicRoutingInterface::RetrievePackedPathFromHeap(
|
||||
void BasicRouting<algorithm::CH>::RetrievePackedPathFromHeap(
|
||||
const SearchEngineData::QueryHeap &forward_heap,
|
||||
const SearchEngineData::QueryHeap &reverse_heap,
|
||||
const NodeID middle_node_id,
|
||||
@@ -163,7 +161,7 @@ void BasicRoutingInterface::RetrievePackedPathFromHeap(
|
||||
RetrievePackedPathFromSingleHeap(reverse_heap, middle_node_id, packed_path);
|
||||
}
|
||||
|
||||
void BasicRoutingInterface::RetrievePackedPathFromSingleHeap(
|
||||
void BasicRouting<algorithm::CH>::RetrievePackedPathFromSingleHeap(
|
||||
const SearchEngineData::QueryHeap &search_heap,
|
||||
const NodeID middle_node_id,
|
||||
std::vector<NodeID> &packed_path) const
|
||||
@@ -193,14 +191,14 @@ void BasicRoutingInterface::RetrievePackedPathFromSingleHeap(
|
||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||
// requires
|
||||
// a force loop, if the heaps have been initialized with positive offsets.
|
||||
void BasicRoutingInterface::Search(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
EdgeWeight &weight,
|
||||
std::vector<NodeID> &packed_leg,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse,
|
||||
const EdgeWeight weight_upper_bound) const
|
||||
void BasicRouting<algorithm::CH>::Search(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
EdgeWeight &weight,
|
||||
std::vector<NodeID> &packed_leg,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse,
|
||||
const EdgeWeight weight_upper_bound) const
|
||||
{
|
||||
NodeID middle = SPECIAL_NODEID;
|
||||
weight = weight_upper_bound;
|
||||
@@ -275,17 +273,16 @@ void BasicRoutingInterface::Search(const std::shared_ptr<const datafacade::BaseD
|
||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||
// requires
|
||||
// a force loop, if the heaps have been initialized with positive offsets.
|
||||
void BasicRoutingInterface::SearchWithCore(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
SearchEngineData::QueryHeap &reverse_core_heap,
|
||||
EdgeWeight &weight,
|
||||
std::vector<NodeID> &packed_leg,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse,
|
||||
EdgeWeight weight_upper_bound) const
|
||||
void BasicRouting<algorithm::CH>::SearchWithCore(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
SearchEngineData::QueryHeap &reverse_core_heap,
|
||||
EdgeWeight &weight,
|
||||
std::vector<NodeID> &packed_leg,
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse,
|
||||
EdgeWeight weight_upper_bound) const
|
||||
{
|
||||
NodeID middle = SPECIAL_NODEID;
|
||||
weight = weight_upper_bound;
|
||||
@@ -305,7 +302,7 @@ void BasicRoutingInterface::SearchWithCore(
|
||||
{
|
||||
if (!forward_heap.Empty())
|
||||
{
|
||||
if (facade->IsCoreNode(forward_heap.Min()))
|
||||
if (facade.IsCoreNode(forward_heap.Min()))
|
||||
{
|
||||
const NodeID node = forward_heap.DeleteMin();
|
||||
const EdgeWeight key = forward_heap.GetKey(node);
|
||||
@@ -327,7 +324,7 @@ void BasicRoutingInterface::SearchWithCore(
|
||||
}
|
||||
if (!reverse_heap.Empty())
|
||||
{
|
||||
if (facade->IsCoreNode(reverse_heap.Min()))
|
||||
if (facade.IsCoreNode(reverse_heap.Min()))
|
||||
{
|
||||
const NodeID node = reverse_heap.DeleteMin();
|
||||
const EdgeWeight key = reverse_heap.GetKey(node);
|
||||
@@ -422,7 +419,7 @@ void BasicRoutingInterface::SearchWithCore(
|
||||
BOOST_ASSERT_MSG((SPECIAL_NODEID != middle && INVALID_EDGE_WEIGHT != weight), "no path found");
|
||||
|
||||
// we need to unpack sub path from core heaps
|
||||
if (facade->IsCoreNode(middle))
|
||||
if (facade.IsCoreNode(middle))
|
||||
{
|
||||
if (weight != forward_core_heap.GetKey(middle) + reverse_core_heap.GetKey(middle))
|
||||
{
|
||||
@@ -461,8 +458,8 @@ void BasicRoutingInterface::SearchWithCore(
|
||||
}
|
||||
}
|
||||
|
||||
bool BasicRoutingInterface::NeedsLoopForward(const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
bool BasicRouting<algorithm::CH>::NeedsLoopForward(const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
{
|
||||
return source_phantom.forward_segment_id.enabled && target_phantom.forward_segment_id.enabled &&
|
||||
source_phantom.forward_segment_id.id == target_phantom.forward_segment_id.id &&
|
||||
@@ -470,8 +467,8 @@ bool BasicRoutingInterface::NeedsLoopForward(const PhantomNode &source_phantom,
|
||||
target_phantom.GetForwardWeightPlusOffset();
|
||||
}
|
||||
|
||||
bool BasicRoutingInterface::NeedsLoopBackwards(const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
bool BasicRouting<algorithm::CH>::NeedsLoopBackwards(const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
{
|
||||
return source_phantom.reverse_segment_id.enabled && target_phantom.reverse_segment_id.enabled &&
|
||||
source_phantom.reverse_segment_id.id == target_phantom.reverse_segment_id.id &&
|
||||
@@ -479,11 +476,10 @@ bool BasicRoutingInterface::NeedsLoopBackwards(const PhantomNode &source_phantom
|
||||
target_phantom.GetReverseWeightPlusOffset();
|
||||
}
|
||||
|
||||
double BasicRoutingInterface::GetPathDistance(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const std::vector<NodeID> &packed_path,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
double BasicRouting<algorithm::CH>::GetPathDistance(const FacadeT &facade,
|
||||
const std::vector<NodeID> &packed_path,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
{
|
||||
std::vector<PathData> unpacked_path;
|
||||
PhantomNodes nodes;
|
||||
@@ -500,7 +496,7 @@ double BasicRoutingInterface::GetPathDistance(
|
||||
double prev_cos = std::cos(prev_lat);
|
||||
for (const auto &p : unpacked_path)
|
||||
{
|
||||
const auto current_coordinate = facade->GetCoordinateOfNode(p.turn_via_node);
|
||||
const auto current_coordinate = facade.GetCoordinateOfNode(p.turn_via_node);
|
||||
|
||||
const double current_lat =
|
||||
static_cast<double>(toFloating(current_coordinate.lat)) * DEGREE_TO_RAD;
|
||||
@@ -539,8 +535,8 @@ double BasicRoutingInterface::GetPathDistance(
|
||||
// Requires the heaps for be empty
|
||||
// If heaps should be adjusted to be initialized outside of this function,
|
||||
// the addition of force_loop parameters might be required
|
||||
double BasicRoutingInterface::GetNetworkDistanceWithCore(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
double BasicRouting<algorithm::CH>::GetNetworkDistanceWithCore(
|
||||
const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
@@ -605,13 +601,12 @@ double BasicRoutingInterface::GetNetworkDistanceWithCore(
|
||||
// Requires the heaps for be empty
|
||||
// If heaps should be adjusted to be initialized outside of this function,
|
||||
// the addition of force_loop parameters might be required
|
||||
double BasicRoutingInterface::GetNetworkDistance(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
EdgeWeight weight_upper_bound) const
|
||||
double BasicRouting<algorithm::CH>::GetNetworkDistance(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
EdgeWeight weight_upper_bound) const
|
||||
{
|
||||
BOOST_ASSERT(forward_heap.Empty());
|
||||
BOOST_ASSERT(reverse_heap.Empty());
|
||||
|
||||
@@ -9,22 +9,21 @@ namespace routing_algorithms
|
||||
|
||||
// allows a uturn at the target_phantom
|
||||
// searches source forward/reverse -> target forward/reverse
|
||||
void ShortestPathRouting::SearchWithUTurn(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
QueryHeap &reverse_core_heap,
|
||||
const bool search_from_forward_node,
|
||||
const bool search_from_reverse_node,
|
||||
const bool search_to_forward_node,
|
||||
const bool search_to_reverse_node,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
const int total_weight_to_forward,
|
||||
const int total_weight_to_reverse,
|
||||
int &new_total_weight,
|
||||
std::vector<NodeID> &leg_packed_path) const
|
||||
void ShortestPathRouting<algorithm::CH>::SearchWithUTurn(const FacadeT &facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
QueryHeap &reverse_core_heap,
|
||||
const bool search_from_forward_node,
|
||||
const bool search_from_reverse_node,
|
||||
const bool search_to_forward_node,
|
||||
const bool search_to_reverse_node,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
const int total_weight_to_forward,
|
||||
const int total_weight_to_reverse,
|
||||
int &new_total_weight,
|
||||
std::vector<NodeID> &leg_packed_path) const
|
||||
{
|
||||
forward_heap.Clear();
|
||||
reverse_heap.Clear();
|
||||
@@ -64,7 +63,7 @@ void ShortestPathRouting::SearchWithUTurn(
|
||||
is_oneway_source && super::NeedsLoopForward(source_phantom, target_phantom);
|
||||
auto needs_loop_backwards =
|
||||
is_oneway_target && super::NeedsLoopBackwards(source_phantom, target_phantom);
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
@@ -100,23 +99,23 @@ void ShortestPathRouting::SearchWithUTurn(
|
||||
// searches shortest path between:
|
||||
// source forward/reverse -> target forward
|
||||
// source forward/reverse -> target reverse
|
||||
void ShortestPathRouting::Search(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
QueryHeap &reverse_core_heap,
|
||||
const bool search_from_forward_node,
|
||||
const bool search_from_reverse_node,
|
||||
const bool search_to_forward_node,
|
||||
const bool search_to_reverse_node,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
const int total_weight_to_forward,
|
||||
const int total_weight_to_reverse,
|
||||
int &new_total_weight_to_forward,
|
||||
int &new_total_weight_to_reverse,
|
||||
std::vector<NodeID> &leg_packed_path_forward,
|
||||
std::vector<NodeID> &leg_packed_path_reverse) const
|
||||
void ShortestPathRouting<algorithm::CH>::Search(const FacadeT &facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
QueryHeap &reverse_core_heap,
|
||||
const bool search_from_forward_node,
|
||||
const bool search_from_reverse_node,
|
||||
const bool search_to_forward_node,
|
||||
const bool search_to_reverse_node,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
const int total_weight_to_forward,
|
||||
const int total_weight_to_reverse,
|
||||
int &new_total_weight_to_forward,
|
||||
int &new_total_weight_to_reverse,
|
||||
std::vector<NodeID> &leg_packed_path_forward,
|
||||
std::vector<NodeID> &leg_packed_path_reverse) const
|
||||
{
|
||||
if (search_to_forward_node)
|
||||
{
|
||||
@@ -143,7 +142,7 @@ void ShortestPathRouting::Search(const std::shared_ptr<const datafacade::BaseDat
|
||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
@@ -194,7 +193,7 @@ void ShortestPathRouting::Search(const std::shared_ptr<const datafacade::BaseDat
|
||||
}
|
||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
@@ -223,12 +222,13 @@ void ShortestPathRouting::Search(const std::shared_ptr<const datafacade::BaseDat
|
||||
}
|
||||
}
|
||||
|
||||
void ShortestPathRouting::UnpackLegs(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const std::vector<NodeID> &total_packed_path,
|
||||
const std::vector<std::size_t> &packed_leg_begin,
|
||||
const int shortest_path_length,
|
||||
InternalRouteResult &raw_route_data) const
|
||||
void ShortestPathRouting<algorithm::CH>::UnpackLegs(
|
||||
const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const std::vector<NodeID> &total_packed_path,
|
||||
const std::vector<std::size_t> &packed_leg_begin,
|
||||
const int shortest_path_length,
|
||||
InternalRouteResult &raw_route_data) const
|
||||
{
|
||||
raw_route_data.unpacked_path_segments.resize(packed_leg_begin.size() - 1);
|
||||
|
||||
@@ -253,17 +253,18 @@ void ShortestPathRouting::UnpackLegs(const std::shared_ptr<const datafacade::Bas
|
||||
}
|
||||
}
|
||||
|
||||
void ShortestPathRouting::operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const boost::optional<bool> continue_straight_at_waypoint,
|
||||
InternalRouteResult &raw_route_data) const
|
||||
void ShortestPathRouting<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const boost::optional<bool> continue_straight_at_waypoint,
|
||||
InternalRouteResult &raw_route_data) const
|
||||
{
|
||||
const bool allow_uturn_at_waypoint =
|
||||
!(continue_straight_at_waypoint ? *continue_straight_at_waypoint
|
||||
: facade->GetContinueStraightDefault());
|
||||
: facade.GetContinueStraightDefault());
|
||||
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &forward_heap = *(engine_working_data.forward_heap_1);
|
||||
QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1);
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
#include "engine/routing_algorithms/tile_turns.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
std::vector<TurnData> TileTurns<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const std::vector<RTreeLeaf> &edges,
|
||||
const std::vector<std::size_t> &sorted_edge_indexes) const
|
||||
{
|
||||
std::vector<TurnData> all_turn_data;
|
||||
|
||||
// Struct to hold info on all the EdgeBasedNodes that are visible in our tile
|
||||
// When we create these, we insure that (source, target) and packed_geometry_id
|
||||
// are all pointed in the same direction.
|
||||
struct EdgeBasedNodeInfo
|
||||
{
|
||||
bool is_geometry_forward; // Is the geometry forward or reverse?
|
||||
unsigned packed_geometry_id;
|
||||
};
|
||||
// Lookup table for edge-based-nodes
|
||||
std::unordered_map<NodeID, EdgeBasedNodeInfo> edge_based_node_info;
|
||||
|
||||
struct SegmentData
|
||||
{
|
||||
NodeID target_node;
|
||||
EdgeID edge_based_node_id;
|
||||
};
|
||||
|
||||
std::unordered_map<NodeID, std::vector<SegmentData>> directed_graph;
|
||||
// Reserve enough space for unique edge-based-nodes on every edge.
|
||||
// Only a tile with all unique edges will use this much, but
|
||||
// it saves us a bunch of re-allocations during iteration.
|
||||
directed_graph.reserve(edges.size() * 2);
|
||||
|
||||
// Build an adjacency list for all the road segments visible in
|
||||
// the tile
|
||||
for (const auto &edge_index : sorted_edge_indexes)
|
||||
{
|
||||
const auto &edge = edges[edge_index];
|
||||
if (edge.forward_segment_id.enabled)
|
||||
{
|
||||
// operator[] will construct an empty vector at [edge.u] if there is no value.
|
||||
directed_graph[edge.u].push_back({edge.v, edge.forward_segment_id.id});
|
||||
if (edge_based_node_info.count(edge.forward_segment_id.id) == 0)
|
||||
{
|
||||
edge_based_node_info[edge.forward_segment_id.id] = {true, edge.packed_geometry_id};
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(edge_based_node_info[edge.forward_segment_id.id].is_geometry_forward ==
|
||||
true);
|
||||
BOOST_ASSERT(edge_based_node_info[edge.forward_segment_id.id].packed_geometry_id ==
|
||||
edge.packed_geometry_id);
|
||||
}
|
||||
}
|
||||
if (edge.reverse_segment_id.enabled)
|
||||
{
|
||||
directed_graph[edge.v].push_back({edge.u, edge.reverse_segment_id.id});
|
||||
if (edge_based_node_info.count(edge.reverse_segment_id.id) == 0)
|
||||
{
|
||||
edge_based_node_info[edge.reverse_segment_id.id] = {false, edge.packed_geometry_id};
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(edge_based_node_info[edge.reverse_segment_id.id].is_geometry_forward ==
|
||||
false);
|
||||
BOOST_ASSERT(edge_based_node_info[edge.reverse_segment_id.id].packed_geometry_id ==
|
||||
edge.packed_geometry_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Given a turn:
|
||||
// u---v
|
||||
// |
|
||||
// w
|
||||
// uv is the "approach"
|
||||
// vw is the "exit"
|
||||
std::vector<contractor::QueryEdge::EdgeData> unpacked_shortcut;
|
||||
std::vector<EdgeWeight> approach_weight_vector;
|
||||
|
||||
// Make sure we traverse the startnodes in a consistent order
|
||||
// to ensure identical PBF encoding on all platforms.
|
||||
std::vector<NodeID> sorted_startnodes;
|
||||
sorted_startnodes.reserve(directed_graph.size());
|
||||
for (const auto &startnode : directed_graph)
|
||||
sorted_startnodes.push_back(startnode.first);
|
||||
std::sort(sorted_startnodes.begin(), sorted_startnodes.end());
|
||||
|
||||
// Look at every node in the directed graph we created
|
||||
for (const auto &startnode : sorted_startnodes)
|
||||
{
|
||||
const auto &nodedata = directed_graph[startnode];
|
||||
// For all the outgoing edges from the node
|
||||
for (const auto &approachedge : nodedata)
|
||||
{
|
||||
// If the target of this edge doesn't exist in our directed
|
||||
// graph, it's probably outside the tile, so we can skip it
|
||||
if (directed_graph.count(approachedge.target_node) == 0)
|
||||
continue;
|
||||
|
||||
// For each of the outgoing edges from our target coordinate
|
||||
for (const auto &exit_edge : directed_graph[approachedge.target_node])
|
||||
{
|
||||
// If the next edge has the same edge_based_node_id, then it's
|
||||
// not a turn, so skip it
|
||||
if (approachedge.edge_based_node_id == exit_edge.edge_based_node_id)
|
||||
continue;
|
||||
|
||||
// Skip u-turns
|
||||
if (startnode == exit_edge.target_node)
|
||||
continue;
|
||||
|
||||
// Find the connection between our source road and the target node
|
||||
// Since we only want to find direct edges, we cannot check shortcut edges here.
|
||||
// Otherwise we might find a forward edge even though a shorter backward edge
|
||||
// exists (due to oneways).
|
||||
//
|
||||
// a > - > - > - b
|
||||
// | |
|
||||
// |------ c ----|
|
||||
//
|
||||
// would offer a backward edge at `b` to `a` (due to the oneway from a to b)
|
||||
// but could also offer a shortcut (b-c-a) from `b` to `a` which is longer.
|
||||
EdgeID smaller_edge_id =
|
||||
facade.FindSmallestEdge(approachedge.edge_based_node_id,
|
||||
exit_edge.edge_based_node_id,
|
||||
[](const contractor::QueryEdge::EdgeData &data) {
|
||||
return data.forward && !data.shortcut;
|
||||
});
|
||||
|
||||
// Depending on how the graph is constructed, we might have to look for
|
||||
// a backwards edge instead. They're equivalent, just one is available for
|
||||
// a forward routing search, and one is used for the backwards dijkstra
|
||||
// steps. Their weight should be the same, we can use either one.
|
||||
// If we didn't find a forward edge, try for a backward one
|
||||
if (SPECIAL_EDGEID == smaller_edge_id)
|
||||
{
|
||||
smaller_edge_id =
|
||||
facade.FindSmallestEdge(exit_edge.edge_based_node_id,
|
||||
approachedge.edge_based_node_id,
|
||||
[](const contractor::QueryEdge::EdgeData &data) {
|
||||
return data.backward && !data.shortcut;
|
||||
});
|
||||
}
|
||||
|
||||
// If no edge was found, it means that there's no connection between these
|
||||
// nodes, due to oneways or turn restrictions. Given the edge-based-nodes
|
||||
// that we're examining here, we *should* only find directly-connected
|
||||
// edges, not shortcuts
|
||||
if (smaller_edge_id != SPECIAL_EDGEID)
|
||||
{
|
||||
const auto &data = facade.GetEdgeData(smaller_edge_id);
|
||||
BOOST_ASSERT_MSG(!data.shortcut, "Connecting edge must not be a shortcut");
|
||||
|
||||
// Now, calculate the sum of the weight of all the segments.
|
||||
if (edge_based_node_info[approachedge.edge_based_node_id].is_geometry_forward)
|
||||
{
|
||||
approach_weight_vector = facade.GetUncompressedForwardWeights(
|
||||
edge_based_node_info[approachedge.edge_based_node_id]
|
||||
.packed_geometry_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
approach_weight_vector = facade.GetUncompressedReverseWeights(
|
||||
edge_based_node_info[approachedge.edge_based_node_id]
|
||||
.packed_geometry_id);
|
||||
}
|
||||
const auto sum_node_weight = std::accumulate(approach_weight_vector.begin(),
|
||||
approach_weight_vector.end(),
|
||||
EdgeWeight{0});
|
||||
|
||||
// The edge.weight is the whole edge weight, which includes the turn
|
||||
// cost.
|
||||
// The turn cost is the edge.weight minus the sum of the individual road
|
||||
// segment weights. This might not be 100% accurate, because some
|
||||
// intersections include stop signs, traffic signals and other
|
||||
// penalties, but at this stage, we can't divide those out, so we just
|
||||
// treat the whole lot as the "turn cost" that we'll stick on the map.
|
||||
const auto turn_cost = data.weight - sum_node_weight;
|
||||
|
||||
// Find the three nodes that make up the turn movement)
|
||||
const auto node_from = startnode;
|
||||
const auto node_via = approachedge.target_node;
|
||||
const auto node_to = exit_edge.target_node;
|
||||
|
||||
const auto coord_from = facade.GetCoordinateOfNode(node_from);
|
||||
const auto coord_via = facade.GetCoordinateOfNode(node_via);
|
||||
const auto coord_to = facade.GetCoordinateOfNode(node_to);
|
||||
|
||||
// Calculate the bearing that we approach the intersection at
|
||||
const auto angle_in = static_cast<int>(
|
||||
util::coordinate_calculation::bearing(coord_from, coord_via));
|
||||
|
||||
const auto exit_bearing = static_cast<int>(
|
||||
util::coordinate_calculation::bearing(coord_via, coord_to));
|
||||
|
||||
// Figure out the angle of the turn
|
||||
auto turn_angle = exit_bearing - angle_in;
|
||||
while (turn_angle > 180)
|
||||
{
|
||||
turn_angle -= 360;
|
||||
}
|
||||
while (turn_angle < -180)
|
||||
{
|
||||
turn_angle += 360;
|
||||
}
|
||||
|
||||
// Save everything we need to later add all the points to the tile.
|
||||
// We need the coordinate of the intersection, the angle in, the turn
|
||||
// angle and the turn cost.
|
||||
all_turn_data.push_back(TurnData{coord_via, angle_in, turn_angle, turn_cost});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return all_turn_data;
|
||||
}
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
Reference in New Issue
Block a user