Implement CoreCH algorithm
This commit is contained in:
parent
922e155763
commit
7da86b5984
@ -11,29 +11,75 @@ namespace algorithm
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Contraction Hiearchy
|
// Contraction Hiearchy
|
||||||
struct CH final {};
|
struct CH final
|
||||||
|
{
|
||||||
|
};
|
||||||
// Contraction Hiearchy with core
|
// Contraction Hiearchy with core
|
||||||
struct CoreCH final {};
|
struct CoreCH final
|
||||||
|
{
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace algorithm_trais
|
namespace algorithm_trais
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename AlgorithmT> struct HasAlternativePathSearch final : std::false_type {};
|
template <typename AlgorithmT> struct HasAlternativePathSearch final : std::false_type
|
||||||
template <typename AlgorithmT> struct HasShortestPathSearch final : std::false_type {};
|
{
|
||||||
template <typename AlgorithmT> struct HasDirectShortestPathSearch final : std::false_type {};
|
};
|
||||||
template <typename AlgorithmT> struct HasMapMatching final : std::false_type {};
|
template <typename AlgorithmT> struct HasShortestPathSearch final : std::false_type
|
||||||
template <typename AlgorithmT> struct HasManyToManySearch final : std::false_type {};
|
{
|
||||||
template <typename AlgorithmT> struct HasGetTileTurns final : std::false_type {};
|
};
|
||||||
|
template <typename AlgorithmT> struct HasDirectShortestPathSearch final : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <typename AlgorithmT> struct HasMapMatching final : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <typename AlgorithmT> struct HasManyToManySearch final : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <typename AlgorithmT> struct HasGetTileTurns final : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template <> struct HasAlternativePathSearch<algorithm::CH> final : std::true_type {};
|
template <> struct HasAlternativePathSearch<algorithm::CH> final : std::true_type
|
||||||
template <> struct HasShortestPathSearch<algorithm::CH> final : std::true_type {};
|
{
|
||||||
template <> struct HasDirectShortestPathSearch<algorithm::CH> final : std::true_type {};
|
};
|
||||||
template <> struct HasMapMatching<algorithm::CH> final : std::true_type {};
|
template <> struct HasShortestPathSearch<algorithm::CH> final : std::true_type
|
||||||
template <> struct HasManyToManySearch<algorithm::CH> final : std::true_type {};
|
{
|
||||||
template <> struct HasGetTileTurns<algorithm::CH> final : std::true_type {};
|
};
|
||||||
|
template <> struct HasDirectShortestPathSearch<algorithm::CH> final : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <> struct HasMapMatching<algorithm::CH> final : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <> struct HasManyToManySearch<algorithm::CH> final : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <> struct HasGetTileTurns<algorithm::CH> final : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
// disbaled because of perfomance reasons
|
||||||
|
template <> struct HasAlternativePathSearch<algorithm::CoreCH> final : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <> struct HasManyToManySearch<algorithm::CoreCH> final : std::false_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <> struct HasShortestPathSearch<algorithm::CoreCH> final : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <> struct HasDirectShortestPathSearch<algorithm::CoreCH> final : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <> struct HasMapMatching<algorithm::CoreCH> final : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
template <> struct HasGetTileTurns<algorithm::CoreCH> final : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,12 @@ template <> class AlgorithmDataFacade<algorithm::CH>
|
|||||||
virtual EdgeID FindSmallestEdge(const NodeID from,
|
virtual EdgeID FindSmallestEdge(const NodeID from,
|
||||||
const NodeID to,
|
const NodeID to,
|
||||||
const std::function<bool(EdgeData)> filter) const = 0;
|
const std::function<bool(EdgeData)> filter) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> class AlgorithmDataFacade<algorithm::CoreCH>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using EdgeData = contractor::QueryEdge::EdgeData;
|
||||||
|
|
||||||
virtual bool IsCoreNode(const NodeID id) const = 0;
|
virtual bool IsCoreNode(const NodeID id) const = 0;
|
||||||
|
|
||||||
|
@ -58,7 +58,6 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
|
|||||||
using GraphEdge = QueryGraph::EdgeArrayEntry;
|
using GraphEdge = QueryGraph::EdgeArrayEntry;
|
||||||
|
|
||||||
std::unique_ptr<QueryGraph> m_query_graph;
|
std::unique_ptr<QueryGraph> m_query_graph;
|
||||||
util::ShM<bool, true>::vector m_is_core_node;
|
|
||||||
|
|
||||||
// allocator that keeps the allocation data
|
// allocator that keeps the allocation data
|
||||||
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
||||||
@ -78,15 +77,6 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
|
|||||||
m_query_graph.reset(new QueryGraph(node_list, edge_list));
|
m_query_graph.reset(new QueryGraph(node_list, edge_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeCoreInformationPointer(storage::DataLayout &data_layout, char *memory_block)
|
|
||||||
{
|
|
||||||
auto core_marker_ptr =
|
|
||||||
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::CH_CORE_MARKER);
|
|
||||||
util::ShM<bool, true>::vector is_core_node(
|
|
||||||
core_marker_ptr, data_layout.num_entries[storage::DataLayout::CH_CORE_MARKER]);
|
|
||||||
m_is_core_node = std::move(is_core_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ContiguousInternalMemoryAlgorithmDataFacade(
|
ContiguousInternalMemoryAlgorithmDataFacade(
|
||||||
std::shared_ptr<ContiguousBlockAllocator> allocator_)
|
std::shared_ptr<ContiguousBlockAllocator> allocator_)
|
||||||
@ -98,21 +88,8 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
|
|||||||
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
|
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
|
||||||
{
|
{
|
||||||
InitializeGraphPointer(data_layout, memory_block);
|
InitializeGraphPointer(data_layout, memory_block);
|
||||||
InitializeCoreInformationPointer(data_layout, memory_block);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCoreNode(const NodeID id) const override final
|
|
||||||
{
|
|
||||||
if (m_is_core_node.size() > 0)
|
|
||||||
{
|
|
||||||
return m_is_core_node.at(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t GetCoreSize() const override final { return m_is_core_node.size(); }
|
|
||||||
|
|
||||||
// search graph access
|
// search graph access
|
||||||
unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); }
|
unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); }
|
||||||
|
|
||||||
@ -164,6 +141,51 @@ class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CoreCH>
|
||||||
|
: public datafacade::AlgorithmDataFacade<algorithm::CoreCH>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
util::ShM<bool, true>::vector m_is_core_node;
|
||||||
|
|
||||||
|
// allocator that keeps the allocation data
|
||||||
|
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
||||||
|
|
||||||
|
void InitializeCoreInformationPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||||
|
{
|
||||||
|
auto core_marker_ptr =
|
||||||
|
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::CH_CORE_MARKER);
|
||||||
|
util::ShM<bool, true>::vector is_core_node(
|
||||||
|
core_marker_ptr, data_layout.num_entries[storage::DataLayout::CH_CORE_MARKER]);
|
||||||
|
m_is_core_node = std::move(is_core_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ContiguousInternalMemoryAlgorithmDataFacade(
|
||||||
|
std::shared_ptr<ContiguousBlockAllocator> allocator_)
|
||||||
|
: allocator(std::move(allocator_))
|
||||||
|
{
|
||||||
|
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
|
||||||
|
{
|
||||||
|
InitializeCoreInformationPointer(data_layout, memory_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCoreNode(const NodeID id) const override final
|
||||||
|
{
|
||||||
|
if (m_is_core_node.size() > 0)
|
||||||
|
{
|
||||||
|
return m_is_core_node.at(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t GetCoreSize() const override final { return m_is_core_node.size(); }
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This base class implements the Datafacade interface for accessing
|
* This base class implements the Datafacade interface for accessing
|
||||||
* data that's stored in a single large block of memory (RAM).
|
* data that's stored in a single large block of memory (RAM).
|
||||||
@ -1050,6 +1072,20 @@ class ContiguousInternalMemoryDataFacade<algorithm::CH>
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class ContiguousInternalMemoryDataFacade<algorithm::CoreCH> final
|
||||||
|
: public ContiguousInternalMemoryDataFacade<algorithm::CH>,
|
||||||
|
public ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CoreCH>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
|
||||||
|
: ContiguousInternalMemoryDataFacade<algorithm::CH>(allocator),
|
||||||
|
ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CoreCH>(allocator)
|
||||||
|
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,8 @@ template <typename AlgorithmT> class Engine final : public EngineInterface
|
|||||||
return tile_plugin.HandleRequest(*facade, algorithms, params, result);
|
return tile_plugin.HandleRequest(*facade, algorithms, params, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool CheckCompability(const EngineConfig &config);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<DataFacadeProvider<AlgorithmT>> facade_provider;
|
std::unique_ptr<DataFacadeProvider<AlgorithmT>> facade_provider;
|
||||||
mutable SearchEngineData heaps;
|
mutable SearchEngineData heaps;
|
||||||
@ -136,6 +138,54 @@ template <typename AlgorithmT> class Engine final : public EngineInterface
|
|||||||
const plugins::MatchPlugin match_plugin;
|
const plugins::MatchPlugin match_plugin;
|
||||||
const plugins::TilePlugin tile_plugin;
|
const plugins::TilePlugin tile_plugin;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> bool Engine<algorithm::CH>::CheckCompability(const EngineConfig &config)
|
||||||
|
{
|
||||||
|
if (config.use_shared_memory)
|
||||||
|
{
|
||||||
|
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
|
||||||
|
using mutex_type = typename decltype(barrier)::mutex_type;
|
||||||
|
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
|
||||||
|
|
||||||
|
auto mem = storage::makeSharedMemory(barrier.data().region);
|
||||||
|
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
|
||||||
|
return layout->GetBlockSize(storage::DataLayout::CH_GRAPH_NODE_LIST) > 0 &&
|
||||||
|
layout->GetBlockSize(storage::DataLayout::CH_GRAPH_EDGE_LIST) > 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ifstream in(config.storage_config.hsgr_data_path.string().c_str());
|
||||||
|
in.seekg(std::ios::end);
|
||||||
|
auto size = in.tellg();
|
||||||
|
return size > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> bool Engine<algorithm::CoreCH>::CheckCompability(const EngineConfig &config)
|
||||||
|
{
|
||||||
|
if (!Engine<algorithm::CH>::CheckCompability(config))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.use_shared_memory)
|
||||||
|
{
|
||||||
|
storage::SharedMonitor<storage::SharedDataTimestamp> barrier;
|
||||||
|
using mutex_type = typename decltype(barrier)::mutex_type;
|
||||||
|
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
|
||||||
|
|
||||||
|
auto mem = storage::makeSharedMemory(barrier.data().region);
|
||||||
|
auto layout = reinterpret_cast<storage::DataLayout *>(mem->Ptr());
|
||||||
|
return layout->GetBlockSize(storage::DataLayout::CH_CORE_MARKER) > 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ifstream in(config.storage_config.core_data_path.string().c_str());
|
||||||
|
in.seekg(std::ios::end);
|
||||||
|
auto size = in.tellg();
|
||||||
|
return size > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,19 +19,20 @@ namespace engine
|
|||||||
class RoutingAlgorithmsInterface
|
class RoutingAlgorithmsInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual InternalRouteResult AlternativePathSearch(const PhantomNodes &phantom_node_pair) const = 0;
|
virtual InternalRouteResult
|
||||||
|
AlternativePathSearch(const PhantomNodes &phantom_node_pair) const = 0;
|
||||||
|
|
||||||
virtual InternalRouteResult
|
virtual InternalRouteResult
|
||||||
ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair,
|
ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair,
|
||||||
const boost::optional<bool> continue_straight_at_waypoint) const = 0;
|
const boost::optional<bool> continue_straight_at_waypoint) const = 0;
|
||||||
|
|
||||||
virtual InternalRouteResult
|
virtual InternalRouteResult
|
||||||
DirectShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair) const = 0;
|
DirectShortestPathSearch(const PhantomNodes &phantom_node_pair) const = 0;
|
||||||
|
|
||||||
virtual std::vector<EdgeWeight>
|
virtual std::vector<EdgeWeight>
|
||||||
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||||
const std::vector<std::size_t> &source_indices,
|
const std::vector<std::size_t> &source_indices,
|
||||||
const std::vector<std::size_t> &target_indices) const = 0;
|
const std::vector<std::size_t> &target_indices) const = 0;
|
||||||
|
|
||||||
virtual routing_algorithms::SubMatchingList
|
virtual routing_algorithms::SubMatchingList
|
||||||
MapMatching(const routing_algorithms::CandidateLists &candidates_list,
|
MapMatching(const routing_algorithms::CandidateLists &candidates_list,
|
||||||
@ -41,7 +42,7 @@ class RoutingAlgorithmsInterface
|
|||||||
|
|
||||||
virtual std::vector<routing_algorithms::TurnData>
|
virtual std::vector<routing_algorithms::TurnData>
|
||||||
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
|
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
|
||||||
const std::vector<std::size_t> &sorted_edge_indexes) const = 0;
|
const std::vector<std::size_t> &sorted_edge_indexes) const = 0;
|
||||||
|
|
||||||
virtual bool HasAlternativePathSearch() const = 0;
|
virtual bool HasAlternativePathSearch() const = 0;
|
||||||
virtual bool HasShortestPathSearch() const = 0;
|
virtual bool HasShortestPathSearch() const = 0;
|
||||||
@ -54,8 +55,9 @@ class RoutingAlgorithmsInterface
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
struct NotImplementedException : public std::runtime_error {};
|
struct NotImplementedException : public std::runtime_error
|
||||||
|
{
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Short-lived object passed to each plugin in request to wrap routing algorithms
|
// Short-lived object passed to each plugin in request to wrap routing algorithms
|
||||||
@ -74,24 +76,24 @@ template <typename AlgorithmT> class RoutingAlgorithms final : public RoutingAlg
|
|||||||
return routing_algorithms::alternativePathSearch(heaps, facade, phantom_node_pair);
|
return routing_algorithms::alternativePathSearch(heaps, facade, phantom_node_pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalRouteResult
|
InternalRouteResult ShortestPathSearch(
|
||||||
ShortestPathSearch(const std::vector<PhantomNodes> &phantom_node_pair,
|
const std::vector<PhantomNodes> &phantom_node_pair,
|
||||||
const boost::optional<bool> continue_straight_at_waypoint) const final override
|
const boost::optional<bool> continue_straight_at_waypoint) const final override
|
||||||
{
|
{
|
||||||
return routing_algorithms::shortestPathSearch(
|
return routing_algorithms::shortestPathSearch(
|
||||||
heaps, facade, phantom_node_pair, continue_straight_at_waypoint);
|
heaps, facade, phantom_node_pair, continue_straight_at_waypoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalRouteResult DirectShortestPathSearch(
|
InternalRouteResult
|
||||||
const std::vector<PhantomNodes> &phantom_node_pair) const final override
|
DirectShortestPathSearch(const PhantomNodes &phantom_nodes) const final override
|
||||||
{
|
{
|
||||||
return routing_algorithms::directShortestPathSearch(heaps, facade, phantom_node_pair);
|
return routing_algorithms::directShortestPathSearch(heaps, facade, phantom_nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<EdgeWeight>
|
std::vector<EdgeWeight>
|
||||||
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
ManyToManySearch(const std::vector<PhantomNode> &phantom_nodes,
|
||||||
const std::vector<std::size_t> &source_indices,
|
const std::vector<std::size_t> &source_indices,
|
||||||
const std::vector<std::size_t> &target_indices) const final override
|
const std::vector<std::size_t> &target_indices) const final override
|
||||||
{
|
{
|
||||||
return routing_algorithms::manyToManySearch(
|
return routing_algorithms::manyToManySearch(
|
||||||
heaps, facade, phantom_nodes, source_indices, target_indices);
|
heaps, facade, phantom_nodes, source_indices, target_indices);
|
||||||
@ -113,7 +115,7 @@ template <typename AlgorithmT> class RoutingAlgorithms final : public RoutingAlg
|
|||||||
|
|
||||||
std::vector<routing_algorithms::TurnData>
|
std::vector<routing_algorithms::TurnData>
|
||||||
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
|
GetTileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
|
||||||
const std::vector<std::size_t> &sorted_edge_indexes) const final override
|
const std::vector<std::size_t> &sorted_edge_indexes) const final override
|
||||||
{
|
{
|
||||||
return routing_algorithms::getTileTurns(facade, edges, sorted_edge_indexes);
|
return routing_algorithms::getTileTurns(facade, edges, sorted_edge_indexes);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,12 @@ directShortestPathSearch(SearchEngineData &,
|
|||||||
InternalRouteResult directShortestPathSearch(
|
InternalRouteResult directShortestPathSearch(
|
||||||
SearchEngineData &engine_working_data,
|
SearchEngineData &engine_working_data,
|
||||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||||
const std::vector<PhantomNodes> &phantom_nodes_vector);
|
const PhantomNodes &phantom_nodes);
|
||||||
|
|
||||||
|
InternalRouteResult directShortestPathSearch(
|
||||||
|
SearchEngineData &engine_working_data,
|
||||||
|
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||||
|
const PhantomNodes &phantom_nodes);
|
||||||
|
|
||||||
} // namespace routing_algorithms
|
} // namespace routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
@ -39,6 +39,14 @@ mapMatching(SearchEngineData &engine_working_data,
|
|||||||
const std::vector<util::Coordinate> &trace_coordinates,
|
const std::vector<util::Coordinate> &trace_coordinates,
|
||||||
const std::vector<unsigned> &trace_timestamps,
|
const std::vector<unsigned> &trace_timestamps,
|
||||||
const std::vector<boost::optional<double>> &trace_gps_precision);
|
const std::vector<boost::optional<double>> &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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,6 +452,28 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
|
|||||||
const bool force_loop_reverse,
|
const bool force_loop_reverse,
|
||||||
const int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
const int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
|
// Alias to be compatible with the overload for CoreCH that needs 4 heaps
|
||||||
|
inline void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||||
|
SearchEngineData::QueryHeap &forward_heap,
|
||||||
|
SearchEngineData::QueryHeap &reverse_heap,
|
||||||
|
SearchEngineData::QueryHeap &,
|
||||||
|
SearchEngineData::QueryHeap &,
|
||||||
|
std::int32_t &weight,
|
||||||
|
std::vector<NodeID> &packed_leg,
|
||||||
|
const bool force_loop_forward,
|
||||||
|
const bool force_loop_reverse,
|
||||||
|
const int duration_upper_bound = INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
search(facade,
|
||||||
|
forward_heap,
|
||||||
|
reverse_heap,
|
||||||
|
weight,
|
||||||
|
packed_leg,
|
||||||
|
force_loop_forward,
|
||||||
|
force_loop_reverse,
|
||||||
|
duration_upper_bound);
|
||||||
|
}
|
||||||
|
|
||||||
// assumes that heaps are already setup correctly.
|
// assumes that heaps are already setup correctly.
|
||||||
// A forced loop might be necessary, if source and target are on the same segment.
|
// A forced loop might be necessary, if source and target are on the same segment.
|
||||||
// If this is the case and the offsets of the respective direction are larger for the source
|
// If this is the case and the offsets of the respective direction are larger for the source
|
||||||
@ -461,16 +483,16 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
|
|||||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||||
// requires
|
// requires
|
||||||
// a force loop, if the heaps have been initialized with positive offsets.
|
// a force loop, if the heaps have been initialized with positive offsets.
|
||||||
void searchWithCore(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||||
SearchEngineData::QueryHeap &forward_heap,
|
SearchEngineData::QueryHeap &forward_heap,
|
||||||
SearchEngineData::QueryHeap &reverse_heap,
|
SearchEngineData::QueryHeap &reverse_heap,
|
||||||
SearchEngineData::QueryHeap &forward_core_heap,
|
SearchEngineData::QueryHeap &forward_core_heap,
|
||||||
SearchEngineData::QueryHeap &reverse_core_heap,
|
SearchEngineData::QueryHeap &reverse_core_heap,
|
||||||
int &weight,
|
int &weight,
|
||||||
std::vector<NodeID> &packed_leg,
|
std::vector<NodeID> &packed_leg,
|
||||||
const bool force_loop_forward,
|
const bool force_loop_forward,
|
||||||
const bool force_loop_reverse,
|
const bool force_loop_reverse,
|
||||||
int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
|
bool needsLoopForward(const PhantomNode &source_phantom, const PhantomNode &target_phantom);
|
||||||
|
|
||||||
@ -484,15 +506,15 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<algo
|
|||||||
// Requires the heaps for be empty
|
// Requires the heaps for be empty
|
||||||
// If heaps should be adjusted to be initialized outside of this function,
|
// If heaps should be adjusted to be initialized outside of this function,
|
||||||
// the addition of force_loop parameters might be required
|
// the addition of force_loop parameters might be required
|
||||||
double getNetworkDistanceWithCore(
|
double
|
||||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||||
SearchEngineData::QueryHeap &forward_heap,
|
SearchEngineData::QueryHeap &forward_heap,
|
||||||
SearchEngineData::QueryHeap &reverse_heap,
|
SearchEngineData::QueryHeap &reverse_heap,
|
||||||
SearchEngineData::QueryHeap &forward_core_heap,
|
SearchEngineData::QueryHeap &forward_core_heap,
|
||||||
SearchEngineData::QueryHeap &reverse_core_heap,
|
SearchEngineData::QueryHeap &reverse_core_heap,
|
||||||
const PhantomNode &source_phantom,
|
const PhantomNode &source_phantom,
|
||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
// Requires the heaps for be empty
|
// Requires the heaps for be empty
|
||||||
// If heaps should be adjusted to be initialized outside of this function,
|
// If heaps should be adjusted to be initialized outside of this function,
|
||||||
@ -505,6 +527,21 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
|
|||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
int duration_upper_bound = INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
|
// Alias to be compatible with the overload for CoreCH that needs 4 heaps
|
||||||
|
inline double
|
||||||
|
getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
||||||
|
SearchEngineData::QueryHeap &forward_heap,
|
||||||
|
SearchEngineData::QueryHeap &reverse_heap,
|
||||||
|
SearchEngineData::QueryHeap &,
|
||||||
|
SearchEngineData::QueryHeap &,
|
||||||
|
const PhantomNode &source_phantom,
|
||||||
|
const PhantomNode &target_phantom,
|
||||||
|
int duration_upper_bound = INVALID_EDGE_WEIGHT)
|
||||||
|
{
|
||||||
|
return getNetworkDistance(
|
||||||
|
facade, forward_heap, reverse_heap, source_phantom, target_phantom, duration_upper_bound);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace routing_algorithms
|
} // namespace routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -30,6 +30,12 @@ shortestPathSearch(SearchEngineData &engine_working_data,
|
|||||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||||
const boost::optional<bool> continue_straight_at_waypoint);
|
const boost::optional<bool> 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);
|
||||||
|
|
||||||
} // namespace routing_algorithms
|
} // namespace routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -115,7 +115,9 @@ Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
|
|||||||
{
|
{
|
||||||
if (!algorithms.HasMapMatching())
|
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());
|
BOOST_ASSERT(parameters.IsValid());
|
||||||
|
@ -35,7 +35,9 @@ Status TablePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryData
|
|||||||
{
|
{
|
||||||
if (!algorithms.HasManyToManySearch())
|
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());
|
BOOST_ASSERT(params.IsValid());
|
||||||
|
@ -149,11 +149,15 @@ Status TripPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataF
|
|||||||
{
|
{
|
||||||
if (!algorithms.HasShortestPathSearch())
|
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())
|
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());
|
BOOST_ASSERT(parameters.IsValid());
|
||||||
|
@ -36,12 +36,18 @@ ViaRoutePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFaca
|
|||||||
|
|
||||||
if (!algorithms.HasShortestPathSearch() && route_parameters.coordinates.size() > 2)
|
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())
|
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 &&
|
if (max_locations_viaroute > 0 &&
|
||||||
@ -95,18 +101,20 @@ ViaRoutePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFaca
|
|||||||
};
|
};
|
||||||
util::for_each_pair(snapped_phantoms, build_phantom_pairs);
|
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());
|
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
|
else
|
||||||
{
|
{
|
||||||
raw_route = algorithms.ShortestPathSearch(raw_route.segment_end_coordinates,
|
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
|
// we can only know this after the fact, different SCC ids still
|
||||||
|
@ -9,32 +9,14 @@ namespace engine
|
|||||||
namespace routing_algorithms
|
namespace routing_algorithms
|
||||||
{
|
{
|
||||||
|
|
||||||
/// This is a striped down version of the general shortest path algorithm.
|
namespace
|
||||||
/// 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)
|
|
||||||
{
|
{
|
||||||
InternalRouteResult raw_route_data;
|
void insertInHeaps(SearchEngineData::QueryHeap &forward_heap,
|
||||||
// Get weight to next pair of target nodes.
|
SearchEngineData::QueryHeap &reverse_heap,
|
||||||
BOOST_ASSERT_MSG(1 == phantom_nodes_vector.size(),
|
const PhantomNodes &nodes)
|
||||||
"Direct Shortest Path Query only accepts a single source and target pair. "
|
{
|
||||||
"Multiple ones have been specified.");
|
const auto &source_phantom = nodes.source_phantom;
|
||||||
const auto &phantom_node_pair = phantom_nodes_vector.front();
|
const auto &target_phantom = nodes.target_phantom;
|
||||||
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();
|
|
||||||
|
|
||||||
BOOST_ASSERT(source_phantom.IsValid());
|
BOOST_ASSERT(source_phantom.IsValid());
|
||||||
BOOST_ASSERT(target_phantom.IsValid());
|
BOOST_ASSERT(target_phantom.IsValid());
|
||||||
|
|
||||||
@ -64,42 +46,16 @@ InternalRouteResult directShortestPathSearch(
|
|||||||
target_phantom.GetReverseWeightPlusOffset(),
|
target_phantom.GetReverseWeightPlusOffset(),
|
||||||
target_phantom.reverse_segment_id.id);
|
target_phantom.reverse_segment_id.id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int weight = INVALID_EDGE_WEIGHT;
|
template <typename AlgorithmT>
|
||||||
std::vector<NodeID> packed_leg;
|
InternalRouteResult
|
||||||
|
extractRoute(const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||||
const bool constexpr DO_NOT_FORCE_LOOPS =
|
const EdgeWeight weight,
|
||||||
false; // prevents forcing of loops, since offsets are set correctly
|
const std::vector<NodeID> &packed_leg,
|
||||||
|
const PhantomNodes &nodes)
|
||||||
if (facade.GetCoreSize() > 0)
|
{
|
||||||
{
|
InternalRouteResult raw_route_data;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// No path found for both target nodes?
|
// No path found for both target nodes?
|
||||||
if (INVALID_EDGE_WEIGHT == weight)
|
if (INVALID_EDGE_WEIGHT == weight)
|
||||||
{
|
{
|
||||||
@ -113,18 +69,79 @@ InternalRouteResult directShortestPathSearch(
|
|||||||
raw_route_data.shortest_path_length = weight;
|
raw_route_data.shortest_path_length = weight;
|
||||||
raw_route_data.unpacked_path_segments.resize(1);
|
raw_route_data.unpacked_path_segments.resize(1);
|
||||||
raw_route_data.source_traversed_in_reverse.push_back(
|
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(
|
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,
|
unpackPath(facade,
|
||||||
packed_leg.begin(),
|
packed_leg.begin(),
|
||||||
packed_leg.end(),
|
packed_leg.end(),
|
||||||
phantom_node_pair,
|
nodes,
|
||||||
raw_route_data.unpacked_path_segments.front());
|
raw_route_data.unpacked_path_segments.front());
|
||||||
|
|
||||||
return raw_route_data;
|
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 routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -47,13 +47,14 @@ unsigned getMedianSampleTime(const std::vector<unsigned> ×tamps)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename AlgorithmT>
|
||||||
SubMatchingList
|
SubMatchingList
|
||||||
mapMatching(SearchEngineData &engine_working_data,
|
mapMatchingImpl(SearchEngineData &engine_working_data,
|
||||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||||
const CandidateLists &candidates_list,
|
const CandidateLists &candidates_list,
|
||||||
const std::vector<util::Coordinate> &trace_coordinates,
|
const std::vector<util::Coordinate> &trace_coordinates,
|
||||||
const std::vector<unsigned> &trace_timestamps,
|
const std::vector<unsigned> &trace_timestamps,
|
||||||
const std::vector<boost::optional<double>> &trace_gps_precision)
|
const std::vector<boost::optional<double>> &trace_gps_precision)
|
||||||
{
|
{
|
||||||
map_matching::MatchingConfidence confidence;
|
map_matching::MatchingConfidence confidence;
|
||||||
map_matching::EmissionLogProbability default_emission_log_probability(DEFAULT_GPS_PRECISION);
|
map_matching::EmissionLogProbability default_emission_log_probability(DEFAULT_GPS_PRECISION);
|
||||||
@ -208,33 +209,15 @@ mapMatching(SearchEngineData &engine_working_data,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_heap.Clear();
|
double network_distance =
|
||||||
reverse_heap.Clear();
|
getNetworkDistance(facade,
|
||||||
|
forward_heap,
|
||||||
double network_distance;
|
reverse_heap,
|
||||||
if (facade.GetCoreSize() > 0)
|
forward_core_heap,
|
||||||
{
|
reverse_core_heap,
|
||||||
forward_core_heap.Clear();
|
prev_unbroken_timestamps_list[s].phantom_node,
|
||||||
reverse_core_heap.Clear();
|
current_timestamps_list[s_prime].phantom_node,
|
||||||
network_distance = getNetworkDistanceWithCore(
|
duration_upper_bound);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get distance diff between loc1/2 and locs/s_prime
|
// get distance diff between loc1/2 and locs/s_prime
|
||||||
const auto d_t = std::abs(network_distance - haversine_distance);
|
const auto d_t = std::abs(network_distance - haversine_distance);
|
||||||
@ -427,6 +410,39 @@ mapMatching(SearchEngineData &engine_working_data,
|
|||||||
return sub_matchings;
|
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 routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
@ -270,16 +270,16 @@ void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
|
|||||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||||
// requires
|
// requires
|
||||||
// a force loop, if the heaps have been initialized with positive offsets.
|
// a force loop, if the heaps have been initialized with positive offsets.
|
||||||
void searchWithCore(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
void search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||||
SearchEngineData::QueryHeap &forward_heap,
|
SearchEngineData::QueryHeap &forward_heap,
|
||||||
SearchEngineData::QueryHeap &reverse_heap,
|
SearchEngineData::QueryHeap &reverse_heap,
|
||||||
SearchEngineData::QueryHeap &forward_core_heap,
|
SearchEngineData::QueryHeap &forward_core_heap,
|
||||||
SearchEngineData::QueryHeap &reverse_core_heap,
|
SearchEngineData::QueryHeap &reverse_core_heap,
|
||||||
EdgeWeight &weight,
|
EdgeWeight &weight,
|
||||||
std::vector<NodeID> &packed_leg,
|
std::vector<NodeID> &packed_leg,
|
||||||
const bool force_loop_forward,
|
const bool force_loop_forward,
|
||||||
const bool force_loop_reverse,
|
const bool force_loop_reverse,
|
||||||
EdgeWeight weight_upper_bound)
|
EdgeWeight weight_upper_bound)
|
||||||
{
|
{
|
||||||
NodeID middle = SPECIAL_NODEID;
|
NodeID middle = SPECIAL_NODEID;
|
||||||
weight = weight_upper_bound;
|
weight = weight_upper_bound;
|
||||||
@ -530,18 +530,20 @@ double getPathDistance(const datafacade::ContiguousInternalMemoryDataFacade<algo
|
|||||||
// Requires the heaps for be empty
|
// Requires the heaps for be empty
|
||||||
// If heaps should be adjusted to be initialized outside of this function,
|
// If heaps should be adjusted to be initialized outside of this function,
|
||||||
// the addition of force_loop parameters might be required
|
// the addition of force_loop parameters might be required
|
||||||
double getNetworkDistanceWithCore(
|
double
|
||||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CoreCH> &facade,
|
||||||
SearchEngineData::QueryHeap &forward_heap,
|
SearchEngineData::QueryHeap &forward_heap,
|
||||||
SearchEngineData::QueryHeap &reverse_heap,
|
SearchEngineData::QueryHeap &reverse_heap,
|
||||||
SearchEngineData::QueryHeap &forward_core_heap,
|
SearchEngineData::QueryHeap &forward_core_heap,
|
||||||
SearchEngineData::QueryHeap &reverse_core_heap,
|
SearchEngineData::QueryHeap &reverse_core_heap,
|
||||||
const PhantomNode &source_phantom,
|
const PhantomNode &source_phantom,
|
||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
EdgeWeight weight_upper_bound)
|
EdgeWeight weight_upper_bound)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(forward_heap.Empty());
|
forward_heap.Clear();
|
||||||
BOOST_ASSERT(reverse_heap.Empty());
|
reverse_heap.Clear();
|
||||||
|
forward_core_heap.Clear();
|
||||||
|
reverse_core_heap.Clear();
|
||||||
|
|
||||||
if (source_phantom.forward_segment_id.enabled)
|
if (source_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
@ -574,16 +576,16 @@ double getNetworkDistanceWithCore(
|
|||||||
|
|
||||||
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
||||||
std::vector<NodeID> packed_path;
|
std::vector<NodeID> packed_path;
|
||||||
searchWithCore(facade,
|
search(facade,
|
||||||
forward_heap,
|
forward_heap,
|
||||||
reverse_heap,
|
reverse_heap,
|
||||||
forward_core_heap,
|
forward_core_heap,
|
||||||
reverse_core_heap,
|
reverse_core_heap,
|
||||||
weight,
|
weight,
|
||||||
packed_path,
|
packed_path,
|
||||||
DO_NOT_FORCE_LOOPS,
|
DO_NOT_FORCE_LOOPS,
|
||||||
DO_NOT_FORCE_LOOPS,
|
DO_NOT_FORCE_LOOPS,
|
||||||
weight_upper_bound);
|
weight_upper_bound);
|
||||||
|
|
||||||
double distance = std::numeric_limits<double>::max();
|
double distance = std::numeric_limits<double>::max();
|
||||||
if (weight != INVALID_EDGE_WEIGHT)
|
if (weight != INVALID_EDGE_WEIGHT)
|
||||||
@ -604,8 +606,8 @@ getNetworkDistance(const datafacade::ContiguousInternalMemoryDataFacade<algorith
|
|||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
EdgeWeight weight_upper_bound)
|
EdgeWeight weight_upper_bound)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(forward_heap.Empty());
|
forward_heap.Clear();
|
||||||
BOOST_ASSERT(reverse_heap.Empty());
|
reverse_heap.Clear();
|
||||||
|
|
||||||
if (source_phantom.forward_segment_id.enabled)
|
if (source_phantom.forward_segment_id.enabled)
|
||||||
{
|
{
|
||||||
|
@ -12,12 +12,16 @@ namespace engine
|
|||||||
namespace routing_algorithms
|
namespace routing_algorithms
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
const static constexpr bool DO_NOT_FORCE_LOOP = false;
|
const static constexpr bool DO_NOT_FORCE_LOOP = false;
|
||||||
using QueryHeap = SearchEngineData::QueryHeap;
|
using QueryHeap = SearchEngineData::QueryHeap;
|
||||||
|
|
||||||
// allows a uturn at the target_phantom
|
// allows a uturn at the target_phantom
|
||||||
// searches source forward/reverse -> target forward/reverse
|
// 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 &forward_heap,
|
||||||
QueryHeap &reverse_heap,
|
QueryHeap &reverse_heap,
|
||||||
QueryHeap &forward_core_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_forwad = is_oneway_source && needsLoopForward(source_phantom, target_phantom);
|
||||||
auto needs_loop_backwards =
|
auto needs_loop_backwards =
|
||||||
is_oneway_target && needsLoopBackwards(source_phantom, target_phantom);
|
is_oneway_target && needsLoopBackwards(source_phantom, target_phantom);
|
||||||
if (facade.GetCoreSize() > 0)
|
|
||||||
{
|
forward_core_heap.Clear();
|
||||||
forward_core_heap.Clear();
|
reverse_core_heap.Clear();
|
||||||
reverse_core_heap.Clear();
|
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
routing_algorithms::search(facade,
|
||||||
searchWithCore(facade,
|
forward_heap,
|
||||||
forward_heap,
|
reverse_heap,
|
||||||
reverse_heap,
|
forward_core_heap,
|
||||||
forward_core_heap,
|
reverse_core_heap,
|
||||||
reverse_core_heap,
|
new_total_weight,
|
||||||
new_total_weight,
|
leg_packed_path,
|
||||||
leg_packed_path,
|
needs_loop_forwad,
|
||||||
needs_loop_forwad,
|
needs_loop_backwards);
|
||||||
needs_loop_backwards);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
search(facade,
|
|
||||||
forward_heap,
|
|
||||||
reverse_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
|
// 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
|
// 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
|
// 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:
|
// searches shortest path between:
|
||||||
// source forward/reverse -> target forward
|
// source forward/reverse -> target forward
|
||||||
// source forward/reverse -> target reverse
|
// 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 &forward_heap,
|
||||||
QueryHeap &reverse_heap,
|
QueryHeap &reverse_heap,
|
||||||
QueryHeap &forward_core_heap,
|
QueryHeap &forward_core_heap,
|
||||||
@ -149,32 +143,19 @@ void Search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
|
|||||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||||
|
|
||||||
if (facade.GetCoreSize() > 0)
|
forward_core_heap.Clear();
|
||||||
{
|
reverse_core_heap.Clear();
|
||||||
forward_core_heap.Clear();
|
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||||
reverse_core_heap.Clear();
|
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
routing_algorithms::search(facade,
|
||||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
forward_heap,
|
||||||
searchWithCore(facade,
|
reverse_heap,
|
||||||
forward_heap,
|
forward_core_heap,
|
||||||
reverse_heap,
|
reverse_core_heap,
|
||||||
forward_core_heap,
|
new_total_weight_to_forward,
|
||||||
reverse_core_heap,
|
leg_packed_path_forward,
|
||||||
new_total_weight_to_forward,
|
needsLoopForward(source_phantom, target_phantom),
|
||||||
leg_packed_path_forward,
|
DO_NOT_FORCE_LOOP);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (search_to_reverse_node)
|
if (search_to_reverse_node)
|
||||||
@ -200,32 +181,19 @@ void Search(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>
|
|||||||
}
|
}
|
||||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||||
if (facade.GetCoreSize() > 0)
|
forward_core_heap.Clear();
|
||||||
{
|
reverse_core_heap.Clear();
|
||||||
forward_core_heap.Clear();
|
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
||||||
reverse_core_heap.Clear();
|
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
||||||
BOOST_ASSERT(forward_core_heap.Size() == 0);
|
routing_algorithms::search(facade,
|
||||||
BOOST_ASSERT(reverse_core_heap.Size() == 0);
|
forward_heap,
|
||||||
searchWithCore(facade,
|
reverse_heap,
|
||||||
forward_heap,
|
forward_core_heap,
|
||||||
reverse_heap,
|
reverse_core_heap,
|
||||||
forward_core_heap,
|
new_total_weight_to_reverse,
|
||||||
reverse_core_heap,
|
leg_packed_path_reverse,
|
||||||
new_total_weight_to_reverse,
|
DO_NOT_FORCE_LOOP,
|
||||||
leg_packed_path_reverse,
|
needsLoopBackwards(source_phantom, target_phantom));
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,11 +227,12 @@ void unpackLegs(const datafacade::ContiguousInternalMemoryDataFacade<algorithm::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename AlgorithmT>
|
||||||
InternalRouteResult
|
InternalRouteResult
|
||||||
shortestPathSearch(SearchEngineData &engine_working_data,
|
shortestPathSearchImpl(SearchEngineData &engine_working_data,
|
||||||
const datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH> &facade,
|
const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade,
|
||||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||||
const boost::optional<bool> continue_straight_at_waypoint)
|
const boost::optional<bool> continue_straight_at_waypoint)
|
||||||
{
|
{
|
||||||
InternalRouteResult raw_route_data;
|
InternalRouteResult raw_route_data;
|
||||||
const bool allow_uturn_at_waypoint =
|
const bool allow_uturn_at_waypoint =
|
||||||
@ -351,7 +320,7 @@ shortestPathSearch(SearchEngineData &engine_working_data,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Search(facade,
|
search(facade,
|
||||||
forward_heap,
|
forward_heap,
|
||||||
reverse_heap,
|
reverse_heap,
|
||||||
forward_core_heap,
|
forward_core_heap,
|
||||||
@ -503,6 +472,27 @@ shortestPathSearch(SearchEngineData &engine_working_data,
|
|||||||
|
|
||||||
return raw_route_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 routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
|
@ -17,8 +17,15 @@ namespace osrm
|
|||||||
// Pimpl idiom
|
// Pimpl idiom
|
||||||
|
|
||||||
OSRM::OSRM(engine::EngineConfig &config)
|
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() = default;
|
||||||
OSRM::OSRM(OSRM &&) noexcept = default;
|
OSRM::OSRM(OSRM &&) noexcept = default;
|
||||||
|
@ -278,6 +278,16 @@ class MockAlgorithmDataFacade<engine::algorithm::CH>
|
|||||||
{
|
{
|
||||||
return SPECIAL_EDGEID;
|
return SPECIAL_EDGEID;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class MockAlgorithmDataFacade<engine::algorithm::CoreCH>
|
||||||
|
: public engine::datafacade::AlgorithmDataFacade<engine::algorithm::CoreCH>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
EdgeData foo;
|
||||||
|
|
||||||
|
public:
|
||||||
bool IsCoreNode(const NodeID /* id */) const override { return false; }
|
bool IsCoreNode(const NodeID /* id */) const override { return false; }
|
||||||
std::size_t GetCoreSize() const override { return 0; }
|
std::size_t GetCoreSize() const override { return 0; }
|
||||||
};
|
};
|
||||||
@ -287,6 +297,14 @@ class MockDataFacade final : public MockBaseDataFacade, public MockAlgorithmData
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class MockDataFacade<engine::algorithm::CoreCH> final
|
||||||
|
: public MockBaseDataFacade,
|
||||||
|
public MockAlgorithmDataFacade<engine::algorithm::CH>,
|
||||||
|
public MockAlgorithmDataFacade<engine::algorithm::CoreCH>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
} // ns test
|
} // ns test
|
||||||
} // ns osrm
|
} // ns osrm
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user