osrm-backend/include/engine/routing_algorithms.hpp
Michael Bell d96960f9cc Support snapping to multiple ways at an input location
This PR improves routing results by adding support for snapping to
multiple ways at input locations.

This means all edges at the snapped location can act as source/target
candidates for routing search, ensuring we always find the best route,
and not the one dependent on the edge selected.
2022-08-27 11:28:25 +01:00

237 lines
9.1 KiB
C++

#ifndef OSRM_ENGINE_ROUTING_ALGORITHM_HPP
#define OSRM_ENGINE_ROUTING_ALGORITHM_HPP
#include "engine/algorithm.hpp"
#include "engine/internal_route_result.hpp"
#include "engine/phantom_node.hpp"
#include "engine/routing_algorithms/alternative_path.hpp"
#include "engine/routing_algorithms/direct_shortest_path.hpp"
#include "engine/routing_algorithms/many_to_many.hpp"
#include "engine/routing_algorithms/map_matching.hpp"
#include "engine/routing_algorithms/shortest_path.hpp"
#include "engine/routing_algorithms/tile_turns.hpp"
namespace osrm
{
namespace engine
{
class RoutingAlgorithmsInterface
{
public:
virtual InternalManyRoutesResult
AlternativePathSearch(const PhantomEndpointCandidates &endpoint_candidates,
unsigned number_of_alternatives) const = 0;
virtual InternalRouteResult
ShortestPathSearch(const std::vector<PhantomNodeCandidates> &waypoint_candidates,
const boost::optional<bool> continue_straight_at_waypoint) const = 0;
virtual InternalRouteResult
DirectShortestPathSearch(const PhantomEndpointCandidates &endpoint_candidates) const = 0;
virtual std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>>
ManyToManySearch(const std::vector<PhantomNodeCandidates> &candidates_list,
const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices,
const bool calculate_distance) const = 0;
virtual routing_algorithms::SubMatchingList
MapMatching(const routing_algorithms::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,
const bool allow_splitting) const = 0;
virtual std::vector<routing_algorithms::TurnData>
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes) const = 0;
virtual const DataFacadeBase &GetFacade() const = 0;
virtual bool HasAlternativePathSearch() const = 0;
virtual bool HasShortestPathSearch() const = 0;
virtual bool HasDirectShortestPathSearch() const = 0;
virtual bool HasMapMatching() const = 0;
virtual bool HasManyToManySearch() const = 0;
virtual bool SupportsDistanceAnnotationType() const = 0;
virtual bool HasGetTileTurns() const = 0;
virtual bool HasExcludeFlags() const = 0;
virtual bool IsValid() const = 0;
};
// Short-lived object passed to each plugin in request to wrap routing algorithms
template <typename Algorithm> class RoutingAlgorithms final : public RoutingAlgorithmsInterface
{
public:
RoutingAlgorithms(SearchEngineData<Algorithm> &heaps,
std::shared_ptr<const DataFacade<Algorithm>> facade)
: heaps(heaps), facade(facade)
{
}
virtual ~RoutingAlgorithms() = default;
InternalManyRoutesResult
AlternativePathSearch(const PhantomEndpointCandidates &endpoint_candidates,
unsigned number_of_alternatives) const final override;
InternalRouteResult ShortestPathSearch(
const std::vector<PhantomNodeCandidates> &waypoint_candidates,
const boost::optional<bool> continue_straight_at_waypoint) const final override;
InternalRouteResult DirectShortestPathSearch(
const PhantomEndpointCandidates &endpoint_candidates) const final override;
std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>>
ManyToManySearch(const std::vector<PhantomNodeCandidates> &candidates_list,
const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices,
const bool calculate_distance) const final override;
routing_algorithms::SubMatchingList
MapMatching(const routing_algorithms::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,
const bool allow_splitting) const final override;
std::vector<routing_algorithms::TurnData>
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes) const final override;
const DataFacadeBase &GetFacade() const final override { return *facade; }
bool HasAlternativePathSearch() const final override
{
return routing_algorithms::HasAlternativePathSearch<Algorithm>::value;
}
bool HasShortestPathSearch() const final override
{
return routing_algorithms::HasShortestPathSearch<Algorithm>::value;
}
bool HasDirectShortestPathSearch() const final override
{
return routing_algorithms::HasDirectShortestPathSearch<Algorithm>::value;
}
bool HasMapMatching() const final override
{
return routing_algorithms::HasMapMatching<Algorithm>::value;
}
bool HasManyToManySearch() const final override
{
return routing_algorithms::HasManyToManySearch<Algorithm>::value;
}
bool SupportsDistanceAnnotationType() const final override
{
return routing_algorithms::SupportsDistanceAnnotationType<Algorithm>::value;
}
bool HasGetTileTurns() const final override
{
return routing_algorithms::HasGetTileTurns<Algorithm>::value;
}
bool HasExcludeFlags() const final override
{
return routing_algorithms::HasExcludeFlags<Algorithm>::value;
}
bool IsValid() const final override { return static_cast<bool>(facade); }
private:
SearchEngineData<Algorithm> &heaps;
std::shared_ptr<const DataFacade<Algorithm>> facade;
};
template <typename Algorithm>
InternalManyRoutesResult RoutingAlgorithms<Algorithm>::AlternativePathSearch(
const PhantomEndpointCandidates &endpoint_candidates, unsigned number_of_alternatives) const
{
return routing_algorithms::alternativePathSearch(
heaps, *facade, endpoint_candidates, number_of_alternatives);
}
template <typename Algorithm>
InternalRouteResult RoutingAlgorithms<Algorithm>::ShortestPathSearch(
const std::vector<PhantomNodeCandidates> &waypoint_candidates,
const boost::optional<bool> continue_straight_at_waypoint) const
{
return routing_algorithms::shortestPathSearch(
heaps, *facade, waypoint_candidates, continue_straight_at_waypoint);
}
template <typename Algorithm>
InternalRouteResult RoutingAlgorithms<Algorithm>::DirectShortestPathSearch(
const PhantomEndpointCandidates &endpoint_candidates) const
{
return routing_algorithms::directShortestPathSearch(heaps, *facade, endpoint_candidates);
}
template <typename Algorithm>
inline routing_algorithms::SubMatchingList RoutingAlgorithms<Algorithm>::MapMatching(
const routing_algorithms::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,
const bool allow_splitting) const
{
return routing_algorithms::mapMatching(heaps,
*facade,
candidates_list,
trace_coordinates,
trace_timestamps,
trace_gps_precision,
allow_splitting);
}
template <typename Algorithm>
std::pair<std::vector<EdgeDuration>, std::vector<EdgeDistance>>
RoutingAlgorithms<Algorithm>::ManyToManySearch(
const std::vector<PhantomNodeCandidates> &candidates_list,
const std::vector<std::size_t> &_source_indices,
const std::vector<std::size_t> &_target_indices,
const bool calculate_distance) const
{
BOOST_ASSERT(!candidates_list.empty());
auto source_indices = _source_indices;
auto target_indices = _target_indices;
if (source_indices.empty())
{
source_indices.resize(candidates_list.size());
std::iota(source_indices.begin(), source_indices.end(), 0);
}
if (target_indices.empty())
{
target_indices.resize(candidates_list.size());
std::iota(target_indices.begin(), target_indices.end(), 0);
}
return routing_algorithms::manyToManySearch(heaps,
*facade,
candidates_list,
std::move(source_indices),
std::move(target_indices),
calculate_distance);
}
template <typename Algorithm>
inline std::vector<routing_algorithms::TurnData> RoutingAlgorithms<Algorithm>::GetTileTurns(
const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
const std::vector<std::size_t> &sorted_edge_indexes) const
{
return routing_algorithms::getTileTurns(*facade, edges, sorted_edge_indexes);
}
} // namespace engine
} // namespace osrm
#endif