implement path query with uturns at via nodes
This commit is contained in:
parent
95b5bcbd49
commit
ee1fdca52e
@ -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)
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user