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/extractor_callbacks.hpp"
|
||||||
#include "extractor/files.hpp"
|
#include "extractor/files.hpp"
|
||||||
#include "extractor/raster_source.hpp"
|
#include "extractor/raster_source.hpp"
|
||||||
|
#include "extractor/restriction_filter.hpp"
|
||||||
#include "extractor/restriction_parser.hpp"
|
#include "extractor/restriction_parser.hpp"
|
||||||
#include "extractor/scripting_environment.hpp"
|
#include "extractor/scripting_environment.hpp"
|
||||||
|
|
||||||
@ -465,6 +466,8 @@ Extractor::BuildEdgeExpandedGraph(ScriptingEnvironment &scripting_environment,
|
|||||||
*node_based_graph,
|
*node_based_graph,
|
||||||
compressed_edge_container);
|
compressed_edge_container);
|
||||||
|
|
||||||
|
turn_restrictions = removeInvalidRestrictions(std::move(turn_restrictions), *node_based_graph);
|
||||||
|
|
||||||
util::NameTable name_table(config.GetPath(".osrm.names").string());
|
util::NameTable name_table(config.GetPath(".osrm.names").string());
|
||||||
|
|
||||||
auto restriction_map = std::make_shared<RestrictionMap>(turn_restrictions);
|
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 =
|
const auto only_restriction_to_node =
|
||||||
restriction_map.CheckForEmanatingIsOnlyTurn(coming_from_node, node_at_intersection);
|
restriction_map.CheckForEmanatingIsOnlyTurn(coming_from_node, node_at_intersection);
|
||||||
if (only_restriction_to_node != SPECIAL_NODEID)
|
if (only_restriction_to_node != SPECIAL_NODEID)
|
||||||
{
|
return only_restriction_to_node;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
// Ignore broken only restrictions.
|
// Ignore broken only restrictions.
|
||||||
return boost::none;
|
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