Skip to content

Commit

Permalink
less new names, forks consider road classes, api clean-up
Browse files Browse the repository at this point in the history
  • Loading branch information
Moritz Kobitzsch authored and TheMarex committed Mar 18, 2016
1 parent d6c5de3 commit a2e4afb
Show file tree
Hide file tree
Showing 10 changed files with 392 additions and 44 deletions.
140 changes: 140 additions & 0 deletions features/guidance/roundabout.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
@routing @guidance
Feature: Basic Roundabout

Background:
Given the profile "testbot"
Given a grid size of 10 meters

Scenario: Enter and Exit
Given the node map
| | | a | | |
| | | b | | |
| h | g | | c | d |
| | | e | | |
| | | f | | |

And the ways
| nodes | roundabout |
| ab | false |
| cd | false |
| ef | false |
| gh | false |
| bcegb | true |

When I route I should get
| waypoints | route | turns |
| a,d | ab,cd,cd | depart, roundabout-exit-1, arrive |
| a,f | ab,ef,ef | depart, roundabout-exit-2, arrive |
| a,h | ab,gh,gh | depart, roundabout-exit-3, arrive |
| d,f | cd,ef,ef | depart, roundabout-exit-1, arrive |
| d,h | cd,gh,gh | depart, roundabout-exit-2, arrive |
| d,a | cd,ab,ab | depart, roundabout-exit-3, arrive |
| f,h | ef,gh,gh | depart, roundabout-exit-1, arrive |
| f,a | ef,ab,ab | depart, roundabout-exit-2, arrive |
| f,d | ef,cd,cd | depart, roundabout-exit-3, arrive |
| h,a | gh,ab,ab | depart, roundabout-exit-1, arrive |
| h,d | gh,cd,cd | depart, roundabout-exit-2, arrive |
| h,f | gh,ef,ef | depart, roundabout-exit-3, arrive |

Scenario: Only Enter
Given the node map
| | | a | | |
| | | b | | |
| h | g | | c | d |
| | | e | | |
| | | f | | |

And the ways
| nodes | roundabout |
| ab | false |
| cd | false |
| ef | false |
| gh | false |
| bcegb | true |

When I route I should get
| waypoints | route | turns |
| a,b | ab,ab | depart, arrive |
| a,c | ab,bcegb | depart, roundabout-enter, arrive |
| a,e | ab,bcegb | depart, roundabout-enter, arrive |
| a,g | ab,bcegb | depart, roundabout-enter, arrive |
| d,c | cd,cd | depart, arrive |
| d,e | cd,bcegb | depart, roundabout-enter, arrive |
| d,g | cd,bcegb | depart, roundabout-enter, arrive |
| d,b | cd,bcegb | depart, roundabout-enter, arrive |
| f,e | ef,ef | depart, arrive |
| f,g | ef,bcegb | depart, roundabout-enter, arrive |
| f,b | ef,bcegb | depart, roundabout-enter, arrive |
| f,c | ef,bcegb | depart, roundabout-enter, arrive |
| h,g | gh,gh | depart, arrive |
| h,b | gh,bcegb | depart, roundabout-enter, arrive |
| h,c | gh,bcegb | depart, roundabout-enter, arrive |
| h,e | gh,bcegb | depart, roundabout-enter, arrive |

Scenario: Only Exit
Given the node map
| | | a | | |
| | | b | | |
| h | g | | c | d |
| | | e | | |
| | | f | | |

And the ways
| nodes | roundabout |
| ab | false |
| cd | false |
| ef | false |
| gh | false |
| bcegb | true |

When I route I should get
| waypoints | route | turns |
| b,a | ab,ab | depart, arrive |
| b,d | bcegb,cd,cd | depart, roundabout-exit-1, arrive |
| b,f | bcegb,ef,ef | depart, roundabout-exit-2, arrive |
| b,h | bcegb,gh,gh | depart, roundabout-exit-3, arrive |
| c,d | cd,cd | depart, arrive |
| c,f | bcegb,ef,ef | depart, roundabout-exit-1, arrive |
| c,h | bcegb,gh,gh | depart, roundabout-exit-2, arrive |
| c,a | bcegb,ab,ab | depart, roundabout-exit-3, arrive |
| e,f | ef,ef | depart, arrive |
| e,h | bcegb,gh,gh | depart, roundabout-exit-1, arrive |
| e,a | bcegb,ab,ab | depart, roundabout-exit-2, arrive |
| e,d | bcegb,cd,cd | depart, roundabout-exit-3, arrive |
| g,h | gh,gh | depart, arrive |
| g,a | bcegb,ab,ab | depart, roundabout-exit-1, arrive |
| g,d | bcegb,cd,cd | depart, roundabout-exit-2, arrive |
| g,f | bcegb,ef,ef | depart, roundabout-exit-3, arrive |

Scenario: Drive Around
Given the node map
| | | a | | |
| | | b | | |
| h | g | | c | d |
| | | e | | |
| | | f | | |

And the ways
| nodes | roundabout |
| ab | false |
| cd | false |
| ef | false |
| gh | false |
| bcegb | true |

When I route I should get
| waypoints | route | turns |
| b,c | bcegb,bcegb | depart, arrive |
| b,e | bcegb,bcegb | depart, arrive |
| b,g | bcegb,bcegb | depart, arrive |
| c,e | bcegb,bcegb | depart, arrive |
| c,g | bcegb,bcegb | depart, arrive |
| c,b | bcegb,bcegb | depart, arrive |
| e,g | bcegb,bcegb | depart, arrive |
| e,b | bcegb,bcegb | depart, arrive |
| e,c | bcegb,bcegb | depart, arrive |
| g,b | bcegb,bcegb | depart, arrive |
| g,c | bcegb,bcegb | depart, arrive |
| g,e | bcegb,bcegb | depart, arrive |

