implement path query with uturns at via nodes

This commit is contained in:
Dennis Luxen 2014-07-16 12:53:33 +02:00
parent 95b5bcbd49
commit ee1fdca52e
2 changed files with 28 additions and 29 deletions

View File

@ -125,7 +125,7 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
} }
else else
{ {
search_engine_ptr->shortest_path(raw_route.segment_end_coordinates, raw_route); search_engine_ptr->shortest_path(raw_route.segment_end_coordinates, route_parameters.uturns, raw_route);
} }
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length) if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)

View File

@ -49,6 +49,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
~ShortestPathRouting() {} ~ShortestPathRouting() {}
void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector, void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
const std::vector<bool> &uturn_indicators,
RawRouteData &raw_route_data) const RawRouteData &raw_route_data) const
{ {
int distance1 = 0; int distance1 = 0;
@ -86,43 +87,44 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
middle1 = UINT_MAX; middle1 = UINT_MAX;
middle2 = UINT_MAX; middle2 = UINT_MAX;
const bool allow_u_turn = current_leg > 0 && uturn_indicators.size() > current_leg && uturn_indicators[current_leg-1];
int min_edge_offset = 0; int min_edge_offset = 0;
// insert new starting nodes into forward heap, adjusted by previous distances. // insert new starting nodes into forward heap, adjusted by previous distances.
if (search_from_1st_node && if ((allow_u_turn || search_from_1st_node) &&
phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID) phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID)
{ {
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.source_phantom.forward_node_id, phantom_node_pair.source_phantom.forward_node_id,
distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id); phantom_node_pair.source_phantom.forward_node_id);
min_edge_offset = std::min(min_edge_offset, distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset()); min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); // SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
forward_heap2.Insert( forward_heap2.Insert(
phantom_node_pair.source_phantom.forward_node_id, phantom_node_pair.source_phantom.forward_node_id,
distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(), (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id); phantom_node_pair.source_phantom.forward_node_id);
min_edge_offset = std::min(min_edge_offset, distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset()); min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << distance1 - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(); // SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
} }
if (search_from_2nd_node && if ((allow_u_turn || search_from_2nd_node) &&
phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID) phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID)
{ {
forward_heap1.Insert( forward_heap1.Insert(
phantom_node_pair.source_phantom.reverse_node_id, phantom_node_pair.source_phantom.reverse_node_id,
distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id); phantom_node_pair.source_phantom.reverse_node_id);
min_edge_offset = std::min(min_edge_offset, distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.reverse_node_id << // SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.reverse_node_id <<
// ", w: " << distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); // ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap2.Insert( forward_heap2.Insert(
phantom_node_pair.source_phantom.reverse_node_id, phantom_node_pair.source_phantom.reverse_node_id,
distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(), (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id); phantom_node_pair.source_phantom.reverse_node_id);
min_edge_offset = std::min(min_edge_offset, distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset()); min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.reverse_node_id << // SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.reverse_node_id <<
// ", w: " << distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(); // ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
} }
// insert new backward nodes into backward heap, unadjusted. // insert new backward nodes into backward heap, unadjusted.
@ -147,12 +149,12 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
// run two-Target Dijkstra routing step. // run two-Target Dijkstra routing step.
while (0 < (forward_heap1.Size() + reverse_heap1.Size())) while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
{ {
if (0 < forward_heap1.Size()) if (!forward_heap1.Empty())
{ {
super::RoutingStep( super::RoutingStep(
forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, min_edge_offset, true); forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, min_edge_offset, true);
} }
if (0 < reverse_heap1.Size()) if (!reverse_heap1.Empty())
{ {
super::RoutingStep( super::RoutingStep(
reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, min_edge_offset, false); reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, min_edge_offset, false);
@ -163,12 +165,12 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
{ {
while (0 < (forward_heap2.Size() + reverse_heap2.Size())) while (0 < (forward_heap2.Size() + reverse_heap2.Size()))
{ {
if (0 < forward_heap2.Size()) if (!forward_heap2.Empty())
{ {
super::RoutingStep( super::RoutingStep(
forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, min_edge_offset, true); forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, min_edge_offset, true);
} }
if (0 < reverse_heap2.Size()) if (!reverse_heap2.Empty())
{ {
super::RoutingStep( super::RoutingStep(
reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, min_edge_offset, false); reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, min_edge_offset, false);
@ -219,15 +221,17 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
} }
// if one of the paths was not found, replace it with the other one. // if one of the paths was not found, replace it with the other one.
if (temporary_packed_leg1.empty()) if ((allow_u_turn && local_upper_bound1 > local_upper_bound2) || temporary_packed_leg1.empty())
{ {
temporary_packed_leg1.clear();
temporary_packed_leg1.insert(temporary_packed_leg1.end(), temporary_packed_leg1.insert(temporary_packed_leg1.end(),
temporary_packed_leg2.begin(), temporary_packed_leg2.begin(),
temporary_packed_leg2.end()); temporary_packed_leg2.end());
local_upper_bound1 = local_upper_bound2; local_upper_bound1 = local_upper_bound2;
} }
if (temporary_packed_leg2.empty()) if ((allow_u_turn && local_upper_bound2 > local_upper_bound1) || temporary_packed_leg2.empty())
{ {
temporary_packed_leg2.clear();
temporary_packed_leg2.insert(temporary_packed_leg2.end(), temporary_packed_leg2.insert(temporary_packed_leg2.end(),
temporary_packed_leg1.begin(), temporary_packed_leg1.begin(),
temporary_packed_leg1.end()); temporary_packed_leg1.end());
@ -240,7 +244,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
BOOST_ASSERT((0 == current_leg) || !packed_legs1[current_leg - 1].empty()); BOOST_ASSERT((0 == current_leg) || !packed_legs1[current_leg - 1].empty());
BOOST_ASSERT((0 == current_leg) || !packed_legs2[current_leg - 1].empty()); BOOST_ASSERT((0 == current_leg) || !packed_legs2[current_leg - 1].empty());
if (0 < current_leg) if (!allow_u_turn && 0 < current_leg)
{ {
const NodeID end_id_of_segment1 = packed_legs1[current_leg - 1].back(); const NodeID end_id_of_segment1 = packed_legs1[current_leg - 1].back();
const NodeID end_id_of_segment2 = packed_legs2[current_leg - 1].back(); const NodeID end_id_of_segment2 = packed_legs2[current_leg - 1].back();
@ -253,13 +257,8 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
std::swap(temporary_packed_leg1, temporary_packed_leg2); std::swap(temporary_packed_leg1, temporary_packed_leg2);
std::swap(local_upper_bound1, local_upper_bound2); std::swap(local_upper_bound1, local_upper_bound2);
} }
}
// remove the shorter path if both legs end at the same segment // remove the shorter path if both legs end at the same segment
if (0 < current_leg)
{
const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
if (start_id_of_leg1 == start_id_of_leg2) if (start_id_of_leg1 == start_id_of_leg2)
{ {
const NodeID last_id_of_packed_legs1 = packed_legs1[current_leg - 1].back(); const NodeID last_id_of_packed_legs1 = packed_legs1[current_leg - 1].back();
@ -287,7 +286,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
temporary_packed_leg2.end()); temporary_packed_leg2.end());
BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size()); BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size());
if ((packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) && if (!allow_u_turn && (packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
phantom_node_pair.target_phantom.isBidirected()) phantom_node_pair.target_phantom.isBidirected())
{ {
const NodeID last_node_id = packed_legs2[current_leg].back(); const NodeID last_node_id = packed_legs2[current_leg].back();