Skip to content

Commit

Permalink
pre-filter turn restrictions for validity
Browse files Browse the repository at this point in the history
  • Loading branch information
Moritz Kobitzsch committed Jul 31, 2017
1 parent 2e9a7d9 commit b1809d1
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 7 deletions.
23 changes: 23 additions & 0 deletions include/extractor/restriction_filter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef OSRM_EXTRACTOR_RESTRICTION_FILTER_HPP_
#define OSRM_EXTRACTOR_RESTRICTION_FILTER_HPP_

#include "extractor/restriction.hpp"
#include "util/node_based_graph.hpp"

#include <vector>

namespace osrm
{
namespace extractor
{

// To avoid handling invalid restrictions / creating unnecessary duplicate nodes for via-ways, we do
// a pre-flight check for restrictions and remove all invalid restrictions from the data. Use as
// `restrictions = removeInvalidRestrictions(std::move(restrictions))`
std::vector<TurnRestriction> removeInvalidRestrictions(std::vector<TurnRestriction>,
const util::NodeBasedDynamicGraph &);

} // namespace extractor
} // namespace osrm

#endif // OSRM_EXTRACTOR_RESTRICTION_FILTER_HPP_
3 changes: 3 additions & 0 deletions src/extractor/extractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "extractor/extractor_callbacks.hpp"
#include "extractor/files.hpp"
#include "extractor/raster_source.hpp"
#include "extractor/restriction_filter.hpp"
#include "extractor/restriction_parser.hpp"
#include "extractor/scripting_environment.hpp"

Expand Down Expand Up @@ -465,6 +466,8 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
*node_based_graph,
compressed_edge_container);

turn_restrictions = removeInvalidRestrictions(std::move(turn_restrictions), *node_based_graph);

util::NameTable name_table(config.GetPath(".osrm.names").string());

auto restriction_map = std::make_shared<RestrictionMap>(turn_restrictions);
Expand Down
9 changes: 2 additions & 7 deletions src/extractor/guidance/intersection_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,13 +405,8 @@ IntersectionGenerator::GetOnlyAllowedTurnIfExistent(const NodeID coming_from_nod
const auto only_restriction_to_node =
restriction_map.CheckForEmanatingIsOnlyTurn(coming_from_node, node_at_intersection);
if (only_restriction_to_node != SPECIAL_NODEID)
{
// if the mentioned node does not exist anymore, we don't return it. This checks for broken
// turn restrictions
for (const auto onto_edge : node_based_graph.GetAdjacentEdgeRange(node_at_intersection))
if (only_restriction_to_node == node_based_graph.GetTarget(onto_edge))
return only_restriction_to_node;
}
return only_restriction_to_node;

// Ignore broken only restrictions.
return boost::none;
}
Expand Down
88 changes: 88 additions & 0 deletions src/extractor/restriction_filter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "extractor/restriction_filter.hpp"
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"

#include <algorithm>
#include <boost/assert.hpp>

namespace osrm
{
namespace extractor
{

std::vector<TurnRestriction>
removeInvalidRestrictions(std::vector<TurnRestriction> restrictions,
const util::NodeBasedDynamicGraph &node_based_graph)
{
// definition of what we presume to be a valid via-node restriction
const auto is_valid_node = [&node_based_graph](const auto &node_restriction) {
// a valid restriction needs to be connected to both its from and to locations
bool found_from = false, found_to = false;
for (auto eid : node_based_graph.GetAdjacentEdgeRange(node_restriction.via))
{
const auto target = node_based_graph.GetTarget(eid);
if (target == node_restriction.from)
found_from = true;
if (target == node_restriction.to)
found_to = true;
}

if (!found_from || !found_to)
return false;

return true;
};

// definition of what we presume to be a valid via-way restriction
const auto is_valid_way = [&node_based_graph, is_valid_node](const auto &way_restriction) {
const auto eid = node_based_graph.FindEdge(way_restriction.in_restriction.via,
way_restriction.out_restriction.via);

// ability filter, we currently cannot handle restrictions that do not match up in geometry:
// restrictions cannot be interrupted by traffic signals or other similar entities that
// cause node penalties
if ((way_restriction.in_restriction.via != way_restriction.out_restriction.from) ||
(way_restriction.out_restriction.via != way_restriction.in_restriction.to))
return false;

// the edge needs to exit (we cannot handle intermediate stuff, so far)
if (eid == SPECIAL_EDGEID)
return false;

const auto &data = node_based_graph.GetEdgeData(eid);

// edge needs to be traversable for a valid restrction
if (data.reversed)
return false;

// is the in restriction referencing the correct nodes
if (!is_valid_node(way_restriction.in_restriction))
return false;

// is the out restriction referencing the correct nodes
if (!is_valid_node(way_restriction.out_restriction))
return false;

return true;
};

const auto is_invalid = [is_valid_way, is_valid_node](const auto &restriction) {
if (restriction.Type() == RestrictionType::NODE_RESTRICTION)
{
return !is_valid_node(restriction.AsNodeRestriction());
}
else
{
BOOST_ASSERT(restriction.Type() == RestrictionType::WAY_RESTRICTION);
return !is_valid_way(restriction.AsWayRestriction());
}
};

restrictions.erase(std::remove_if(restrictions.begin(), restrictions.end(), is_invalid),
restrictions.end());

return restrictions;
}

} // namespace extractor
} // namespace osrm

0 comments on commit b1809d1

Please sign in to comment.