enable suppression name suffix changes
This commit is contained in:
@@ -29,14 +29,26 @@ namespace engine
|
||||
namespace guidance
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// invalidate a step and set its content to nothing
|
||||
void invalidateStep(RouteStep &step)
|
||||
{
|
||||
step = {};
|
||||
step.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
};
|
||||
|
||||
void print(const std::vector<RouteStep> &steps)
|
||||
{
|
||||
std::cout << "Path\n";
|
||||
int segment = 0;
|
||||
for (const auto &step : steps)
|
||||
{
|
||||
const auto type = static_cast<int>(step.maneuver.instruction.type);
|
||||
const auto modifier = static_cast<int>(step.maneuver.instruction.direction_modifier);
|
||||
const auto type =
|
||||
static_cast<std::underlying_type<TurnType>::type>(step.maneuver.instruction.type);
|
||||
const auto modifier = static_cast<std::underlying_type<DirectionModifier>::type>(
|
||||
step.maneuver.instruction.direction_modifier);
|
||||
|
||||
std::cout << "\t[" << ++segment << "]: " << type << " " << modifier
|
||||
<< " Duration: " << step.duration << " Distance: " << step.distance
|
||||
@@ -53,37 +65,6 @@ void print(const std::vector<RouteStep> &steps)
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
void print(const std::vector<RouteStep> &steps)
|
||||
{
|
||||
std::cout << "Path\n";
|
||||
int segment = 0;
|
||||
for (const auto &step : steps)
|
||||
{
|
||||
const auto type = static_cast<int>(step.maneuver.instruction.type);
|
||||
const auto modifier = static_cast<int>(step.maneuver.instruction.direction_modifier);
|
||||
|
||||
std::cout << "\t[" << ++segment << "]: " << type << " " << modifier
|
||||
<< " Duration: " << step.duration << " Distance: " << step.distance
|
||||
<< " Geometry: " << step.geometry_begin << " " << step.geometry_end
|
||||
<< " exit: " << step.maneuver.exit
|
||||
<< " Intersections: " << step.maneuver.intersections.size() << " [";
|
||||
|
||||
for (auto intersection : step.maneuver.intersections)
|
||||
std::cout << "(" << intersection.duration << " " << intersection.distance << ")";
|
||||
|
||||
std::cout << "] name[" << step.name_id << "]: " << step.name << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool canMergeTrivially(const RouteStep &destination, const RouteStep &source)
|
||||
{
|
||||
return destination.maneuver.exit == 0 && destination.name_id == source.name_id &&
|
||||
isSilent(source.maneuver.instruction);
|
||||
}
|
||||
|
||||
RouteStep forwardInto(RouteStep destination, const RouteStep &source)
|
||||
{
|
||||
// Merge a turn into a silent turn
|
||||
@@ -95,13 +76,6 @@ RouteStep forwardInto(RouteStep destination, const RouteStep &source)
|
||||
return destination;
|
||||
}
|
||||
|
||||
// invalidate a step and set its content to nothing
|
||||
inline void invalidateStep(RouteStep &step)
|
||||
{
|
||||
step = {};
|
||||
step.maneuver.instruction = TurnInstruction::NO_TURN();
|
||||
};
|
||||
|
||||
void fixFinalRoundabout(std::vector<RouteStep> &steps)
|
||||
{
|
||||
for (std::size_t propagation_index = steps.size() - 1; propagation_index > 0;
|
||||
@@ -194,7 +168,7 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
BOOST_ASSERT(leavesRoundabout(steps[1].maneuver.instruction) ||
|
||||
steps[1].maneuver.instruction.type == TurnType::StayOnRoundabout);
|
||||
steps[0].geometry_end = 1;
|
||||
steps[1] = detail::forwardInto(steps[1], steps[0]);
|
||||
steps[1] = forwardInto(steps[1], steps[0]);
|
||||
steps[0].duration = 0;
|
||||
steps[0].distance = 0;
|
||||
const auto exitToEnter = [](const TurnType type) {
|
||||
@@ -223,7 +197,7 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
--propagation_index)
|
||||
{
|
||||
auto &propagation_step = steps[propagation_index];
|
||||
propagation_step = detail::forwardInto(propagation_step, steps[propagation_index + 1]);
|
||||
propagation_step = forwardInto(propagation_step, steps[propagation_index + 1]);
|
||||
if (entersRoundabout(propagation_step.maneuver.instruction))
|
||||
{
|
||||
propagation_step.maneuver.exit = step.maneuver.exit;
|
||||
@@ -334,7 +308,7 @@ RouteStep elongate(RouteStep step, const RouteStep &by_step)
|
||||
// A check whether two instructions can be treated as one. This is only the case for very short
|
||||
// maneuvers that can, in some form, be seen as one. The additional in_step is to find out about
|
||||
// a possible u-turn.
|
||||
inline bool collapsable(const RouteStep &step)
|
||||
bool collapsable(const RouteStep &step)
|
||||
{
|
||||
const constexpr double MAX_COLLAPSE_DISTANCE = 25;
|
||||
return step.distance < MAX_COLLAPSE_DISTANCE;
|
||||
@@ -345,6 +319,8 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
const std::size_t one_back_index,
|
||||
const std::size_t step_index)
|
||||
{
|
||||
BOOST_ASSERT(step_index < steps.size());
|
||||
BOOST_ASSERT(one_back_index < steps.size());
|
||||
const auto ¤t_step = steps[step_index];
|
||||
|
||||
const auto &one_back_step = steps[one_back_index];
|
||||
@@ -357,6 +333,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
// Very Short New Name
|
||||
if (TurnType::NewName == one_back_step.maneuver.instruction.type)
|
||||
{
|
||||
BOOST_ASSERT(two_back_index < steps.size());
|
||||
if (one_back_step.mode == steps[two_back_index].mode)
|
||||
{
|
||||
steps[two_back_index] = elongate(std::move(steps[two_back_index]), one_back_step);
|
||||
@@ -387,6 +364,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
current_step.maneuver.bearing_after))
|
||||
|
||||
{
|
||||
BOOST_ASSERT(two_back_index < steps.size());
|
||||
// the simple case is a u-turn that changes directly into the in-name again
|
||||
const bool direct_u_turn = steps[two_back_index].name == current_step.name;
|
||||
|
||||
@@ -420,7 +398,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace
|
||||
|
||||
// Post processing can invalidate some instructions. For example StayOnRoundabout
|
||||
// is turned into exit counts. These instructions are removed by the following function
|
||||
@@ -469,7 +447,7 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
|
||||
into.maneuver.intersections.push_back(
|
||||
{last_step.duration, last_step.distance, intersection.maneuver.location});
|
||||
|
||||
return detail::forwardInto(std::move(into), intersection);
|
||||
return forwardInto(std::move(into), intersection);
|
||||
};
|
||||
|
||||
// count the exits forward. if enter/exit roundabout happen both, no further treatment is
|
||||
@@ -484,7 +462,7 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
|
||||
if (entersRoundabout(instruction))
|
||||
{
|
||||
last_valid_instruction = step_index;
|
||||
has_entered_roundabout = detail::setUpRoundabout(step);
|
||||
has_entered_roundabout = setUpRoundabout(step);
|
||||
|
||||
if (has_entered_roundabout && step_index + 1 < steps.size())
|
||||
steps[step_index + 1].maneuver.exit = step.maneuver.exit;
|
||||
@@ -506,7 +484,7 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
|
||||
// the first valid instruction
|
||||
last_valid_instruction = 1;
|
||||
}
|
||||
detail::closeOffRoundabout(has_entered_roundabout, steps, step_index);
|
||||
closeOffRoundabout(has_entered_roundabout, steps, step_index);
|
||||
has_entered_roundabout = false;
|
||||
on_roundabout = false;
|
||||
}
|
||||
@@ -529,7 +507,7 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
|
||||
// A roundabout without exit translates to enter-roundabout.
|
||||
if (has_entered_roundabout || on_roundabout)
|
||||
{
|
||||
detail::fixFinalRoundabout(steps);
|
||||
fixFinalRoundabout(steps);
|
||||
}
|
||||
|
||||
return removeNoTurnInstructions(std::move(steps));
|
||||
@@ -541,6 +519,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
// Get the previous non-invalid instruction
|
||||
const auto getPreviousIndex = [&steps](std::size_t index) {
|
||||
BOOST_ASSERT(index > 0);
|
||||
BOOST_ASSERT(index < steps.size());
|
||||
--index;
|
||||
while (index > 0 && steps[index].maneuver.instruction == TurnInstruction::NO_TURN())
|
||||
--index;
|
||||
@@ -553,6 +532,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
{
|
||||
const auto ¤t_step = steps[step_index];
|
||||
const auto one_back_index = getPreviousIndex(step_index);
|
||||
BOOST_ASSERT(one_back_index < steps.size());
|
||||
|
||||
// cannot collapse the depart instruction
|
||||
if (one_back_index == 0 || current_step.maneuver.instruction == TurnInstruction::NO_TURN())
|
||||
@@ -560,6 +540,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
|
||||
const auto &one_back_step = steps[one_back_index];
|
||||
const auto two_back_index = getPreviousIndex(one_back_index);
|
||||
BOOST_ASSERT(two_back_index < steps.size());
|
||||
|
||||
// If we look at two consecutive name changes, we can check for a name oszillation.
|
||||
// A name oszillation changes from name A shortly to name B and back to A.
|
||||
@@ -574,20 +555,20 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
if (current_step.mode == one_back_step.mode &&
|
||||
one_back_step.mode == steps[two_back_index].mode)
|
||||
{
|
||||
steps[two_back_index] = detail::elongate(
|
||||
detail::elongate(std::move(steps[two_back_index]), steps[one_back_index]),
|
||||
steps[step_index]);
|
||||
detail::invalidateStep(steps[one_back_index]);
|
||||
detail::invalidateStep(steps[step_index]);
|
||||
steps[two_back_index] =
|
||||
elongate(elongate(std::move(steps[two_back_index]), steps[one_back_index]),
|
||||
steps[step_index]);
|
||||
invalidateStep(steps[one_back_index]);
|
||||
invalidateStep(steps[step_index]);
|
||||
}
|
||||
// TODO discuss: we could think about changing the new-name to a pure notification
|
||||
// about mode changes
|
||||
}
|
||||
}
|
||||
else if (detail::collapsable(one_back_step))
|
||||
else if (collapsable(one_back_step))
|
||||
{
|
||||
// check for one of the multiple collapse scenarios and, if possible, collapse the turn
|
||||
detail::collapseTurnAt(steps, two_back_index, one_back_index, step_index);
|
||||
collapseTurnAt(steps, two_back_index, one_back_index, step_index);
|
||||
}
|
||||
}
|
||||
return removeNoTurnInstructions(std::move(steps));
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/timing_util.hpp"
|
||||
|
||||
#include "extractor/suffix_table.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
@@ -320,8 +321,10 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
// Three nested loop look super-linear, but we are dealing with a (kind of)
|
||||
// linear number of turns only.
|
||||
util::Percent progress(m_node_based_graph->GetNumberOfNodes());
|
||||
SuffixTable street_name_suffix_table(lua_state);
|
||||
guidance::TurnAnalysis turn_analysis(*m_node_based_graph, m_node_info_list, *m_restriction_map,
|
||||
m_barrier_nodes, m_compressed_edge_container, name_table);
|
||||
m_barrier_nodes, m_compressed_edge_container, name_table,
|
||||
street_name_suffix_table);
|
||||
for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
||||
{
|
||||
progress.printStatus(node_u);
|
||||
|
||||
@@ -27,8 +27,10 @@ inline bool requiresAnnouncement(const EdgeData &from, const EdgeData &to)
|
||||
|
||||
IntersectionHandler::IntersectionHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const util::NameTable &name_table)
|
||||
: node_based_graph(node_based_graph), node_info_list(node_info_list), name_table(name_table)
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table)
|
||||
: node_based_graph(node_based_graph), node_info_list(node_info_list), name_table(name_table),
|
||||
street_name_suffix_table(street_name_suffix_table)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -86,7 +88,8 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t
|
||||
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
if (in_data.name_id != out_data.name_id &&
|
||||
requiresNameAnnounced(name_table.GetNameForID(in_data.name_id),
|
||||
name_table.GetNameForID(out_data.name_id)))
|
||||
name_table.GetNameForID(out_data.name_id),
|
||||
street_name_suffix_table))
|
||||
{
|
||||
// obvious turn onto a through street is a merge
|
||||
if (through_street)
|
||||
|
||||
@@ -44,8 +44,9 @@ inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_base
|
||||
|
||||
MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const util::NameTable &name_table)
|
||||
: IntersectionHandler(node_based_graph, node_info_list, name_table)
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table)
|
||||
: IntersectionHandler(node_based_graph, node_info_list, name_table, street_name_suffix_table)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,10 @@ namespace guidance
|
||||
|
||||
RoundaboutHandler::RoundaboutHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const util::NameTable &name_table,
|
||||
const CompressedEdgeContainer &compressed_edge_container)
|
||||
: IntersectionHandler(node_based_graph, node_info_list, name_table),
|
||||
const SuffixTable &street_name_suffix_table)
|
||||
: IntersectionHandler(node_based_graph, node_info_list, name_table, street_name_suffix_table),
|
||||
compressed_edge_container(compressed_edge_container)
|
||||
{
|
||||
}
|
||||
@@ -142,9 +143,11 @@ bool RoundaboutHandler::qualifiesAsRoundaboutIntersection(
|
||||
if (!has_limited_size)
|
||||
return false;
|
||||
|
||||
const bool simple_exits = !std::find_if( roundabout_nodes.begin(), roundabout_nodes.end(), [this]( const NodeID node ){
|
||||
return (node_based_graph.GetOutDegree(node) > 3);
|
||||
});
|
||||
const bool simple_exits =
|
||||
roundabout_nodes.end() ==
|
||||
std::find_if(roundabout_nodes.begin(), roundabout_nodes.end(), [this](const NodeID node) {
|
||||
return (node_based_graph.GetOutDegree(node) > 3);
|
||||
});
|
||||
|
||||
if (!simple_exits)
|
||||
return false;
|
||||
@@ -219,7 +222,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
||||
// roundabout does not keep its name
|
||||
if (roundabout_name_id != 0 && roundabout_name_id != edge_data.name_id &&
|
||||
requiresNameAnnounced(name_table.GetNameForID(roundabout_name_id),
|
||||
name_table.GetNameForID(edge_data.name_id)))
|
||||
name_table.GetNameForID(edge_data.name_id),
|
||||
street_name_suffix_table))
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
|
||||
@@ -33,15 +33,16 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const RestrictionMap &restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const util::NameTable &name_table)
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table)
|
||||
: node_based_graph(node_based_graph), intersection_generator(node_based_graph,
|
||||
restriction_map,
|
||||
barrier_nodes,
|
||||
node_info_list,
|
||||
compressed_edge_container),
|
||||
roundabout_handler(node_based_graph, node_info_list, name_table, compressed_edge_container),
|
||||
motorway_handler(node_based_graph, node_info_list, name_table),
|
||||
turn_handler(node_based_graph, node_info_list, name_table)
|
||||
roundabout_handler(node_based_graph, node_info_list, compressed_edge_container, name_table, street_name_suffix_table),
|
||||
motorway_handler(node_based_graph, node_info_list, name_table,street_name_suffix_table),
|
||||
turn_handler(node_based_graph, node_info_list, name_table,street_name_suffix_table)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,9 @@ namespace guidance
|
||||
|
||||
TurnHandler::TurnHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const util::NameTable &name_table)
|
||||
: IntersectionHandler(node_based_graph, node_info_list, name_table)
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table)
|
||||
: IntersectionHandler(node_based_graph, node_info_list, name_table, street_name_suffix_table)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -406,22 +407,23 @@ Intersection TurnHandler::assignLeftTurns(const EdgeID via_edge,
|
||||
Intersection intersection,
|
||||
const std::size_t starting_at) const
|
||||
{
|
||||
BOOST_ASSERT(!intersection.empty());
|
||||
BOOST_ASSERT(starting_at <= intersection.size());
|
||||
for (auto &road : intersection)
|
||||
road = mirror(road);
|
||||
const auto switch_left_and_right = []( Intersection &intersection )
|
||||
{
|
||||
BOOST_ASSERT(!intersection.empty());
|
||||
|
||||
std::reverse(intersection.begin() + 1, intersection.end());
|
||||
for (auto &road : intersection)
|
||||
road = mirror(std::move(road));
|
||||
|
||||
std::reverse(intersection.begin() + 1, intersection.end());
|
||||
};
|
||||
|
||||
switch_left_and_right(intersection);
|
||||
// account for the u-turn in the beginning
|
||||
const auto count = intersection.size() - starting_at + 1;
|
||||
|
||||
intersection = assignRightTurns(via_edge, std::move(intersection), count);
|
||||
switch_left_and_right(intersection);
|
||||
|
||||
std::reverse(intersection.begin() + 1, intersection.end());
|
||||
|
||||
for (auto &road : intersection)
|
||||
road = mirror(road);
|
||||
|
||||
return intersection;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "extractor/suffix_table.hpp"
|
||||
|
||||
#include "util/lua_util.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace extractor
|
||||
{
|
||||
|
||||
SuffixTable::SuffixTable(lua_State *lua_state)
|
||||
{
|
||||
BOOST_ASSERT(lua_state != nullptr);
|
||||
if (!util::luaFunctionExists(lua_state, "get_name_suffix_list"))
|
||||
return;
|
||||
|
||||
std::vector<std::string> suffixes_vector;
|
||||
try
|
||||
{
|
||||
// call lua profile to compute turn penalty
|
||||
luabind::call_function<void>(lua_state, "get_name_suffix_list",
|
||||
boost::ref(suffixes_vector));
|
||||
}
|
||||
catch (const luabind::error &er)
|
||||
{
|
||||
util::SimpleLogger().Write(logWARNING) << er.what();
|
||||
}
|
||||
|
||||
for (auto &suffix : suffixes_vector)
|
||||
boost::algorithm::to_lower(suffix);
|
||||
suffix_set.insert(std::begin(suffixes_vector), std::end(suffixes_vector));
|
||||
}
|
||||
|
||||
bool SuffixTable::isSuffix(const std::string &possible_suffix) const
|
||||
{
|
||||
return suffix_set.count(possible_suffix) > 0;
|
||||
}
|
||||
|
||||
} /* namespace extractor */
|
||||
} /* namespace osrm */
|
||||
Reference in New Issue
Block a user