less new names, forks consider road classes, api clean-up
This commit is contained in:
committed by
Patrick Niklaus
parent
a674028c37
commit
71c0d5253d
@@ -28,17 +28,23 @@ namespace json
|
||||
namespace detail
|
||||
{
|
||||
|
||||
const constexpr char *modifier_names[] = {"uturn", "sharp right", "right", "slight right",
|
||||
"straight", "slight left", "left", "sharp left"};
|
||||
const constexpr char *modifier_names[] = {"uturn",
|
||||
"sharp right",
|
||||
"right",
|
||||
"slight right",
|
||||
"straight",
|
||||
"slight left",
|
||||
"left",
|
||||
"sharp left"};
|
||||
|
||||
// translations of TurnTypes. Not all types are exposed to the outside world.
|
||||
// invalid types should never be returned as part of the API
|
||||
const constexpr char *turn_type_names[] = {
|
||||
"invalid", "no turn", "invalid", "new name", "continue", "turn",
|
||||
"turn", "turn", "turn", "merge", "ramp", "ramp",
|
||||
"ramp", "ramp", "fork", "end of road", "roundabout", "invalid",
|
||||
"roundabout", "invalid", "traffic circle", "invalid", "traffic circle", "invalid",
|
||||
"invalid", "restriction", "notification"};
|
||||
"invalid", "no turn", "invalid", "new name", "continue", "turn",
|
||||
"turn", "turn", "turn", "turn", "merge", "ramp",
|
||||
"ramp", "ramp", "ramp", "ramp", "fork", "end of road",
|
||||
"roundabout", "invalid", "roundabout", "invalid", "traffic circle", "invalid",
|
||||
"traffic circle", "invalid", "invalid", "restriction", "notification"};
|
||||
const constexpr char *waypoint_type_names[] = {"invalid", "arrive", "depart"};
|
||||
|
||||
// Check whether to include a modifier in the result of the API
|
||||
@@ -50,23 +56,6 @@ inline bool isValidModifier(const guidance::StepManeuver maneuver)
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool isMultiTurn(const TurnType type)
|
||||
{
|
||||
return (type == TurnType::FirstTurn || type == TurnType::SecondTurn ||
|
||||
type == TurnType::ThirdTurn);
|
||||
}
|
||||
|
||||
inline std::string getCount(const TurnType type)
|
||||
{
|
||||
if (type == TurnType::FirstTurn)
|
||||
return "1";
|
||||
if (type == TurnType::SecondTurn)
|
||||
return "2";
|
||||
if (type == TurnType::ThirdTurn)
|
||||
return "3";
|
||||
return "0";
|
||||
}
|
||||
|
||||
std::string instructionTypeToString(const TurnType type)
|
||||
{
|
||||
return turn_type_names[static_cast<std::size_t>(type)];
|
||||
@@ -152,8 +141,6 @@ util::json::Object makeStepManeuver(const guidance::StepManeuver &maneuver)
|
||||
else
|
||||
step_maneuver.values["type"] = detail::waypointTypeToString(maneuver.waypoint_type);
|
||||
|
||||
if (detail::isMultiTurn(maneuver.instruction.type))
|
||||
step_maneuver.values["count"] = detail::getCount(maneuver.instruction.type);
|
||||
if (detail::isValidModifier(maneuver))
|
||||
step_maneuver.values["modifier"] =
|
||||
detail::instructionModifierToString(maneuver.instruction.direction_modifier);
|
||||
|
||||
@@ -35,12 +35,13 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
std::shared_ptr<const RestrictionMap> restriction_map,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
SpeedProfileProperties speed_profile)
|
||||
SpeedProfileProperties speed_profile,
|
||||
const util::NameTable &name_table)
|
||||
: m_max_edge_id(0), m_node_info_list(node_info_list),
|
||||
m_node_based_graph(std::move(node_based_graph)),
|
||||
m_restriction_map(std::move(restriction_map)), m_barrier_nodes(barrier_nodes),
|
||||
m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
|
||||
speed_profile(std::move(speed_profile))
|
||||
speed_profile(std::move(speed_profile)), name_table(name_table)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -124,10 +125,9 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeI
|
||||
// traverse arrays from start and end respectively
|
||||
for (const auto i : util::irange(std::size_t{ 0 }, geometry_size))
|
||||
{
|
||||
BOOST_ASSERT(
|
||||
current_edge_source_coordinate_id ==
|
||||
m_compressed_edge_container.GetBucketReference(edge_id_2)[geometry_size - 1 - i]
|
||||
.node_id);
|
||||
BOOST_ASSERT(current_edge_source_coordinate_id ==
|
||||
m_compressed_edge_container.GetBucketReference(
|
||||
edge_id_2)[geometry_size - 1 - i].node_id);
|
||||
const NodeID current_edge_target_coordinate_id = forward_geometry[i].node_id;
|
||||
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
|
||||
|
||||
@@ -305,8 +305,8 @@ 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());
|
||||
guidance::TurnAnalysis turn_analysis( *m_node_based_graph, m_node_info_list,
|
||||
*m_restriction_map, m_barrier_nodes, m_compressed_edge_container );
|
||||
guidance::TurnAnalysis turn_analysis(*m_node_based_graph, m_node_info_list, *m_restriction_map,
|
||||
m_barrier_nodes, m_compressed_edge_container, name_table);
|
||||
for (const auto node_u : util::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
||||
{
|
||||
// progress.printStatus(node_u);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "util/timing_util.hpp"
|
||||
#include "util/lua_util.hpp"
|
||||
#include "util/graph_loader.hpp"
|
||||
#include "util/name_table.hpp"
|
||||
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@@ -521,10 +522,12 @@ Extractor::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_n
|
||||
|
||||
compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
|
||||
|
||||
util::NameTable name_table(config.names_file_name);
|
||||
|
||||
EdgeBasedGraphFactory edge_based_graph_factory(
|
||||
node_based_graph, compressed_edge_container, barrier_nodes, traffic_lights,
|
||||
std::const_pointer_cast<RestrictionMap const>(restriction_map),
|
||||
internal_to_external_node_map, speed_profile);
|
||||
internal_to_external_node_map, speed_profile, name_table);
|
||||
|
||||
edge_based_graph_factory.Run(config.edge_output_path, lua_state,
|
||||
config.edge_segment_lookup_path, config.edge_penalty_path,
|
||||
|
||||
@@ -55,10 +55,11 @@ TurnAnalysis::TurnAnalysis(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const RestrictionMap &restriction_map,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const CompressedEdgeContainer &compressed_edge_container)
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
const util::NameTable &name_table)
|
||||
: node_based_graph(node_based_graph), node_info_list(node_info_list),
|
||||
restriction_map(restriction_map), barrier_nodes(barrier_nodes),
|
||||
compressed_edge_container(compressed_edge_container)
|
||||
compressed_edge_container(compressed_edge_container), name_table(name_table)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -784,7 +785,9 @@ TurnInstruction TurnAnalysis::getInstructionForObvious(const std::size_t num_can
|
||||
{
|
||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||
const auto &out_data = node_based_graph.GetEdgeData(candidate.eid);
|
||||
if (in_data.name_id != out_data.name_id)
|
||||
if (in_data.name_id != out_data.name_id &&
|
||||
requiresNameAnnounced(name_table.get_name_for_id(in_data.name_id),
|
||||
name_table.get_name_for_id(out_data.name_id)))
|
||||
return {TurnType::NewName, getTurnDirection(candidate.angle)};
|
||||
else
|
||||
return {TurnType::Suppressed, getTurnDirection(candidate.angle)};
|
||||
@@ -859,6 +862,7 @@ std::vector<TurnCandidate> TurnAnalysis::handleThreeWayTurn(
|
||||
angularDeviation(turn.angle, STRAIGHT_ANGLE) >
|
||||
1.4);
|
||||
};
|
||||
|
||||
/* Two nearly straight turns -> FORK
|
||||
OOOOOOO
|
||||
/
|
||||
@@ -871,7 +875,26 @@ std::vector<TurnCandidate> TurnAnalysis::handleThreeWayTurn(
|
||||
{
|
||||
if (turn_candidates[1].valid && turn_candidates[2].valid)
|
||||
{
|
||||
assignFork(via_edge, turn_candidates[2], turn_candidates[1]);
|
||||
const auto left_class =
|
||||
node_based_graph.GetEdgeData(turn_candidates[2].eid).road_classification.road_class;
|
||||
const auto right_class =
|
||||
node_based_graph.GetEdgeData(turn_candidates[1].eid).road_classification.road_class;
|
||||
if (canBeSeenAsFork(left_class, right_class))
|
||||
assignFork(via_edge, turn_candidates[2], turn_candidates[1]);
|
||||
else if (getPriority(left_class) > getPriority(right_class))
|
||||
{
|
||||
turn_candidates[1].instruction =
|
||||
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[1]);
|
||||
turn_candidates[2].instruction = {findBasicTurnType(via_edge, turn_candidates[2]),
|
||||
DirectionModifier::SlightLeft};
|
||||
}
|
||||
else
|
||||
{
|
||||
turn_candidates[2].instruction =
|
||||
getInstructionForObvious(turn_candidates.size(), via_edge, turn_candidates[2]);
|
||||
turn_candidates[1].instruction = {findBasicTurnType(via_edge, turn_candidates[1]),
|
||||
DirectionModifier::SlightRight};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1073,7 +1096,27 @@ void TurnAnalysis::handleDistinctConflict(const EdgeID via_edge,
|
||||
if (getTurnDirection(left.angle) == DirectionModifier::Straight ||
|
||||
getTurnDirection(left.angle) == DirectionModifier::SlightLeft ||
|
||||
getTurnDirection(right.angle) == DirectionModifier::SlightRight)
|
||||
assignFork(via_edge, left, right);
|
||||
{
|
||||
const auto left_class =
|
||||
node_based_graph.GetEdgeData(left.eid).road_classification.road_class;
|
||||
const auto right_class =
|
||||
node_based_graph.GetEdgeData(right.eid).road_classification.road_class;
|
||||
if (canBeSeenAsFork(left_class, right_class))
|
||||
assignFork(via_edge, left, right);
|
||||
else if (getPriority(left_class) > getPriority(right_class))
|
||||
{
|
||||
// FIXME this should possibly know about the actual candidates?
|
||||
right.instruction = getInstructionForObvious(4, via_edge, right);
|
||||
left.instruction = {findBasicTurnType(via_edge, left), DirectionModifier::SlightLeft};
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME this should possibly know about the actual candidates?
|
||||
left.instruction = getInstructionForObvious(4, via_edge, left);
|
||||
right.instruction = {findBasicTurnType(via_edge, right),
|
||||
DirectionModifier::SlightRight};
|
||||
}
|
||||
}
|
||||
|
||||
const auto left_type = findBasicTurnType(via_edge, left);
|
||||
const auto right_type = findBasicTurnType(via_edge, right);
|
||||
@@ -1196,8 +1239,27 @@ std::vector<TurnCandidate> TurnAnalysis::handleComplexTurn(
|
||||
{
|
||||
if (fork_range.second - fork_range.first == 1)
|
||||
{
|
||||
assignFork(via_edge, turn_candidates[fork_range.second],
|
||||
turn_candidates[fork_range.first]);
|
||||
auto &left = turn_candidates[fork_range.second];
|
||||
auto &right = turn_candidates[fork_range.first];
|
||||
const auto left_class =
|
||||
node_based_graph.GetEdgeData(left.eid).road_classification.road_class;
|
||||
const auto right_class =
|
||||
node_based_graph.GetEdgeData(right.eid).road_classification.road_class;
|
||||
if (canBeSeenAsFork(left_class, right_class))
|
||||
assignFork(via_edge, left, right);
|
||||
else if (getPriority(left_class) > getPriority(right_class))
|
||||
{
|
||||
right.instruction =
|
||||
getInstructionForObvious(turn_candidates.size(), via_edge, right);
|
||||
left.instruction = {findBasicTurnType(via_edge, left),
|
||||
DirectionModifier::SlightLeft};
|
||||
}
|
||||
else
|
||||
{
|
||||
left.instruction = getInstructionForObvious(turn_candidates.size(), via_edge, left);
|
||||
right.instruction = {findBasicTurnType(via_edge, right),
|
||||
DirectionModifier::SlightRight};
|
||||
}
|
||||
}
|
||||
else if (fork_range.second - fork_range.second == 2)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "util/name_table.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
NameTable::NameTable(const std::string &filename)
|
||||
{
|
||||
boost::filesystem::ifstream name_stream(filename, std::ios::binary);
|
||||
|
||||
name_stream >> m_name_table;
|
||||
|
||||
unsigned number_of_chars = 0;
|
||||
name_stream.read(reinterpret_cast<char *>(&number_of_chars), sizeof(number_of_chars));
|
||||
BOOST_ASSERT_MSG(0 != number_of_chars, "name file broken");
|
||||
m_names_char_list.resize(number_of_chars + 1); //+1 gives sentinel element
|
||||
name_stream.read(reinterpret_cast<char *>(&m_names_char_list[0]),
|
||||
number_of_chars * sizeof(m_names_char_list[0]));
|
||||
if (0 == m_names_char_list.size())
|
||||
{
|
||||
util::SimpleLogger().Write(logWARNING) << "list of street names is empty";
|
||||
}
|
||||
}
|
||||
|
||||
std::string NameTable::get_name_for_id(const unsigned name_id) const
|
||||
{
|
||||
if (std::numeric_limits<unsigned>::max() == name_id)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
auto range = m_name_table.GetRange(name_id);
|
||||
|
||||
std::string result;
|
||||
result.reserve(range.size());
|
||||
if (range.begin() != range.end())
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_names_char_list.begin() + range.front(),
|
||||
m_names_char_list.begin() + range.back() + 1, result.begin());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace util
|
||||
} // namespace osrm
|
||||
Reference in New Issue
Block a user