From ee1fdca52eba219773e2ec94ea7c6b0ae0a9c3df Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Wed, 16 Jul 2014 12:53:33 +0200 Subject: [PATCH] implement path query with uturns at via nodes --- Plugins/ViaRoutePlugin.h | 2 +- RoutingAlgorithms/ShortestPathRouting.h | 55 ++++++++++++------------- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/Plugins/ViaRoutePlugin.h b/Plugins/ViaRoutePlugin.h index b82d514a9..6547bbb73 100644 --- a/Plugins/ViaRoutePlugin.h +++ b/Plugins/ViaRoutePlugin.h @@ -125,7 +125,7 @@ template 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) diff --git a/RoutingAlgorithms/ShortestPathRouting.h b/RoutingAlgorithms/ShortestPathRouting.h index 3c3d6ef7c..62ca13b21 100644 --- a/RoutingAlgorithms/ShortestPathRouting.h +++ b/RoutingAlgorithms/ShortestPathRouting.h @@ -49,6 +49,7 @@ template class ShortestPathRouting : public BasicRoutingInte ~ShortestPathRouting() {} void operator()(const std::vector &phantom_nodes_vector, + const std::vector &uturn_indicators, RawRouteData &raw_route_data) const { int distance1 = 0; @@ -86,43 +87,44 @@ template 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 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 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 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 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 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 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();