Scenario: Mixed Entry and Exit
6 changes: 5 additions & 1 deletion include/extractor/edge_based_graph_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "util/node_based_graph.hpp"
#include "util/typedefs.hpp"
#include "util/deallocating_vector.hpp"
#include "util/name_table.hpp"

#include <algorithm>
#include <cstdint>
Expand Down Expand Up @@ -51,7 +52,8 @@ class 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);

void Run(const std::string &original_edge_data_filename,
lua_State *lua_state,
Expand Down Expand Up @@ -106,6 +108,8 @@ class EdgeBasedGraphFactory

SpeedProfileProperties speed_profile;

const util::NameTable &name_table;

void CompressGeometry();
unsigned RenumberEdges();
void GenerateEdgeExpandedNodes();
Expand Down
70 changes: 70 additions & 0 deletions include/extractor/guidance/toolkit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
#include "extractor/guidance/classification_data.hpp"
#include "extractor/guidance/turn_instruction.hpp"

#include <algorithm>
#include <map>
#include <cmath>
#include <cstdint>
#include <string>
#include <iostream>

namespace osrm
{
Expand Down Expand Up @@ -331,6 +334,73 @@ inline bool isDistinct(const DirectionModifier first, const DirectionModifier se
return true;
}

inline bool requiresNameAnnounced(const std::string &from, const std::string &to)
{
// FIXME, handle in profile to begin with?
// this uses the encoding of references in the profile, which is very BAD
// Input for this function should be a struct separating streetname, suffix (e.g. road,
// boulevard, North, West ...), and a list of references
std::string from_name = "", from_ref = "", to_name = "", to_ref = "";

auto split = [](const std::string &name, std::string &out_name, std::string &out_ref)
{
const auto ref_begin = name.find_first_of('(');
if (ref_begin != std::string::npos)
{
out_name = name.substr(0, ref_begin);
out_ref = name.substr(ref_begin + 1, name.find_first_of(')') - 1);
}
else
{
out_name = name;
out_ref = "";
}
};

split(from, from_name, from_ref);
split(to, to_name, to_ref);

// check similarity of names
if (from_name != "" && to_name != "")
{
if ((from_name.back() >= '0' && from_name.back() <= '9') ||
(to_name.back() >= '0' && to_name.back() <= '9'))
return from_name != to_name;
if (from.find("Weg ") == 0 && to_name.find("Weg ") == 0)
return from_name != to_name;
auto from_itr = from_name.begin();
auto to_itr = to_name.begin();
for (; from_itr != from_name.end() && to_itr != to_name.end() && *from_itr == *to_itr;
++to_itr, ++from_itr)
{
/* do nothing */
}

const auto common_length = std::distance(from_name.begin(), from_itr);
return (100 * common_length / std::min(to_name.length(), from_name.length())) < 80;
}
else if (from_ref != "" && to_ref != "")
{
// references are contained in one another
if (from_ref.find(to_ref) != std::string::npos ||
to_ref.find(from_ref) != std::string::npos)
return false;
}
return true;
}

inline int getPriority( const FunctionalRoadClass road_class )
{
const constexpr int road_priority[] = {10, 0, 10, 2, 10, 4, 10, 6, 10, 8, 10, 11, 10, 12, 10, 14};
return road_priority[static_cast<int>(road_class)];
}

inline bool canBeSeenAsFork(const FunctionalRoadClass first, const FunctionalRoadClass second)
{
// forks require similar road categories
return std::abs(getPriority(first) - getPriority(second)) <= 1;
}

} // namespace guidance
} // namespace extractor
} // namespace osrm
Expand Down
6 changes: 5 additions & 1 deletion include/extractor/guidance/turn_analysis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "extractor/restriction_map.hpp"
#include "extractor/compressed_edge_container.hpp"

#include "util/name_table.hpp"

#include <cstdint>

#include <string>
Expand Down Expand Up @@ -53,7 +55,8 @@ class TurnAnalysis
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);

// the entry into the turn analysis
std::vector<TurnCandidate> getTurns(const NodeID from_node, const EdgeID via_eid) const;
Expand All @@ -64,6 +67,7 @@ class TurnAnalysis
const RestrictionMap &restriction_map;
const std::unordered_set<NodeID> &barrier_nodes;
const CompressedEdgeContainer &compressed_edge_container;
const util::NameTable &name_table;

// Check for restrictions/barriers and generate a list of valid and invalid turns present at the
// node reached
Expand Down
26 changes: 26 additions & 0 deletions include/util/name_table.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef OSRM_UTIL_NAME_TABLE_HPP
#define OSRM_UTIL_NAME_TABLE_HPP

#include "util/shared_memory_vector_wrapper.hpp"
#include "util/range_table.hpp"

#include <string>

namespace osrm
{
namespace util
{
class NameTable
{
private:
//FIXME should this use shared memory
RangeTable<16, false> m_name_table;
ShM<char, false>::vector m_names_char_list;
public:
NameTable( const std::string &filename );
std::string get_name_for_id(const unsigned name_id) const;
};
} // namespace util
} // namespace osrm

#endif // OSRM_UTIL_NAME_TABLE_HPP
39 changes: 13 additions & 26 deletions src/engine/api/json_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)];
Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit a2e4afb

Please sign in to comment.