implement MLD shortest path plugin

This commit is contained in:
Michael Krasnyk
2017-04-03 12:50:37 +02:00
parent a1fa1c610c
commit 48a098a9c7
14 changed files with 266 additions and 128 deletions
+3
View File
@@ -96,6 +96,9 @@ template <> struct HasGetTileTurns<corech::Algorithm> final : std::true_type
template <> struct HasDirectShortestPathSearch<mld::Algorithm> final : std::true_type
{
};
template <> struct HasShortestPathSearch<mld::Algorithm> final : std::true_type
{
};
}
}
}
+2 -9
View File
@@ -187,7 +187,8 @@ inline std::vector<routing_algorithms::TurnData> RoutingAlgorithms<Algorithm>::G
// CoreCH overrides
template <>
InternalRouteResult inline RoutingAlgorithms<routing_algorithms::corech::Algorithm>::AlternativePathSearch(const PhantomNodes &) const
InternalRouteResult inline RoutingAlgorithms<
routing_algorithms::corech::Algorithm>::AlternativePathSearch(const PhantomNodes &) const
{
throw util::exception("AlternativePathSearch is disabled due to performance reasons");
}
@@ -210,14 +211,6 @@ InternalRouteResult inline RoutingAlgorithms<
throw util::exception("AlternativePathSearch is not implemented");
}
template <>
inline InternalRouteResult
RoutingAlgorithms<routing_algorithms::mld::Algorithm>::ShortestPathSearch(
const std::vector<PhantomNodes> &, const boost::optional<bool>) const
{
throw util::exception("ShortestPathSearch is not implemented");
}
template <>
inline std::vector<EdgeWeight>
RoutingAlgorithms<routing_algorithms::mld::Algorithm>::ManyToManySearch(
@@ -22,7 +22,7 @@ static const constexpr double DEFAULT_GPS_PRECISION = 5;
//[1] "Hidden Markov Map Matching Through Noise and Sparseness";
// P. Newson and J. Krumm; 2009; ACM GIS
template<typename Algorithm>
template <typename Algorithm>
SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
const CandidateLists &candidates_list,
@@ -30,7 +30,6 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
const std::vector<unsigned> &trace_timestamps,
const std::vector<boost::optional<double>> &trace_gps_precision,
const bool allow_splitting);
}
}
}
@@ -37,6 +37,10 @@ static constexpr bool FORWARD_DIRECTION = true;
static constexpr bool REVERSE_DIRECTION = false;
static constexpr bool DO_NOT_FORCE_LOOPS = false;
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
template <bool DIRECTION, typename Heap>
void insertNodesInHeap(Heap &heap, const PhantomNode &phantom_node)
{
@@ -365,10 +365,11 @@ inline void search(const datafacade::ContiguousInternalMemoryDataFacade<Algorith
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
SearchEngineData<Algorithm>::QueryHeap &,
SearchEngineData<Algorithm>::QueryHeap &,
std::int32_t &weight,
EdgeWeight &weight,
std::vector<NodeID> &packed_leg,
const bool force_loop_forward,
const bool force_loop_reverse,
const PhantomNodes & /*phantom_nodes*/,
const int duration_upper_bound = INVALID_EDGE_WEIGHT)
{
search(facade,
@@ -381,10 +382,6 @@ inline void search(const datafacade::ContiguousInternalMemoryDataFacade<Algorith
duration_upper_bound);
}
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<ch::Algorithm> &facade,
const std::vector<NodeID> &packed_path,
const PhantomNode &source_phantom,
@@ -437,6 +434,7 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<corech::Algorit
std::vector<NodeID> &packed_leg,
const bool force_loop_forward,
const bool force_loop_reverse,
const PhantomNodes &phantom_nodes,
int duration_upper_bound = INVALID_EDGE_WEIGHT);
// Requires the heaps for be empty
@@ -451,6 +449,17 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<corech::
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT);
template <typename RandomIter, typename FacadeT>
void unpackPath(const FacadeT &facade,
RandomIter packed_path_begin,
RandomIter packed_path_end,
const PhantomNodes &phantom_nodes,
std::vector<PathData> &unpacked_path)
{
return ch::unpackPath(facade, packed_path_begin, packed_path_end, phantom_nodes, unpacked_path);
}
} // namespace corech
} // namespace routing_algorithms
@@ -174,6 +174,8 @@ std::tuple<EdgeWeight, NodeID, NodeID, std::vector<EdgeID>>
search(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const bool force_loop_forward,
const bool force_loop_reverse,
Args... args)
{
@@ -268,7 +270,7 @@ search(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
NodeID subpath_source, subpath_target;
std::vector<EdgeID> subpath;
std::tie(subpath_weight, subpath_source, subpath_target, subpath) =
search(facade, forward_heap, reverse_heap, sublevel, parent_cell_id);
search(facade, forward_heap, reverse_heap, force_loop_forward, force_loop_reverse, sublevel, parent_cell_id);
BOOST_ASSERT(!subpath.empty());
BOOST_ASSERT(subpath_source == source);
BOOST_ASSERT(subpath_target == target);
@@ -279,6 +281,63 @@ search(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
return std::make_tuple(weight, source_node, target_node, std::move(unpacked_path));
}
// Alias to be compatible with the overload for CoreCH that needs 4 heaps
inline void search(const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
SearchEngineData<Algorithm>::QueryHeap &forward_heap,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
SearchEngineData<Algorithm>::QueryHeap &,
SearchEngineData<Algorithm>::QueryHeap &,
EdgeWeight &weight,
std::vector<NodeID> &packed_leg,
const bool force_loop_forward,
const bool force_loop_reverse,
const PhantomNodes &phantom_nodes,
const int duration_upper_bound = INVALID_EDGE_WEIGHT)
{
(void)duration_upper_bound;
NodeID source_node, target_node;
std::vector<EdgeID> unpacked_edges;
std::tie(weight, source_node, target_node, unpacked_edges) =
mld::search(facade, forward_heap, reverse_heap, force_loop_forward, force_loop_reverse, phantom_nodes);
if (weight != INVALID_EDGE_WEIGHT)
{
packed_leg.push_back(source_node);
std::transform(unpacked_edges.begin(),
unpacked_edges.end(),
std::back_inserter(packed_leg),
[&facade](const auto edge) { return facade.GetTarget(edge); });
}
}
template <typename RandomIter, typename FacadeT>
void unpackPath(const FacadeT &facade,
RandomIter packed_path_begin,
RandomIter packed_path_end,
const PhantomNodes &phantom_nodes,
std::vector<PathData> &unpacked_path)
{
const auto nodes_number = std::distance(packed_path_begin, packed_path_end);
BOOST_ASSERT(nodes_number > 0);
std::vector<EdgeID> unpacked_edges;
auto source_node = *packed_path_begin, target_node = *packed_path_begin;
if (nodes_number > 1)
{
target_node = *std::prev(packed_path_end);
util::for_each_pair(packed_path_begin,
packed_path_end,
[&facade, &unpacked_edges](const auto from, const auto to) {
unpacked_edges.push_back(facade.FindEdge(from, to));
});
}
annotatePath(facade, source_node, target_node, unpacked_edges, phantom_nodes, unpacked_path);
}
} // namespace mld
} // namespace routing_algorithms
} // namespace engine
@@ -13,7 +13,7 @@ namespace engine
namespace routing_algorithms
{
template<typename Algorithm>
template <typename Algorithm>
InternalRouteResult
shortestPathSearch(SearchEngineData<Algorithm> &engine_working_data,
const datafacade::ContiguousInternalMemoryDataFacade<Algorithm> &facade,
+4
View File
@@ -75,8 +75,12 @@ template <> struct SearchEngineData<routing_algorithms::mld::Algorithm>
static SearchEngineHeapPtr forward_heap_1;
static SearchEngineHeapPtr reverse_heap_1;
static SearchEngineHeapPtr forward_heap_2;
static SearchEngineHeapPtr reverse_heap_2;
void InitializeOrClearFirstThreadLocalStorage(unsigned number_of_nodes);
void InitializeOrClearSecondThreadLocalStorage(unsigned number_of_nodes);
};
}
}