2016-01-02 11:13:44 -05:00
|
|
|
#include "extractor/restriction_map.hpp"
|
2014-05-05 19:35:43 -04:00
|
|
|
|
2016-01-05 10:51:13 -05:00
|
|
|
namespace osrm
|
|
|
|
{
|
|
|
|
namespace extractor
|
|
|
|
{
|
|
|
|
|
2015-02-19 03:19:51 -05:00
|
|
|
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)
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2015-11-24 19:33:19 -05:00
|
|
|
// 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());
|
2015-02-19 03:19:51 -05:00
|
|
|
m_restriction_start_nodes.insert(restriction.from.node);
|
|
|
|
m_no_turn_via_node_set.insert(restriction.via.node);
|
2014-05-19 06:53:27 -04:00
|
|
|
|
2015-11-24 19:33:19 -05:00
|
|
|
// 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)};
|
2014-05-19 06:53:27 -04:00
|
|
|
|
2015-02-19 03:19:51 -05:00
|
|
|
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)
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2015-02-19 03:19:51 -05:00
|
|
|
continue;
|
2014-05-08 17:29:24 -04:00
|
|
|
}
|
2015-02-19 03:19:51 -05:00
|
|
|
else if (restriction.flags.is_only)
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2015-02-19 03:19:51 -05:00
|
|
|
// 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();
|
2014-05-05 19:35:43 -04:00
|
|
|
}
|
|
|
|
}
|
2015-02-19 03:19:51 -05:00
|
|
|
++m_count;
|
2015-11-24 19:33:19 -05:00
|
|
|
BOOST_ASSERT(restriction.to.node < std::numeric_limits<NodeID>::max());
|
2016-05-27 15:05:04 -04:00
|
|
|
m_restriction_bucket_list.at(index).emplace_back(restriction.to.node,
|
|
|
|
restriction.flags.is_only);
|
2014-05-05 19:35:43 -04:00
|
|
|
}
|
2015-02-19 03:19:51 -05:00
|
|
|
}
|
2014-05-05 19:35:43 -04:00
|
|
|
|
2014-12-19 10:46:12 -05:00
|
|
|
bool RestrictionMap::IsViaNode(const NodeID node) const
|
|
|
|
{
|
|
|
|
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
|
2014-05-05 19:35:43 -04:00
|
|
|
}
|
|
|
|
|
2014-05-22 08:53:53 -04:00
|
|
|
// Replaces start edge (v, w) with (u, w). Only start node changes.
|
2014-06-05 09:40:52 -04:00
|
|
|
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
|
|
|
|
const NodeID node_v,
|
|
|
|
const NodeID node_w)
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2014-06-05 09:40:52 -04:00
|
|
|
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
|
|
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
|
|
|
BOOST_ASSERT(node_w != SPECIAL_NODEID);
|
2014-05-08 17:29:24 -04:00
|
|
|
|
2014-06-10 11:26:05 -04:00
|
|
|
if (!IsSourceNode(node_v))
|
2014-05-22 05:41:32 -04:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-05-08 17:29:24 -04:00
|
|
|
|
2014-06-26 04:14:25 -04:00
|
|
|
const auto restriction_iterator = m_restriction_map.find({node_v, node_w});
|
2014-05-08 17:29:24 -04:00
|
|
|
if (restriction_iterator != m_restriction_map.end())
|
|
|
|
{
|
2014-05-05 19:35:43 -04:00
|
|
|
const unsigned index = restriction_iterator->second;
|
|
|
|
// remove old restriction start (v,w)
|
2014-05-08 17:29:24 -04:00
|
|
|
m_restriction_map.erase(restriction_iterator);
|
2014-06-10 11:26:05 -04:00
|
|
|
m_restriction_start_nodes.emplace(node_u);
|
|
|
|
// insert new restriction start (u,w) (pointing to index)
|
2014-06-26 04:14:25 -04:00
|
|
|
RestrictionSource new_source = {node_u, node_w};
|
2014-05-22 05:41:32 -04:00
|
|
|
m_restriction_map.emplace(new_source, index);
|
2014-05-05 19:35:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 08:53:53 -04:00
|
|
|
// 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
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2014-06-05 09:40:52 -04:00
|
|
|
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
|
|
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
2014-05-05 19:35:43 -04:00
|
|
|
|
2014-06-10 11:26:05 -04:00
|
|
|
if (!IsSourceNode(node_u))
|
2014-05-22 05:41:32 -04:00
|
|
|
{
|
2014-05-22 08:53:53 -04:00
|
|
|
return SPECIAL_NODEID;
|
2014-05-22 05:41:32 -04:00
|
|
|
}
|
2014-05-05 19:35:43 -04:00
|
|
|
|
2014-08-07 12:34:39 -04:00
|
|
|
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
|
2014-05-08 17:29:24 -04:00
|
|
|
if (restriction_iter != m_restriction_map.end())
|
|
|
|
{
|
2014-05-05 19:35:43 -04:00
|
|
|
const unsigned index = restriction_iter->second;
|
2014-08-07 12:34:39 -04:00
|
|
|
const auto &bucket = m_restriction_bucket_list.at(index);
|
2014-06-25 10:03:11 -04:00
|
|
|
for (const RestrictionTarget &restriction_target : bucket)
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2014-06-25 11:12:15 -04:00
|
|
|
if (restriction_target.is_only)
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2014-06-25 11:12:15 -04:00
|
|
|
return restriction_target.target_node;
|
2014-05-05 19:35:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-05-22 08:53:53 -04:00
|
|
|
return SPECIAL_NODEID;
|
2014-05-05 19:35:43 -04:00
|
|
|
}
|
|
|
|
|
2014-05-22 08:53:53 -04:00
|
|
|
// Checks if turn <u,v,w> is actually a turn restriction.
|
2014-06-05 09:40:52 -04:00
|
|
|
bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u,
|
|
|
|
const NodeID node_v,
|
|
|
|
const NodeID node_w) const
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2014-06-05 09:40:52 -04:00
|
|
|
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
|
|
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
|
|
|
BOOST_ASSERT(node_w != SPECIAL_NODEID);
|
2014-05-05 19:35:43 -04:00
|
|
|
|
2014-06-10 11:26:05 -04:00
|
|
|
if (!IsSourceNode(node_u))
|
2014-05-22 05:41:32 -04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-05 19:35:43 -04:00
|
|
|
|
2014-08-07 12:34:39 -04:00
|
|
|
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
|
2015-01-22 06:39:41 -05:00
|
|
|
if (restriction_iter == m_restriction_map.end())
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2015-01-22 06:39:41 -05:00
|
|
|
return false;
|
|
|
|
}
|
2015-01-16 09:49:29 -05:00
|
|
|
|
2015-01-22 06:39:41 -05:00
|
|
|
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
|
2015-02-19 03:19:51 -05:00
|
|
|
!restriction_target.is_only) // and not an only_-restr.
|
2014-05-08 17:29:24 -04:00
|
|
|
{
|
2015-01-22 06:39:41 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (node_w != restriction_target.target_node && // target not found
|
|
|
|
restriction_target.is_only) // and is an only restriction
|
|
|
|
{
|
|
|
|
return true;
|
2014-05-05 19:35:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-22 05:41:32 -04:00
|
|
|
|
2014-05-22 08:53:53 -04:00
|
|
|
// check of node is the start of any restriction
|
2014-06-10 11:26:05 -04:00
|
|
|
bool RestrictionMap::IsSourceNode(const NodeID node) const
|
2014-05-22 05:41:32 -04:00
|
|
|
{
|
2016-01-03 12:55:42 -05:00
|
|
|
return m_restriction_start_nodes.find(node) != m_restriction_start_nodes.end();
|
2014-05-22 05:41:32 -04:00
|
|
|
}
|
2016-01-05 10:51:13 -05:00
|
|
|
}
|
|
|
|
}
|