Port OSRM, Engine and Datafacades to be algorithm aware
This commit is contained in:
parent
71e95c92b6
commit
2fa8d0f534
37
include/engine/algorithm.hpp
Normal file
37
include/engine/algorithm.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef OSRM_ENGINE_ALGORITHM_HPP
|
||||
#define OSRM_ENGINE_ALGORITHM_HPP
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace algorithm
|
||||
{
|
||||
|
||||
// Contraction Hiearchy
|
||||
struct CH;
|
||||
}
|
||||
|
||||
namespace algorithm_trais
|
||||
{
|
||||
template <typename AlgorithmT> struct HasAlternativeRouting final
|
||||
{
|
||||
template <template <typename A> class FacadeT> bool operator()(const FacadeT<AlgorithmT> &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct HasAlternativeRouting<algorithm::CH> final
|
||||
{
|
||||
template <template <typename A> class FacadeT>
|
||||
bool operator()(const FacadeT<algorithm::CH> &facade)
|
||||
{
|
||||
return facade.GetCoreSize() == 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -24,9 +24,10 @@ namespace engine
|
||||
// This class monitors the shared memory region that contains the pointers to
|
||||
// the data and layout regions that should be used. This region is updated
|
||||
// once a new dataset arrives.
|
||||
class DataWatchdog
|
||||
template <typename AlgorithmT> class DataWatchdog final
|
||||
{
|
||||
using mutex_type = typename storage::SharedMonitor<storage::SharedDataTimestamp>::mutex_type;
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
|
||||
|
||||
public:
|
||||
DataWatchdog() : active(true), timestamp(0)
|
||||
@ -35,7 +36,7 @@ class DataWatchdog
|
||||
{
|
||||
boost::interprocess::scoped_lock<mutex_type> current_region_lock(barrier.get_mutex());
|
||||
|
||||
facade = std::make_shared<datafacade::ContiguousInternalMemoryDataFacade>(
|
||||
facade = std::make_shared<const FacadeT>(
|
||||
std::make_unique<datafacade::SharedMemoryAllocator>(barrier.data().region));
|
||||
timestamp = barrier.data().timestamp;
|
||||
}
|
||||
@ -43,14 +44,14 @@ class DataWatchdog
|
||||
watcher = std::thread(&DataWatchdog::Run, this);
|
||||
}
|
||||
|
||||
~DataWatchdog()
|
||||
virtual ~DataWatchdog()
|
||||
{
|
||||
active = false;
|
||||
barrier.notify_all();
|
||||
watcher.join();
|
||||
}
|
||||
|
||||
auto GetDataFacade() const { return facade; }
|
||||
std::shared_ptr<const FacadeT> Get() const { return facade; }
|
||||
|
||||
private:
|
||||
void Run()
|
||||
@ -67,7 +68,7 @@ class DataWatchdog
|
||||
if (timestamp != barrier.data().timestamp)
|
||||
{
|
||||
auto region = barrier.data().region;
|
||||
facade = std::make_shared<datafacade::ContiguousInternalMemoryDataFacade>(
|
||||
facade = std::make_shared<const FacadeT>(
|
||||
std::make_unique<datafacade::SharedMemoryAllocator>(region));
|
||||
timestamp = barrier.data().timestamp;
|
||||
util::Log() << "updated facade to region " << region << " with timestamp "
|
||||
@ -82,7 +83,7 @@ class DataWatchdog
|
||||
std::thread watcher;
|
||||
bool active;
|
||||
unsigned timestamp;
|
||||
std::shared_ptr<datafacade::ContiguousInternalMemoryDataFacade> facade;
|
||||
std::shared_ptr<const FacadeT> facade;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
61
include/engine/datafacade/algorithm_datafacade.hpp
Normal file
61
include/engine/datafacade/algorithm_datafacade.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef OSRM_ENGINE_DATAFACADE_ALGORITHM_DATAFACADE_HPP
|
||||
#define OSRM_ENGINE_DATAFACADE_ALGORITHM_DATAFACADE_HPP
|
||||
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace datafacade
|
||||
{
|
||||
|
||||
using EdgeRange = util::range<EdgeID>;
|
||||
|
||||
template <typename AlgorithmT> class AlgorithmDataFacade;
|
||||
|
||||
template <> class AlgorithmDataFacade<algorithm::CH>
|
||||
{
|
||||
public:
|
||||
using EdgeData = contractor::QueryEdge::EdgeData;
|
||||
|
||||
// search graph access
|
||||
virtual unsigned GetNumberOfNodes() const = 0;
|
||||
|
||||
virtual unsigned GetNumberOfEdges() const = 0;
|
||||
|
||||
virtual unsigned GetOutDegree(const NodeID n) const = 0;
|
||||
|
||||
virtual NodeID GetTarget(const EdgeID e) const = 0;
|
||||
|
||||
virtual const EdgeData &GetEdgeData(const EdgeID e) const = 0;
|
||||
|
||||
virtual EdgeID BeginEdges(const NodeID n) const = 0;
|
||||
|
||||
virtual EdgeID EndEdges(const NodeID n) const = 0;
|
||||
|
||||
virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0;
|
||||
|
||||
// searches for a specific edge
|
||||
virtual EdgeID FindEdge(const NodeID from, const NodeID to) const = 0;
|
||||
|
||||
virtual EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const = 0;
|
||||
|
||||
virtual EdgeID
|
||||
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const = 0;
|
||||
|
||||
virtual EdgeID FindSmallestEdge(const NodeID from,
|
||||
const NodeID to,
|
||||
const std::function<bool(EdgeData)> filter) const = 0;
|
||||
|
||||
virtual bool IsCoreNode(const NodeID id) const = 0;
|
||||
|
||||
virtual std::size_t GetCoreSize() const = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
#ifndef CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP
|
||||
#define CONTIGUOUS_INTERNALMEM_DATAFACADE_HPP
|
||||
|
||||
#include "engine/datafacade/algorithm_datafacade.hpp"
|
||||
#include "engine/datafacade/contiguous_block_allocator.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
|
||||
@ -13,6 +14,7 @@
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/geospatial_query.hpp"
|
||||
#include "util/exception.hpp"
|
||||
#include "util/exception_utils.hpp"
|
||||
@ -44,6 +46,124 @@ namespace engine
|
||||
namespace datafacade
|
||||
{
|
||||
|
||||
template <typename AlgorithmT> class ContiguousInternalMemoryAlgorithmDataFacade;
|
||||
|
||||
template <>
|
||||
class ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
|
||||
: public datafacade::AlgorithmDataFacade<algorithm::CH>
|
||||
{
|
||||
private:
|
||||
using QueryGraph = util::StaticGraph<EdgeData, true>;
|
||||
using GraphNode = QueryGraph::NodeArrayEntry;
|
||||
using GraphEdge = QueryGraph::EdgeArrayEntry;
|
||||
|
||||
std::unique_ptr<QueryGraph> m_query_graph;
|
||||
util::ShM<bool, true>::vector m_is_core_node;
|
||||
|
||||
// allocator that keeps the allocation data
|
||||
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
||||
|
||||
void InitializeGraphPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
auto graph_nodes_ptr = data_layout.GetBlockPtr<GraphNode>(
|
||||
memory_block, storage::DataLayout::CH_GRAPH_NODE_LIST);
|
||||
|
||||
auto graph_edges_ptr = data_layout.GetBlockPtr<GraphEdge>(
|
||||
memory_block, storage::DataLayout::CH_GRAPH_EDGE_LIST);
|
||||
|
||||
util::ShM<GraphNode, true>::vector node_list(
|
||||
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::CH_GRAPH_NODE_LIST]);
|
||||
util::ShM<GraphEdge, true>::vector edge_list(
|
||||
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::CH_GRAPH_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:
|
||||
ContiguousInternalMemoryAlgorithmDataFacade(
|
||||
std::shared_ptr<ContiguousBlockAllocator> allocator_)
|
||||
: allocator(std::move(allocator_))
|
||||
{
|
||||
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
|
||||
}
|
||||
|
||||
void InitializeInternalPointers(storage::DataLayout &data_layout, char *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
|
||||
unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); }
|
||||
|
||||
unsigned GetNumberOfEdges() const override final { return m_query_graph->GetNumberOfEdges(); }
|
||||
|
||||
unsigned GetOutDegree(const NodeID n) const override final
|
||||
{
|
||||
return m_query_graph->GetOutDegree(n);
|
||||
}
|
||||
|
||||
NodeID GetTarget(const EdgeID e) const override final { return m_query_graph->GetTarget(e); }
|
||||
|
||||
EdgeData &GetEdgeData(const EdgeID e) const override final
|
||||
{
|
||||
return m_query_graph->GetEdgeData(e);
|
||||
}
|
||||
|
||||
EdgeID BeginEdges(const NodeID n) const override final { return m_query_graph->BeginEdges(n); }
|
||||
|
||||
EdgeID EndEdges(const NodeID n) const override final { return m_query_graph->EndEdges(n); }
|
||||
|
||||
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
|
||||
{
|
||||
return m_query_graph->GetAdjacentEdgeRange(node);
|
||||
}
|
||||
|
||||
// searches for a specific edge
|
||||
EdgeID FindEdge(const NodeID from, const NodeID to) const override final
|
||||
{
|
||||
return m_query_graph->FindEdge(from, to);
|
||||
}
|
||||
|
||||
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const override final
|
||||
{
|
||||
return m_query_graph->FindEdgeInEitherDirection(from, to);
|
||||
}
|
||||
|
||||
EdgeID
|
||||
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const override final
|
||||
{
|
||||
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
|
||||
}
|
||||
|
||||
EdgeID FindSmallestEdge(const NodeID from,
|
||||
const NodeID to,
|
||||
std::function<bool(EdgeData)> filter) const override final
|
||||
{
|
||||
return m_query_graph->FindSmallestEdge(from, to, filter);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This base class implements the Datafacade interface for accessing
|
||||
* data that's stored in a single large block of memory (RAM).
|
||||
@ -51,13 +171,10 @@ namespace datafacade
|
||||
* In this case "internal memory" refers to RAM - as opposed to "external memory",
|
||||
* which usually refers to disk.
|
||||
*/
|
||||
class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
{
|
||||
private:
|
||||
using super = BaseDataFacade;
|
||||
using QueryGraph = util::StaticGraph<EdgeData, true>;
|
||||
using GraphNode = QueryGraph::NodeArrayEntry;
|
||||
using GraphEdge = QueryGraph::EdgeArrayEntry;
|
||||
using IndexBlock = util::RangeTable<16, true>::BlockT;
|
||||
using RTreeLeaf = super::RTreeLeaf;
|
||||
using SharedRTree =
|
||||
@ -65,11 +182,10 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade>;
|
||||
using RTreeNode = SharedRTree::TreeNode;
|
||||
|
||||
unsigned m_check_sum;
|
||||
std::unique_ptr<QueryGraph> m_query_graph;
|
||||
std::string m_timestamp;
|
||||
extractor::ProfileProperties *m_profile_properties;
|
||||
|
||||
unsigned m_check_sum;
|
||||
util::ShM<util::Coordinate, true>::vector m_coordinate_list;
|
||||
util::PackedVector<OSMNodeID, true> m_osmnodeid_list;
|
||||
util::ShM<GeometryID, true>::vector m_via_geometry_list;
|
||||
@ -118,14 +234,7 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
util::ShM<DiscreteBearing, true>::vector m_bearing_values_table;
|
||||
|
||||
// allocator that keeps the allocation data
|
||||
std::unique_ptr<ContiguousBlockAllocator> allocator;
|
||||
|
||||
void InitializeChecksumPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
m_check_sum =
|
||||
*data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::HSGR_CHECKSUM);
|
||||
util::Log() << "set checksum: " << m_check_sum;
|
||||
}
|
||||
std::shared_ptr<ContiguousBlockAllocator> allocator;
|
||||
|
||||
void InitializeProfilePropertiesPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
@ -143,6 +252,13 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
m_timestamp.begin());
|
||||
}
|
||||
|
||||
void InitializeChecksumPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
m_check_sum =
|
||||
*data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::HSGR_CHECKSUM);
|
||||
util::Log() << "set checksum: " << m_check_sum;
|
||||
}
|
||||
|
||||
void InitializeRTreePointers(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
BOOST_ASSERT_MSG(!m_coordinate_list.empty(), "coordinates must be loaded before r-tree");
|
||||
@ -168,21 +284,6 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
new SharedGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
|
||||
}
|
||||
|
||||
void InitializeGraphPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
auto graph_nodes_ptr =
|
||||
data_layout.GetBlockPtr<GraphNode>(memory_block, storage::DataLayout::GRAPH_NODE_LIST);
|
||||
|
||||
auto graph_edges_ptr =
|
||||
data_layout.GetBlockPtr<GraphEdge>(memory_block, storage::DataLayout::GRAPH_EDGE_LIST);
|
||||
|
||||
util::ShM<GraphNode, true>::vector node_list(
|
||||
graph_nodes_ptr, data_layout.num_entries[storage::DataLayout::GRAPH_NODE_LIST]);
|
||||
util::ShM<GraphEdge, true>::vector edge_list(
|
||||
graph_edges_ptr, data_layout.num_entries[storage::DataLayout::GRAPH_EDGE_LIST]);
|
||||
m_query_graph.reset(new QueryGraph(node_list, edge_list));
|
||||
}
|
||||
|
||||
void InitializeNodeAndEdgeInformationPointers(storage::DataLayout &data_layout,
|
||||
char *memory_block)
|
||||
{
|
||||
@ -290,15 +391,6 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
m_lane_description_masks = std::move(masks);
|
||||
}
|
||||
|
||||
void InitializeCoreInformationPointer(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
auto core_marker_ptr =
|
||||
data_layout.GetBlockPtr<unsigned>(memory_block, storage::DataLayout::CORE_MARKER);
|
||||
util::ShM<bool, true>::vector is_core_node(
|
||||
core_marker_ptr, data_layout.num_entries[storage::DataLayout::CORE_MARKER]);
|
||||
m_is_core_node = std::move(is_core_node);
|
||||
}
|
||||
|
||||
void InitializeTurnPenalties(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
auto turn_weight_penalties_ptr = data_layout.GetBlockPtr<TurnPenalty>(
|
||||
@ -428,7 +520,6 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
|
||||
void InitializeInternalPointers(storage::DataLayout &data_layout, char *memory_block)
|
||||
{
|
||||
InitializeGraphPointer(data_layout, memory_block);
|
||||
InitializeChecksumPointer(data_layout, memory_block);
|
||||
InitializeNodeAndEdgeInformationPointers(data_layout, memory_block);
|
||||
InitializeTurnPenalties(data_layout, memory_block);
|
||||
@ -437,7 +528,6 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
InitializeViaNodeListPointer(data_layout, memory_block);
|
||||
InitializeNamePointers(data_layout, memory_block);
|
||||
InitializeTurnLaneDescriptionsPointers(data_layout, memory_block);
|
||||
InitializeCoreInformationPointer(data_layout, memory_block);
|
||||
InitializeProfilePropertiesPointer(data_layout, memory_block);
|
||||
InitializeRTreePointers(data_layout, memory_block);
|
||||
InitializeIntersectionClassPointers(data_layout, memory_block);
|
||||
@ -446,62 +536,12 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
public:
|
||||
// allows switching between process_memory/shared_memory datafacade, based on the type of
|
||||
// allocator
|
||||
ContiguousInternalMemoryDataFacade(std::unique_ptr<ContiguousBlockAllocator> allocator_)
|
||||
ContiguousInternalMemoryDataFacadeBase(std::shared_ptr<ContiguousBlockAllocator> allocator_)
|
||||
: allocator(std::move(allocator_))
|
||||
{
|
||||
InitializeInternalPointers(allocator->GetLayout(), allocator->GetMemory());
|
||||
}
|
||||
|
||||
// search graph access
|
||||
unsigned GetNumberOfNodes() const override final { return m_query_graph->GetNumberOfNodes(); }
|
||||
|
||||
unsigned GetNumberOfEdges() const override final { return m_query_graph->GetNumberOfEdges(); }
|
||||
|
||||
unsigned GetOutDegree(const NodeID n) const override final
|
||||
{
|
||||
return m_query_graph->GetOutDegree(n);
|
||||
}
|
||||
|
||||
NodeID GetTarget(const EdgeID e) const override final { return m_query_graph->GetTarget(e); }
|
||||
|
||||
EdgeData &GetEdgeData(const EdgeID e) const override final
|
||||
{
|
||||
return m_query_graph->GetEdgeData(e);
|
||||
}
|
||||
|
||||
EdgeID BeginEdges(const NodeID n) const override final { return m_query_graph->BeginEdges(n); }
|
||||
|
||||
EdgeID EndEdges(const NodeID n) const override final { return m_query_graph->EndEdges(n); }
|
||||
|
||||
EdgeRange GetAdjacentEdgeRange(const NodeID node) const override final
|
||||
{
|
||||
return m_query_graph->GetAdjacentEdgeRange(node);
|
||||
}
|
||||
|
||||
// searches for a specific edge
|
||||
EdgeID FindEdge(const NodeID from, const NodeID to) const override final
|
||||
{
|
||||
return m_query_graph->FindEdge(from, to);
|
||||
}
|
||||
|
||||
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const override final
|
||||
{
|
||||
return m_query_graph->FindEdgeInEitherDirection(from, to);
|
||||
}
|
||||
|
||||
EdgeID
|
||||
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const override final
|
||||
{
|
||||
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
|
||||
}
|
||||
|
||||
EdgeID FindSmallestEdge(const NodeID from,
|
||||
const NodeID to,
|
||||
std::function<bool(EdgeData)> filter) const override final
|
||||
{
|
||||
return m_query_graph->FindSmallestEdge(from, to, filter);
|
||||
}
|
||||
|
||||
// node and edge information access
|
||||
util::Coordinate GetCoordinateOfNode(const NodeID id) const override final
|
||||
{
|
||||
@ -825,18 +865,6 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
return m_name_table.GetDestinationsForID(id);
|
||||
}
|
||||
|
||||
bool IsCoreNode(const NodeID id) const override final
|
||||
{
|
||||
if (m_is_core_node.size() > 0)
|
||||
{
|
||||
return m_is_core_node.at(id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual std::size_t GetCoreSize() const override final { return m_is_core_node.size(); }
|
||||
|
||||
// Returns the data source ids that were used to supply the edge
|
||||
// weights.
|
||||
virtual std::vector<DatasourceID>
|
||||
@ -1006,6 +1034,22 @@ class ContiguousInternalMemoryDataFacade : public BaseDataFacade
|
||||
m_lane_description_offsets[lane_description_id + 1]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AlgorithmT> class ContiguousInternalMemoryDataFacade;
|
||||
|
||||
template <>
|
||||
class ContiguousInternalMemoryDataFacade<algorithm::CH>
|
||||
: public ContiguousInternalMemoryDataFacadeBase,
|
||||
public ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>
|
||||
{
|
||||
public:
|
||||
ContiguousInternalMemoryDataFacade(std::shared_ptr<ContiguousBlockAllocator> allocator)
|
||||
: ContiguousInternalMemoryDataFacadeBase(allocator),
|
||||
ContiguousInternalMemoryAlgorithmDataFacade<algorithm::CH>(allocator)
|
||||
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,47 +36,19 @@ namespace datafacade
|
||||
{
|
||||
|
||||
using StringView = util::StringView;
|
||||
using EdgeRange = util::range<EdgeID>;
|
||||
|
||||
class BaseDataFacade
|
||||
{
|
||||
public:
|
||||
using EdgeData = contractor::QueryEdge::EdgeData;
|
||||
using RTreeLeaf = extractor::EdgeBasedNode;
|
||||
BaseDataFacade() {}
|
||||
virtual ~BaseDataFacade() {}
|
||||
|
||||
// search graph access
|
||||
virtual unsigned GetNumberOfNodes() const = 0;
|
||||
|
||||
virtual unsigned GetNumberOfEdges() const = 0;
|
||||
|
||||
virtual unsigned GetOutDegree(const NodeID n) const = 0;
|
||||
|
||||
virtual NodeID GetTarget(const EdgeID e) const = 0;
|
||||
|
||||
virtual const EdgeData &GetEdgeData(const EdgeID e) const = 0;
|
||||
|
||||
virtual EdgeID BeginEdges(const NodeID n) const = 0;
|
||||
|
||||
virtual EdgeID EndEdges(const NodeID n) const = 0;
|
||||
|
||||
virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0;
|
||||
|
||||
// searches for a specific edge
|
||||
virtual EdgeID FindEdge(const NodeID from, const NodeID to) const = 0;
|
||||
|
||||
virtual EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const = 0;
|
||||
|
||||
virtual EdgeID
|
||||
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const = 0;
|
||||
|
||||
virtual EdgeID FindSmallestEdge(const NodeID from,
|
||||
const NodeID to,
|
||||
const std::function<bool(EdgeData)> filter) const = 0;
|
||||
virtual unsigned GetCheckSum() const = 0;
|
||||
|
||||
// node and edge information access
|
||||
virtual util::Coordinate GetCoordinateOfNode(const NodeID id) const = 0;
|
||||
|
||||
virtual OSMNodeID GetOSMNodeIDOfNode(const NodeID id) const = 0;
|
||||
|
||||
virtual GeometryID GetGeometryIndexForEdgeID(const EdgeID id) const = 0;
|
||||
@ -163,10 +135,6 @@ class BaseDataFacade
|
||||
virtual extractor::guidance::TurnLaneDescription
|
||||
GetTurnDescription(const LaneDescriptionID lane_description_id) const = 0;
|
||||
|
||||
virtual unsigned GetCheckSum() const = 0;
|
||||
|
||||
virtual bool IsCoreNode(const NodeID id) const = 0;
|
||||
|
||||
virtual NameID GetNameIndexFromEdgeID(const EdgeID id) const = 0;
|
||||
|
||||
virtual StringView GetNameForID(const NameID id) const = 0;
|
||||
@ -177,8 +145,6 @@ class BaseDataFacade
|
||||
|
||||
virtual StringView GetDestinationsForID(const NameID id) const = 0;
|
||||
|
||||
virtual std::size_t GetCoreSize() const = 0;
|
||||
|
||||
virtual std::string GetTimestamp() const = 0;
|
||||
|
||||
virtual bool GetContinueStraightDefault() const = 0;
|
||||
|
56
include/engine/datafacade_provider.hpp
Normal file
56
include/engine/datafacade_provider.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef OSRM_ENGINE_DATAFACADE_PROVIDER_HPP
|
||||
#define OSRM_ENGINE_DATAFACADE_PROVIDER_HPP
|
||||
|
||||
#include "engine/data_watchdog.hpp"
|
||||
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
|
||||
#include "engine/datafacade/process_memory_allocator.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
|
||||
template <typename AlgorithmT> class DataFacadeProvider
|
||||
{
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
|
||||
|
||||
public:
|
||||
virtual ~DataFacadeProvider() = default;
|
||||
|
||||
virtual std::shared_ptr<const FacadeT> Get() const = 0;
|
||||
};
|
||||
|
||||
template <typename AlgorithmT> class ImmutableProvider final : public DataFacadeProvider<AlgorithmT>
|
||||
{
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
|
||||
|
||||
public:
|
||||
ImmutableProvider(const storage::StorageConfig &config)
|
||||
: immutable_data_facade(std::make_shared<FacadeT>(
|
||||
std::make_shared<datafacade::ProcessMemoryAllocator>(config)))
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<const FacadeT> Get() const override final { return immutable_data_facade; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<const FacadeT> immutable_data_facade;
|
||||
};
|
||||
|
||||
template <typename AlgorithmT> class WatchingProvider final : public DataFacadeProvider<AlgorithmT>
|
||||
{
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT>;
|
||||
DataWatchdog<AlgorithmT> watchdog;
|
||||
|
||||
public:
|
||||
std::shared_ptr<const FacadeT> Get() const override final
|
||||
{
|
||||
// We need a singleton here because multiple instances of DataWatchdog
|
||||
// conflict on shared memory mappings
|
||||
return watchdog.Get();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -9,7 +9,8 @@
|
||||
#include "engine/api/trip_parameters.hpp"
|
||||
#include "engine/data_watchdog.hpp"
|
||||
#include "engine/datafacade/contiguous_block_allocator.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/datafacade_provider.hpp"
|
||||
#include "engine/engine_config.hpp"
|
||||
#include "engine/engine_config.hpp"
|
||||
#include "engine/plugins/match.hpp"
|
||||
#include "engine/plugins/nearest.hpp"
|
||||
@ -17,6 +18,7 @@
|
||||
#include "engine/plugins/tile.hpp"
|
||||
#include "engine/plugins/trip.hpp"
|
||||
#include "engine/plugins/viaroute.hpp"
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
#include "engine/status.hpp"
|
||||
#include "util/exception.hpp"
|
||||
#include "util/exception_utils.hpp"
|
||||
@ -30,26 +32,102 @@ namespace osrm
|
||||
namespace engine
|
||||
{
|
||||
|
||||
class Engine final
|
||||
class EngineInterface
|
||||
{
|
||||
public:
|
||||
explicit Engine(const EngineConfig &config);
|
||||
virtual ~EngineInterface(){};
|
||||
virtual Status Route(const api::RouteParameters ¶meters,
|
||||
util::json::Object &result) const = 0;
|
||||
virtual Status Table(const api::TableParameters ¶meters,
|
||||
util::json::Object &result) const = 0;
|
||||
virtual Status Nearest(const api::NearestParameters ¶meters,
|
||||
util::json::Object &result) const = 0;
|
||||
virtual Status Trip(const api::TripParameters ¶meters,
|
||||
util::json::Object &result) const = 0;
|
||||
virtual Status Match(const api::MatchParameters ¶meters,
|
||||
util::json::Object &result) const = 0;
|
||||
virtual Status Tile(const api::TileParameters ¶meters, std::string &result) const = 0;
|
||||
};
|
||||
|
||||
template <typename AlgorithmT> class Engine final : public EngineInterface
|
||||
{
|
||||
public:
|
||||
explicit Engine(const EngineConfig &config)
|
||||
: route_plugin(config.max_locations_viaroute), //
|
||||
table_plugin(config.max_locations_distance_table), //
|
||||
nearest_plugin(config.max_results_nearest), //
|
||||
trip_plugin(config.max_locations_trip), //
|
||||
match_plugin(config.max_locations_map_matching), //
|
||||
tile_plugin() //
|
||||
|
||||
{
|
||||
if (config.use_shared_memory)
|
||||
{
|
||||
facade_provider = std::make_unique<WatchingProvider<AlgorithmT>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
facade_provider =
|
||||
std::make_unique<ImmutableProvider<AlgorithmT>>(config.storage_config);
|
||||
}
|
||||
}
|
||||
|
||||
Engine(Engine &&) noexcept = delete;
|
||||
Engine &operator=(Engine &&) noexcept = delete;
|
||||
|
||||
Engine(const Engine &) = delete;
|
||||
Engine &operator=(const Engine &) = delete;
|
||||
virtual ~Engine(){};
|
||||
|
||||
Status Route(const api::RouteParameters ¶meters, util::json::Object &result) const;
|
||||
Status Table(const api::TableParameters ¶meters, util::json::Object &result) const;
|
||||
Status Nearest(const api::NearestParameters ¶meters, util::json::Object &result) const;
|
||||
Status Trip(const api::TripParameters ¶meters, util::json::Object &result) const;
|
||||
Status Match(const api::MatchParameters ¶meters, util::json::Object &result) const;
|
||||
Status Tile(const api::TileParameters ¶meters, std::string &result) const;
|
||||
Status Route(const api::RouteParameters ¶ms,
|
||||
util::json::Object &result) const override final
|
||||
{
|
||||
auto facade = facade_provider->Get();
|
||||
auto algorithms = RoutingAlgorithms<AlgorithmT>{heaps, *facade};
|
||||
return route_plugin.HandleRequest(*facade, algorithms, params, result);
|
||||
}
|
||||
|
||||
Status Table(const api::TableParameters ¶ms,
|
||||
util::json::Object &result) const override final
|
||||
{
|
||||
auto facade = facade_provider->Get();
|
||||
auto algorithms = RoutingAlgorithms<AlgorithmT>{heaps, *facade};
|
||||
return table_plugin.HandleRequest(*facade, algorithms, params, result);
|
||||
}
|
||||
|
||||
Status Nearest(const api::NearestParameters ¶ms,
|
||||
util::json::Object &result) const override final
|
||||
{
|
||||
auto facade = facade_provider->Get();
|
||||
auto algorithms = RoutingAlgorithms<AlgorithmT>{heaps, *facade};
|
||||
return nearest_plugin.HandleRequest(*facade, algorithms, params, result);
|
||||
}
|
||||
|
||||
Status Trip(const api::TripParameters ¶ms, util::json::Object &result) const override final
|
||||
{
|
||||
auto facade = facade_provider->Get();
|
||||
auto algorithms = RoutingAlgorithms<AlgorithmT>{heaps, *facade};
|
||||
return trip_plugin.HandleRequest(*facade, algorithms, params, result);
|
||||
}
|
||||
|
||||
Status Match(const api::MatchParameters ¶ms,
|
||||
util::json::Object &result) const override final
|
||||
{
|
||||
auto facade = facade_provider->Get();
|
||||
auto algorithms = RoutingAlgorithms<AlgorithmT>{heaps, *facade};
|
||||
return match_plugin.HandleRequest(*facade, algorithms, params, result);
|
||||
}
|
||||
|
||||
Status Tile(const api::TileParameters ¶ms, std::string &result) const override final
|
||||
{
|
||||
auto facade = facade_provider->Get();
|
||||
auto algorithms = RoutingAlgorithms<AlgorithmT>{heaps, *facade};
|
||||
return tile_plugin.HandleRequest(*facade, algorithms, params, result);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<DataWatchdog> watchdog;
|
||||
std::unique_ptr<DataFacadeProvider<AlgorithmT>> facade_provider;
|
||||
mutable SearchEngineData heaps;
|
||||
|
||||
const plugins::ViaRoutePlugin route_plugin;
|
||||
const plugins::TablePlugin table_plugin;
|
||||
@ -57,10 +135,6 @@ class Engine final
|
||||
const plugins::TripPlugin trip_plugin;
|
||||
const plugins::MatchPlugin match_plugin;
|
||||
const plugins::TilePlugin tile_plugin;
|
||||
|
||||
// note in case of shared memory this will be empty, since the watchdog
|
||||
// will provide us with the up-to-date facade
|
||||
std::shared_ptr<const datafacade::BaseDataFacade> immutable_data_facade;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "engine/api/match_parameters.hpp"
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
|
||||
#include "engine/map_matching/bayes_classifier.hpp"
|
||||
#include "engine/routing_algorithms/map_matching.hpp"
|
||||
@ -24,23 +25,19 @@ class MatchPlugin : public BasePlugin
|
||||
using SubMatching = map_matching::SubMatching;
|
||||
using SubMatchingList = routing_algorithms::SubMatchingList;
|
||||
using CandidateLists = routing_algorithms::CandidateLists;
|
||||
static const constexpr double DEFAULT_GPS_PRECISION = 5;
|
||||
static const constexpr double RADIUS_MULTIPLIER = 3;
|
||||
|
||||
MatchPlugin(const int max_locations_map_matching)
|
||||
: map_matching(heaps, DEFAULT_GPS_PRECISION), shortest_path(heaps),
|
||||
max_locations_map_matching(max_locations_map_matching)
|
||||
: max_locations_map_matching(max_locations_map_matching)
|
||||
{
|
||||
}
|
||||
|
||||
Status HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::MatchParameters ¶meters,
|
||||
util::json::Object &json_result) const;
|
||||
|
||||
private:
|
||||
mutable SearchEngineData heaps;
|
||||
mutable routing_algorithms::MapMatching map_matching;
|
||||
mutable routing_algorithms::ShortestPathRouting shortest_path;
|
||||
const int max_locations_map_matching;
|
||||
};
|
||||
}
|
||||
|
@ -2,7 +2,9 @@
|
||||
#define NEAREST_HPP
|
||||
|
||||
#include "engine/api/nearest_parameters.hpp"
|
||||
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
#include "osrm/json_container.hpp"
|
||||
|
||||
namespace osrm
|
||||
@ -17,7 +19,8 @@ class NearestPlugin final : public BasePlugin
|
||||
public:
|
||||
explicit NearestPlugin(const int max_results);
|
||||
|
||||
Status HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::NearestParameters ¶ms,
|
||||
util::json::Object &result) const;
|
||||
|
||||
|
@ -273,14 +273,15 @@ class BasePlugin
|
||||
}
|
||||
|
||||
// we didn't find a fitting node, return error
|
||||
if (!phantom_node_pairs[i].first.IsValid(facade.GetNumberOfNodes()))
|
||||
if (!phantom_node_pairs[i].first.IsValid())
|
||||
{
|
||||
// TODO document why?
|
||||
// This ensures the list of phantom nodes only consists of valid nodes.
|
||||
// We can use this on the call-site to detect an error.
|
||||
phantom_node_pairs.pop_back();
|
||||
break;
|
||||
}
|
||||
BOOST_ASSERT(phantom_node_pairs[i].first.IsValid(facade.GetNumberOfNodes()));
|
||||
BOOST_ASSERT(phantom_node_pairs[i].second.IsValid(facade.GetNumberOfNodes()));
|
||||
BOOST_ASSERT(phantom_node_pairs[i].first.IsValid());
|
||||
BOOST_ASSERT(phantom_node_pairs[i].second.IsValid());
|
||||
}
|
||||
return phantom_node_pairs;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
|
||||
#include "engine/api/table_parameters.hpp"
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
#include "engine/routing_algorithms/many_to_many.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
@ -20,13 +21,12 @@ class TablePlugin final : public BasePlugin
|
||||
public:
|
||||
explicit TablePlugin(const int max_locations_distance_table);
|
||||
|
||||
Status HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::TableParameters ¶ms,
|
||||
util::json::Object &result) const;
|
||||
|
||||
private:
|
||||
mutable SearchEngineData heaps;
|
||||
mutable routing_algorithms::ManyToManyRouting distance_table;
|
||||
const int max_locations_distance_table;
|
||||
};
|
||||
}
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
#include "engine/api/tile_parameters.hpp"
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
#include "engine/routing_algorithms/routing_base.hpp"
|
||||
#include "engine/routing_algorithms/shortest_path.hpp"
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
* This plugin generates Mapbox Vector tiles that show the internal
|
||||
@ -26,7 +26,8 @@ namespace plugins
|
||||
class TilePlugin final : public BasePlugin
|
||||
{
|
||||
public:
|
||||
Status HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::TileParameters ¶meters,
|
||||
std::string &pbf_buffer) const;
|
||||
};
|
||||
|
@ -4,10 +4,9 @@
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
|
||||
#include "engine/api/trip_parameters.hpp"
|
||||
#include "engine/routing_algorithms/many_to_many.hpp"
|
||||
#include "engine/routing_algorithms/shortest_path.hpp"
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
|
||||
#include "osrm/json_container.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
@ -29,23 +28,18 @@ namespace plugins
|
||||
class TripPlugin final : public BasePlugin
|
||||
{
|
||||
private:
|
||||
mutable SearchEngineData heaps;
|
||||
mutable routing_algorithms::ShortestPathRouting shortest_path;
|
||||
mutable routing_algorithms::ManyToManyRouting duration_table;
|
||||
const int max_locations_trip;
|
||||
|
||||
InternalRouteResult ComputeRoute(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
InternalRouteResult ComputeRoute(const RoutingAlgorithmsInterface &algorithms,
|
||||
const std::vector<PhantomNode> &phantom_node_list,
|
||||
const std::vector<NodeID> &trip,
|
||||
const bool roundtrip) const;
|
||||
|
||||
public:
|
||||
explicit TripPlugin(const int max_locations_trip_)
|
||||
: shortest_path(heaps), duration_table(heaps), max_locations_trip(max_locations_trip_)
|
||||
{
|
||||
}
|
||||
explicit TripPlugin(const int max_locations_trip_) : max_locations_trip(max_locations_trip_) {}
|
||||
|
||||
Status HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::TripParameters ¶meters,
|
||||
util::json::Object &json_result) const;
|
||||
};
|
||||
|
@ -1,13 +1,11 @@
|
||||
#ifndef VIA_ROUTE_HPP
|
||||
#define VIA_ROUTE_HPP
|
||||
|
||||
#include "engine/api/route_api.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/plugins/plugin_base.hpp"
|
||||
|
||||
#include "engine/routing_algorithms/alternative_path.hpp"
|
||||
#include "engine/routing_algorithms/direct_shortest_path.hpp"
|
||||
#include "engine/routing_algorithms/shortest_path.hpp"
|
||||
#include "engine/api/route_api.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/json_container.hpp"
|
||||
|
||||
@ -28,16 +26,13 @@ namespace plugins
|
||||
class ViaRoutePlugin final : public BasePlugin
|
||||
{
|
||||
private:
|
||||
mutable SearchEngineData heaps;
|
||||
mutable routing_algorithms::ShortestPathRouting shortest_path;
|
||||
mutable routing_algorithms::AlternativeRouting alternative_path;
|
||||
mutable routing_algorithms::DirectShortestPathRouting direct_shortest_path;
|
||||
const int max_locations_viaroute;
|
||||
|
||||
public:
|
||||
explicit ViaRoutePlugin(int max_locations_viaroute);
|
||||
|
||||
Status HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::RouteParameters &route_parameters,
|
||||
util::json::Object &json_result) const;
|
||||
};
|
||||
|
125
include/engine/routing_algorithms.hpp
Normal file
125
include/engine/routing_algorithms.hpp
Normal file
@ -0,0 +1,125 @@
|
||||
#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 void AlternativeRouting(const PhantomNodes &phantom_node_pair,
|
||||
InternalRouteResult &raw_route_data) const = 0;
|
||||
|
||||
virtual void ShortestRouting(const std::vector<PhantomNodes> &phantom_node_pair,
|
||||
const boost::optional<bool> continue_straight_at_waypoint,
|
||||
InternalRouteResult &raw_route_data) const = 0;
|
||||
|
||||
virtual void DirectShortestPathRouting(const std::vector<PhantomNodes> &phantom_node_pair,
|
||||
InternalRouteResult &raw_route_data) const = 0;
|
||||
|
||||
virtual std::vector<EdgeWeight>
|
||||
ManyToManyRouting(const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) 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 = 0;
|
||||
|
||||
virtual std::vector<routing_algorithms::TurnData>
|
||||
TileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
|
||||
const std::vector<std::size_t> &sorted_edge_indexes) const = 0;
|
||||
|
||||
virtual bool HasAlternativeRouting() const = 0;
|
||||
};
|
||||
|
||||
// Short-lived object passed to each plugin in request to wrap routing algorithms
|
||||
template <typename AlgorithmT> class RoutingAlgorithms final : public RoutingAlgorithmsInterface
|
||||
{
|
||||
public:
|
||||
RoutingAlgorithms(SearchEngineData &heaps,
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade)
|
||||
: facade(facade), alternative_routing(heaps), shortest_path_routing(heaps),
|
||||
direct_shortest_path_routing(heaps), many_to_many_routing(heaps), map_matching(heaps)
|
||||
{
|
||||
}
|
||||
|
||||
void AlternativeRouting(const PhantomNodes &phantom_node_pair,
|
||||
InternalRouteResult &raw_route_data) const final override
|
||||
{
|
||||
alternative_routing(facade, phantom_node_pair, raw_route_data);
|
||||
}
|
||||
|
||||
void ShortestRouting(const std::vector<PhantomNodes> &phantom_node_pair,
|
||||
const boost::optional<bool> continue_straight_at_waypoint,
|
||||
InternalRouteResult &raw_route_data) const final override
|
||||
{
|
||||
shortest_path_routing(
|
||||
facade, phantom_node_pair, continue_straight_at_waypoint, raw_route_data);
|
||||
}
|
||||
|
||||
void DirectShortestPathRouting(const std::vector<PhantomNodes> &phantom_node_pair,
|
||||
InternalRouteResult &raw_route_data) const final override
|
||||
{
|
||||
direct_shortest_path_routing(facade, phantom_node_pair, raw_route_data);
|
||||
}
|
||||
|
||||
std::vector<EdgeWeight>
|
||||
ManyToManyRouting(const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const final override
|
||||
{
|
||||
return many_to_many_routing(facade, phantom_nodes, source_indices, target_indices);
|
||||
}
|
||||
|
||||
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 final override
|
||||
{
|
||||
return map_matching(
|
||||
facade, candidates_list, trace_coordinates, trace_timestamps, trace_gps_precision);
|
||||
}
|
||||
|
||||
std::vector<routing_algorithms::TurnData>
|
||||
TileTurns(const std::vector<datafacade::BaseDataFacade::RTreeLeaf> &edges,
|
||||
const std::vector<std::size_t> &sorted_edge_indexes) const final override
|
||||
{
|
||||
return tile_turns(facade, edges, sorted_edge_indexes);
|
||||
}
|
||||
|
||||
bool HasAlternativeRouting() const final override
|
||||
{
|
||||
return algorithm_trais::HasAlternativeRouting<AlgorithmT>()(facade);
|
||||
};
|
||||
|
||||
private:
|
||||
// Owned by shared-ptr passed to the query
|
||||
const datafacade::ContiguousInternalMemoryDataFacade<AlgorithmT> &facade;
|
||||
|
||||
mutable routing_algorithms::AlternativeRouting<AlgorithmT> alternative_routing;
|
||||
mutable routing_algorithms::ShortestPathRouting<AlgorithmT> shortest_path_routing;
|
||||
mutable routing_algorithms::DirectShortestPathRouting<AlgorithmT> direct_shortest_path_routing;
|
||||
mutable routing_algorithms::ManyToManyRouting<AlgorithmT> many_to_many_routing;
|
||||
mutable routing_algorithms::MapMatching<AlgorithmT> map_matching;
|
||||
routing_algorithms::TileTurns<AlgorithmT> tile_turns;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/routing_algorithms/routing_base.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
|
||||
@ -27,9 +29,12 @@ const double constexpr VIAPATH_ALPHA = 0.10;
|
||||
const double constexpr VIAPATH_EPSILON = 0.15; // alternative at most 15% longer
|
||||
const double constexpr VIAPATH_GAMMA = 0.75; // alternative shares at most 75% with the shortest.
|
||||
|
||||
class AlternativeRouting final : private BasicRoutingInterface
|
||||
template <typename AlgorithmT> class AlternativeRouting;
|
||||
|
||||
template <> class AlternativeRouting<algorithm::CH> final : private BasicRouting<algorithm::CH>
|
||||
{
|
||||
using super = BasicRoutingInterface;
|
||||
using super = BasicRouting<algorithm::CH>;
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>;
|
||||
using QueryHeap = SearchEngineData::QueryHeap;
|
||||
using SearchSpaceEdge = std::pair<NodeID, NodeID>;
|
||||
|
||||
@ -59,7 +64,7 @@ class AlternativeRouting final : private BasicRoutingInterface
|
||||
|
||||
virtual ~AlternativeRouting() {}
|
||||
|
||||
void operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void operator()(const FacadeT &facade,
|
||||
const PhantomNodes &phantom_node_pair,
|
||||
InternalRouteResult &raw_route_data);
|
||||
|
||||
@ -77,8 +82,7 @@ class AlternativeRouting final : private BasicRoutingInterface
|
||||
// compute and unpack <s,..,v> and <v,..,t> by exploring search spaces
|
||||
// from v and intersecting against queues. only half-searches have to be
|
||||
// done at this stage
|
||||
void
|
||||
ComputeLengthAndSharingOfViaPath(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ComputeLengthAndSharingOfViaPath(const FacadeT &facade,
|
||||
const NodeID via_node,
|
||||
int *real_length_of_via_path,
|
||||
int *sharing_of_via_path,
|
||||
@ -87,7 +91,7 @@ class AlternativeRouting final : private BasicRoutingInterface
|
||||
|
||||
// todo: reorder parameters
|
||||
template <bool is_forward_directed>
|
||||
void AlternativeRoutingStep(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void AlternativeRoutingStep(const FacadeT &facade,
|
||||
QueryHeap &heap1,
|
||||
QueryHeap &heap2,
|
||||
NodeID *middle_node,
|
||||
@ -150,14 +154,14 @@ class AlternativeRouting final : private BasicRoutingInterface
|
||||
}
|
||||
}
|
||||
|
||||
for (auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const auto &data = facade.GetEdgeData(edge);
|
||||
const bool edge_is_forward_directed =
|
||||
(is_forward_directed ? data.forward : data.backward);
|
||||
if (edge_is_forward_directed)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
|
||||
BOOST_ASSERT(edge_weight > 0);
|
||||
@ -181,7 +185,7 @@ class AlternativeRouting final : private BasicRoutingInterface
|
||||
}
|
||||
|
||||
// conduct T-Test
|
||||
bool ViaNodeCandidatePassesTTest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
bool ViaNodeCandidatePassesTTest(const FacadeT &facade,
|
||||
QueryHeap &existing_forward_heap,
|
||||
QueryHeap &existing_reverse_heap,
|
||||
QueryHeap &new_forward_heap,
|
||||
|
@ -1,15 +1,10 @@
|
||||
#ifndef DIRECT_SHORTEST_PATH_HPP
|
||||
#define DIRECT_SHORTEST_PATH_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/routing_algorithms/routing_base.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/timing_util.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
namespace osrm
|
||||
@ -19,15 +14,19 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
template <typename AlgorithmT> class DirectShortestPathRouting;
|
||||
|
||||
/// 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.
|
||||
class DirectShortestPathRouting final : public BasicRoutingInterface
|
||||
template <>
|
||||
class DirectShortestPathRouting<algorithm::CH> final : public BasicRouting<algorithm::CH>
|
||||
{
|
||||
using super = BasicRoutingInterface;
|
||||
using super = BasicRouting<algorithm::CH>;
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>;
|
||||
using QueryHeap = SearchEngineData::QueryHeap;
|
||||
SearchEngineData &engine_working_data;
|
||||
|
||||
@ -39,7 +38,7 @@ class DirectShortestPathRouting final : public BasicRoutingInterface
|
||||
|
||||
~DirectShortestPathRouting() {}
|
||||
|
||||
void operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
InternalRouteResult &raw_route_data) const;
|
||||
};
|
||||
|
@ -1,8 +1,9 @@
|
||||
#ifndef MANY_TO_MANY_ROUTING_HPP
|
||||
#define MANY_TO_MANY_ROUTING_HPP
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/routing_algorithms/routing_base.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@ -20,9 +21,12 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
class ManyToManyRouting final : public BasicRoutingInterface
|
||||
template <typename AlgorithmT> class ManyToManyRouting;
|
||||
|
||||
template <> class ManyToManyRouting<algorithm::CH> final : public BasicRouting<algorithm::CH>
|
||||
{
|
||||
using super = BasicRoutingInterface;
|
||||
using super = BasicRouting<algorithm::CH>;
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>;
|
||||
using QueryHeap = SearchEngineData::ManyToManyQueryHeap;
|
||||
SearchEngineData &engine_working_data;
|
||||
|
||||
@ -46,13 +50,12 @@ class ManyToManyRouting final : public BasicRoutingInterface
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<EdgeWeight>
|
||||
operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
std::vector<EdgeWeight> operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const;
|
||||
|
||||
void ForwardRoutingStep(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ForwardRoutingStep(const FacadeT &facade,
|
||||
const unsigned row_idx,
|
||||
const unsigned number_of_targets,
|
||||
QueryHeap &query_heap,
|
||||
@ -60,25 +63,25 @@ class ManyToManyRouting final : public BasicRoutingInterface
|
||||
std::vector<EdgeWeight> &weights_table,
|
||||
std::vector<EdgeWeight> &durations_table) const;
|
||||
|
||||
void BackwardRoutingStep(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void BackwardRoutingStep(const FacadeT &facade,
|
||||
const unsigned column_idx,
|
||||
QueryHeap &query_heap,
|
||||
SearchSpaceWithBuckets &search_space_with_buckets) const;
|
||||
|
||||
template <bool forward_direction>
|
||||
inline void RelaxOutgoingEdges(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
inline void RelaxOutgoingEdges(const FacadeT &facade,
|
||||
const NodeID node,
|
||||
const EdgeWeight weight,
|
||||
const EdgeWeight duration,
|
||||
QueryHeap &query_heap) const
|
||||
{
|
||||
for (auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const auto &data = facade->GetEdgeData(edge);
|
||||
const auto &data = facade.GetEdgeData(edge);
|
||||
const bool direction_flag = (forward_direction ? data.forward : data.backward);
|
||||
if (direction_flag)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
const EdgeWeight edge_duration = data.duration;
|
||||
|
||||
@ -104,18 +107,18 @@ class ManyToManyRouting final : public BasicRoutingInterface
|
||||
|
||||
// Stalling
|
||||
template <bool forward_direction>
|
||||
inline bool StallAtNode(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
inline bool StallAtNode(const FacadeT &facade,
|
||||
const NodeID node,
|
||||
const EdgeWeight weight,
|
||||
QueryHeap &query_heap) const
|
||||
{
|
||||
for (auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const auto &data = facade->GetEdgeData(edge);
|
||||
const auto &data = facade.GetEdgeData(edge);
|
||||
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
|
||||
if (reverse_flag)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
||||
if (query_heap.WasInserted(to))
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef MAP_MATCHING_HPP
|
||||
#define MAP_MATCHING_HPP
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/routing_algorithms/routing_base.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/map_matching/hidden_markov_model.hpp"
|
||||
#include "engine/map_matching/matching_confidence.hpp"
|
||||
#include "engine/map_matching/sub_matching.hpp"
|
||||
@ -37,11 +37,15 @@ using SubMatchingList = std::vector<map_matching::SubMatching>;
|
||||
constexpr static const unsigned MAX_BROKEN_STATES = 10;
|
||||
static const constexpr double MATCHING_BETA = 10;
|
||||
constexpr static const double MAX_DISTANCE_DELTA = 2000.;
|
||||
static const constexpr double DEFAULT_GPS_PRECISION = 5;
|
||||
|
||||
template <typename AlgorithmT> class MapMatching;
|
||||
|
||||
// implements a hidden markov model map matching algorithm
|
||||
class MapMatching final : public BasicRoutingInterface
|
||||
template <> class MapMatching<algorithm::CH> final : public BasicRouting<algorithm::CH>
|
||||
{
|
||||
using super = BasicRoutingInterface;
|
||||
using super = BasicRouting<algorithm::CH>;
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>;
|
||||
using QueryHeap = SearchEngineData::QueryHeap;
|
||||
SearchEngineData &engine_working_data;
|
||||
map_matching::EmissionLogProbability default_emission_log_probability;
|
||||
@ -52,15 +56,15 @@ class MapMatching final : public BasicRoutingInterface
|
||||
unsigned GetMedianSampleTime(const std::vector<unsigned> ×tamps) const;
|
||||
|
||||
public:
|
||||
MapMatching(SearchEngineData &engine_working_data, const double default_gps_precision)
|
||||
MapMatching(SearchEngineData &engine_working_data)
|
||||
: engine_working_data(engine_working_data),
|
||||
default_emission_log_probability(default_gps_precision),
|
||||
default_emission_log_probability(DEFAULT_GPS_PRECISION),
|
||||
transition_log_probability(MATCHING_BETA)
|
||||
{
|
||||
}
|
||||
|
||||
SubMatchingList
|
||||
operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
operator()(const FacadeT &facade,
|
||||
const CandidateLists &candidates_list,
|
||||
const std::vector<util::Coordinate> &trace_coordinates,
|
||||
const std::vector<unsigned> &trace_timestamps,
|
||||
|
@ -2,10 +2,13 @@
|
||||
#define ROUTING_BASE_HPP
|
||||
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
|
||||
#include "engine/edge_unpacker.hpp"
|
||||
#include "engine/internal_route_result.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/turn_bearing.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
@ -32,10 +35,15 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
class BasicRoutingInterface
|
||||
template <typename AlgorithmT> class BasicRouting;
|
||||
|
||||
// TODO: There is no reason these functions are contained in a class other then for namespace
|
||||
// purposes. This should be a namespace with free functions.
|
||||
template <> class BasicRouting<algorithm::CH>
|
||||
{
|
||||
protected:
|
||||
using EdgeData = datafacade::BaseDataFacade::EdgeData;
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>;
|
||||
using EdgeData = typename FacadeT::EdgeData;
|
||||
|
||||
public:
|
||||
/*
|
||||
@ -67,7 +75,7 @@ class BasicRoutingInterface
|
||||
Since we are dealing with a graph that contains _negative_ edges,
|
||||
we need to add an offset to the termination criterion.
|
||||
*/
|
||||
void RoutingStep(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void RoutingStep(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
NodeID &middle_node_id,
|
||||
@ -78,17 +86,15 @@ class BasicRoutingInterface
|
||||
const bool force_loop_forward,
|
||||
const bool force_loop_reverse) const;
|
||||
|
||||
template <bool UseDuration>
|
||||
EdgeWeight GetLoopWeight(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
NodeID node) const
|
||||
template <bool UseDuration> EdgeWeight GetLoopWeight(const FacadeT &facade, NodeID node) const
|
||||
{
|
||||
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
|
||||
for (auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const auto &data = facade->GetEdgeData(edge);
|
||||
const auto &data = facade.GetEdgeData(edge);
|
||||
if (data.forward)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
if (to == node)
|
||||
{
|
||||
const auto value = UseDuration ? data.duration : data.weight;
|
||||
@ -100,7 +106,7 @@ class BasicRoutingInterface
|
||||
}
|
||||
|
||||
template <typename RandomIter>
|
||||
void UnpackPath(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void UnpackPath(const FacadeT &facade,
|
||||
RandomIter packed_path_begin,
|
||||
RandomIter packed_path_end,
|
||||
const PhantomNodes &phantom_node_pair,
|
||||
@ -120,7 +126,7 @@ class BasicRoutingInterface
|
||||
*std::prev(packed_path_end) == phantom_node_pair.target_phantom.reverse_segment_id.id);
|
||||
|
||||
UnpackCHPath(
|
||||
*facade,
|
||||
facade,
|
||||
packed_path_begin,
|
||||
packed_path_end,
|
||||
[this,
|
||||
@ -132,14 +138,14 @@ class BasicRoutingInterface
|
||||
const EdgeData &edge_data) {
|
||||
|
||||
BOOST_ASSERT_MSG(!edge_data.shortcut, "original edge flagged as shortcut");
|
||||
const auto name_index = facade->GetNameIndexFromEdgeID(edge_data.id);
|
||||
const auto turn_instruction = facade->GetTurnInstructionForEdgeID(edge_data.id);
|
||||
const auto name_index = facade.GetNameIndexFromEdgeID(edge_data.id);
|
||||
const auto turn_instruction = facade.GetTurnInstructionForEdgeID(edge_data.id);
|
||||
const extractor::TravelMode travel_mode =
|
||||
(unpacked_path.empty() && start_traversed_in_reverse)
|
||||
? phantom_node_pair.source_phantom.backward_travel_mode
|
||||
: facade->GetTravelModeForEdgeID(edge_data.id);
|
||||
: facade.GetTravelModeForEdgeID(edge_data.id);
|
||||
|
||||
const auto geometry_index = facade->GetGeometryIndexForEdgeID(edge_data.id);
|
||||
const auto geometry_index = facade.GetGeometryIndexForEdgeID(edge_data.id);
|
||||
std::vector<NodeID> id_vector;
|
||||
|
||||
std::vector<EdgeWeight> weight_vector;
|
||||
@ -147,19 +153,17 @@ class BasicRoutingInterface
|
||||
std::vector<DatasourceID> datasource_vector;
|
||||
if (geometry_index.forward)
|
||||
{
|
||||
id_vector = facade->GetUncompressedForwardGeometry(geometry_index.id);
|
||||
weight_vector = facade->GetUncompressedForwardWeights(geometry_index.id);
|
||||
duration_vector = facade->GetUncompressedForwardDurations(geometry_index.id);
|
||||
datasource_vector =
|
||||
facade->GetUncompressedForwardDatasources(geometry_index.id);
|
||||
id_vector = facade.GetUncompressedForwardGeometry(geometry_index.id);
|
||||
weight_vector = facade.GetUncompressedForwardWeights(geometry_index.id);
|
||||
duration_vector = facade.GetUncompressedForwardDurations(geometry_index.id);
|
||||
datasource_vector = facade.GetUncompressedForwardDatasources(geometry_index.id);
|
||||
}
|
||||
else
|
||||
{
|
||||
id_vector = facade->GetUncompressedReverseGeometry(geometry_index.id);
|
||||
weight_vector = facade->GetUncompressedReverseWeights(geometry_index.id);
|
||||
duration_vector = facade->GetUncompressedReverseDurations(geometry_index.id);
|
||||
datasource_vector =
|
||||
facade->GetUncompressedReverseDatasources(geometry_index.id);
|
||||
id_vector = facade.GetUncompressedReverseGeometry(geometry_index.id);
|
||||
weight_vector = facade.GetUncompressedReverseWeights(geometry_index.id);
|
||||
duration_vector = facade.GetUncompressedReverseDurations(geometry_index.id);
|
||||
datasource_vector = facade.GetUncompressedReverseDatasources(geometry_index.id);
|
||||
}
|
||||
BOOST_ASSERT(id_vector.size() > 0);
|
||||
BOOST_ASSERT(datasource_vector.size() > 0);
|
||||
@ -194,17 +198,17 @@ class BasicRoutingInterface
|
||||
util::guidance::TurnBearing(0)});
|
||||
}
|
||||
BOOST_ASSERT(unpacked_path.size() > 0);
|
||||
if (facade->hasLaneData(edge_data.id))
|
||||
unpacked_path.back().lane_data = facade->GetLaneData(edge_data.id);
|
||||
if (facade.hasLaneData(edge_data.id))
|
||||
unpacked_path.back().lane_data = facade.GetLaneData(edge_data.id);
|
||||
|
||||
unpacked_path.back().entry_classid = facade->GetEntryClassID(edge_data.id);
|
||||
unpacked_path.back().entry_classid = facade.GetEntryClassID(edge_data.id);
|
||||
unpacked_path.back().turn_instruction = turn_instruction;
|
||||
unpacked_path.back().duration_until_turn +=
|
||||
facade->GetDurationPenaltyForEdgeID(edge_data.id);
|
||||
facade.GetDurationPenaltyForEdgeID(edge_data.id);
|
||||
unpacked_path.back().weight_until_turn +=
|
||||
facade->GetWeightPenaltyForEdgeID(edge_data.id);
|
||||
unpacked_path.back().pre_turn_bearing = facade->PreTurnBearing(edge_data.id);
|
||||
unpacked_path.back().post_turn_bearing = facade->PostTurnBearing(edge_data.id);
|
||||
facade.GetWeightPenaltyForEdgeID(edge_data.id);
|
||||
unpacked_path.back().pre_turn_bearing = facade.PreTurnBearing(edge_data.id);
|
||||
unpacked_path.back().post_turn_bearing = facade.PostTurnBearing(edge_data.id);
|
||||
});
|
||||
|
||||
std::size_t start_index = 0, end_index = 0;
|
||||
@ -218,16 +222,16 @@ class BasicRoutingInterface
|
||||
|
||||
if (target_traversed_in_reverse)
|
||||
{
|
||||
id_vector = facade->GetUncompressedReverseGeometry(
|
||||
id_vector = facade.GetUncompressedReverseGeometry(
|
||||
phantom_node_pair.target_phantom.packed_geometry_id);
|
||||
|
||||
weight_vector = facade->GetUncompressedReverseWeights(
|
||||
weight_vector = facade.GetUncompressedReverseWeights(
|
||||
phantom_node_pair.target_phantom.packed_geometry_id);
|
||||
|
||||
duration_vector = facade->GetUncompressedReverseDurations(
|
||||
duration_vector = facade.GetUncompressedReverseDurations(
|
||||
phantom_node_pair.target_phantom.packed_geometry_id);
|
||||
|
||||
datasource_vector = facade->GetUncompressedReverseDatasources(
|
||||
datasource_vector = facade.GetUncompressedReverseDatasources(
|
||||
phantom_node_pair.target_phantom.packed_geometry_id);
|
||||
|
||||
if (is_local_path)
|
||||
@ -246,16 +250,16 @@ class BasicRoutingInterface
|
||||
}
|
||||
end_index = phantom_node_pair.target_phantom.fwd_segment_position;
|
||||
|
||||
id_vector = facade->GetUncompressedForwardGeometry(
|
||||
id_vector = facade.GetUncompressedForwardGeometry(
|
||||
phantom_node_pair.target_phantom.packed_geometry_id);
|
||||
|
||||
weight_vector = facade->GetUncompressedForwardWeights(
|
||||
weight_vector = facade.GetUncompressedForwardWeights(
|
||||
phantom_node_pair.target_phantom.packed_geometry_id);
|
||||
|
||||
duration_vector = facade->GetUncompressedForwardDurations(
|
||||
duration_vector = facade.GetUncompressedForwardDurations(
|
||||
phantom_node_pair.target_phantom.packed_geometry_id);
|
||||
|
||||
datasource_vector = facade->GetUncompressedForwardDatasources(
|
||||
datasource_vector = facade.GetUncompressedForwardDatasources(
|
||||
phantom_node_pair.target_phantom.packed_geometry_id);
|
||||
}
|
||||
|
||||
@ -339,7 +343,7 @@ class BasicRoutingInterface
|
||||
* @param to the node the CH edge finishes at
|
||||
* @param unpacked_path the sequence of original NodeIDs that make up the expanded CH edge
|
||||
*/
|
||||
void UnpackEdge(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void UnpackEdge(const FacadeT &facade,
|
||||
const NodeID from,
|
||||
const NodeID to,
|
||||
std::vector<NodeID> &unpacked_path) const;
|
||||
@ -365,7 +369,7 @@ class BasicRoutingInterface
|
||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||
// requires
|
||||
// a force loop, if the heaps have been initialized with positive offsets.
|
||||
void Search(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void Search(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
std::int32_t &weight,
|
||||
@ -383,7 +387,7 @@ class BasicRoutingInterface
|
||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||
// requires
|
||||
// a force loop, if the heaps have been initialized with positive offsets.
|
||||
void SearchWithCore(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void SearchWithCore(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
@ -400,7 +404,7 @@ class BasicRoutingInterface
|
||||
bool NeedsLoopBackwards(const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const;
|
||||
|
||||
double GetPathDistance(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
double GetPathDistance(const FacadeT &facade,
|
||||
const std::vector<NodeID> &packed_path,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const;
|
||||
@ -408,8 +412,7 @@ class BasicRoutingInterface
|
||||
// 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 std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
double GetNetworkDistanceWithCore(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
@ -421,7 +424,7 @@ class BasicRoutingInterface
|
||||
// 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 GetNetworkDistance(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
double GetNetworkDistance(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
const PhantomNode &source_phantom,
|
||||
|
@ -1,13 +1,11 @@
|
||||
#ifndef SHORTEST_PATH_HPP
|
||||
#define SHORTEST_PATH_HPP
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/routing_algorithms/routing_base.hpp"
|
||||
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/integer_range.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
@ -20,9 +18,12 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
class ShortestPathRouting final : public BasicRoutingInterface
|
||||
template <typename AlgorithmT> class ShortestPathRouting;
|
||||
|
||||
template <> class ShortestPathRouting<algorithm::CH> final : public BasicRouting<algorithm::CH>
|
||||
{
|
||||
using super = BasicRoutingInterface;
|
||||
using super = BasicRouting<algorithm::CH>;
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>;
|
||||
using QueryHeap = SearchEngineData::QueryHeap;
|
||||
SearchEngineData &engine_working_data;
|
||||
const static constexpr bool DO_NOT_FORCE_LOOP = false;
|
||||
@ -37,7 +38,7 @@ class ShortestPathRouting final : public BasicRoutingInterface
|
||||
|
||||
// allows a uturn at the target_phantom
|
||||
// searches source forward/reverse -> target forward/reverse
|
||||
void SearchWithUTurn(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void SearchWithUTurn(const FacadeT &facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
@ -56,7 +57,7 @@ class ShortestPathRouting final : public BasicRoutingInterface
|
||||
// searches shortest path between:
|
||||
// source forward/reverse -> target forward
|
||||
// source forward/reverse -> target reverse
|
||||
void Search(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void Search(const FacadeT &facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
@ -74,14 +75,14 @@ class ShortestPathRouting final : public BasicRoutingInterface
|
||||
std::vector<NodeID> &leg_packed_path_forward,
|
||||
std::vector<NodeID> &leg_packed_path_reverse) const;
|
||||
|
||||
void UnpackLegs(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void UnpackLegs(const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const std::vector<NodeID> &total_packed_path,
|
||||
const std::vector<std::size_t> &packed_leg_begin,
|
||||
const int shortest_path_length,
|
||||
InternalRouteResult &raw_route_data) const;
|
||||
|
||||
void operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const boost::optional<bool> continue_straight_at_waypoint,
|
||||
InternalRouteResult &raw_route_data) const;
|
||||
|
46
include/engine/routing_algorithms/tile_turns.hpp
Normal file
46
include/engine/routing_algorithms/tile_turns.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef OSRM_ENGINE_ROUTING_ALGORITHMS_TILE_TURNS_HPP
|
||||
#define OSRM_ENGINE_ROUTING_ALGORITHMS_TILE_TURNS_HPP
|
||||
|
||||
#include "engine/routing_algorithms/routing_base.hpp"
|
||||
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/search_engine_data.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
template <typename AlgorithmT> class TileTurns;
|
||||
|
||||
// Used to accumulate all the information we want in the tile about a turn.
|
||||
struct TurnData final
|
||||
{
|
||||
const util::Coordinate coordinate;
|
||||
const int in_angle;
|
||||
const int turn_angle;
|
||||
const int weight;
|
||||
};
|
||||
|
||||
/// This class is used to extract turn information for the tile plugin from a CH graph
|
||||
template <> class TileTurns<algorithm::CH> final : public BasicRouting<algorithm::CH>
|
||||
{
|
||||
using super = BasicRouting<algorithm::CH>;
|
||||
using FacadeT = datafacade::ContiguousInternalMemoryDataFacade<algorithm::CH>;
|
||||
|
||||
using RTreeLeaf = datafacade::BaseDataFacade::RTreeLeaf;
|
||||
|
||||
public:
|
||||
std::vector<TurnData> operator()(const FacadeT &facade,
|
||||
const std::vector<RTreeLeaf> &edges,
|
||||
const std::vector<std::size_t> &sorted_edge_indexes) const;
|
||||
};
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
||||
|
||||
#endif
|
@ -23,7 +23,7 @@ namespace trip
|
||||
{
|
||||
|
||||
// computes the distance of a given permutation
|
||||
EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_table,
|
||||
inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_table,
|
||||
const std::vector<NodeID> &location_order,
|
||||
const EdgeWeight min_route_dist,
|
||||
const std::size_t number_of_locations)
|
||||
@ -59,7 +59,7 @@ EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_table,
|
||||
}
|
||||
|
||||
// computes the route by computing all permutations and selecting the shortest
|
||||
std::vector<NodeID> BruteForceTrip(const std::size_t number_of_locations,
|
||||
inline std::vector<NodeID> BruteForceTrip(const std::size_t number_of_locations,
|
||||
const util::DistTableWrapper<EdgeWeight> &dist_table)
|
||||
{
|
||||
// set initial order in which nodes are visited to 0, 1, 2, 3, ...
|
||||
|
@ -23,7 +23,7 @@ namespace trip
|
||||
// given a route and a new location, find the best place of insertion and
|
||||
// check the distance of roundtrip when the new location is additionally visited
|
||||
using NodeIDIter = std::vector<NodeID>::iterator;
|
||||
std::pair<EdgeWeight, NodeIDIter>
|
||||
inline std::pair<EdgeWeight, NodeIDIter>
|
||||
GetShortestRoundTrip(const NodeID new_loc,
|
||||
const util::DistTableWrapper<EdgeWeight> &dist_table,
|
||||
const std::size_t number_of_locations,
|
||||
@ -76,7 +76,7 @@ GetShortestRoundTrip(const NodeID new_loc,
|
||||
}
|
||||
|
||||
// given two initial start nodes, find a roundtrip route using the farthest insertion algorithm
|
||||
std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
|
||||
inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
|
||||
const util::DistTableWrapper<EdgeWeight> &dist_table,
|
||||
const NodeID &start1,
|
||||
const NodeID &start2)
|
||||
@ -134,7 +134,8 @@ std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
|
||||
return route;
|
||||
}
|
||||
|
||||
std::vector<NodeID> FarthestInsertionTrip(const std::size_t number_of_locations,
|
||||
inline std::vector<NodeID>
|
||||
FarthestInsertionTrip(const std::size_t number_of_locations,
|
||||
const util::DistTableWrapper<EdgeWeight> &dist_table)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -131,7 +131,7 @@ class OSRM final
|
||||
Status Tile(const TileParameters ¶meters, std::string &result) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<engine::Engine> engine_;
|
||||
std::unique_ptr<engine::EngineInterface> engine_;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ struct MatchParameters;
|
||||
struct TileParameters;
|
||||
} // ns api
|
||||
|
||||
class Engine;
|
||||
class EngineInterface;
|
||||
struct EngineConfig;
|
||||
} // ns engine
|
||||
} // ns osrm
|
||||
|
@ -21,8 +21,8 @@ const constexpr char CANARY[4] = {'O', 'S', 'R', 'M'};
|
||||
const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
|
||||
"NAME_ID_LIST",
|
||||
"VIA_NODE_LIST",
|
||||
"GRAPH_NODE_LIST",
|
||||
"GRAPH_EDGE_LIST",
|
||||
"CH_GRAPH_NODE_LIST",
|
||||
"CH_GRAPH_EDGE_LIST",
|
||||
"COORDINATE_LIST",
|
||||
"OSM_NODE_ID_LIST",
|
||||
"TURN_INSTRUCTION",
|
||||
@ -38,7 +38,7 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA",
|
||||
"HSGR_CHECKSUM",
|
||||
"TIMESTAMP",
|
||||
"FILE_INDEX_PATH",
|
||||
"CORE_MARKER",
|
||||
"CH_CORE_MARKER",
|
||||
"DATASOURCES_LIST",
|
||||
"DATASOURCE_NAME_DATA",
|
||||
"DATASOURCE_NAME_OFFSETS",
|
||||
@ -65,8 +65,8 @@ struct DataLayout
|
||||
NAME_CHAR_DATA = 0,
|
||||
NAME_ID_LIST,
|
||||
VIA_NODE_LIST,
|
||||
GRAPH_NODE_LIST,
|
||||
GRAPH_EDGE_LIST,
|
||||
CH_GRAPH_NODE_LIST,
|
||||
CH_GRAPH_EDGE_LIST,
|
||||
COORDINATE_LIST,
|
||||
OSM_NODE_ID_LIST,
|
||||
TURN_INSTRUCTION,
|
||||
@ -82,7 +82,7 @@ struct DataLayout
|
||||
HSGR_CHECKSUM,
|
||||
TIMESTAMP,
|
||||
FILE_INDEX_PATH,
|
||||
CORE_MARKER,
|
||||
CH_CORE_MARKER,
|
||||
DATASOURCES_LIST,
|
||||
DATASOURCE_NAME_DATA,
|
||||
DATASOURCE_NAME_OFFSETS,
|
||||
@ -121,7 +121,7 @@ struct DataLayout
|
||||
inline uint64_t GetBlockSize(BlockID bid) const
|
||||
{
|
||||
// special bit encoding
|
||||
if (bid == CORE_MARKER)
|
||||
if (bid == CH_CORE_MARKER)
|
||||
{
|
||||
return (num_entries[bid] / 32 + 1) * entry_size[bid];
|
||||
}
|
||||
|
@ -1,110 +0,0 @@
|
||||
#include "engine/engine.hpp"
|
||||
#include "engine/api/route_parameters.hpp"
|
||||
#include "engine/engine_config.hpp"
|
||||
#include "engine/status.hpp"
|
||||
|
||||
#include "engine/datafacade/contiguous_internalmem_datafacade.hpp"
|
||||
#include "engine/datafacade/process_memory_allocator.hpp"
|
||||
|
||||
#include "util/log.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
// Abstracted away the query locking into a template function
|
||||
// Works the same for every plugin.
|
||||
template <typename ParameterT, typename PluginT, typename ResultT>
|
||||
osrm::engine::Status
|
||||
RunQuery(const std::unique_ptr<osrm::engine::DataWatchdog> &watchdog,
|
||||
const std::shared_ptr<const osrm::engine::datafacade::BaseDataFacade> &immutable_facade,
|
||||
const ParameterT ¶meters,
|
||||
PluginT &plugin,
|
||||
ResultT &result)
|
||||
{
|
||||
if (watchdog)
|
||||
{
|
||||
BOOST_ASSERT(!immutable_facade);
|
||||
auto facade = watchdog->GetDataFacade();
|
||||
|
||||
return plugin.HandleRequest(facade, parameters, result);
|
||||
}
|
||||
|
||||
BOOST_ASSERT(immutable_facade);
|
||||
|
||||
return plugin.HandleRequest(immutable_facade, parameters, result);
|
||||
}
|
||||
|
||||
} // anon. ns
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
|
||||
Engine::Engine(const EngineConfig &config)
|
||||
: route_plugin(config.max_locations_viaroute), //
|
||||
table_plugin(config.max_locations_distance_table), //
|
||||
nearest_plugin(config.max_results_nearest), //
|
||||
trip_plugin(config.max_locations_trip), //
|
||||
match_plugin(config.max_locations_map_matching), //
|
||||
tile_plugin() //
|
||||
|
||||
{
|
||||
if (config.use_shared_memory)
|
||||
{
|
||||
watchdog = std::make_unique<DataWatchdog>();
|
||||
BOOST_ASSERT(watchdog);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!config.storage_config.IsValid())
|
||||
{
|
||||
throw util::exception("Invalid file paths given!" + SOURCE_REF);
|
||||
}
|
||||
auto allocator =
|
||||
std::make_unique<datafacade::ProcessMemoryAllocator>(config.storage_config);
|
||||
immutable_data_facade =
|
||||
std::make_shared<const datafacade::ContiguousInternalMemoryDataFacade>(
|
||||
std::move(allocator));
|
||||
}
|
||||
}
|
||||
|
||||
Status Engine::Route(const api::RouteParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(watchdog, immutable_data_facade, params, route_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Table(const api::TableParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(watchdog, immutable_data_facade, params, table_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Nearest(const api::NearestParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(watchdog, immutable_data_facade, params, nearest_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Trip(const api::TripParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(watchdog, immutable_data_facade, params, trip_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Match(const api::MatchParameters ¶ms, util::json::Object &result) const
|
||||
{
|
||||
return RunQuery(watchdog, immutable_data_facade, params, match_plugin, result);
|
||||
}
|
||||
|
||||
Status Engine::Tile(const api::TileParameters ¶ms, std::string &result) const
|
||||
{
|
||||
return RunQuery(watchdog, immutable_data_facade, params, tile_plugin, result);
|
||||
}
|
||||
|
||||
} // engine ns
|
||||
} // osrm ns
|
@ -19,8 +19,10 @@ bool Hint::IsValid(const util::Coordinate new_input_coordinates,
|
||||
{
|
||||
auto is_same_input_coordinate = new_input_coordinates.lon == phantom.input_location.lon &&
|
||||
new_input_coordinates.lat == phantom.input_location.lat;
|
||||
return is_same_input_coordinate && phantom.IsValid(facade.GetNumberOfNodes()) &&
|
||||
facade.GetCheckSum() == data_checksum;
|
||||
// FIXME this does not use the number of nodes to validate the phantom because
|
||||
// GetNumberOfNodes()
|
||||
// depends on the graph which is algorithm dependent
|
||||
return is_same_input_coordinate && phantom.IsValid() && facade.GetCheckSum() == data_checksum;
|
||||
}
|
||||
|
||||
std::string Hint::ToBase64() const
|
||||
|
@ -108,7 +108,8 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
|
||||
}
|
||||
}
|
||||
|
||||
Status MatchPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status MatchPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::MatchParameters ¶meters,
|
||||
util::json::Object &json_result) const
|
||||
{
|
||||
@ -144,7 +145,7 @@ Status MatchPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDa
|
||||
if (parameters.radiuses.empty())
|
||||
{
|
||||
search_radiuses.resize(parameters.coordinates.size(),
|
||||
DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER);
|
||||
routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -159,13 +160,13 @@ Status MatchPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDa
|
||||
}
|
||||
else
|
||||
{
|
||||
return DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER;
|
||||
return routing_algorithms::DEFAULT_GPS_PRECISION * RADIUS_MULTIPLIER;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
auto candidates_lists = GetPhantomNodesInRange(*facade, parameters, search_radiuses);
|
||||
auto candidates_lists = GetPhantomNodesInRange(facade, parameters, search_radiuses);
|
||||
|
||||
filterCandidates(parameters.coordinates, candidates_lists);
|
||||
if (std::all_of(candidates_lists.begin(),
|
||||
@ -180,11 +181,8 @@ Status MatchPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDa
|
||||
}
|
||||
|
||||
// call the actual map matching
|
||||
SubMatchingList sub_matchings = map_matching(facade,
|
||||
candidates_lists,
|
||||
parameters.coordinates,
|
||||
parameters.timestamps,
|
||||
parameters.radiuses);
|
||||
SubMatchingList sub_matchings = algorithms.MapMatching(
|
||||
candidates_lists, parameters.coordinates, parameters.timestamps, parameters.radiuses);
|
||||
|
||||
if (sub_matchings.size() == 0)
|
||||
{
|
||||
@ -210,12 +208,12 @@ Status MatchPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDa
|
||||
// force uturns to be on, since we split the phantom nodes anyway and only have
|
||||
// bi-directional
|
||||
// phantom nodes for possible uturns
|
||||
shortest_path(
|
||||
facade, sub_routes[index].segment_end_coordinates, {false}, sub_routes[index]);
|
||||
algorithms.ShortestRouting(
|
||||
sub_routes[index].segment_end_coordinates, {false}, sub_routes[index]);
|
||||
BOOST_ASSERT(sub_routes[index].shortest_path_length != INVALID_EDGE_WEIGHT);
|
||||
}
|
||||
|
||||
api::MatchAPI match_api{*facade, parameters};
|
||||
api::MatchAPI match_api{facade, parameters};
|
||||
match_api.MakeResponse(sub_matchings, sub_routes, json_result);
|
||||
|
||||
return Status::Ok;
|
||||
|
@ -19,7 +19,9 @@ namespace plugins
|
||||
|
||||
NearestPlugin::NearestPlugin(const int max_results_) : max_results{max_results_} {}
|
||||
|
||||
Status NearestPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status
|
||||
NearestPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface & /*algorithms*/,
|
||||
const api::NearestParameters ¶ms,
|
||||
util::json::Object &json_result) const
|
||||
{
|
||||
@ -42,7 +44,7 @@ Status NearestPlugin::HandleRequest(const std::shared_ptr<const datafacade::Base
|
||||
return Error("InvalidOptions", "Only one input coordinate is supported", json_result);
|
||||
}
|
||||
|
||||
auto phantom_nodes = GetPhantomNodes(*facade, params, params.number_of_results);
|
||||
auto phantom_nodes = GetPhantomNodes(facade, params, params.number_of_results);
|
||||
|
||||
if (phantom_nodes.front().size() == 0)
|
||||
{
|
||||
@ -50,7 +52,7 @@ Status NearestPlugin::HandleRequest(const std::shared_ptr<const datafacade::Base
|
||||
}
|
||||
BOOST_ASSERT(phantom_nodes.front().size() > 0);
|
||||
|
||||
api::NearestAPI nearest_api(*facade, params);
|
||||
api::NearestAPI nearest_api(facade, params);
|
||||
nearest_api.MakeResponse(phantom_nodes, json_result);
|
||||
|
||||
return Status::Ok;
|
||||
|
@ -24,11 +24,12 @@ namespace plugins
|
||||
{
|
||||
|
||||
TablePlugin::TablePlugin(const int max_locations_distance_table)
|
||||
: distance_table(heaps), max_locations_distance_table(max_locations_distance_table)
|
||||
: max_locations_distance_table(max_locations_distance_table)
|
||||
{
|
||||
}
|
||||
|
||||
Status TablePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status TablePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::TableParameters ¶ms,
|
||||
util::json::Object &result) const
|
||||
{
|
||||
@ -59,16 +60,16 @@ Status TablePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDa
|
||||
return Error("TooBig", "Too many table coordinates", result);
|
||||
}
|
||||
|
||||
auto snapped_phantoms = SnapPhantomNodes(GetPhantomNodes(*facade, params));
|
||||
auto snapped_phantoms = SnapPhantomNodes(GetPhantomNodes(facade, params));
|
||||
auto result_table =
|
||||
distance_table(facade, snapped_phantoms, params.sources, params.destinations);
|
||||
algorithms.ManyToManyRouting(snapped_phantoms, params.sources, params.destinations);
|
||||
|
||||
if (result_table.empty())
|
||||
{
|
||||
return Error("NoTable", "No table found", result);
|
||||
}
|
||||
|
||||
api::TableAPI table_api{*facade, params};
|
||||
api::TableAPI table_api{facade, params};
|
||||
table_api.MakeResponse(result_table, snapped_phantoms, result);
|
||||
|
||||
return Status::Ok;
|
||||
|
@ -32,8 +32,13 @@ namespace engine
|
||||
{
|
||||
namespace plugins
|
||||
{
|
||||
|
||||
constexpr const static int MIN_ZOOM_FOR_TURNS = 15;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
using RTreeLeaf = datafacade::BaseDataFacade::RTreeLeaf;
|
||||
// TODO: Port all this encoding logic to https://github.com/mapbox/vector-tile, which wasn't
|
||||
// available when this code was originally written.
|
||||
|
||||
@ -72,33 +77,12 @@ struct point_type_i final
|
||||
const std::int64_t y;
|
||||
};
|
||||
|
||||
// Used to accumulate all the information we want in the tile about
|
||||
// a turn.
|
||||
struct TurnData final
|
||||
{
|
||||
TurnData(const util::Coordinate coordinate_,
|
||||
const std::size_t _in,
|
||||
const std::size_t _out,
|
||||
const std::size_t _weight)
|
||||
: coordinate(std::move(coordinate_)), in_angle_offset(_in), turn_angle_offset(_out),
|
||||
weight_offset(_weight)
|
||||
{
|
||||
}
|
||||
|
||||
const util::Coordinate coordinate;
|
||||
const std::size_t in_angle_offset;
|
||||
const std::size_t turn_angle_offset;
|
||||
const std::size_t weight_offset;
|
||||
};
|
||||
|
||||
using FixedPoint = Point<std::int32_t>;
|
||||
using FloatPoint = Point<double>;
|
||||
|
||||
using FixedLine = std::vector<FixedPoint>;
|
||||
using FloatLine = std::vector<FloatPoint>;
|
||||
|
||||
constexpr const static int MIN_ZOOM_FOR_TURNS = 15;
|
||||
|
||||
// We use boost::geometry to clip lines/points that are outside or cross the boundary
|
||||
// of the tile we're rendering. We need these types defined to use boosts clipping
|
||||
// logic
|
||||
@ -247,33 +231,58 @@ FixedPoint coordinatesToTilePoint(const util::Coordinate point, const BBox &tile
|
||||
return FixedPoint{px, py};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const api::TileParameters ¶meters,
|
||||
std::string &pbf_buffer) const
|
||||
std::vector<RTreeLeaf> getEdges(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
unsigned x,
|
||||
unsigned y,
|
||||
unsigned z)
|
||||
{
|
||||
BOOST_ASSERT(parameters.IsValid());
|
||||
|
||||
double min_lon, min_lat, max_lon, max_lat;
|
||||
|
||||
// Convert the z,x,y mercator tile coordinates into WGS84 lon/lat values
|
||||
//
|
||||
util::web_mercator::xyzToWGS84(parameters.x,
|
||||
parameters.y,
|
||||
parameters.z,
|
||||
min_lon,
|
||||
min_lat,
|
||||
max_lon,
|
||||
max_lat,
|
||||
util::web_mercator::TILE_SIZE * 0.10);
|
||||
util::web_mercator::xyzToWGS84(
|
||||
x, y, z, min_lon, min_lat, max_lon, max_lat, util::web_mercator::TILE_SIZE * 0.10);
|
||||
|
||||
util::Coordinate southwest{util::FloatLongitude{min_lon}, util::FloatLatitude{min_lat}};
|
||||
util::Coordinate northeast{util::FloatLongitude{max_lon}, util::FloatLatitude{max_lat}};
|
||||
|
||||
// Fetch all the segments that are in our bounding box.
|
||||
// This hits the OSRM StaticRTree
|
||||
const auto edges = facade->GetEdgesInBox(southwest, northeast);
|
||||
return facade.GetEdgesInBox(southwest, northeast);
|
||||
}
|
||||
|
||||
std::vector<std::size_t> getEdgeIndex(const std::vector<RTreeLeaf> &edges)
|
||||
{
|
||||
// In order to ensure consistent tile encoding, we need to process
|
||||
// all edges in the same order. Differences in OSX/Linux/Windows
|
||||
// sorting methods mean that GetEdgesInBox doesn't return the same
|
||||
// ordered array on all platforms.
|
||||
// GetEdgesInBox is marked `const`, so we can't sort the array itself,
|
||||
// instead we create an array of indexes and sort that instead.
|
||||
std::vector<std::size_t> sorted_edge_indexes(edges.size(), 0);
|
||||
std::iota(sorted_edge_indexes.begin(), sorted_edge_indexes.end(), 0); // fill with 1,2,3,...N
|
||||
|
||||
// Now, sort that array based on the edges list, using the u/v node IDs
|
||||
// as the sort condition
|
||||
std::sort(sorted_edge_indexes.begin(),
|
||||
sorted_edge_indexes.end(),
|
||||
[&edges](const std::size_t &left, const std::size_t &right) -> bool {
|
||||
return (edges[left].u != edges[right].u) ? edges[left].u < edges[right].u
|
||||
: edges[left].v < edges[right].v;
|
||||
});
|
||||
|
||||
return sorted_edge_indexes;
|
||||
}
|
||||
|
||||
void encodeVectorTile(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
unsigned x,
|
||||
unsigned y,
|
||||
unsigned z,
|
||||
const std::vector<RTreeLeaf> &edges,
|
||||
const std::vector<std::size_t> &sorted_edge_indexes,
|
||||
const std::vector<routing_algorithms::TurnData> &all_turn_data,
|
||||
std::string &pbf_buffer)
|
||||
{
|
||||
|
||||
// Vector tiles encode properties as references to a common lookup table.
|
||||
// When we add a property to a "feature", we actually attach the index of the value
|
||||
@ -302,7 +311,6 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
std::uint8_t max_datasource_id = 0;
|
||||
|
||||
// This is where we accumulate information on turns
|
||||
std::vector<TurnData> all_turn_data;
|
||||
|
||||
// Helper function for adding a new value to the line_ints lookup table. Returns
|
||||
// the index of the value in the table, adding the value if it doesn't already
|
||||
@ -358,260 +366,6 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
return offset;
|
||||
};
|
||||
|
||||
// In order to ensure consistent tile encoding, we need to process
|
||||
// all edges in the same order. Differences in OSX/Linux/Windows
|
||||
// sorting methods mean that GetEdgesInBox doesn't return the same
|
||||
// ordered array on all platforms.
|
||||
// GetEdgesInBox is marked `const`, so we can't sort the array itself,
|
||||
// instead we create an array of indexes and sort that instead.
|
||||
std::vector<std::size_t> sorted_edge_indexes(edges.size(), 0);
|
||||
std::iota(sorted_edge_indexes.begin(), sorted_edge_indexes.end(), 0); // fill with 1,2,3,...N
|
||||
|
||||
// Now, sort that array based on the edges list, using the u/v node IDs
|
||||
// as the sort condition
|
||||
std::sort(sorted_edge_indexes.begin(),
|
||||
sorted_edge_indexes.end(),
|
||||
[&edges](const std::size_t &left, const std::size_t &right) -> bool {
|
||||
return (edges[left].u != edges[right].u) ? edges[left].u < edges[right].u
|
||||
: edges[left].v < edges[right].v;
|
||||
});
|
||||
// From here on, we'll iterate over the sorted_edge_indexes instead of `edges` directly.
|
||||
// Note, that we do this because `
|
||||
|
||||
// If we're zooming into 16 or higher, include turn data. Why? Because turns make the map
|
||||
// really cramped, so we don't bother including the data for tiles that span a large area.
|
||||
if (parameters.z >= MIN_ZOOM_FOR_TURNS)
|
||||
{
|
||||
// Struct to hold info on all the EdgeBasedNodes that are visible in our tile
|
||||
// When we create these, we insure that (source, target) and packed_geometry_id
|
||||
// are all pointed in the same direction.
|
||||
struct EdgeBasedNodeInfo
|
||||
{
|
||||
bool is_geometry_forward; // Is the geometry forward or reverse?
|
||||
unsigned packed_geometry_id;
|
||||
};
|
||||
// Lookup table for edge-based-nodes
|
||||
std::unordered_map<NodeID, EdgeBasedNodeInfo> edge_based_node_info;
|
||||
|
||||
struct SegmentData
|
||||
{
|
||||
NodeID target_node;
|
||||
EdgeID edge_based_node_id;
|
||||
};
|
||||
|
||||
std::unordered_map<NodeID, std::vector<SegmentData>> directed_graph;
|
||||
// Reserve enough space for unique edge-based-nodes on every edge.
|
||||
// Only a tile with all unique edges will use this much, but
|
||||
// it saves us a bunch of re-allocations during iteration.
|
||||
directed_graph.reserve(edges.size() * 2);
|
||||
|
||||
// Build an adjacency list for all the road segments visible in
|
||||
// the tile
|
||||
for (const auto &edge_index : sorted_edge_indexes)
|
||||
{
|
||||
const auto &edge = edges[edge_index];
|
||||
if (edge.forward_segment_id.enabled)
|
||||
{
|
||||
// operator[] will construct an empty vector at [edge.u] if there is no value.
|
||||
directed_graph[edge.u].push_back({edge.v, edge.forward_segment_id.id});
|
||||
if (edge_based_node_info.count(edge.forward_segment_id.id) == 0)
|
||||
{
|
||||
edge_based_node_info[edge.forward_segment_id.id] = {true,
|
||||
edge.packed_geometry_id};
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
edge_based_node_info[edge.forward_segment_id.id].is_geometry_forward ==
|
||||
true);
|
||||
BOOST_ASSERT(
|
||||
edge_based_node_info[edge.forward_segment_id.id].packed_geometry_id ==
|
||||
edge.packed_geometry_id);
|
||||
}
|
||||
}
|
||||
if (edge.reverse_segment_id.enabled)
|
||||
{
|
||||
directed_graph[edge.v].push_back({edge.u, edge.reverse_segment_id.id});
|
||||
if (edge_based_node_info.count(edge.reverse_segment_id.id) == 0)
|
||||
{
|
||||
edge_based_node_info[edge.reverse_segment_id.id] = {false,
|
||||
edge.packed_geometry_id};
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
edge_based_node_info[edge.reverse_segment_id.id].is_geometry_forward ==
|
||||
false);
|
||||
BOOST_ASSERT(
|
||||
edge_based_node_info[edge.reverse_segment_id.id].packed_geometry_id ==
|
||||
edge.packed_geometry_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Given a turn:
|
||||
// u---v
|
||||
// |
|
||||
// w
|
||||
// uv is the "approach"
|
||||
// vw is the "exit"
|
||||
std::vector<contractor::QueryEdge::EdgeData> unpacked_shortcut;
|
||||
std::vector<EdgeWeight> approach_weight_vector;
|
||||
|
||||
// Make sure we traverse the startnodes in a consistent order
|
||||
// to ensure identical PBF encoding on all platforms.
|
||||
std::vector<NodeID> sorted_startnodes;
|
||||
sorted_startnodes.reserve(directed_graph.size());
|
||||
for (const auto &startnode : directed_graph)
|
||||
sorted_startnodes.push_back(startnode.first);
|
||||
std::sort(sorted_startnodes.begin(), sorted_startnodes.end());
|
||||
|
||||
// Look at every node in the directed graph we created
|
||||
for (const auto &startnode : sorted_startnodes)
|
||||
{
|
||||
const auto &nodedata = directed_graph[startnode];
|
||||
// For all the outgoing edges from the node
|
||||
for (const auto &approachedge : nodedata)
|
||||
{
|
||||
// If the target of this edge doesn't exist in our directed
|
||||
// graph, it's probably outside the tile, so we can skip it
|
||||
if (directed_graph.count(approachedge.target_node) == 0)
|
||||
continue;
|
||||
|
||||
// For each of the outgoing edges from our target coordinate
|
||||
for (const auto &exit_edge : directed_graph[approachedge.target_node])
|
||||
{
|
||||
// If the next edge has the same edge_based_node_id, then it's
|
||||
// not a turn, so skip it
|
||||
if (approachedge.edge_based_node_id == exit_edge.edge_based_node_id)
|
||||
continue;
|
||||
|
||||
// Skip u-turns
|
||||
if (startnode == exit_edge.target_node)
|
||||
continue;
|
||||
|
||||
// Find the connection between our source road and the target node
|
||||
// Since we only want to find direct edges, we cannot check shortcut edges here.
|
||||
// Otherwise we might find a forward edge even though a shorter backward edge
|
||||
// exists (due to oneways).
|
||||
//
|
||||
// a > - > - > - b
|
||||
// | |
|
||||
// |------ c ----|
|
||||
//
|
||||
// would offer a backward edge at `b` to `a` (due to the oneway from a to b)
|
||||
// but could also offer a shortcut (b-c-a) from `b` to `a` which is longer.
|
||||
EdgeID smaller_edge_id =
|
||||
facade->FindSmallestEdge(approachedge.edge_based_node_id,
|
||||
exit_edge.edge_based_node_id,
|
||||
[](const contractor::QueryEdge::EdgeData &data) {
|
||||
return data.forward && !data.shortcut;
|
||||
});
|
||||
|
||||
// Depending on how the graph is constructed, we might have to look for
|
||||
// a backwards edge instead. They're equivalent, just one is available for
|
||||
// a forward routing search, and one is used for the backwards dijkstra
|
||||
// steps. Their weight should be the same, we can use either one.
|
||||
// If we didn't find a forward edge, try for a backward one
|
||||
if (SPECIAL_EDGEID == smaller_edge_id)
|
||||
{
|
||||
smaller_edge_id = facade->FindSmallestEdge(
|
||||
exit_edge.edge_based_node_id,
|
||||
approachedge.edge_based_node_id,
|
||||
[](const contractor::QueryEdge::EdgeData &data) {
|
||||
return data.backward && !data.shortcut;
|
||||
});
|
||||
}
|
||||
|
||||
// If no edge was found, it means that there's no connection between these
|
||||
// nodes, due to oneways or turn restrictions. Given the edge-based-nodes
|
||||
// that we're examining here, we *should* only find directly-connected
|
||||
// edges, not shortcuts
|
||||
if (smaller_edge_id != SPECIAL_EDGEID)
|
||||
{
|
||||
const auto &data = facade->GetEdgeData(smaller_edge_id);
|
||||
BOOST_ASSERT_MSG(!data.shortcut, "Connecting edge must not be a shortcut");
|
||||
|
||||
// Now, calculate the sum of the weight of all the segments.
|
||||
if (edge_based_node_info[approachedge.edge_based_node_id]
|
||||
.is_geometry_forward)
|
||||
{
|
||||
approach_weight_vector = facade->GetUncompressedForwardWeights(
|
||||
edge_based_node_info[approachedge.edge_based_node_id]
|
||||
.packed_geometry_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
approach_weight_vector = facade->GetUncompressedReverseWeights(
|
||||
edge_based_node_info[approachedge.edge_based_node_id]
|
||||
.packed_geometry_id);
|
||||
}
|
||||
const auto sum_node_weight = std::accumulate(approach_weight_vector.begin(),
|
||||
approach_weight_vector.end(),
|
||||
EdgeWeight{0});
|
||||
|
||||
// The edge.weight is the whole edge weight, which includes the turn
|
||||
// cost.
|
||||
// The turn cost is the edge.weight minus the sum of the individual road
|
||||
// segment weights. This might not be 100% accurate, because some
|
||||
// intersections include stop signs, traffic signals and other
|
||||
// penalties, but at this stage, we can't divide those out, so we just
|
||||
// treat the whole lot as the "turn cost" that we'll stick on the map.
|
||||
const auto turn_cost = data.weight - sum_node_weight;
|
||||
|
||||
// Find the three nodes that make up the turn movement)
|
||||
const auto node_from = startnode;
|
||||
const auto node_via = approachedge.target_node;
|
||||
const auto node_to = exit_edge.target_node;
|
||||
|
||||
const auto coord_from = facade->GetCoordinateOfNode(node_from);
|
||||
const auto coord_via = facade->GetCoordinateOfNode(node_via);
|
||||
const auto coord_to = facade->GetCoordinateOfNode(node_to);
|
||||
|
||||
// Calculate the bearing that we approach the intersection at
|
||||
const auto angle_in = static_cast<int>(
|
||||
util::coordinate_calculation::bearing(coord_from, coord_via));
|
||||
|
||||
// Add the angle to the values table for the vector tile, and get the
|
||||
// index
|
||||
// of that value in the table
|
||||
const auto angle_in_index = use_point_int_value(angle_in);
|
||||
|
||||
// Calculate the bearing leading away from the intersection
|
||||
const auto exit_bearing = static_cast<int>(
|
||||
util::coordinate_calculation::bearing(coord_via, coord_to));
|
||||
|
||||
// Figure out the angle of the turn
|
||||
auto turn_angle = exit_bearing - angle_in;
|
||||
while (turn_angle > 180)
|
||||
{
|
||||
turn_angle -= 360;
|
||||
}
|
||||
while (turn_angle < -180)
|
||||
{
|
||||
turn_angle += 360;
|
||||
}
|
||||
|
||||
// Add the turn angle value to the value lookup table for the vector
|
||||
// tile.
|
||||
const auto turn_angle_index = use_point_int_value(turn_angle);
|
||||
// And, same for the actual turn cost value - it goes in the lookup
|
||||
// table,
|
||||
// not directly on the feature itself.
|
||||
const auto turn_cost_index = use_point_float_value(
|
||||
turn_cost / 10.0); // Note conversion to float here
|
||||
|
||||
// Save everything we need to later add all the points to the tile.
|
||||
// We need the coordinate of the intersection, the angle in, the turn
|
||||
// angle and the turn cost.
|
||||
all_turn_data.emplace_back(
|
||||
coord_via, angle_in_index, turn_angle_index, turn_cost_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vector tiles encode feature properties as indexes into a lookup table. So, we need
|
||||
// to "pre-loop" over all the edges to create the lookup tables. Once we have those, we
|
||||
// can then encode the features, and we'll know the indexes that feature properties
|
||||
@ -621,9 +375,9 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
const auto &edge = edges[edge_index];
|
||||
|
||||
const auto forward_datasource_vector =
|
||||
facade->GetUncompressedForwardDatasources(edge.packed_geometry_id);
|
||||
facade.GetUncompressedForwardDatasources(edge.packed_geometry_id);
|
||||
const auto reverse_datasource_vector =
|
||||
facade->GetUncompressedReverseDatasources(edge.packed_geometry_id);
|
||||
facade.GetUncompressedReverseDatasources(edge.packed_geometry_id);
|
||||
|
||||
BOOST_ASSERT(edge.fwd_segment_position < forward_datasource_vector.size());
|
||||
const auto forward_datasource = forward_datasource_vector[edge.fwd_segment_position];
|
||||
@ -639,13 +393,8 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
|
||||
// Convert tile coordinates into mercator coordinates
|
||||
double min_mercator_lon, min_mercator_lat, max_mercator_lon, max_mercator_lat;
|
||||
util::web_mercator::xyzToMercator(parameters.x,
|
||||
parameters.y,
|
||||
parameters.z,
|
||||
min_mercator_lon,
|
||||
min_mercator_lat,
|
||||
max_mercator_lon,
|
||||
max_mercator_lat);
|
||||
util::web_mercator::xyzToMercator(
|
||||
x, y, z, min_mercator_lon, min_mercator_lat, max_mercator_lon, max_mercator_lat);
|
||||
const BBox tile_bbox{min_mercator_lon, min_mercator_lat, max_mercator_lon, max_mercator_lat};
|
||||
|
||||
// Protobuf serializes blocks when objects go out of scope, hence
|
||||
@ -673,9 +422,9 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
{
|
||||
const auto &edge = edges[edge_index];
|
||||
const auto forward_weight_vector =
|
||||
facade->GetUncompressedForwardWeights(edge.packed_geometry_id);
|
||||
facade.GetUncompressedForwardWeights(edge.packed_geometry_id);
|
||||
const auto reverse_weight_vector =
|
||||
facade->GetUncompressedReverseWeights(edge.packed_geometry_id);
|
||||
facade.GetUncompressedReverseWeights(edge.packed_geometry_id);
|
||||
const auto forward_weight = forward_weight_vector[edge.fwd_segment_position];
|
||||
const auto reverse_weight = reverse_weight_vector[reverse_weight_vector.size() -
|
||||
edge.fwd_segment_position - 1];
|
||||
@ -691,20 +440,20 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
{
|
||||
const auto &edge = edges[edge_index];
|
||||
// Get coordinates for start/end nodes of segment (NodeIDs u and v)
|
||||
const auto a = facade->GetCoordinateOfNode(edge.u);
|
||||
const auto b = facade->GetCoordinateOfNode(edge.v);
|
||||
const auto a = facade.GetCoordinateOfNode(edge.u);
|
||||
const auto b = facade.GetCoordinateOfNode(edge.v);
|
||||
// Calculate the length in meters
|
||||
const double length =
|
||||
osrm::util::coordinate_calculation::haversineDistance(a, b);
|
||||
|
||||
const auto forward_weight_vector =
|
||||
facade->GetUncompressedForwardWeights(edge.packed_geometry_id);
|
||||
facade.GetUncompressedForwardWeights(edge.packed_geometry_id);
|
||||
const auto reverse_weight_vector =
|
||||
facade->GetUncompressedReverseWeights(edge.packed_geometry_id);
|
||||
facade.GetUncompressedReverseWeights(edge.packed_geometry_id);
|
||||
const auto forward_datasource_vector =
|
||||
facade->GetUncompressedForwardDatasources(edge.packed_geometry_id);
|
||||
facade.GetUncompressedForwardDatasources(edge.packed_geometry_id);
|
||||
const auto reverse_datasource_vector =
|
||||
facade->GetUncompressedReverseDatasources(edge.packed_geometry_id);
|
||||
facade.GetUncompressedReverseDatasources(edge.packed_geometry_id);
|
||||
const auto forward_weight = forward_weight_vector[edge.fwd_segment_position];
|
||||
const auto reverse_weight =
|
||||
reverse_weight_vector[reverse_weight_vector.size() -
|
||||
@ -715,7 +464,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
reverse_datasource_vector[reverse_datasource_vector.size() -
|
||||
edge.fwd_segment_position - 1];
|
||||
|
||||
auto name = facade->GetNameForID(edge.name_id);
|
||||
auto name = facade.GetNameForID(edge.name_id);
|
||||
|
||||
const auto name_offset = [&name, &names, &name_offsets]() {
|
||||
auto iter = name_offsets.find(name);
|
||||
@ -875,7 +624,7 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
util::vector_tile::VARIANT_TAG);
|
||||
// Attribute value 1 == string type
|
||||
values_writer.add_string(util::vector_tile::VARIANT_TYPE_STRING,
|
||||
facade->GetDatasourceName(i).to_string());
|
||||
facade.GetDatasourceName(i).to_string());
|
||||
}
|
||||
for (auto value : used_line_ints)
|
||||
{
|
||||
@ -918,8 +667,9 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
int id = 1;
|
||||
|
||||
// Helper function to encode a new point feature on a vector tile.
|
||||
const auto encode_tile_point = [&point_layer_writer, &used_point_ints, &id](
|
||||
const FixedPoint &tile_point, const TurnData &point_turn_data) {
|
||||
const auto encode_tile_point = [&](
|
||||
const FixedPoint &tile_point,
|
||||
const routing_algorithms::TurnData &point_turn_data) {
|
||||
protozero::pbf_writer feature_writer(point_layer_writer,
|
||||
util::vector_tile::FEATURE_TAG);
|
||||
// Field 3 is the "geometry type" field. Value 1 is "point"
|
||||
@ -928,17 +678,23 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
util::vector_tile::GEOMETRY_TYPE_POINT); // geometry type
|
||||
feature_writer.add_uint64(util::vector_tile::ID_TAG, id++); // id
|
||||
{
|
||||
const auto in_angle_offset = use_point_int_value(point_turn_data.in_angle);
|
||||
const auto turn_angle_offset =
|
||||
use_point_int_value(point_turn_data.turn_angle);
|
||||
const auto weight_offset = use_point_float_value(
|
||||
point_turn_data.weight / 10.0); // Note conversion to float here
|
||||
|
||||
// Write out the 3 properties we want on the feature. These
|
||||
// refer to indexes in the properties lookup table, which we
|
||||
// add to the tile after we add all features.
|
||||
protozero::packed_field_uint32 field(
|
||||
feature_writer, util::vector_tile::FEATURE_ATTRIBUTES_TAG);
|
||||
field.add_element(0); // "bearing_in" tag key offset
|
||||
field.add_element(point_turn_data.in_angle_offset);
|
||||
field.add_element(in_angle_offset);
|
||||
field.add_element(1); // "turn_angle" tag key offset
|
||||
field.add_element(point_turn_data.turn_angle_offset);
|
||||
field.add_element(turn_angle_offset);
|
||||
field.add_element(2); // "cost" tag key offset
|
||||
field.add_element(used_point_ints.size() + point_turn_data.weight_offset);
|
||||
field.add_element(used_point_ints.size() + weight_offset);
|
||||
}
|
||||
{
|
||||
// Add the geometry as the last field in this feature
|
||||
@ -983,6 +739,31 @@ Status TilePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
}
|
||||
// protozero serializes data during object destructors, so once the scope closes,
|
||||
// our result buffer will have all the tile data encoded into it.
|
||||
}
|
||||
}
|
||||
|
||||
Status TilePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::TileParameters ¶meters,
|
||||
std::string &pbf_buffer) const
|
||||
{
|
||||
BOOST_ASSERT(parameters.IsValid());
|
||||
|
||||
auto edges = getEdges(facade, parameters.x, parameters.y, parameters.y);
|
||||
|
||||
auto edge_index = getEdgeIndex(edges);
|
||||
|
||||
std::vector<routing_algorithms::TurnData> turns;
|
||||
|
||||
// If we're zooming into 16 or higher, include turn data. Why? Because turns make the map
|
||||
// really cramped, so we don't bother including the data for tiles that span a large area.
|
||||
if (parameters.z >= MIN_ZOOM_FOR_TURNS)
|
||||
{
|
||||
turns = algorithms.TileTurns(edges, edge_index);
|
||||
}
|
||||
|
||||
encodeVectorTile(
|
||||
facade, parameters.x, parameters.y, parameters.y, edges, edge_index, turns, pbf_buffer);
|
||||
|
||||
return Status::Ok;
|
||||
}
|
||||
|
@ -52,8 +52,7 @@ bool IsSupportedParameterCombination(const bool fixed_start,
|
||||
|
||||
// given the node order in which to visit, compute the actual route (with geometry, travel time and
|
||||
// so on) and return the result
|
||||
InternalRouteResult
|
||||
TripPlugin::ComputeRoute(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
InternalRouteResult TripPlugin::ComputeRoute(const RoutingAlgorithmsInterface &algorithms,
|
||||
const std::vector<PhantomNode> &snapped_phantoms,
|
||||
const std::vector<NodeID> &trip,
|
||||
const bool roundtrip) const
|
||||
@ -86,7 +85,7 @@ TripPlugin::ComputeRoute(const std::shared_ptr<const datafacade::BaseDataFacade>
|
||||
BOOST_ASSERT(min_route.segment_end_coordinates.size() == trip.size() - 1);
|
||||
}
|
||||
|
||||
shortest_path(facade, min_route.segment_end_coordinates, {false}, min_route);
|
||||
algorithms.ShortestRouting(min_route.segment_end_coordinates, {false}, min_route);
|
||||
BOOST_ASSERT_MSG(min_route.shortest_path_length < INVALID_EDGE_WEIGHT, "unroutable route");
|
||||
return min_route;
|
||||
}
|
||||
@ -143,7 +142,8 @@ void ManipulateTableForFSE(const std::size_t source_id,
|
||||
//********* End of changes to table *************************************
|
||||
}
|
||||
|
||||
Status TripPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status TripPlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::TripParameters ¶meters,
|
||||
util::json::Object &json_result) const
|
||||
{
|
||||
@ -179,7 +179,7 @@ Status TripPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
return Error("InvalidValue", "Invalid coordinate value.", json_result);
|
||||
}
|
||||
|
||||
auto phantom_node_pairs = GetPhantomNodes(*facade, parameters);
|
||||
auto phantom_node_pairs = GetPhantomNodes(facade, parameters);
|
||||
if (phantom_node_pairs.size() != number_of_locations)
|
||||
{
|
||||
return Error("NoSegment",
|
||||
@ -201,7 +201,7 @@ Status TripPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
|
||||
// compute the duration table of all phantom nodes
|
||||
auto result_table = util::DistTableWrapper<EdgeWeight>(
|
||||
duration_table(facade, snapped_phantoms, {}, {}), number_of_locations);
|
||||
algorithms.ManyToManyRouting(snapped_phantoms, {}, {}), number_of_locations);
|
||||
|
||||
if (result_table.size() == 0)
|
||||
{
|
||||
@ -250,12 +250,13 @@ Status TripPlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDat
|
||||
}
|
||||
|
||||
// get the route when visiting all destinations in optimized order
|
||||
InternalRouteResult route = ComputeRoute(facade, snapped_phantoms, trip, parameters.roundtrip);
|
||||
InternalRouteResult route =
|
||||
ComputeRoute(algorithms, snapped_phantoms, trip, parameters.roundtrip);
|
||||
|
||||
// get api response
|
||||
const std::vector<std::vector<NodeID>> trips = {trip};
|
||||
const std::vector<InternalRouteResult> routes = {route};
|
||||
api::TripAPI trip_api{*facade, parameters};
|
||||
api::TripAPI trip_api{facade, parameters};
|
||||
trip_api.MakeResponse(trips, routes, snapped_phantoms, json_result);
|
||||
|
||||
return Status::Ok;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "engine/plugins/viaroute.hpp"
|
||||
#include "engine/api/route_api.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "engine/routing_algorithms.hpp"
|
||||
#include "engine/status.hpp"
|
||||
|
||||
#include "util/for_each_pair.hpp"
|
||||
@ -22,12 +22,13 @@ namespace plugins
|
||||
{
|
||||
|
||||
ViaRoutePlugin::ViaRoutePlugin(int max_locations_viaroute)
|
||||
: shortest_path(heaps), alternative_path(heaps), direct_shortest_path(heaps),
|
||||
max_locations_viaroute(max_locations_viaroute)
|
||||
: max_locations_viaroute(max_locations_viaroute)
|
||||
{
|
||||
}
|
||||
|
||||
Status ViaRoutePlugin::HandleRequest(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
Status
|
||||
ViaRoutePlugin::HandleRequest(const datafacade::ContiguousInternalMemoryDataFacadeBase &facade,
|
||||
const RoutingAlgorithmsInterface &algorithms,
|
||||
const api::RouteParameters &route_parameters,
|
||||
util::json::Object &json_result) const
|
||||
{
|
||||
@ -48,7 +49,7 @@ Status ViaRoutePlugin::HandleRequest(const std::shared_ptr<const datafacade::Bas
|
||||
return Error("InvalidValue", "Invalid coordinate value.", json_result);
|
||||
}
|
||||
|
||||
auto phantom_node_pairs = GetPhantomNodes(*facade, route_parameters);
|
||||
auto phantom_node_pairs = GetPhantomNodes(facade, route_parameters);
|
||||
if (phantom_node_pairs.size() != route_parameters.coordinates.size())
|
||||
{
|
||||
return Error("NoSegment",
|
||||
@ -62,7 +63,7 @@ Status ViaRoutePlugin::HandleRequest(const std::shared_ptr<const datafacade::Bas
|
||||
|
||||
const bool continue_straight_at_waypoint = route_parameters.continue_straight
|
||||
? *route_parameters.continue_straight
|
||||
: facade->GetContinueStraightDefault();
|
||||
: facade.GetContinueStraightDefault();
|
||||
|
||||
InternalRouteResult raw_route;
|
||||
auto build_phantom_pairs = [&raw_route, continue_straight_at_waypoint](
|
||||
@ -86,28 +87,26 @@ Status ViaRoutePlugin::HandleRequest(const std::shared_ptr<const datafacade::Bas
|
||||
|
||||
if (1 == raw_route.segment_end_coordinates.size())
|
||||
{
|
||||
if (route_parameters.alternatives && facade->GetCoreSize() == 0)
|
||||
if (route_parameters.alternatives && algorithms.HasAlternativeRouting())
|
||||
{
|
||||
alternative_path(facade, raw_route.segment_end_coordinates.front(), raw_route);
|
||||
algorithms.AlternativeRouting(raw_route.segment_end_coordinates.front(), raw_route);
|
||||
}
|
||||
else
|
||||
{
|
||||
direct_shortest_path(facade, raw_route.segment_end_coordinates, raw_route);
|
||||
algorithms.DirectShortestPathRouting(raw_route.segment_end_coordinates, raw_route);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shortest_path(facade,
|
||||
raw_route.segment_end_coordinates,
|
||||
route_parameters.continue_straight,
|
||||
raw_route);
|
||||
algorithms.ShortestRouting(
|
||||
raw_route.segment_end_coordinates, route_parameters.continue_straight, raw_route);
|
||||
}
|
||||
|
||||
// we can only know this after the fact, different SCC ids still
|
||||
// allow for connection in one direction.
|
||||
if (raw_route.is_valid())
|
||||
{
|
||||
api::RouteAPI route_api{*facade, route_parameters};
|
||||
api::RouteAPI route_api{facade, route_parameters};
|
||||
route_api.MakeResponse(raw_route, json_result);
|
||||
}
|
||||
else
|
||||
|
@ -7,7 +7,7 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
void AlternativeRouting::operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void AlternativeRouting<algorithm::CH>::operator()(const FacadeT &facade,
|
||||
const PhantomNodes &phantom_node_pair,
|
||||
InternalRouteResult &raw_route_data)
|
||||
{
|
||||
@ -17,9 +17,9 @@ void AlternativeRouting::operator()(const std::shared_ptr<const datafacade::Base
|
||||
std::vector<SearchSpaceEdge> reverse_search_space;
|
||||
|
||||
// Init queues, semi-expensive because access to TSS invokes a sys-call
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearThirdThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearThirdThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &forward_heap1 = *(engine_working_data.forward_heap_1);
|
||||
QueryHeap &reverse_heap1 = *(engine_working_data.reverse_heap_1);
|
||||
@ -320,7 +320,8 @@ void AlternativeRouting::operator()(const std::shared_ptr<const datafacade::Base
|
||||
}
|
||||
}
|
||||
|
||||
void AlternativeRouting::RetrievePackedAlternatePath(const QueryHeap &forward_heap1,
|
||||
void AlternativeRouting<algorithm::CH>::RetrievePackedAlternatePath(
|
||||
const QueryHeap &forward_heap1,
|
||||
const QueryHeap &reverse_heap1,
|
||||
const QueryHeap &forward_heap2,
|
||||
const QueryHeap &reverse_heap2,
|
||||
@ -343,15 +344,15 @@ void AlternativeRouting::RetrievePackedAlternatePath(const QueryHeap &forward_he
|
||||
// compute and unpack <s,..,v> and <v,..,t> by exploring search spaces
|
||||
// from v and intersecting against queues. only half-searches have to be
|
||||
// done at this stage
|
||||
void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void AlternativeRouting<algorithm::CH>::ComputeLengthAndSharingOfViaPath(
|
||||
const FacadeT &facade,
|
||||
const NodeID via_node,
|
||||
int *real_length_of_via_path,
|
||||
int *sharing_of_via_path,
|
||||
const std::vector<NodeID> &packed_shortest_path,
|
||||
const EdgeWeight min_edge_offset)
|
||||
{
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &existing_forward_heap = *engine_working_data.forward_heap_1;
|
||||
QueryHeap &existing_reverse_heap = *engine_working_data.reverse_heap_1;
|
||||
@ -422,9 +423,9 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
if (packed_s_v_path[current_node] == packed_shortest_path[current_node] &&
|
||||
packed_s_v_path[current_node + 1] == packed_shortest_path[current_node + 1])
|
||||
{
|
||||
EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_s_v_path[current_node],
|
||||
EdgeID edgeID = facade.FindEdgeInEitherDirection(packed_s_v_path[current_node],
|
||||
packed_s_v_path[current_node + 1]);
|
||||
*sharing_of_via_path += facade->GetEdgeData(edgeID).weight;
|
||||
*sharing_of_via_path += facade.GetEdgeData(edgeID).weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -455,9 +456,9 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
++current_node)
|
||||
{
|
||||
EdgeID selected_edge =
|
||||
facade->FindEdgeInEitherDirection(partially_unpacked_via_path[current_node],
|
||||
facade.FindEdgeInEitherDirection(partially_unpacked_via_path[current_node],
|
||||
partially_unpacked_via_path[current_node + 1]);
|
||||
*sharing_of_via_path += facade->GetEdgeData(selected_edge).weight;
|
||||
*sharing_of_via_path += facade.GetEdgeData(selected_edge).weight;
|
||||
}
|
||||
|
||||
// Second, partially unpack v-->t in reverse order until paths deviate and note lengths
|
||||
@ -468,9 +469,9 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
if (packed_v_t_path[via_path_index - 1] == packed_shortest_path[shortest_path_index - 1] &&
|
||||
packed_v_t_path[via_path_index] == packed_shortest_path[shortest_path_index])
|
||||
{
|
||||
EdgeID edgeID = facade->FindEdgeInEitherDirection(packed_v_t_path[via_path_index - 1],
|
||||
EdgeID edgeID = facade.FindEdgeInEitherDirection(packed_v_t_path[via_path_index - 1],
|
||||
packed_v_t_path[via_path_index]);
|
||||
*sharing_of_via_path += facade->GetEdgeData(edgeID).weight;
|
||||
*sharing_of_via_path += facade.GetEdgeData(edgeID).weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -499,9 +500,9 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
partially_unpacked_shortest_path[shortest_path_index])
|
||||
{
|
||||
EdgeID edgeID =
|
||||
facade->FindEdgeInEitherDirection(partially_unpacked_via_path[via_path_index - 1],
|
||||
facade.FindEdgeInEitherDirection(partially_unpacked_via_path[via_path_index - 1],
|
||||
partially_unpacked_via_path[via_path_index]);
|
||||
*sharing_of_via_path += facade->GetEdgeData(edgeID).weight;
|
||||
*sharing_of_via_path += facade.GetEdgeData(edgeID).weight;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -513,8 +514,8 @@ void AlternativeRouting::ComputeLengthAndSharingOfViaPath(
|
||||
}
|
||||
|
||||
// conduct T-Test
|
||||
bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
bool AlternativeRouting<algorithm::CH>::ViaNodeCandidatePassesTTest(
|
||||
const FacadeT &facade,
|
||||
QueryHeap &existing_forward_heap,
|
||||
QueryHeap &existing_reverse_heap,
|
||||
QueryHeap &new_forward_heap,
|
||||
@ -606,8 +607,8 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
for (std::size_t i = packed_s_v_path.size() - 1; (i > 0) && unpack_stack.empty(); --i)
|
||||
{
|
||||
const EdgeID current_edge_id =
|
||||
facade->FindEdgeInEitherDirection(packed_s_v_path[i - 1], packed_s_v_path[i]);
|
||||
const EdgeWeight length_of_current_edge = facade->GetEdgeData(current_edge_id).weight;
|
||||
facade.FindEdgeInEitherDirection(packed_s_v_path[i - 1], packed_s_v_path[i]);
|
||||
const EdgeWeight length_of_current_edge = facade.GetEdgeData(current_edge_id).weight;
|
||||
if ((length_of_current_edge + unpacked_until_weight) >= T_threshold)
|
||||
{
|
||||
unpack_stack.emplace(packed_s_v_path[i - 1], packed_s_v_path[i]);
|
||||
@ -624,21 +625,21 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
const SearchSpaceEdge via_path_edge = unpack_stack.top();
|
||||
unpack_stack.pop();
|
||||
EdgeID edge_in_via_path_id =
|
||||
facade->FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
|
||||
facade.FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
|
||||
|
||||
if (SPECIAL_EDGEID == edge_in_via_path_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const EdgeData ¤t_edge_data = facade->GetEdgeData(edge_in_via_path_id);
|
||||
const EdgeData ¤t_edge_data = facade.GetEdgeData(edge_in_via_path_id);
|
||||
const bool current_edge_is_shortcut = current_edge_data.shortcut;
|
||||
if (current_edge_is_shortcut)
|
||||
{
|
||||
const NodeID via_path_middle_node_id = current_edge_data.id;
|
||||
const EdgeID second_segment_edge_id =
|
||||
facade->FindEdgeInEitherDirection(via_path_middle_node_id, via_path_edge.second);
|
||||
const int second_segment_length = facade->GetEdgeData(second_segment_edge_id).weight;
|
||||
facade.FindEdgeInEitherDirection(via_path_middle_node_id, via_path_edge.second);
|
||||
const int second_segment_length = facade.GetEdgeData(second_segment_edge_id).weight;
|
||||
// attention: !unpacking in reverse!
|
||||
// Check if second segment is the one to go over treshold? if yes add second segment
|
||||
// to stack, else push first segment to stack and add weight of second one.
|
||||
@ -669,8 +670,8 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
++i)
|
||||
{
|
||||
const EdgeID edgeID =
|
||||
facade->FindEdgeInEitherDirection(packed_v_t_path[i], packed_v_t_path[i + 1]);
|
||||
int length_of_current_edge = facade->GetEdgeData(edgeID).weight;
|
||||
facade.FindEdgeInEitherDirection(packed_v_t_path[i], packed_v_t_path[i + 1]);
|
||||
int length_of_current_edge = facade.GetEdgeData(edgeID).weight;
|
||||
if (length_of_current_edge + unpacked_until_weight >= T_threshold)
|
||||
{
|
||||
unpack_stack.emplace(packed_v_t_path[i], packed_v_t_path[i + 1]);
|
||||
@ -687,20 +688,20 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
const SearchSpaceEdge via_path_edge = unpack_stack.top();
|
||||
unpack_stack.pop();
|
||||
EdgeID edge_in_via_path_id =
|
||||
facade->FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
|
||||
facade.FindEdgeInEitherDirection(via_path_edge.first, via_path_edge.second);
|
||||
if (SPECIAL_EDGEID == edge_in_via_path_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const EdgeData ¤t_edge_data = facade->GetEdgeData(edge_in_via_path_id);
|
||||
const EdgeData ¤t_edge_data = facade.GetEdgeData(edge_in_via_path_id);
|
||||
const bool IsViaEdgeShortCut = current_edge_data.shortcut;
|
||||
if (IsViaEdgeShortCut)
|
||||
{
|
||||
const NodeID middleOfViaPath = current_edge_data.id;
|
||||
EdgeID edgeIDOfFirstSegment =
|
||||
facade->FindEdgeInEitherDirection(via_path_edge.first, middleOfViaPath);
|
||||
int lengthOfFirstSegment = facade->GetEdgeData(edgeIDOfFirstSegment).weight;
|
||||
facade.FindEdgeInEitherDirection(via_path_edge.first, middleOfViaPath);
|
||||
int lengthOfFirstSegment = facade.GetEdgeData(edgeIDOfFirstSegment).weight;
|
||||
// Check if first segment is the one to go over treshold? if yes first segment to
|
||||
// stack, else push second segment to stack and add weight of first one.
|
||||
if (unpacked_until_weight + lengthOfFirstSegment >= T_threshold)
|
||||
@ -723,7 +724,7 @@ bool AlternativeRouting::ViaNodeCandidatePassesTTest(
|
||||
|
||||
t_test_path_length += unpacked_until_weight;
|
||||
// Run actual T-Test query and compare if weight equal.
|
||||
engine_working_data.InitializeOrClearThirdThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearThirdThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &forward_heap3 = *engine_working_data.forward_heap_3;
|
||||
QueryHeap &reverse_heap3 = *engine_working_data.reverse_heap_3;
|
||||
|
@ -13,8 +13,8 @@ namespace routing_algorithms
|
||||
/// by the previous route.
|
||||
/// This variation is only an optimazation for graphs with slow queries, for example
|
||||
/// not fully contracted graphs.
|
||||
void DirectShortestPathRouting::
|
||||
operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void DirectShortestPathRouting<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
InternalRouteResult &raw_route_data) const
|
||||
{
|
||||
@ -26,7 +26,7 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const auto &source_phantom = phantom_node_pair.source_phantom;
|
||||
const auto &target_phantom = phantom_node_pair.target_phantom;
|
||||
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
QueryHeap &forward_heap = *(engine_working_data.forward_heap_1);
|
||||
QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1);
|
||||
forward_heap.Clear();
|
||||
@ -68,9 +68,9 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const bool constexpr DO_NOT_FORCE_LOOPS =
|
||||
false; // prevents forcing of loops, since offsets are set correctly
|
||||
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
QueryHeap &forward_core_heap = *(engine_working_data.forward_heap_2);
|
||||
QueryHeap &reverse_core_heap = *(engine_working_data.reverse_heap_2);
|
||||
forward_core_heap.Clear();
|
||||
|
@ -7,8 +7,8 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
std::vector<EdgeWeight> ManyToManyRouting::
|
||||
operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
std::vector<EdgeWeight> ManyToManyRouting<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNode> &phantom_nodes,
|
||||
const std::vector<std::size_t> &source_indices,
|
||||
const std::vector<std::size_t> &target_indices) const
|
||||
@ -22,7 +22,7 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
std::vector<EdgeWeight> weights_table(number_of_entries, INVALID_EDGE_WEIGHT);
|
||||
std::vector<EdgeWeight> durations_table(number_of_entries, MAXIMAL_EDGE_DURATION);
|
||||
|
||||
engine_working_data.InitializeOrClearManyToManyThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearManyToManyThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &query_heap = *(engine_working_data.many_to_many_heap);
|
||||
|
||||
@ -122,8 +122,8 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
return durations_table;
|
||||
}
|
||||
|
||||
void ManyToManyRouting::ForwardRoutingStep(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ManyToManyRouting<algorithm::CH>::ForwardRoutingStep(
|
||||
const FacadeT &facade,
|
||||
const unsigned row_idx,
|
||||
const unsigned number_of_targets,
|
||||
QueryHeap &query_heap,
|
||||
@ -179,8 +179,8 @@ void ManyToManyRouting::ForwardRoutingStep(
|
||||
RelaxOutgoingEdges<true>(facade, node, source_weight, source_duration, query_heap);
|
||||
}
|
||||
|
||||
void ManyToManyRouting::BackwardRoutingStep(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ManyToManyRouting<algorithm::CH>::BackwardRoutingStep(
|
||||
const FacadeT &facade,
|
||||
const unsigned column_idx,
|
||||
QueryHeap &query_heap,
|
||||
SearchSpaceWithBuckets &search_space_with_buckets) const
|
||||
|
@ -7,7 +7,8 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
unsigned MapMatching::GetMedianSampleTime(const std::vector<unsigned> ×tamps) const
|
||||
unsigned
|
||||
MapMatching<algorithm::CH>::GetMedianSampleTime(const std::vector<unsigned> ×tamps) const
|
||||
{
|
||||
BOOST_ASSERT(timestamps.size() > 1);
|
||||
|
||||
@ -22,8 +23,8 @@ unsigned MapMatching::GetMedianSampleTime(const std::vector<unsigned> ×tamp
|
||||
return *median;
|
||||
}
|
||||
|
||||
SubMatchingList MapMatching::
|
||||
operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
SubMatchingList MapMatching<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const CandidateLists &candidates_list,
|
||||
const std::vector<util::Coordinate> &trace_coordinates,
|
||||
const std::vector<unsigned> &trace_timestamps,
|
||||
@ -50,7 +51,7 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
const auto max_distance_delta = [&] {
|
||||
if (use_timestamps)
|
||||
{
|
||||
return median_sample_time * facade->GetMapMatchingMaxSpeed();
|
||||
return median_sample_time * facade.GetMapMatchingMaxSpeed();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -109,8 +110,8 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
return sub_matchings;
|
||||
}
|
||||
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &forward_heap = *(engine_working_data.forward_heap_1);
|
||||
QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1);
|
||||
@ -182,7 +183,7 @@ operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
reverse_heap.Clear();
|
||||
|
||||
double network_distance;
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
|
@ -7,8 +7,7 @@ namespace engine
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
void BasicRoutingInterface::RoutingStep(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void BasicRouting<algorithm::CH>::RoutingStep(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
NodeID &middle_node_id,
|
||||
@ -35,13 +34,13 @@ void BasicRoutingInterface::RoutingStep(
|
||||
new_weight < 0)
|
||||
{
|
||||
// check whether there is a loop present at the node
|
||||
for (const auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (const auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const EdgeData &data = facade.GetEdgeData(edge);
|
||||
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
|
||||
if (forward_directionFlag)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
if (to == node)
|
||||
{
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
@ -77,13 +76,13 @@ void BasicRoutingInterface::RoutingStep(
|
||||
// Stalling
|
||||
if (stalling)
|
||||
{
|
||||
for (const auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (const auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const EdgeData &data = facade.GetEdgeData(edge);
|
||||
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
|
||||
if (reverse_flag)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
|
||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
||||
@ -99,13 +98,13 @@ void BasicRoutingInterface::RoutingStep(
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto edge : facade->GetAdjacentEdgeRange(node))
|
||||
for (const auto edge : facade.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
const EdgeData &data = facade->GetEdgeData(edge);
|
||||
const EdgeData &data = facade.GetEdgeData(edge);
|
||||
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
|
||||
if (forward_directionFlag)
|
||||
{
|
||||
const NodeID to = facade->GetTarget(edge);
|
||||
const NodeID to = facade.GetTarget(edge);
|
||||
const EdgeWeight edge_weight = data.weight;
|
||||
|
||||
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
|
||||
@ -134,15 +133,14 @@ void BasicRoutingInterface::RoutingStep(
|
||||
* @param to the node the CH edge finishes at
|
||||
* @param unpacked_path the sequence of original NodeIDs that make up the expanded CH edge
|
||||
*/
|
||||
void BasicRoutingInterface::UnpackEdge(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void BasicRouting<algorithm::CH>::UnpackEdge(const FacadeT &facade,
|
||||
const NodeID from,
|
||||
const NodeID to,
|
||||
std::vector<NodeID> &unpacked_path) const
|
||||
{
|
||||
std::array<NodeID, 2> path{{from, to}};
|
||||
UnpackCHPath(
|
||||
*facade,
|
||||
facade,
|
||||
path.begin(),
|
||||
path.end(),
|
||||
[&unpacked_path](const std::pair<NodeID, NodeID> &edge, const EdgeData & /* data */) {
|
||||
@ -151,7 +149,7 @@ void BasicRoutingInterface::UnpackEdge(
|
||||
unpacked_path.emplace_back(to);
|
||||
}
|
||||
|
||||
void BasicRoutingInterface::RetrievePackedPathFromHeap(
|
||||
void BasicRouting<algorithm::CH>::RetrievePackedPathFromHeap(
|
||||
const SearchEngineData::QueryHeap &forward_heap,
|
||||
const SearchEngineData::QueryHeap &reverse_heap,
|
||||
const NodeID middle_node_id,
|
||||
@ -163,7 +161,7 @@ void BasicRoutingInterface::RetrievePackedPathFromHeap(
|
||||
RetrievePackedPathFromSingleHeap(reverse_heap, middle_node_id, packed_path);
|
||||
}
|
||||
|
||||
void BasicRoutingInterface::RetrievePackedPathFromSingleHeap(
|
||||
void BasicRouting<algorithm::CH>::RetrievePackedPathFromSingleHeap(
|
||||
const SearchEngineData::QueryHeap &search_heap,
|
||||
const NodeID middle_node_id,
|
||||
std::vector<NodeID> &packed_path) const
|
||||
@ -193,7 +191,7 @@ void BasicRoutingInterface::RetrievePackedPathFromSingleHeap(
|
||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||
// requires
|
||||
// a force loop, if the heaps have been initialized with positive offsets.
|
||||
void BasicRoutingInterface::Search(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void BasicRouting<algorithm::CH>::Search(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
EdgeWeight &weight,
|
||||
@ -275,8 +273,7 @@ void BasicRoutingInterface::Search(const std::shared_ptr<const datafacade::BaseD
|
||||
// && source_phantom.GetForwardWeightPlusOffset() > target_phantom.GetForwardWeightPlusOffset())
|
||||
// requires
|
||||
// a force loop, if the heaps have been initialized with positive offsets.
|
||||
void BasicRoutingInterface::SearchWithCore(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void BasicRouting<algorithm::CH>::SearchWithCore(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
@ -305,7 +302,7 @@ void BasicRoutingInterface::SearchWithCore(
|
||||
{
|
||||
if (!forward_heap.Empty())
|
||||
{
|
||||
if (facade->IsCoreNode(forward_heap.Min()))
|
||||
if (facade.IsCoreNode(forward_heap.Min()))
|
||||
{
|
||||
const NodeID node = forward_heap.DeleteMin();
|
||||
const EdgeWeight key = forward_heap.GetKey(node);
|
||||
@ -327,7 +324,7 @@ void BasicRoutingInterface::SearchWithCore(
|
||||
}
|
||||
if (!reverse_heap.Empty())
|
||||
{
|
||||
if (facade->IsCoreNode(reverse_heap.Min()))
|
||||
if (facade.IsCoreNode(reverse_heap.Min()))
|
||||
{
|
||||
const NodeID node = reverse_heap.DeleteMin();
|
||||
const EdgeWeight key = reverse_heap.GetKey(node);
|
||||
@ -422,7 +419,7 @@ void BasicRoutingInterface::SearchWithCore(
|
||||
BOOST_ASSERT_MSG((SPECIAL_NODEID != middle && INVALID_EDGE_WEIGHT != weight), "no path found");
|
||||
|
||||
// we need to unpack sub path from core heaps
|
||||
if (facade->IsCoreNode(middle))
|
||||
if (facade.IsCoreNode(middle))
|
||||
{
|
||||
if (weight != forward_core_heap.GetKey(middle) + reverse_core_heap.GetKey(middle))
|
||||
{
|
||||
@ -461,7 +458,7 @@ void BasicRoutingInterface::SearchWithCore(
|
||||
}
|
||||
}
|
||||
|
||||
bool BasicRoutingInterface::NeedsLoopForward(const PhantomNode &source_phantom,
|
||||
bool BasicRouting<algorithm::CH>::NeedsLoopForward(const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
{
|
||||
return source_phantom.forward_segment_id.enabled && target_phantom.forward_segment_id.enabled &&
|
||||
@ -470,7 +467,7 @@ bool BasicRoutingInterface::NeedsLoopForward(const PhantomNode &source_phantom,
|
||||
target_phantom.GetForwardWeightPlusOffset();
|
||||
}
|
||||
|
||||
bool BasicRoutingInterface::NeedsLoopBackwards(const PhantomNode &source_phantom,
|
||||
bool BasicRouting<algorithm::CH>::NeedsLoopBackwards(const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
{
|
||||
return source_phantom.reverse_segment_id.enabled && target_phantom.reverse_segment_id.enabled &&
|
||||
@ -479,8 +476,7 @@ bool BasicRoutingInterface::NeedsLoopBackwards(const PhantomNode &source_phantom
|
||||
target_phantom.GetReverseWeightPlusOffset();
|
||||
}
|
||||
|
||||
double BasicRoutingInterface::GetPathDistance(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
double BasicRouting<algorithm::CH>::GetPathDistance(const FacadeT &facade,
|
||||
const std::vector<NodeID> &packed_path,
|
||||
const PhantomNode &source_phantom,
|
||||
const PhantomNode &target_phantom) const
|
||||
@ -500,7 +496,7 @@ double BasicRoutingInterface::GetPathDistance(
|
||||
double prev_cos = std::cos(prev_lat);
|
||||
for (const auto &p : unpacked_path)
|
||||
{
|
||||
const auto current_coordinate = facade->GetCoordinateOfNode(p.turn_via_node);
|
||||
const auto current_coordinate = facade.GetCoordinateOfNode(p.turn_via_node);
|
||||
|
||||
const double current_lat =
|
||||
static_cast<double>(toFloating(current_coordinate.lat)) * DEGREE_TO_RAD;
|
||||
@ -539,8 +535,8 @@ double BasicRoutingInterface::GetPathDistance(
|
||||
// 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 BasicRoutingInterface::GetNetworkDistanceWithCore(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
double BasicRouting<algorithm::CH>::GetNetworkDistanceWithCore(
|
||||
const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
SearchEngineData::QueryHeap &forward_core_heap,
|
||||
@ -605,8 +601,7 @@ double BasicRoutingInterface::GetNetworkDistanceWithCore(
|
||||
// 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 BasicRoutingInterface::GetNetworkDistance(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
double BasicRouting<algorithm::CH>::GetNetworkDistance(const FacadeT &facade,
|
||||
SearchEngineData::QueryHeap &forward_heap,
|
||||
SearchEngineData::QueryHeap &reverse_heap,
|
||||
const PhantomNode &source_phantom,
|
||||
|
@ -9,8 +9,7 @@ namespace routing_algorithms
|
||||
|
||||
// allows a uturn at the target_phantom
|
||||
// searches source forward/reverse -> target forward/reverse
|
||||
void ShortestPathRouting::SearchWithUTurn(
|
||||
const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ShortestPathRouting<algorithm::CH>::SearchWithUTurn(const FacadeT &facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
@ -64,7 +63,7 @@ void ShortestPathRouting::SearchWithUTurn(
|
||||
is_oneway_source && super::NeedsLoopForward(source_phantom, target_phantom);
|
||||
auto needs_loop_backwards =
|
||||
is_oneway_target && super::NeedsLoopBackwards(source_phantom, target_phantom);
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
@ -100,7 +99,7 @@ void ShortestPathRouting::SearchWithUTurn(
|
||||
// searches shortest path between:
|
||||
// source forward/reverse -> target forward
|
||||
// source forward/reverse -> target reverse
|
||||
void ShortestPathRouting::Search(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ShortestPathRouting<algorithm::CH>::Search(const FacadeT &facade,
|
||||
QueryHeap &forward_heap,
|
||||
QueryHeap &reverse_heap,
|
||||
QueryHeap &forward_core_heap,
|
||||
@ -143,7 +142,7 @@ void ShortestPathRouting::Search(const std::shared_ptr<const datafacade::BaseDat
|
||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
@ -194,7 +193,7 @@ void ShortestPathRouting::Search(const std::shared_ptr<const datafacade::BaseDat
|
||||
}
|
||||
BOOST_ASSERT(forward_heap.Size() > 0);
|
||||
BOOST_ASSERT(reverse_heap.Size() > 0);
|
||||
if (facade->GetCoreSize() > 0)
|
||||
if (facade.GetCoreSize() > 0)
|
||||
{
|
||||
forward_core_heap.Clear();
|
||||
reverse_core_heap.Clear();
|
||||
@ -223,7 +222,8 @@ void ShortestPathRouting::Search(const std::shared_ptr<const datafacade::BaseDat
|
||||
}
|
||||
}
|
||||
|
||||
void ShortestPathRouting::UnpackLegs(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ShortestPathRouting<algorithm::CH>::UnpackLegs(
|
||||
const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const std::vector<NodeID> &total_packed_path,
|
||||
const std::vector<std::size_t> &packed_leg_begin,
|
||||
@ -253,17 +253,18 @@ void ShortestPathRouting::UnpackLegs(const std::shared_ptr<const datafacade::Bas
|
||||
}
|
||||
}
|
||||
|
||||
void ShortestPathRouting::operator()(const std::shared_ptr<const datafacade::BaseDataFacade> facade,
|
||||
void ShortestPathRouting<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const std::vector<PhantomNodes> &phantom_nodes_vector,
|
||||
const boost::optional<bool> continue_straight_at_waypoint,
|
||||
InternalRouteResult &raw_route_data) const
|
||||
{
|
||||
const bool allow_uturn_at_waypoint =
|
||||
!(continue_straight_at_waypoint ? *continue_straight_at_waypoint
|
||||
: facade->GetContinueStraightDefault());
|
||||
: facade.GetContinueStraightDefault());
|
||||
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade->GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearFirstThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
engine_working_data.InitializeOrClearSecondThreadLocalStorage(facade.GetNumberOfNodes());
|
||||
|
||||
QueryHeap &forward_heap = *(engine_working_data.forward_heap_1);
|
||||
QueryHeap &reverse_heap = *(engine_working_data.reverse_heap_1);
|
||||
|
228
src/engine/routing_algorithms/tile_turns.cpp
Normal file
228
src/engine/routing_algorithms/tile_turns.cpp
Normal file
@ -0,0 +1,228 @@
|
||||
#include "engine/routing_algorithms/tile_turns.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace engine
|
||||
{
|
||||
namespace routing_algorithms
|
||||
{
|
||||
|
||||
std::vector<TurnData> TileTurns<algorithm::CH>::
|
||||
operator()(const FacadeT &facade,
|
||||
const std::vector<RTreeLeaf> &edges,
|
||||
const std::vector<std::size_t> &sorted_edge_indexes) const
|
||||
{
|
||||
std::vector<TurnData> all_turn_data;
|
||||
|
||||
// Struct to hold info on all the EdgeBasedNodes that are visible in our tile
|
||||
// When we create these, we insure that (source, target) and packed_geometry_id
|
||||
// are all pointed in the same direction.
|
||||
struct EdgeBasedNodeInfo
|
||||
{
|
||||
bool is_geometry_forward; // Is the geometry forward or reverse?
|
||||
unsigned packed_geometry_id;
|
||||
};
|
||||
// Lookup table for edge-based-nodes
|
||||
std::unordered_map<NodeID, EdgeBasedNodeInfo> edge_based_node_info;
|
||||
|
||||
struct SegmentData
|
||||
{
|
||||
NodeID target_node;
|
||||
EdgeID edge_based_node_id;
|
||||
};
|
||||
|
||||
std::unordered_map<NodeID, std::vector<SegmentData>> directed_graph;
|
||||
// Reserve enough space for unique edge-based-nodes on every edge.
|
||||
// Only a tile with all unique edges will use this much, but
|
||||
// it saves us a bunch of re-allocations during iteration.
|
||||
directed_graph.reserve(edges.size() * 2);
|
||||
|
||||
// Build an adjacency list for all the road segments visible in
|
||||
// the tile
|
||||
for (const auto &edge_index : sorted_edge_indexes)
|
||||
{
|
||||
const auto &edge = edges[edge_index];
|
||||
if (edge.forward_segment_id.enabled)
|
||||
{
|
||||
// operator[] will construct an empty vector at [edge.u] if there is no value.
|
||||
directed_graph[edge.u].push_back({edge.v, edge.forward_segment_id.id});
|
||||
if (edge_based_node_info.count(edge.forward_segment_id.id) == 0)
|
||||
{
|
||||
edge_based_node_info[edge.forward_segment_id.id] = {true, edge.packed_geometry_id};
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(edge_based_node_info[edge.forward_segment_id.id].is_geometry_forward ==
|
||||
true);
|
||||
BOOST_ASSERT(edge_based_node_info[edge.forward_segment_id.id].packed_geometry_id ==
|
||||
edge.packed_geometry_id);
|
||||
}
|
||||
}
|
||||
if (edge.reverse_segment_id.enabled)
|
||||
{
|
||||
directed_graph[edge.v].push_back({edge.u, edge.reverse_segment_id.id});
|
||||
if (edge_based_node_info.count(edge.reverse_segment_id.id) == 0)
|
||||
{
|
||||
edge_based_node_info[edge.reverse_segment_id.id] = {false, edge.packed_geometry_id};
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(edge_based_node_info[edge.reverse_segment_id.id].is_geometry_forward ==
|
||||
false);
|
||||
BOOST_ASSERT(edge_based_node_info[edge.reverse_segment_id.id].packed_geometry_id ==
|
||||
edge.packed_geometry_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Given a turn:
|
||||
// u---v
|
||||
// |
|
||||
// w
|
||||
// uv is the "approach"
|
||||
// vw is the "exit"
|
||||
std::vector<contractor::QueryEdge::EdgeData> unpacked_shortcut;
|
||||
std::vector<EdgeWeight> approach_weight_vector;
|
||||
|
||||
// Make sure we traverse the startnodes in a consistent order
|
||||
// to ensure identical PBF encoding on all platforms.
|
||||
std::vector<NodeID> sorted_startnodes;
|
||||
sorted_startnodes.reserve(directed_graph.size());
|
||||
for (const auto &startnode : directed_graph)
|
||||
sorted_startnodes.push_back(startnode.first);
|
||||
std::sort(sorted_startnodes.begin(), sorted_startnodes.end());
|
||||
|
||||
// Look at every node in the directed graph we created
|
||||
for (const auto &startnode : sorted_startnodes)
|
||||
{
|
||||
const auto &nodedata = directed_graph[startnode];
|
||||
// For all the outgoing edges from the node
|
||||
for (const auto &approachedge : nodedata)
|
||||
{
|
||||
// If the target of this edge doesn't exist in our directed
|
||||
// graph, it's probably outside the tile, so we can skip it
|
||||
if (directed_graph.count(approachedge.target_node) == 0)
|
||||
continue;
|
||||
|
||||
// For each of the outgoing edges from our target coordinate
|
||||
for (const auto &exit_edge : directed_graph[approachedge.target_node])
|
||||
{
|
||||
// If the next edge has the same edge_based_node_id, then it's
|
||||
// not a turn, so skip it
|
||||
if (approachedge.edge_based_node_id == exit_edge.edge_based_node_id)
|
||||
continue;
|
||||
|
||||
// Skip u-turns
|
||||
if (startnode == exit_edge.target_node)
|
||||
continue;
|
||||
|
||||
// Find the connection between our source road and the target node
|
||||
// Since we only want to find direct edges, we cannot check shortcut edges here.
|
||||
// Otherwise we might find a forward edge even though a shorter backward edge
|
||||
// exists (due to oneways).
|
||||
//
|
||||
// a > - > - > - b
|
||||
// | |
|
||||
// |------ c ----|
|
||||
//
|
||||
// would offer a backward edge at `b` to `a` (due to the oneway from a to b)
|
||||
// but could also offer a shortcut (b-c-a) from `b` to `a` which is longer.
|
||||
EdgeID smaller_edge_id =
|
||||
facade.FindSmallestEdge(approachedge.edge_based_node_id,
|
||||
exit_edge.edge_based_node_id,
|
||||
[](const contractor::QueryEdge::EdgeData &data) {
|
||||
return data.forward && !data.shortcut;
|
||||
});
|
||||
|
||||
// Depending on how the graph is constructed, we might have to look for
|
||||
// a backwards edge instead. They're equivalent, just one is available for
|
||||
// a forward routing search, and one is used for the backwards dijkstra
|
||||
// steps. Their weight should be the same, we can use either one.
|
||||
// If we didn't find a forward edge, try for a backward one
|
||||
if (SPECIAL_EDGEID == smaller_edge_id)
|
||||
{
|
||||
smaller_edge_id =
|
||||
facade.FindSmallestEdge(exit_edge.edge_based_node_id,
|
||||
approachedge.edge_based_node_id,
|
||||
[](const contractor::QueryEdge::EdgeData &data) {
|
||||
return data.backward && !data.shortcut;
|
||||
});
|
||||
}
|
||||
|
||||
// If no edge was found, it means that there's no connection between these
|
||||
// nodes, due to oneways or turn restrictions. Given the edge-based-nodes
|
||||
// that we're examining here, we *should* only find directly-connected
|
||||
// edges, not shortcuts
|
||||
if (smaller_edge_id != SPECIAL_EDGEID)
|
||||
{
|
||||
const auto &data = facade.GetEdgeData(smaller_edge_id);
|
||||
BOOST_ASSERT_MSG(!data.shortcut, "Connecting edge must not be a shortcut");
|
||||
|
||||
// Now, calculate the sum of the weight of all the segments.
|
||||
if (edge_based_node_info[approachedge.edge_based_node_id].is_geometry_forward)
|
||||
{
|
||||
approach_weight_vector = facade.GetUncompressedForwardWeights(
|
||||
edge_based_node_info[approachedge.edge_based_node_id]
|
||||
.packed_geometry_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
approach_weight_vector = facade.GetUncompressedReverseWeights(
|
||||
edge_based_node_info[approachedge.edge_based_node_id]
|
||||
.packed_geometry_id);
|
||||
}
|
||||
const auto sum_node_weight = std::accumulate(approach_weight_vector.begin(),
|
||||
approach_weight_vector.end(),
|
||||
EdgeWeight{0});
|
||||
|
||||
// The edge.weight is the whole edge weight, which includes the turn
|
||||
// cost.
|
||||
// The turn cost is the edge.weight minus the sum of the individual road
|
||||
// segment weights. This might not be 100% accurate, because some
|
||||
// intersections include stop signs, traffic signals and other
|
||||
// penalties, but at this stage, we can't divide those out, so we just
|
||||
// treat the whole lot as the "turn cost" that we'll stick on the map.
|
||||
const auto turn_cost = data.weight - sum_node_weight;
|
||||
|
||||
// Find the three nodes that make up the turn movement)
|
||||
const auto node_from = startnode;
|
||||
const auto node_via = approachedge.target_node;
|
||||
const auto node_to = exit_edge.target_node;
|
||||
|
||||
const auto coord_from = facade.GetCoordinateOfNode(node_from);
|
||||
const auto coord_via = facade.GetCoordinateOfNode(node_via);
|
||||
const auto coord_to = facade.GetCoordinateOfNode(node_to);
|
||||
|
||||
// Calculate the bearing that we approach the intersection at
|
||||
const auto angle_in = static_cast<int>(
|
||||
util::coordinate_calculation::bearing(coord_from, coord_via));
|
||||
|
||||
const auto exit_bearing = static_cast<int>(
|
||||
util::coordinate_calculation::bearing(coord_via, coord_to));
|
||||
|
||||
// Figure out the angle of the turn
|
||||
auto turn_angle = exit_bearing - angle_in;
|
||||
while (turn_angle > 180)
|
||||
{
|
||||
turn_angle -= 360;
|
||||
}
|
||||
while (turn_angle < -180)
|
||||
{
|
||||
turn_angle += 360;
|
||||
}
|
||||
|
||||
// Save everything we need to later add all the points to the tile.
|
||||
// We need the coordinate of the intersection, the angle in, the turn
|
||||
// angle and the turn cost.
|
||||
all_turn_data.push_back(TurnData{coord_via, angle_in, turn_angle, turn_cost});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return all_turn_data;
|
||||
}
|
||||
|
||||
} // namespace routing_algorithms
|
||||
} // namespace engine
|
||||
} // namespace osrm
|
@ -1,4 +1,5 @@
|
||||
#include "osrm/osrm.hpp"
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/api/match_parameters.hpp"
|
||||
#include "engine/api/nearest_parameters.hpp"
|
||||
#include "engine/api/route_parameters.hpp"
|
||||
@ -15,7 +16,10 @@ namespace osrm
|
||||
|
||||
// Pimpl idiom
|
||||
|
||||
OSRM::OSRM(engine::EngineConfig &config) : engine_(std::make_unique<engine::Engine>(config)) {}
|
||||
OSRM::OSRM(engine::EngineConfig &config)
|
||||
: engine_(std::make_unique<engine::Engine<engine::algorithm::CH>>(config))
|
||||
{
|
||||
}
|
||||
OSRM::~OSRM() = default;
|
||||
OSRM::OSRM(OSRM &&) noexcept = default;
|
||||
OSRM &OSRM::operator=(OSRM &&) noexcept = default;
|
||||
|
@ -240,9 +240,9 @@ void Storage::PopulateLayout(DataLayout &layout)
|
||||
|
||||
const auto hsgr_header = serialization::readHSGRHeader(hsgr_file);
|
||||
layout.SetBlockSize<unsigned>(DataLayout::HSGR_CHECKSUM, 1);
|
||||
layout.SetBlockSize<QueryGraph::NodeArrayEntry>(DataLayout::GRAPH_NODE_LIST,
|
||||
layout.SetBlockSize<QueryGraph::NodeArrayEntry>(DataLayout::CH_GRAPH_NODE_LIST,
|
||||
hsgr_header.number_of_nodes);
|
||||
layout.SetBlockSize<QueryGraph::EdgeArrayEntry>(DataLayout::GRAPH_EDGE_LIST,
|
||||
layout.SetBlockSize<QueryGraph::EdgeArrayEntry>(DataLayout::CH_GRAPH_EDGE_LIST,
|
||||
hsgr_header.number_of_edges);
|
||||
}
|
||||
|
||||
@ -271,7 +271,7 @@ void Storage::PopulateLayout(DataLayout &layout)
|
||||
{
|
||||
io::FileReader core_marker_file(config.core_data_path, io::FileReader::HasNoFingerprint);
|
||||
const auto number_of_core_markers = core_marker_file.ReadElementCount32();
|
||||
layout.SetBlockSize<unsigned>(DataLayout::CORE_MARKER, number_of_core_markers);
|
||||
layout.SetBlockSize<unsigned>(DataLayout::CH_CORE_MARKER, number_of_core_markers);
|
||||
}
|
||||
|
||||
// load turn weight penalties
|
||||
@ -412,12 +412,12 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
||||
// load the nodes of the search graph
|
||||
QueryGraph::NodeArrayEntry *graph_node_list_ptr =
|
||||
layout.GetBlockPtr<QueryGraph::NodeArrayEntry, true>(memory_ptr,
|
||||
DataLayout::GRAPH_NODE_LIST);
|
||||
DataLayout::CH_GRAPH_NODE_LIST);
|
||||
|
||||
// load the edges of the search graph
|
||||
QueryGraph::EdgeArrayEntry *graph_edge_list_ptr =
|
||||
layout.GetBlockPtr<QueryGraph::EdgeArrayEntry, true>(memory_ptr,
|
||||
DataLayout::GRAPH_EDGE_LIST);
|
||||
DataLayout::CH_GRAPH_EDGE_LIST);
|
||||
|
||||
serialization::readHSGR(hsgr_file,
|
||||
graph_node_list_ptr,
|
||||
@ -723,7 +723,7 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr)
|
||||
core_marker_file.ReadInto(unpacked_core_markers.data(), number_of_core_markers);
|
||||
|
||||
const auto core_marker_ptr =
|
||||
layout.GetBlockPtr<unsigned, true>(memory_ptr, DataLayout::CORE_MARKER);
|
||||
layout.GetBlockPtr<unsigned, true>(memory_ptr, DataLayout::CH_CORE_MARKER);
|
||||
|
||||
for (auto i = 0u; i < number_of_core_markers; ++i)
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE(hint_encoding_decoding_roundtrip)
|
||||
|
||||
const Coordinate coordinate;
|
||||
const PhantomNode phantom;
|
||||
const osrm::test::MockDataFacade facade{};
|
||||
const osrm::test::MockDataFacade<osrm::engine::algorithm::CH> facade{};
|
||||
|
||||
const Hint hint{phantom, facade.GetCheckSum()};
|
||||
|
||||
@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(hint_encoding_decoding_roundtrip_bytewise)
|
||||
|
||||
const Coordinate coordinate;
|
||||
const PhantomNode phantom;
|
||||
const osrm::test::MockDataFacade facade{};
|
||||
const osrm::test::MockDataFacade<osrm::engine::algorithm::CH> facade{};
|
||||
|
||||
const Hint hint{phantom, facade.GetCheckSum()};
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
#include "extractor/guidance/turn_lane_types.hpp"
|
||||
#include "engine/algorithm.hpp"
|
||||
#include "engine/datafacade/algorithm_datafacade.hpp"
|
||||
#include "engine/datafacade/datafacade_base.hpp"
|
||||
#include "util/guidance/bearing_class.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
@ -17,47 +19,11 @@ namespace osrm
|
||||
namespace test
|
||||
{
|
||||
|
||||
class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
class MockBaseDataFacade : public engine::datafacade::BaseDataFacade
|
||||
{
|
||||
using StringView = util::StringView;
|
||||
|
||||
private:
|
||||
EdgeData foo;
|
||||
|
||||
public:
|
||||
unsigned GetNumberOfNodes() const override { return 0; }
|
||||
unsigned GetNumberOfEdges() const override { return 0; }
|
||||
unsigned GetOutDegree(const NodeID /* n */) const override { return 0; }
|
||||
NodeID GetTarget(const EdgeID /* e */) const override { return SPECIAL_NODEID; }
|
||||
const EdgeData &GetEdgeData(const EdgeID /* e */) const override { return foo; }
|
||||
EdgeID BeginEdges(const NodeID /* n */) const override { return SPECIAL_EDGEID; }
|
||||
EdgeID EndEdges(const NodeID /* n */) const override { return SPECIAL_EDGEID; }
|
||||
osrm::engine::datafacade::EdgeRange GetAdjacentEdgeRange(const NodeID /* node */) const override
|
||||
{
|
||||
return util::irange(static_cast<EdgeID>(0), static_cast<EdgeID>(0));
|
||||
}
|
||||
EdgeID FindEdge(const NodeID /* from */, const NodeID /* to */) const override
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
EdgeID FindEdgeInEitherDirection(const NodeID /* from */, const NodeID /* to */) const override
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
|
||||
EdgeID FindSmallestEdge(const NodeID /* from */,
|
||||
const NodeID /* to */,
|
||||
std::function<bool(EdgeData)> /* filter */) const override
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
|
||||
EdgeID FindEdgeIndicateIfReverse(const NodeID /* from */,
|
||||
const NodeID /* to */,
|
||||
bool & /* result */) const override
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
util::Coordinate GetCoordinateOfNode(const NodeID /* id */) const override
|
||||
{
|
||||
return {util::FixedLongitude{0}, util::FixedLatitude{0}};
|
||||
@ -211,7 +177,6 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
}
|
||||
|
||||
unsigned GetCheckSum() const override { return 0; }
|
||||
bool IsCoreNode(const NodeID /* id */) const override { return false; }
|
||||
|
||||
NameID GetNameIndexFromEdgeID(const EdgeID /* id */) const override { return 0; }
|
||||
|
||||
@ -220,7 +185,6 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
StringView GetPronunciationForID(const NameID) const override final { return {}; }
|
||||
StringView GetDestinationsForID(const NameID) const override final { return {}; }
|
||||
|
||||
std::size_t GetCoreSize() const override { return 0; }
|
||||
std::string GetTimestamp() const override { return ""; }
|
||||
bool GetContinueStraightDefault() const override { return true; }
|
||||
double GetMapMatchingMaxSpeed() const override { return 180 / 3.6; }
|
||||
@ -270,6 +234,59 @@ class MockDataFacade final : public engine::datafacade::BaseDataFacade
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename AlgorithmT> class MockAlgorithmDataFacade;
|
||||
|
||||
template <>
|
||||
class MockAlgorithmDataFacade<engine::algorithm::CH>
|
||||
: public engine::datafacade::AlgorithmDataFacade<engine::algorithm::CH>
|
||||
{
|
||||
private:
|
||||
EdgeData foo;
|
||||
|
||||
public:
|
||||
unsigned GetNumberOfNodes() const override { return 0; }
|
||||
unsigned GetNumberOfEdges() const override { return 0; }
|
||||
unsigned GetOutDegree(const NodeID /* n */) const override { return 0; }
|
||||
NodeID GetTarget(const EdgeID /* e */) const override { return SPECIAL_NODEID; }
|
||||
const EdgeData &GetEdgeData(const EdgeID /* e */) const override { return foo; }
|
||||
EdgeID BeginEdges(const NodeID /* n */) const override { return SPECIAL_EDGEID; }
|
||||
EdgeID EndEdges(const NodeID /* n */) const override { return SPECIAL_EDGEID; }
|
||||
osrm::engine::datafacade::EdgeRange GetAdjacentEdgeRange(const NodeID /* node */) const override
|
||||
{
|
||||
return util::irange(static_cast<EdgeID>(0), static_cast<EdgeID>(0));
|
||||
}
|
||||
EdgeID FindEdge(const NodeID /* from */, const NodeID /* to */) const override
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
EdgeID FindEdgeInEitherDirection(const NodeID /* from */, const NodeID /* to */) const override
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
|
||||
EdgeID FindSmallestEdge(const NodeID /* from */,
|
||||
const NodeID /* to */,
|
||||
std::function<bool(EdgeData)> /* filter */) const override
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
|
||||
EdgeID FindEdgeIndicateIfReverse(const NodeID /* from */,
|
||||
const NodeID /* to */,
|
||||
bool & /* result */) const override
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
bool IsCoreNode(const NodeID /* id */) const override { return false; }
|
||||
std::size_t GetCoreSize() const override { return 0; }
|
||||
};
|
||||
|
||||
template <typename AlgorithmT>
|
||||
class MockDataFacade final : public MockBaseDataFacade, public MockAlgorithmDataFacade<AlgorithmT>
|
||||
{
|
||||
};
|
||||
|
||||
} // ns test
|
||||
} // ns osrm
|
||||
|
||||
|
@ -358,8 +358,8 @@ BOOST_AUTO_TEST_CASE(radius_regression_test)
|
||||
std::string nodes_path;
|
||||
build_rtree<GraphFixture, MiniStaticRTree>("test_angle", &fixture, leaves_path, nodes_path);
|
||||
MiniStaticRTree rtree(nodes_path, leaves_path, fixture.coords);
|
||||
MockDataFacade mockfacade;
|
||||
engine::GeospatialQuery<MiniStaticRTree, MockDataFacade> query(
|
||||
MockDataFacade<engine::algorithm::CH> mockfacade;
|
||||
engine::GeospatialQuery<MiniStaticRTree, MockDataFacade<engine::algorithm::CH>> query(
|
||||
rtree, fixture.coords, mockfacade);
|
||||
|
||||
Coordinate input(FloatLongitude{5.2}, FloatLatitude{5.0});
|
||||
@ -385,8 +385,8 @@ BOOST_AUTO_TEST_CASE(bearing_tests)
|
||||
std::string nodes_path;
|
||||
build_rtree<GraphFixture, MiniStaticRTree>("test_bearing", &fixture, leaves_path, nodes_path);
|
||||
MiniStaticRTree rtree(nodes_path, leaves_path, fixture.coords);
|
||||
MockDataFacade mockfacade;
|
||||
engine::GeospatialQuery<MiniStaticRTree, MockDataFacade> query(
|
||||
MockDataFacade<engine::algorithm::CH> mockfacade;
|
||||
engine::GeospatialQuery<MiniStaticRTree, MockDataFacade<engine::algorithm::CH>> query(
|
||||
rtree, fixture.coords, mockfacade);
|
||||
|
||||
Coordinate input(FloatLongitude{5.1}, FloatLatitude{5.0});
|
||||
@ -459,8 +459,8 @@ BOOST_AUTO_TEST_CASE(bbox_search_tests)
|
||||
std::string nodes_path;
|
||||
build_rtree<GraphFixture, MiniStaticRTree>("test_bbox", &fixture, leaves_path, nodes_path);
|
||||
MiniStaticRTree rtree(nodes_path, leaves_path, fixture.coords);
|
||||
MockDataFacade mockfacade;
|
||||
engine::GeospatialQuery<MiniStaticRTree, MockDataFacade> query(
|
||||
MockDataFacade<engine::algorithm::CH> mockfacade;
|
||||
engine::GeospatialQuery<MiniStaticRTree, MockDataFacade<engine::algorithm::CH>> query(
|
||||
rtree, fixture.coords, mockfacade);
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user