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
{
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)

View File

@ -49,6 +49,7 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
~ShortestPathRouting() {}
void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
const std::vector<bool> &uturn_indicators,
RawRouteData &raw_route_data) const
{
int distance1 = 0;
@ -86,43 +87,44 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
middle1 = 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;
// 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)
{
forward_heap1.Insert(
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);
min_edge_offset = std::min(min_edge_offset, 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();
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: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
forward_heap2.Insert(
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);
min_edge_offset = std::min(min_edge_offset, 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();
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: " << (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)
{
forward_heap1.Insert(
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);
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 <<
// ", w: " << distance2 - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
// ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap2.Insert(
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);
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 <<
// ", 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.
@ -147,12 +149,12 @@ template <class DataFacadeT> class ShortestPathRouting : public BasicRoutingInte
// run two-Target Dijkstra routing step.
while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
{
if (0 < forward_heap1.Size())
if (!forward_heap1.Empty())
{
super::RoutingStep(
forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, min_edge_offset, true);
}
if (0 < reverse_heap1.Size())
if (!reverse_heap1.Empty())
{
super::RoutingStep(
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()))
{
if (0 < forward_heap2.Size())
if (!forward_heap2.Empty())
{
super::RoutingStep(
forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, min_edge_offset, true);
}
if (0 < reverse_heap2.Size())
if (!reverse_heap2.Empty())
{
super::RoutingStep(
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 (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_leg2.begin(),
temporary_packed_leg2.end());
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_leg1.begin(),
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_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_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(local_upper_bound1, local_upper_bound2);
}
}
// 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();
// remove the shorter path if both legs end at the same segment
if (start_id_of_leg1 == start_id_of_leg2)
{
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());
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())
{
const NodeID last_node_id = packed_legs2[current_leg].back();