Currently OSRM only supports turn restrictions with a single via-node or one via-way. OSM allows for multiple via-ways to represent longer and more complex restrictions. This PR extends the use of duplicate nodes for representng via-way turn restrictions to also support multi via-way restrictions. Effectively, this increases the edge-based graph size by the number of edges in multi via-way restrictions. However, given the low number of these restrictions it has little effect on total graph size. In addition, we add a new step in the extraction phase that constructs a restriction graph to support more complex relationships between restrictions, such as nested restrictions and overlapping restrictions.
81 lines
2.3 KiB
C++
81 lines
2.3 KiB
C++
#ifndef OSRM_EXTRACTOR_NODE_RESTRICTION_MAP_HPP_
|
|
#define OSRM_EXTRACTOR_NODE_RESTRICTION_MAP_HPP_
|
|
|
|
#include "extractor/restriction.hpp"
|
|
#include "restriction_graph.hpp"
|
|
#include "util/typedefs.hpp"
|
|
|
|
#include <boost/range/adaptor/filtered.hpp>
|
|
#include <boost/unordered_map.hpp>
|
|
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace osrm
|
|
{
|
|
namespace extractor
|
|
{
|
|
|
|
// Allows easy check for whether a node restriction is present at a given intersection
|
|
template <typename RestrictionFilter> class NodeRestrictionMap
|
|
{
|
|
public:
|
|
NodeRestrictionMap(const RestrictionGraph &restriction_graph)
|
|
: restriction_graph(restriction_graph), index_filter(RestrictionFilter{})
|
|
{
|
|
}
|
|
|
|
// Find all restrictions applicable to (from,via,*) turns
|
|
auto Restrictions(NodeID from, NodeID via) const
|
|
{
|
|
return getRange(from, via) | boost::adaptors::filtered(index_filter);
|
|
};
|
|
|
|
// Find all restrictions applicable to (from,via,to) turns
|
|
auto Restrictions(NodeID from, NodeID via, NodeID to) const
|
|
{
|
|
const auto turnFilter = [this, to](const auto &restriction) {
|
|
return index_filter(restriction) && restriction->IsTurnRestricted(to);
|
|
};
|
|
return getRange(from, via) | boost::adaptors::filtered(turnFilter);
|
|
};
|
|
|
|
private:
|
|
RestrictionGraph::RestrictionRange getRange(NodeID from, NodeID via) const
|
|
{
|
|
const auto start_node_it = restriction_graph.start_edge_to_node.find({from, via});
|
|
if (start_node_it != restriction_graph.start_edge_to_node.end())
|
|
{
|
|
return restriction_graph.GetRestrictions(start_node_it->second);
|
|
}
|
|
return {};
|
|
}
|
|
const RestrictionGraph &restriction_graph;
|
|
const RestrictionFilter index_filter;
|
|
};
|
|
|
|
// Restriction filters to use as index defaults
|
|
struct ConditionalOnly
|
|
{
|
|
bool operator()(const TurnRestriction *restriction) const
|
|
{
|
|
return !restriction->IsUnconditional();
|
|
};
|
|
};
|
|
|
|
struct UnconditionalOnly
|
|
{
|
|
bool operator()(const TurnRestriction *restriction) const
|
|
{
|
|
return restriction->IsUnconditional();
|
|
};
|
|
};
|
|
|
|
using RestrictionMap = NodeRestrictionMap<UnconditionalOnly>;
|
|
using ConditionalRestrictionMap = NodeRestrictionMap<ConditionalOnly>;
|
|
|
|
} // namespace extractor
|
|
} // namespace osrm
|
|
|
|
#endif // OSRM_EXTRACTOR_NODE_RESTRICTION_MAP_HPP_
|