osrm-backend/src/extractor/restriction_map.cpp

155 lines
5.6 KiB
C++
Raw Normal View History

2016-01-02 11:13:44 -05:00
#include "extractor/restriction_map.hpp"
RestrictionMap::RestrictionMap(const std::vector<TurnRestriction> &restriction_list) : m_count(0)
{
// decompose restriction consisting of a start, via and end node into a
// a pair of starting edge and a list of all end nodes
for (auto &restriction : restriction_list)
{
// This downcasting is OK because when this is called, the node IDs have been
// renumbered into internal values, which should be well under 2^32
// This will be a problem if we have more than 2^32 actual restrictions
BOOST_ASSERT(restriction.from.node < std::numeric_limits<NodeID>::max());
BOOST_ASSERT(restriction.via.node < std::numeric_limits<NodeID>::max());
m_restriction_start_nodes.insert(restriction.from.node);
m_no_turn_via_node_set.insert(restriction.via.node);
// This explicit downcasting is also OK for the same reason.
2016-01-05 06:04:04 -05:00
RestrictionSource restriction_source = {static_cast<NodeID>(restriction.from.node),
static_cast<NodeID>(restriction.via.node)};
std::size_t index;
auto restriction_iter = m_restriction_map.find(restriction_source);
if (restriction_iter == m_restriction_map.end())
{
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restriction_source, index);
}
else
{
index = restriction_iter->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->is_only)
{
continue;
}
else if (restriction.flags.is_only)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_count -= m_restriction_bucket_list.at(index).size();
m_restriction_bucket_list.at(index).clear();
}
}
++m_count;
BOOST_ASSERT(restriction.to.node < std::numeric_limits<NodeID>::max());
m_restriction_bucket_list.at(index)
.emplace_back(restriction.to.node, restriction.flags.is_only);
}
}
bool RestrictionMap::IsViaNode(const NodeID node) const
{
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
}
// Replaces start edge (v, w) with (u, w). Only start node changes.
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w)
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
if (!IsSourceNode(node_v))
{
return;
}
const auto restriction_iterator = m_restriction_map.find({node_v, node_w});
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
// remove old restriction start (v,w)
m_restriction_map.erase(restriction_iterator);
m_restriction_start_nodes.emplace(node_u);
// insert new restriction start (u,w) (pointing to index)
RestrictionSource new_source = {node_u, node_w};
m_restriction_map.emplace(new_source, index);
}
}
// Check if edge (u, v) is the start of any turn restriction.
// If so returns id of first target node.
2014-06-26 07:50:15 -04:00
NodeID RestrictionMap::CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
if (!IsSourceNode(node_u))
{
return SPECIAL_NODEID;
}
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter != m_restriction_map.end())
{
const unsigned index = restriction_iter->second;
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
{
2014-06-25 11:12:15 -04:00
if (restriction_target.is_only)
{
2014-06-25 11:12:15 -04:00
return restriction_target.target_node;
}
}
}
return SPECIAL_NODEID;
}
// Checks if turn <u,v,w> is actually a turn restriction.
bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u,
const NodeID node_v,
const NodeID node_w) const
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
BOOST_ASSERT(node_w != SPECIAL_NODEID);
if (!IsSourceNode(node_u))
{
return false;
}
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter == m_restriction_map.end())
{
return false;
}
const unsigned index = restriction_iter->second;
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
{
if (node_w == restriction_target.target_node && // target found
!restriction_target.is_only) // and not an only_-restr.
{
return true;
}
if (node_w != restriction_target.target_node && // target not found
restriction_target.is_only) // and is an only restriction
{
return true;
}
}
return false;
}
// check of node is the start of any restriction
bool RestrictionMap::IsSourceNode(const NodeID node) const
{
2016-01-03 12:55:42 -05:00
return m_restriction_start_nodes.find(node) != m_restriction_start_nodes.end();
}