less new names, forks consider road classes, api clean-up

This commit is contained in:
Moritz Kobitzsch
2016-03-16 15:47:33 +01:00
committed by Patrick Niklaus
parent a674028c37
commit 71c0d5253d
10 changed files with 392 additions and 44 deletions
+13 -26
View File
@@ -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);
+8 -8
View File
@@ -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);
+4 -1
View File
@@ -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,
+69 -7
View File
@@ -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)
{
+52
View File
@@ -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