Port OSRM, Engine and Datafacades to be algorithm aware

This commit is contained in:
Patrick Niklaus
2017-01-09 20:40:33 +00:00
committed by Patrick Niklaus
parent 71e95c92b6
commit 2fa8d0f534
47 changed files with 1384 additions and 1047 deletions
+37
View 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
+7 -6
View File
@@ -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;
};
}
}
@@ -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)
{
}
};
}
}
}
+2 -36
View File
@@ -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
View 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
+88 -14
View File
@@ -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 &parameters,
util::json::Object &result) const = 0;
virtual Status Table(const api::TableParameters &parameters,
util::json::Object &result) const = 0;
virtual Status Nearest(const api::NearestParameters &parameters,
util::json::Object &result) const = 0;
virtual Status Trip(const api::TripParameters &parameters,
util::json::Object &result) const = 0;
virtual Status Match(const api::MatchParameters &parameters,
util::json::Object &result) const = 0;
virtual Status Tile(const api::TileParameters &parameters, 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 &parameters, util::json::Object &result) const;
Status Table(const api::TableParameters &parameters, util::json::Object &result) const;
Status Nearest(const api::NearestParameters &parameters, util::json::Object &result) const;
Status Trip(const api::TripParameters &parameters, util::json::Object &result) const;
Status Match(const api::MatchParameters &parameters, util::json::Object &result) const;
Status Tile(const api::TileParameters &parameters, std::string &result) const;
Status Route(const api::RouteParameters &params,
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 &params,
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 &params,
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 &params, 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 &params,
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 &params, 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;
};
}
}
+4 -7
View File
@@ -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 &parameters,
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;
};
}
+4 -1
View File
@@ -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 &params,
util::json::Object &result) const;
+5 -4
View File
@@ -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;
}
+3 -3
View File
@@ -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 &params,
util::json::Object &result) const;
private:
mutable SearchEngineData heaps;
mutable routing_algorithms::ManyToManyRouting distance_table;
const int max_locations_distance_table;
};
}
+5 -4
View File
@@ -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 &parameters,
std::string &pbf_buffer) const;
};
+6 -12
View File
@@ -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 &parameters,
util::json::Object &json_result) const;
};
+5 -10
View File
@@ -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
View 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,17 +82,16 @@ 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,
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);
void 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);
// 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,
const std::vector<PhantomNode> &phantom_nodes,
const std::vector<std::size_t> &source_indices,
const std::vector<std::size_t> &target_indices) const;
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> &timestamps) 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,20 +412,19 @@ 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,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT) const;
double GetNetworkDistanceWithCore(const FacadeT &facade,
SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
SearchEngineData::QueryHeap &forward_core_heap,
SearchEngineData::QueryHeap &reverse_core_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT) const;
// 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;
@@ -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
+6 -6
View File
@@ -23,10 +23,10 @@ namespace trip
{
// computes the distance of a given permutation
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)
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)
{
EdgeWeight route_dist = 0;
std::size_t current_index = 0;
@@ -59,8 +59,8 @@ 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,
const util::DistTableWrapper<EdgeWeight> &dist_table)
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, ...
std::vector<NodeID> node_order(number_of_locations);
@@ -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,10 +76,10 @@ 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,
const util::DistTableWrapper<EdgeWeight> &dist_table,
const NodeID &start1,
const NodeID &start2)
inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
const util::DistTableWrapper<EdgeWeight> &dist_table,
const NodeID &start1,
const NodeID &start2)
{
BOOST_ASSERT_MSG(number_of_locations * number_of_locations == dist_table.size(),
"number_of_locations and dist_table size do not match");
@@ -134,8 +134,9 @@ std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
return route;
}
std::vector<NodeID> FarthestInsertionTrip(const std::size_t number_of_locations,
const util::DistTableWrapper<EdgeWeight> &dist_table)
inline std::vector<NodeID>
FarthestInsertionTrip(const std::size_t number_of_locations,
const util::DistTableWrapper<EdgeWeight> &dist_table)
{
//////////////////////////////////////////////////////////////////////////////////////////////////
// START FARTHEST INSERTION HERE