pre-filter turn restrictions for validity
This commit is contained in:
parent
2e9a7d9c1a
commit
b1809d1667
23
include/extractor/restriction_filter.hpp
Normal file
23
include/extractor/restriction_filter.hpp
Normal file
@ -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_
|
@ -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"
|
||||
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
88
src/extractor/restriction_filter.cpp
Normal file
88
src/extractor/restriction_filter.cpp
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user