- refactor conditional restriction handling to not use external data (first OSM nodes on ways) - BREAKING: changes internal file format of osrm.restrictions - add support for general conditional penalties based on edge-based nodes (requires unique edges between nodes)
102 lines
3.0 KiB
C++
102 lines
3.0 KiB
C++
#ifndef OSRM_EXTRACTOR_RESTRICTION_INDEX_HPP_
|
|
#define OSRM_EXTRACTOR_RESTRICTION_INDEX_HPP_
|
|
|
|
#include "extractor/restriction.hpp"
|
|
#include "util/typedefs.hpp"
|
|
|
|
#include <boost/unordered_map.hpp>
|
|
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace osrm
|
|
{
|
|
namespace extractor
|
|
{
|
|
|
|
// allows easy check for whether a node intersection is present at a given intersection
|
|
template <typename restriction_type> class RestrictionIndex
|
|
{
|
|
public:
|
|
using value_type = restriction_type;
|
|
|
|
template <typename extractor_type>
|
|
RestrictionIndex(std::vector<restriction_type> &restrictions, extractor_type extractor);
|
|
|
|
bool IsIndexed(NodeID first, NodeID second) const;
|
|
|
|
auto Restrictions(NodeID first, NodeID second) const
|
|
{
|
|
return restriction_hash.equal_range(std::make_pair(first, second));
|
|
};
|
|
|
|
auto Size() const { return restriction_hash.size(); }
|
|
|
|
private:
|
|
boost::unordered_multimap<std::pair<NodeID, NodeID>, restriction_type *> restriction_hash;
|
|
};
|
|
|
|
template <typename restriction_type>
|
|
template <typename extractor_type>
|
|
RestrictionIndex<restriction_type>::RestrictionIndex(std::vector<restriction_type> &restrictions,
|
|
extractor_type extractor)
|
|
{
|
|
// build a multi-map
|
|
for (auto &restriction : restrictions)
|
|
restriction_hash.insert(std::make_pair(extractor(restriction), &restriction));
|
|
}
|
|
|
|
template <typename restriction_type>
|
|
bool RestrictionIndex<restriction_type>::IsIndexed(const NodeID first, const NodeID second) const
|
|
{
|
|
return restriction_hash.count(std::make_pair(first, second));
|
|
}
|
|
|
|
struct IndexNodeByFromAndVia
|
|
{
|
|
std::pair<NodeID, NodeID> operator()(const TurnRestriction &restriction)
|
|
{
|
|
const auto &node = restriction.AsNodeRestriction();
|
|
return std::make_pair(node.from, node.via);
|
|
};
|
|
};
|
|
|
|
// check wheter a turn is restricted within a restriction_index
|
|
template <typename restriction_map_type>
|
|
std::pair<bool, typename restriction_map_type::value_type *>
|
|
isRestricted(const NodeID from,
|
|
const NodeID via,
|
|
const NodeID to,
|
|
const restriction_map_type &restriction_map)
|
|
{
|
|
const auto range = restriction_map.Restrictions(from, via);
|
|
|
|
// check if a given node_restriction is targeting node
|
|
const auto to_is_restricted = [to](const auto &pair) {
|
|
const auto &restriction = *pair.second;
|
|
if (restriction.Type() == RestrictionType::NODE_RESTRICTION)
|
|
{
|
|
auto const &as_node = restriction.AsNodeRestriction();
|
|
auto const restricted = restriction.is_only ? (to != as_node.to) : (to == as_node.to);
|
|
|
|
return restricted;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
auto itr = std::find_if(range.first, range.second, to_is_restricted);
|
|
|
|
if (itr != range.second)
|
|
return {true, itr->second};
|
|
else
|
|
return {false, NULL};
|
|
}
|
|
|
|
using RestrictionMap = RestrictionIndex<TurnRestriction>;
|
|
using ConditionalRestrictionMap = RestrictionIndex<ConditionalTurnRestriction>;
|
|
|
|
} // namespace extractor
|
|
} // namespace osrm
|
|
|
|
#endif // OSRM_EXTRACTOR_RESTRICTION_INDEX_HPP_
|