Implement CoreCH algorithm
This commit is contained in:
committed by
Patrick Niklaus
parent
922e155763
commit
7da86b5984
@@ -115,7 +115,9 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
|
||||
{
|
||||
if (!algorithms.HasMapMatching())
|
||||
{
|
||||
return Error("NotImplemented", "Map matching is not implemented for the chosen search algorithm.", json_result);
|
||||
return Error("NotImplemented",
|
||||
"Map matching is not implemented for the chosen search algorithm.",
|
||||
json_result);
|
||||
}
|
||||
|
||||
BOOST_ASSERT(parameters.IsValid());
|
||||
|
||||
@@ -35,7 +35,9 @@ Status TablePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
|
||||
{
|
||||
if (!algorithms.HasManyToManySearch())
|
||||
{
|
||||
return Error("NotImplemented", "Many to many search is not implemented for the chosen search algorithm.", result);
|
||||
return Error("NotImplemented",
|
||||
"Many to many search is not implemented for the chosen search algorithm.",
|
||||
result);
|
||||
}
|
||||
|
||||
BOOST_ASSERT(params.IsValid());
|
||||
|
||||
@@ -149,11 +149,15 @@ Status TripPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataF
|
||||
{
|
||||
if (!algorithms.HasShortestPathSearch())
|
||||
{
|
||||
return Error("NotImplemented", "Shortest path search is not implemented for the chosen search algorithm.", json_result);
|
||||
return Error("NotImplemented",
|
||||
"Shortest path search is not implemented for the chosen search algorithm.",
|
||||
json_result);
|
||||
}
|
||||
if (!algorithms.HasManyToManySearch())
|
||||
{
|
||||
return Error("NotImplemented", "Many to many search is not implemented for the chosen search algorithm.", json_result);
|
||||
return Error("NotImplemented",
|
||||
"Many to many search is not implemented for the chosen search algorithm.",
|
||||
json_result);
|
||||
}
|
||||
|
||||
BOOST_ASSERT(parameters.IsValid());
|
||||
|
||||
@@ -36,12 +36,18 @@ ViaRoutePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFaca
|
||||
|
||||
if (!algorithms.HasShortestPathSearch() && route_parameters.coordinates.size() > 2)
|
||||
{
|
||||
return Error("NotImplemented", "Shortest path search is not implemented for the chosen search algorithm. Only two coordinates supported.", json_result);
|
||||
return Error("NotImplemented",
|
||||
"Shortest path search is not implemented for the chosen search algorithm. "
|
||||
"Only two coordinates supported.",
|
||||
json_result);
|
||||
}
|
||||
|
||||
if (!algorithms.HasDirectShortestPathSearch() && !algorithms.HasShortestPathSearch())
|
||||
{
|
||||
return Error("NotImplemented", "Direct shortest path search is not implemented for the chosen search algorithm.", json_result);
|
||||
return Error(
|
||||
"NotImplemented",
|
||||
"Direct shortest path search is not implemented for the chosen search algorithm.",
|
||||
json_result);
|
||||
}
|
||||
|
||||
if (max_locations_viaroute > 0 &&
|
||||
@@ -95,18 +101,20 @@ ViaRoutePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFaca
|
||||
};
|
||||
util::for_each_pair(snapped_phantoms, build_phantom_pairs);
|
||||
|
||||
if (1 == raw_route.segment_end_coordinates.size() && algorithms.HasAlternativePathSearch() && route_parameters.alternatives)
|
||||
if (1 == raw_route.segment_end_coordinates.size() && algorithms.HasAlternativePathSearch() &&
|
||||
route_parameters.alternatives)
|
||||
{
|
||||
raw_route = algorithms.AlternativePathSearch(raw_route.segment_end_coordinates.front());
|
||||
}
|
||||
else if (1 == raw_route.segment_end_coordinates.size() && algorithms.HasDirectShortestPathSearch())
|
||||
else if (1 == raw_route.segment_end_coordinates.size() &&
|
||||
algorithms.HasDirectShortestPathSearch())
|
||||
{
|
||||
raw_route = algorithms.DirectShortestPathSearch(raw_route.segment_end_coordinates);
|
||||
raw_route = algorithms.DirectShortestPathSearch(raw_route.segment_end_coordinates.front());
|
||||
}
|
||||
else
|
||||
{
|
||||
raw_route = algorithms.ShortestPathSearch(raw_route.segment_end_coordinates,
|
||||
route_parameters.continue_straight);
|
||||
route_parameters.continue_straight);
|
||||
}
|
||||
|
||||
// we can only know this after the fact, different SCC ids still
|
||||
|
||||
@@ -9,32 +9,14 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
/// This is a striped down version of the general shortest path algorithm.
|
||||
/// The general algorithm always computes two queries for each leg. This is only
|
||||
/// necessary in case of vias, where the directions of the start node is constrainted
|
||||
/// by the previous route.
|
||||
/// This variation is only an optimazation for graphs with slow queries, for example
|
||||
/// not fully contracted graphs.
|
||||
InternalRouteResult directShortestPathSearch(
|
||||
SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector)
|
||||
namespace
|
||||
{
|
||||
InternalRouteResult raw_route_data;
|
||||
// Get weight to next pair of target nodes.
|
||||
BOOST_ASSERT_MSG(1 == phantom_nodes_vector.size(),
|
||||
"Direct Shortest Path Query only accepts a single source and target pair. "
|
||||
"Multiple ones have been specified.");
|
||||
const auto &phantom_node_pair = phantom_nodes_vector.front();
|
||||
const auto &source_phantom = phantom_node_pair.source_phantom;
|
||||
const auto &target_phantom = phantom_node_pair.target_phantom;
|
||||
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
auto &forward_heap = *(engine_working_data.forward_heap_1);
|
||||
auto &reverse_heap = *(engine_working_data.reverse_heap_1);
|
||||
forward_heap.Clear();
|
||||
reverse_heap.Clear();
|
||||
|
||||
void insertInHeaps(SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
const PhantomNodes &nodes)
|
||||
{
|
||||
const auto &source_phantom = nodes.source_phantom;
|
||||
const auto &target_phantom = nodes.target_phantom;
|
||||
BOOST_ASSERT(source_phantom.IsValid());
|
||||
BOOST_ASSERT(target_phantom.IsValid());
|
||||
|
||||
@@ -64,42 +46,16 @@ InternalRouteResult directShortestPathSearch(
|
||||
target_phantom.GetReverseWeightPlusOffset(),
|
||||
target_phantom.reverse_segment_id.id);
|
||||
}
|
||||
}
|
||||
|
||||
int weight = INVALID_EDGE_WEIGHT;
|
||||
std::vector<NodeID> packed_leg;
|
||||
|
||||
const bool constexpr DO_NOT_FORCE_LOOPS =
|
||||
false; // prevents forcing of loops, since offsets are set correctly
|
||||
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
auto &forward_core_heap = *(engine_working_data.forward_heap_2);
|
||||
auto &reverse_core_heap = *(engine_working_data.reverse_heap_2);
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
|
||||
searchWithCore(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
weight,
|
||||
packed_leg,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
weight,
|
||||
packed_leg,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
}
|
||||
|
||||
template <typename AlgorithmT>
|
||||
InternalRouteResult
|
||||
extractRoute(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||
const EdgeWeight weight,
|
||||
const std::vector<NodeID> &packed_leg,
|
||||
const PhantomNodes &nodes)
|
||||
{
|
||||
InternalRouteResult raw_route_data;
|
||||
// No path found for both target nodes?
|
||||
if (INVALID_EDGE_WEIGHT == weight)
|
||||
{
|
||||
@@ -113,18 +69,79 @@ InternalRouteResult directShortestPathSearch(
|
||||
raw_route_data.shortest_path_length = weight;
|
||||
raw_route_data.unpacked_path_segments.resize(1);
|
||||
raw_route_data.source_traversed_in_reverse.push_back(
|
||||
(packed_leg.front() != phantom_node_pair.source_phantom.forward_segment_id.id));
|
||||
(packed_leg.front() != nodes.source_phantom.forward_segment_id.id));
|
||||
raw_route_data.target_traversed_in_reverse.push_back(
|
||||
(packed_leg.back() != phantom_node_pair.target_phantom.forward_segment_id.id));
|
||||
(packed_leg.back() != nodes.target_phantom.forward_segment_id.id));
|
||||
|
||||
unpackPath(facade,
|
||||
packed_leg.begin(),
|
||||
packed_leg.end(),
|
||||
phantom_node_pair,
|
||||
nodes,
|
||||
raw_route_data.unpacked_path_segments.front());
|
||||
|
||||
return raw_route_data;
|
||||
}
|
||||
|
||||
// prevents forcing of loops, since offsets are set correctly
|
||||
static const bool constexpr DO_NOT_FORCE_LOOPS = false;
|
||||
}
|
||||
|
||||
/// This is a striped down version of the general shortest path algorithm.
|
||||
/// The general algorithm always computes two queries for each leg. This is only
|
||||
/// necessary in case of vias, where the directions of the start node is constrainted
|
||||
/// by the previous route.
|
||||
/// This variation is only an optimazation for graphs with slow queries, for example
|
||||
/// not fully contracted graphs.
|
||||
template <typename AlgorithmT>
|
||||
InternalRouteResult directShortestPathSearchImpl(
|
||||
SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||
const PhantomNodes &phantom_nodes)
|
||||
{
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
auto &forward_heap = *(engine_working_data.forward_heap_1);
|
||||
auto &reverse_heap = *(engine_working_data.reverse_heap_1);
|
||||
auto &forward_core_heap = *(engine_working_data.forward_heap_2);
|
||||
auto &reverse_core_heap = *(engine_working_data.reverse_heap_2);
|
||||
forward_heap.Clear();
|
||||
reverse_heap.Clear();
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
|
||||
int weight = INVALID_EDGE_WEIGHT;
|
||||
std::vector<NodeID> packed_leg;
|
||||
insertInHeaps(forward_heap, reverse_heap, phantom_nodes);
|
||||
|
||||
search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
weight,
|
||||
packed_leg,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS);
|
||||
|
||||
return extractRoute(facade, weight, packed_leg, phantom_nodes);
|
||||
}
|
||||
|
||||
InternalRouteResult directShortestPathSearch(
|
||||
SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||
const PhantomNodes &phantom_nodes)
|
||||
{
|
||||
return directShortestPathSearchImpl(engine_working_data, facade, phantom_nodes);
|
||||
}
|
||||
|
||||
InternalRouteResult directShortestPathSearch(
|
||||
SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
const PhantomNodes &phantom_nodes)
|
||||
{
|
||||
return directShortestPathSearchImpl(engine_working_data, facade, phantom_nodes);
|
||||
}
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -47,13 +47,14 @@ unsigned getMedianSampleTime(const std::vector<unsigned> ×tamps)
|
||||
}
|
||||
}
|
||||
|
||||
template <typename AlgorithmT>
|
||||
SubMatchingList
|
||||
mapMatching(SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
const CandidateLists &candidates_list,
|
||||
const std::vector<util::Coordinate> &trace_coordinates,
|
||||
const std::vector<unsigned> &trace_timestamps,
|
||||
const std::vector<boost::optional<double>> &trace_gps_precision)
|
||||
mapMatchingImpl(SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||
const CandidateLists &candidates_list,
|
||||
const std::vector<util::Coordinate> &trace_coordinates,
|
||||
const std::vector<unsigned> &trace_timestamps,
|
||||
const std::vector<boost::optional<double>> &trace_gps_precision)
|
||||
{
|
||||
map_matching::MatchingConfidence confidence;
|
||||
map_matching::EmissionLogProbability default_emission_log_probability(DEFAULT_GPS_PRECISION);
|
||||
@@ -208,33 +209,15 @@ mapMatching(SearchEngineData &engine_working_data,
|
||||
continue;
|
||||
}
|
||||
|
||||
forward_heap.Clear();
|
||||
reverse_heap.Clear();
|
||||
|
||||
double network_distance;
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
network_distance = getNetworkDistanceWithCore(
|
||||
facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
prev_unbroken_timestamps_list[s].phantom_node,
|
||||
current_timestamps_list[s_prime].phantom_node,
|
||||
duration_upper_bound);
|
||||
}
|
||||
else
|
||||
{
|
||||
network_distance =
|
||||
getNetworkDistance(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
prev_unbroken_timestamps_list[s].phantom_node,
|
||||
current_timestamps_list[s_prime].phantom_node);
|
||||
}
|
||||
double network_distance =
|
||||
getNetworkDistance(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
prev_unbroken_timestamps_list[s].phantom_node,
|
||||
current_timestamps_list[s_prime].phantom_node,
|
||||
duration_upper_bound);
|
||||
|
||||
// get distance diff between loc1/2 and locs/s_prime
|
||||
const auto d_t = std::abs(network_distance - haversine_distance);
|
||||
@@ -427,6 +410,39 @@ mapMatching(SearchEngineData &engine_working_data,
|
||||
return sub_matchings;
|
||||
}
|
||||
|
||||
SubMatchingList
|
||||
mapMatching(SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
const CandidateLists &candidates_list,
|
||||
const std::vector<util::Coordinate> &trace_coordinates,
|
||||
const std::vector<unsigned> &trace_timestamps,
|
||||
const std::vector<boost::optional<double>> &trace_gps_precision)
|
||||
{
|
||||
return mapMatchingImpl(engine_working_data,
|
||||
facade,
|
||||
candidates_list,
|
||||
trace_coordinates,
|
||||
trace_timestamps,
|
||||
trace_gps_precision);
|
||||
}
|
||||
|
||||
SubMatchingList
|
||||
mapMatching(SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||
const CandidateLists &candidates_list,
|
||||
const std::vector<util::Coordinate> &trace_coordinates,
|
||||
const std::vector<unsigned> &trace_timestamps,
|
||||
const std::vector<boost::optional<double>> &trace_gps_precision)
|
||||
{
|
||||
|
||||
return mapMatchingImpl(engine_working_data,
|
||||
facade,
|
||||
candidates_list,
|
||||
trace_coordinates,
|
||||
trace_timestamps,
|
||||
trace_gps_precision);
|
||||
}
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
@@ -270,16 +270,16 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
|
||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||
// requires
|
||||
// a force loop, if the heaps have been initialized with positive offsets.
|
||||
void searchWithCore(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &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)
|
||||
void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &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)
|
||||
{
|
||||
NodeID middle = SPECIAL_NODEID;
|
||||
weight = weight_upper_bound;
|
||||
@@ -530,18 +530,20 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<algo
|
||||
// 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 getNetworkDistanceWithCore(
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
SearchEngineData::QueryHeap &reverse_core_heap,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
EdgeWeight weight_upper_bound)
|
||||
double
|
||||
getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
SearchEngineData::QueryHeap &reverse_core_heap,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom,
|
||||
EdgeWeight weight_upper_bound)
|
||||
{
|
||||
BOOST_ASSERT(forward_heap.Empty());
|
||||
BOOST_ASSERT(reverse_heap.Empty());
|
||||
forward_heap.Clear();
|
||||
reverse_heap.Clear();
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
|
||||
if (source_phantom.forward_segment_id.enabled)
|
||||
{
|
||||
@@ -574,16 +576,16 @@ double getNetworkDistanceWithCore(
|
||||
|
||||
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
||||
std::vector<NodeID> packed_path;
|
||||
searchWithCore(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
weight,
|
||||
packed_path,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
weight_upper_bound);
|
||||
search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
weight,
|
||||
packed_path,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
DO_NOT_FORCE_LOOPS,
|
||||
weight_upper_bound);
|
||||
|
||||
double distance = std::numeric_limits<double>::max();
|
||||
if (weight != INVALID_EDGE_WEIGHT)
|
||||
@@ -604,8 +606,8 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
|
||||
const PhantomNode &target_phantom,
|
||||
EdgeWeight weight_upper_bound)
|
||||
{
|
||||
BOOST_ASSERT(forward_heap.Empty());
|
||||
BOOST_ASSERT(reverse_heap.Empty());
|
||||
forward_heap.Clear();
|
||||
reverse_heap.Clear();
|
||||
|
||||
if (source_phantom.forward_segment_id.enabled)
|
||||
{
|
||||
|
||||
@@ -12,12 +12,16 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const static constexpr bool DO_NOT_FORCE_LOOP = false;
|
||||
using QueryHeap = SearchEngineData::QueryHeap;
|
||||
|
||||
// allows a uturn at the target_phantom
|
||||
// searches source forward/reverse -> target forward/reverse
|
||||
void searchWithUTurn(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
template <typename AlgorithmT>
|
||||
void searchWithUTurn(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
@@ -70,32 +74,21 @@ void searchWithUTurn(const datafacade::ContiguousInternalMemoryDataFacade<algori
|
||||
auto needs_loop_forwad = is_oneway_source && needsLoopForward(source_phantom, target_phantom);
|
||||
auto needs_loop_backwards =
|
||||
is_oneway_target && needsLoopBackwards(source_phantom, target_phantom);
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||
searchWithCore(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
new_total_weight,
|
||||
leg_packed_path,
|
||||
needs_loop_forwad,
|
||||
needs_loop_backwards);
|
||||
}
|
||||
else
|
||||
{
|
||||
search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
new_total_weight,
|
||||
leg_packed_path,
|
||||
needs_loop_forwad,
|
||||
needs_loop_backwards);
|
||||
}
|
||||
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||
routing_algorithms::search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
new_total_weight,
|
||||
leg_packed_path,
|
||||
needs_loop_forwad,
|
||||
needs_loop_backwards);
|
||||
|
||||
// if no route is found between two parts of the via-route, the entire route becomes
|
||||
// invalid. Adding to invalid edge weight sadly doesn't return an invalid edge weight. Here
|
||||
// we prevent the possible overflow, faking the addition of infinity + x == infinity
|
||||
@@ -106,7 +99,8 @@ void searchWithUTurn(const datafacade::ContiguousInternalMemoryDataFacade<algori
|
||||
// searches shortest path between:
|
||||
// source forward/reverse -> target forward
|
||||
// source forward/reverse -> target reverse
|
||||
void Search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
template <typename AlgorithmT>
|
||||
void search(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
@@ -149,32 +143,19 @@ void Search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
|
||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||
searchWithCore(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
new_total_weight_to_forward,
|
||||
leg_packed_path_forward,
|
||||
needsLoopForward(source_phantom, target_phantom),
|
||||
DO_NOT_FORCE_LOOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
new_total_weight_to_forward,
|
||||
leg_packed_path_forward,
|
||||
needsLoopForward(source_phantom, target_phantom),
|
||||
DO_NOT_FORCE_LOOP);
|
||||
}
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||
routing_algorithms::search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
new_total_weight_to_forward,
|
||||
leg_packed_path_forward,
|
||||
needsLoopForward(source_phantom, target_phantom),
|
||||
DO_NOT_FORCE_LOOP);
|
||||
}
|
||||
|
||||
if (search_to_reverse_node)
|
||||
@@ -200,32 +181,19 @@ void Search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
|
||||
}
|
||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||
searchWithCore(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
new_total_weight_to_reverse,
|
||||
leg_packed_path_reverse,
|
||||
DO_NOT_FORCE_LOOP,
|
||||
needsLoopBackwards(source_phantom, target_phantom));
|
||||
}
|
||||
else
|
||||
{
|
||||
search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
new_total_weight_to_reverse,
|
||||
leg_packed_path_reverse,
|
||||
DO_NOT_FORCE_LOOP,
|
||||
needsLoopBackwards(source_phantom, target_phantom));
|
||||
}
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||
routing_algorithms::search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
reverse_core_heap,
|
||||
new_total_weight_to_reverse,
|
||||
leg_packed_path_reverse,
|
||||
DO_NOT_FORCE_LOOP,
|
||||
needsLoopBackwards(source_phantom, target_phantom));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,11 +227,12 @@ void unpackLegs(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::
|
||||
}
|
||||
}
|
||||
|
||||
template <typename AlgorithmT>
|
||||
InternalRouteResult
|
||||
shortestPathSearch(SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const boost::optional<bool> continue_straight_at_waypoint)
|
||||
shortestPathSearchImpl(SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const boost::optional<bool> continue_straight_at_waypoint)
|
||||
{
|
||||
InternalRouteResult raw_route_data;
|
||||
const bool allow_uturn_at_waypoint =
|
||||
@@ -351,7 +320,7 @@ shortestPathSearch(SearchEngineData &engine_working_data,
|
||||
}
|
||||
else
|
||||
{
|
||||
Search(facade,
|
||||
search(facade,
|
||||
forward_heap,
|
||||
reverse_heap,
|
||||
forward_core_heap,
|
||||
@@ -503,6 +472,27 @@ shortestPathSearch(SearchEngineData &engine_working_data,
|
||||
|
||||
return raw_route_data;
|
||||
}
|
||||
}
|
||||
|
||||
InternalRouteResult
|
||||
shortestPathSearch(SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const boost::optional<bool> continue_straight_at_waypoint)
|
||||
{
|
||||
return shortestPathSearchImpl(
|
||||
engine_working_data, facade, phantom_nodes_vector, continue_straight_at_waypoint);
|
||||
}
|
||||
|
||||
InternalRouteResult
|
||||
shortestPathSearch(SearchEngineData &engine_working_data,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const boost::optional<bool> continue_straight_at_waypoint)
|
||||
{
|
||||
return shortestPathSearchImpl(
|
||||
engine_working_data, facade, phantom_nodes_vector, continue_straight_at_waypoint);
|
||||
}
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
|
||||
+8
-1
@@ -17,8 +17,15 @@ namespace osrm
|
||||
// Pimpl idiom
|
||||
|
||||
OSRM::OSRM(engine::EngineConfig &config)
|
||||
: engine_(std::make_unique<engine::Engine<engine::algorithm::CH>>(config))
|
||||
{
|
||||
if (engine::Engine<engine::algorithm::CoreCH>::CheckCompability(config))
|
||||
{
|
||||
engine_ = std::make_unique<engine::Engine<engine::algorithm::CoreCH>>(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
engine_ = std::make_unique<engine::Engine<engine::algorithm::CH>>(config);
|
||||
}
|
||||
}
|
||||
OSRM::~OSRM() = default;
|
||||
OSRM::OSRM(OSRM &&) noexcept = default;
|
||||
|
||||
Reference in New Issue
Block a user