make implementation of restriction map independent of graph type
This commit is contained in:
parent
4b583e8ce9
commit
13bf4fab32
@ -389,10 +389,10 @@ void EdgeBasedGraphFactory::CompressGeometry()
|
|||||||
|
|
||||||
// update any involved turn restrictions
|
// update any involved turn restrictions
|
||||||
m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w);
|
m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w);
|
||||||
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w);
|
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w, m_node_based_graph);
|
||||||
|
|
||||||
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
|
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
|
||||||
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u);
|
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u, m_node_based_graph);
|
||||||
|
|
||||||
// store compressed geometry in container
|
// store compressed geometry in container
|
||||||
m_geometry_compressor.CompressEdge(
|
m_geometry_compressor.CompressEdge(
|
||||||
|
@ -510,8 +510,7 @@ Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
|
|||||||
SimpleLogger().Write() << "Generating edge-expanded graph representation";
|
SimpleLogger().Write() << "Generating edge-expanded graph representation";
|
||||||
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph =
|
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph =
|
||||||
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
|
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
|
||||||
std::unique_ptr<RestrictionMap> restriction_map =
|
std::unique_ptr<RestrictionMap> restriction_map = osrm::make_unique<RestrictionMap>(restriction_list);
|
||||||
std::unique_ptr<RestrictionMap>(new RestrictionMap(node_based_graph, restriction_list));
|
|
||||||
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
|
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
|
||||||
std::make_shared<EdgeBasedGraphFactory>(node_based_graph,
|
std::make_shared<EdgeBasedGraphFactory>(node_based_graph,
|
||||||
std::move(restriction_map),
|
std::move(restriction_map),
|
||||||
|
@ -27,98 +27,53 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include "restriction_map.hpp"
|
#include "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)
|
||||||
|
{
|
||||||
|
m_restriction_start_nodes.insert(restriction.from.node);
|
||||||
|
m_no_turn_via_node_set.insert(restriction.via.node);
|
||||||
|
|
||||||
|
RestrictionSource restriction_source = {restriction.from.node, restriction.via.node};
|
||||||
|
|
||||||
|
unsigned 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;
|
||||||
|
m_restriction_bucket_list.at(index)
|
||||||
|
.emplace_back(restriction.to.node, restriction.flags.is_only);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool RestrictionMap::IsViaNode(const NodeID node) const
|
bool RestrictionMap::IsViaNode(const NodeID node) const
|
||||||
{
|
{
|
||||||
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
|
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
RestrictionMap::RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &graph,
|
|
||||||
const std::vector<TurnRestriction> &restriction_list)
|
|
||||||
: m_count(0), m_graph(graph)
|
|
||||||
{
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
m_restriction_start_nodes.insert(restriction.from.node);
|
|
||||||
m_no_turn_via_node_set.insert(restriction.via.node);
|
|
||||||
|
|
||||||
RestrictionSource restriction_source = {restriction.from.node, restriction.via.node};
|
|
||||||
|
|
||||||
unsigned 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;
|
|
||||||
m_restriction_bucket_list.at(index)
|
|
||||||
.emplace_back(restriction.to.node, restriction.flags.is_only);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace end v with w in each turn restriction containing u as via node
|
|
||||||
void RestrictionMap::FixupArrivingTurnRestriction(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 (!IsViaNode(node_u))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find all potential start edges. It is more efficent to get a (small) list
|
|
||||||
// of potential start edges than iterating over all buckets
|
|
||||||
std::vector<NodeID> predecessors;
|
|
||||||
for (const EdgeID current_edge_id : m_graph->GetAdjacentEdgeRange(node_u))
|
|
||||||
{
|
|
||||||
const NodeID target = m_graph->GetTarget(current_edge_id);
|
|
||||||
if (node_v != target)
|
|
||||||
{
|
|
||||||
predecessors.push_back(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const NodeID node_x : predecessors)
|
|
||||||
{
|
|
||||||
const auto restriction_iterator = m_restriction_map.find({node_x, node_u});
|
|
||||||
if (restriction_iterator == m_restriction_map.end())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned index = restriction_iterator->second;
|
|
||||||
auto &bucket = m_restriction_bucket_list.at(index);
|
|
||||||
for (RestrictionTarget &restriction_target : bucket)
|
|
||||||
{
|
|
||||||
if (node_v == restriction_target.target_node)
|
|
||||||
{
|
|
||||||
restriction_target.target_node = node_w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replaces start edge (v, w) with (u, w). Only start node changes.
|
// Replaces start edge (v, w) with (u, w). Only start node changes.
|
||||||
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
|
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
|
||||||
|
@ -30,13 +30,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "node_based_graph.hpp"
|
|
||||||
#include "restriction.hpp"
|
#include "restriction.hpp"
|
||||||
#include "../Util/std_hash.hpp"
|
#include "../Util/std_hash.hpp"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct RestrictionSource
|
struct RestrictionSource
|
||||||
{
|
{
|
||||||
@ -94,26 +96,84 @@ template <> struct hash<RestrictionTarget>
|
|||||||
class RestrictionMap
|
class RestrictionMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RestrictionMap(const std::shared_ptr<NodeBasedDynamicGraph> &graph,
|
RestrictionMap(const std::vector<TurnRestriction> &restriction_list);
|
||||||
const std::vector<TurnRestriction> &input_restrictions_list);
|
|
||||||
|
// Replace end v with w in each turn restriction containing u as via node
|
||||||
|
template<class GraphT>
|
||||||
|
void FixupArrivingTurnRestriction(const NodeID node_u,
|
||||||
|
const NodeID node_v,
|
||||||
|
const NodeID node_w,
|
||||||
|
const std::shared_ptr<GraphT> &graph)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
||||||
|
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
||||||
|
BOOST_ASSERT(node_w != SPECIAL_NODEID);
|
||||||
|
|
||||||
|
if (!IsViaNode(node_u))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find all potential start edges. It is more efficent to get a (small) list
|
||||||
|
// of potential start edges than iterating over all buckets
|
||||||
|
std::vector<NodeID> predecessors;
|
||||||
|
for (const EdgeID current_edge_id : graph->GetAdjacentEdgeRange(node_u))
|
||||||
|
{
|
||||||
|
const NodeID target = graph->GetTarget(current_edge_id);
|
||||||
|
if (node_v != target)
|
||||||
|
{
|
||||||
|
predecessors.push_back(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const NodeID node_x : predecessors)
|
||||||
|
{
|
||||||
|
const auto restriction_iterator = m_restriction_map.find({node_x, node_u});
|
||||||
|
if (restriction_iterator == m_restriction_map.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned index = restriction_iterator->second;
|
||||||
|
auto &bucket = m_restriction_bucket_list.at(index);
|
||||||
|
for (RestrictionTarget &restriction_target : bucket)
|
||||||
|
{
|
||||||
|
if (node_v == restriction_target.target_node)
|
||||||
|
{
|
||||||
|
restriction_target.target_node = node_w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FixupArrivingTurnRestriction(const NodeID u, const NodeID v, const NodeID w);
|
|
||||||
void FixupStartingTurnRestriction(const NodeID u, const NodeID v, const NodeID w);
|
|
||||||
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
|
|
||||||
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
|
|
||||||
bool IsViaNode(const NodeID node) const;
|
bool IsViaNode(const NodeID node) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Replaces start edge (v, w) with (u, w). Only start node changes.
|
||||||
|
void FixupStartingTurnRestriction(const NodeID node_u,
|
||||||
|
const NodeID node_v,
|
||||||
|
const NodeID node_w);
|
||||||
|
|
||||||
|
// Check if edge (u, v) is the start of any turn restriction.
|
||||||
|
// If so returns id of first target node.
|
||||||
|
NodeID CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const;
|
||||||
|
// Checks if turn <u,v,w> is actually a turn restriction.
|
||||||
|
bool CheckIfTurnIsRestricted(const NodeID node_u,
|
||||||
|
const NodeID node_v,
|
||||||
|
const NodeID node_w) const;
|
||||||
|
|
||||||
std::size_t size()
|
std::size_t size()
|
||||||
{
|
{
|
||||||
return m_count;
|
return m_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// check of node is the start of any restriction
|
||||||
bool IsSourceNode(const NodeID node) const;
|
bool IsSourceNode(const NodeID node) const;
|
||||||
|
|
||||||
using EmanatingRestrictionsVector = std::vector<RestrictionTarget>;
|
using EmanatingRestrictionsVector = std::vector<RestrictionTarget>;
|
||||||
using EdgeData = NodeBasedDynamicGraph::EdgeData;
|
|
||||||
|
|
||||||
std::size_t m_count;
|
std::size_t m_count;
|
||||||
std::shared_ptr<NodeBasedDynamicGraph> m_graph;
|
|
||||||
//! index -> list of (target, isOnly)
|
//! index -> list of (target, isOnly)
|
||||||
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
|
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
|
||||||
//! maps (start, via) -> bucket index
|
//! maps (start, via) -> bucket index
|
||||||
|
Loading…
Reference in New Issue
Block a user