move hardcoded road priorities into profiles, change road classification

This commit is contained in:
Moritz Kobitzsch 2016-06-24 16:06:45 +02:00 committed by Patrick Niklaus
parent fd6bb5ec1f
commit 1fc63e1e72
No known key found for this signature in database
GPG Key ID: E426891B5F978B1B
23 changed files with 451 additions and 527 deletions

View File

@ -1,3 +1,7 @@
# 5.4.0
- Profiles
- includes library guidance.lua that offers preliminary configuration on guidance.
# 5.3.0 # 5.3.0
Changes from 5.3.0-rc.3 Changes from 5.3.0-rc.3
- Guidance - Guidance

View File

@ -32,3 +32,16 @@ Given an OpenStreetMap way, the way_function will either return nothing (meaning
All other calculations stem from that, including the returned timings in driving directions, but also, less directly, it feeds into the actual routing decisions the engine will take (a way with a slow traversal speed, may be less favoured than a way with fast traversal speed, but it depends how long it is, and... what it connects to in the rest of the network graph) All other calculations stem from that, including the returned timings in driving directions, but also, less directly, it feeds into the actual routing decisions the engine will take (a way with a slow traversal speed, may be less favoured than a way with fast traversal speed, but it depends how long it is, and... what it connects to in the rest of the network graph)
Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the way_function. Instead a way_function will examine the tagging (e.g. `way:get_value_by_key("highway")` and many others), process this information in various ways, calling other local functions, referencing the global variables and look-up hashes, before arriving at the result. Using the power of the scripting language you wouldn't typically see something as simple as a `result.forward_speed = 20` line within the way_function. Instead a way_function will examine the tagging (e.g. `way:get_value_by_key("highway")` and many others), process this information in various ways, calling other local functions, referencing the global variables and look-up hashes, before arriving at the result.
## Guidance
The guidance parameters in profiles are currently a work in progress. They can and will change.
Please be aware of this when using guidance configuration possibilities.
### Road Classification
Guidance uses road classes to decide on when/if to emit specific instructions and to discover which road is obvious when following a route.
Classification uses three flags and a priority-category.
The flags indicate whether a road is a motorway (required for on/off ramps), a link type (the ramps itself, if also a motorway) and whether a road may be omittted in considerations (is considered purely for connectivity).
The priority-category influences the decision which road is considered the obvious choice and which roads can be seen as fork.
Forks can be emitted between roads of similar priority category only. Obvious choices follow a major priority road, if the priority difference is large.

View File

@ -271,20 +271,20 @@ Feature: Turn Lane Guidance
| | | i | | | | | | i | | |
And the ways And the ways
| nodes | turn:lanes:forward | highway | junction | # | | nodes | turn:lanes:forward | highway | junction | # |
| ab | slight_right\|slight_right\|slight_right | primary | | | | ab | slight_right\|slight_right\|slight_right | primary | | |
| bc | slight_left\|slight_right\|slight_right | primary | roundabout | top | | bc | slight_left\|slight_right\|slight_right | primary | roundabout | top |
| cd | | primary | roundabout | top | | cd | | primary | roundabout | top |
| de | | primary | roundabout | top | | de | | primary | roundabout | top |
| eb | | primary | roundabout | top | | eb | | primary | roundabout | top |
| df | | primary | | | | df | | primary | | |
| cg | slight_right\|slight_right | primary | | | | cg | slight_right\|slight_right | primary | | |
| gh | slight_left\|slight_right | primary | roundabout | bot | | gh | slight_left\|slight_right | primary | roundabout | bot |
| hi | | primary | roundabout | bot | | hi | | primary | roundabout | bot |
| ij | slight_left\|slight_right | primary | roundabout | bot | | ij | slight_left\|slight_right | primary | roundabout | bot |
| jg | | primary | roundabout | bot | | jg | | primary | roundabout | bot |
| hk | | primary | | | | hk | | primary | | |
| jl | | primary | | | | jl | | primary | | |
When I route I should get When I route I should get
| # | waypoints | route | turns | lanes | | # | waypoints | route | turns | lanes |
@ -301,13 +301,13 @@ Feature: Turn Lane Guidance
| | | c | | | | | | c | | |
And the ways And the ways
| nodes | turn:lanes:forward | highway | junction | | nodes | turn:lanes:forward | highway | junction |
| ab | | primary | | | ab | | primary | |
| bc | | primary | roundabout | | bc | | primary | roundabout |
| cd | slight_left\|slight_left\|slight_right | primary | roundabout | | cd | slight_left\|slight_left\|slight_right | primary | roundabout |
| de | | primary | roundabout | | de | | primary | roundabout |
| eb | | primary | roundabout | | eb | | primary | roundabout |
| df | | primary | | | df | | primary | |
When I route I should get When I route I should get
| waypoints | route | turns | lanes | | waypoints | route | turns | lanes |

View File

@ -2,6 +2,7 @@
#define EXTRACTION_WAY_HPP #define EXTRACTION_WAY_HPP
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "extractor/guidance/road_classification.hpp"
#include "util/guidance/turn_lanes.hpp" #include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
@ -38,6 +39,7 @@ struct ExtractionWay
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE; backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
turn_lanes_forward.clear(); turn_lanes_forward.clear();
turn_lanes_backward.clear(); turn_lanes_backward.clear();
road_classification = guidance::RoadClassification();
} }
// These accessors exists because it's not possible to take the address of a bitfield, // These accessors exists because it's not possible to take the address of a bitfield,
@ -60,6 +62,7 @@ struct ExtractionWay
bool is_startpoint; bool is_startpoint;
TravelMode forward_travel_mode : 4; TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4; TravelMode backward_travel_mode : 4;
guidance::RoadClassification road_classification;
}; };
} }
} }

View File

@ -1,84 +0,0 @@
#ifndef OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
#define OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
#include <cstdint>
#include <string>
// Forward Declaration to allow usage of external osmium::Way
namespace osmium
{
class Way;
}
namespace osrm
{
namespace extractor
{
namespace guidance
{
enum class FunctionalRoadClass : std::uint8_t
{
UNKNOWN = 0,
MOTORWAY,
MOTORWAY_LINK,
TRUNK,
TRUNK_LINK,
PRIMARY,
PRIMARY_LINK,
SECONDARY,
SECONDARY_LINK,
TERTIARY,
TERTIARY_LINK,
UNCLASSIFIED,
RESIDENTIAL,
SERVICE,
LIVING_STREET,
LOW_PRIORITY_ROAD // a road simply included for connectivity. Should be avoided at all cost
};
FunctionalRoadClass functionalRoadClassFromTag(std::string const &tag);
inline bool isRampClass(const FunctionalRoadClass road_class)
{
// Primary Roads and down are usually too small to announce their links as ramps
return road_class == FunctionalRoadClass::MOTORWAY_LINK ||
road_class == FunctionalRoadClass::TRUNK_LINK;
}
// Links are usually smaller than ramps, but are sometimes tagged
// as MOTORWAY_LINK if they exit/enter a motorway/trunk road.
inline bool isLinkClass(const FunctionalRoadClass road_class)
{
return road_class == FunctionalRoadClass::MOTORWAY_LINK ||
road_class == FunctionalRoadClass::TRUNK_LINK ||
road_class == FunctionalRoadClass::PRIMARY_LINK ||
road_class == FunctionalRoadClass::SECONDARY_LINK ||
road_class == FunctionalRoadClass::TERTIARY_LINK;
}
// check wheter a class is a motorway like class
inline bool isMotorwayClass(const FunctionalRoadClass road_class)
{
return road_class == FunctionalRoadClass::MOTORWAY || road_class == FunctionalRoadClass::TRUNK;
}
// TODO augment this with all data required for guidance generation
struct RoadClassificationData
{
FunctionalRoadClass road_class = FunctionalRoadClass::UNKNOWN;
void augment(const osmium::Way &way);
};
inline bool operator==(const RoadClassificationData lhs, const RoadClassificationData rhs)
{
return lhs.road_class == rhs.road_class;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm
#endif // OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_

View File

@ -0,0 +1,130 @@
#ifndef OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
#define OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_
#include <cmath>
#include <cstdint>
#include <string>
#include <unordered_map>
#include <osmium/osm.hpp>
namespace osrm
{
namespace extractor
{
namespace guidance
{
namespace RoadPriorityClass
{
typedef std::uint8_t Enum;
// Top priority Road
const constexpr Enum MOTORWAY = 0;
// Second highest priority
const constexpr Enum TRUNK = 2;
// Main roads
const constexpr Enum PRIMARY = 4;
const constexpr Enum SECONDARY = 6;
const constexpr Enum TERTIARY = 8;
// Residential Categories
const constexpr Enum MAIN_RESIDENTIAL = 10;
const constexpr Enum SIDE_RESIDENTIAL = 11;
// Link Category
const constexpr Enum LINK_ROAD = 14;
// Bike Accessible
const constexpr Enum BIKE_PATH = 16;
// Walk Accessible
const constexpr Enum FOOT_PATH = 18;
// Link types are usually not considered in forks, unless amongst each other.
// a road simply offered for connectivity. Will be ignored in forks/other decisions. Always
// considered non-obvious to continue on
const constexpr Enum CONNECTIVITY = 31;
} // namespace Road Class
#pragma pack(push, 1)
class RoadClassification
{
// a class that behaves like a motorway (separated directions)
std::uint8_t motorway_class : 1;
// all types of link classes
std::uint8_t link_class : 1;
// a low priority class is a pure connectivity way. It can be ignored in multiple decisions
// (e.g. fork on a primary vs service will not happen)
std::uint8_t may_be_ignored : 1;
// the road priority is used as an indicator for forks. If the roads are of similar priority
// (difference <=1), we can see the road as a fork. Else one of the road classes is seen as
// obvious choice
RoadPriorityClass::Enum road_priority_class : 5;
public:
// default construction
RoadClassification()
: motorway_class(0), link_class(0), may_be_ignored(1),
road_priority_class(RoadPriorityClass::CONNECTIVITY)
{
}
RoadClassification(bool motorway_class,
bool link_class,
bool may_be_ignored,
RoadPriorityClass::Enum road_priority_class)
: motorway_class(motorway_class), link_class(link_class), may_be_ignored(may_be_ignored),
road_priority_class(road_priority_class)
{
}
bool IsMotorwayClass() const { return (0 != motorway_class) && (0 == link_class); }
void SetMotorwayFlag(const bool new_value) { motorway_class = new_value; }
bool IsRampClass() const { return (0 != motorway_class) && (0 != link_class); }
bool IsLinkClass() const { return (0 != link_class); }
void SetLinkClass(const bool new_value) { link_class = new_value; }
bool IsLowPriorityRoadClass() const { return (0 != may_be_ignored); }
void SetLowPriorityFlag(const bool new_value) { may_be_ignored = new_value; }
std::uint32_t GetPriority() const
{
return static_cast<std::uint32_t>(road_priority_class);
}
RoadPriorityClass::Enum GetClass() const { return road_priority_class; }
void SetClass(const RoadPriorityClass::Enum new_value)
{
road_priority_class = new_value;
}
bool operator==(const RoadClassification &other) const
{
return motorway_class == other.motorway_class && link_class == other.link_class &&
may_be_ignored == other.may_be_ignored &&
road_priority_class == other.road_priority_class;
}
bool operator!=(const RoadClassification &other ) const
{
return !(*this == other);
}
std::string ToString() const
{
return std::string() + (motorway_class ? "motorway" : "normal") +
(link_class ? "_link" : "") + (may_be_ignored ? " ignorable " : " important ") +
std::to_string(road_priority_class);
}
};
#pragma pack(pop)
static_assert(sizeof(RoadClassification) == 1,"Road Classification should fit a byte. Increasing this has a severe impact on memory.");
inline bool canBeSeenAsFork(const RoadClassification first, const RoadClassification second)
{
return std::abs(static_cast<int>(first.GetPriority()) -
static_cast<int>(second.GetPriority())) <= 1;
}
} // namespace guidance
} // namespace extractor
} // namespace osrm
#endif // OSRM_EXTRACTOR_CLASSIFICATION_DATA_HPP_

View File

@ -12,7 +12,6 @@
#include "extractor/query_node.hpp" #include "extractor/query_node.hpp"
#include "extractor/suffix_table.hpp" #include "extractor/suffix_table.hpp"
#include "extractor/guidance/classification_data.hpp"
#include "extractor/guidance/discrete_angle.hpp" #include "extractor/guidance/discrete_angle.hpp"
#include "extractor/guidance/intersection.hpp" #include "extractor/guidance/intersection.hpp"
#include "extractor/guidance/turn_instruction.hpp" #include "extractor/guidance/turn_instruction.hpp"
@ -46,12 +45,6 @@ using util::guidance::leavesRoundabout;
namespace detail namespace detail
{ {
const constexpr double DESIRED_SEGMENT_LENGTH = 10.0; const constexpr double DESIRED_SEGMENT_LENGTH = 10.0;
const constexpr bool shiftable_ccw[] = {false, true, true, false, false, true, true, false};
const constexpr bool shiftable_cw[] = {false, false, true, true, false, false, true, true};
const constexpr std::uint8_t modifier_bounds[detail::num_direction_modifiers] = {
0, 36, 93, 121, 136, 163, 220, 255};
const constexpr double discrete_angle_step_size = 360. / 24;
template <typename IteratorType> template <typename IteratorType>
util::Coordinate util::Coordinate
@ -156,163 +149,6 @@ getRepresentativeCoordinate(const NodeID from_node,
} }
} }
// shift an instruction around the degree circle in CCW order
inline DirectionModifier::Enum forcedShiftCCW(const DirectionModifier::Enum modifier)
{
return static_cast<DirectionModifier::Enum>((static_cast<std::uint32_t>(modifier) + 1) %
detail::num_direction_modifiers);
}
inline DirectionModifier::Enum shiftCCW(const DirectionModifier::Enum modifier)
{
if (detail::shiftable_ccw[static_cast<int>(modifier)])
return forcedShiftCCW(modifier);
else
return modifier;
}
// shift an instruction around the degree circle in CW order
inline DirectionModifier::Enum forcedShiftCW(const DirectionModifier::Enum modifier)
{
return static_cast<DirectionModifier::Enum>(
(static_cast<std::uint32_t>(modifier) + detail::num_direction_modifiers - 1) %
detail::num_direction_modifiers);
}
inline DirectionModifier::Enum shiftCW(const DirectionModifier::Enum modifier)
{
if (detail::shiftable_cw[static_cast<int>(modifier)])
return forcedShiftCW(modifier);
else
return modifier;
}
inline bool isBasic(const TurnType::Enum type)
{
return type == TurnType::Turn || type == TurnType::EndOfRoad;
}
inline bool isUturn(const TurnInstruction instruction)
{
return isBasic(instruction.type) && instruction.direction_modifier == DirectionModifier::UTurn;
}
inline bool resolve(TurnInstruction &to_resolve, const TurnInstruction neighbor, bool resolve_cw)
{
const auto shifted_turn = resolve_cw ? shiftCW(to_resolve.direction_modifier)
: shiftCCW(to_resolve.direction_modifier);
if (shifted_turn == neighbor.direction_modifier ||
shifted_turn == to_resolve.direction_modifier)
return false;
to_resolve.direction_modifier = shifted_turn;
return true;
}
inline bool resolveTransitive(TurnInstruction &first,
TurnInstruction &second,
const TurnInstruction third,
bool resolve_cw)
{
if (resolve(second, third, resolve_cw))
{
first.direction_modifier =
resolve_cw ? shiftCW(first.direction_modifier) : shiftCCW(first.direction_modifier);
return true;
}
return false;
}
inline bool isSlightTurn(const TurnInstruction turn)
{
return (isBasic(turn.type) || turn.type == TurnType::NoTurn) &&
(turn.direction_modifier == DirectionModifier::Straight ||
turn.direction_modifier == DirectionModifier::SlightRight ||
turn.direction_modifier == DirectionModifier::SlightLeft);
}
inline bool isSlightModifier(const DirectionModifier::Enum direction_modifier)
{
return (direction_modifier == DirectionModifier::Straight ||
direction_modifier == DirectionModifier::SlightRight ||
direction_modifier == DirectionModifier::SlightLeft);
}
inline bool isSharpTurn(const TurnInstruction turn)
{
return isBasic(turn.type) && (turn.direction_modifier == DirectionModifier::SharpLeft ||
turn.direction_modifier == DirectionModifier::SharpRight);
}
inline bool isStraight(const TurnInstruction turn)
{
return (isBasic(turn.type) || turn.type == TurnType::NoTurn) &&
turn.direction_modifier == DirectionModifier::Straight;
}
inline bool isConflict(const TurnInstruction first, const TurnInstruction second)
{
return (first.type == second.type && first.direction_modifier == second.direction_modifier) ||
(isStraight(first) && isStraight(second));
}
inline DiscreteAngle discretizeAngle(const double angle)
{
BOOST_ASSERT(angle >= 0. && angle <= 360.);
return DiscreteAngle(static_cast<std::uint8_t>(
(angle + 0.5 * detail::discrete_angle_step_size) / detail::discrete_angle_step_size));
}
inline double angleFromDiscreteAngle(const DiscreteAngle angle)
{
return static_cast<double>(angle) * detail::discrete_angle_step_size +
0.5 * detail::discrete_angle_step_size;
}
inline double getAngularPenalty(const double angle, DirectionModifier::Enum modifier)
{
// these are not aligned with getTurnDirection but represent an ideal center
const double center[] = {0, 45, 90, 135, 180, 225, 270, 315};
return angularDeviation(center[static_cast<int>(modifier)], angle);
}
inline double getTurnConfidence(const double angle, TurnInstruction instruction)
{
// special handling of U-Turns and Roundabout
if (!isBasic(instruction.type) || instruction.direction_modifier == DirectionModifier::UTurn)
return 1.0;
const double deviations[] = {0, 45, 50, 30, 20, 30, 50, 45};
const double difference = getAngularPenalty(angle, instruction.direction_modifier);
const double max_deviation = deviations[static_cast<int>(instruction.direction_modifier)];
return 1.0 - (difference / max_deviation) * (difference / max_deviation);
}
inline bool canBeSuppressed(const TurnType::Enum type)
{
if (type == TurnType::Turn)
return true;
return false;
}
inline bool isLowPriorityRoadClass(const FunctionalRoadClass road_class)
{
return road_class == FunctionalRoadClass::LOW_PRIORITY_ROAD ||
road_class == FunctionalRoadClass::SERVICE;
}
inline bool isDistinct(const DirectionModifier::Enum first, const DirectionModifier::Enum second)
{
if ((first + 1) % detail::num_direction_modifiers == second)
return false;
if ((second + 1) % detail::num_direction_modifiers == first)
return false;
return true;
}
inline std::pair<std::string, std::string> getPrefixAndSuffix(const std::string &data) inline std::pair<std::string, std::string> getPrefixAndSuffix(const std::string &data)
{ {
const auto suffix_pos = data.find_last_of(' '); const auto suffix_pos = data.find_last_of(' ');
@ -422,26 +258,6 @@ inline bool requiresNameAnnounced(const std::string &from,
return !obvious_change; return !obvious_change;
} }
inline int getPriority(const FunctionalRoadClass road_class)
{
// The road priorities indicate which roads can bee seen as more or less equal.
// They are used in Fork-Discovery. Possibly should be moved to profiles post v5?
// A fork can happen between road types that are at most 1 priority apart from each other
const constexpr int road_priority[] = {
14, 0, 14, 2, 14, 4, 14, 6, 14, 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
// Based on the priorities assigned above, we can set forks only if the road priorities match
// closely.
// Potentially we could include features like number of lanes here and others?
// Should also be moved to profiles
return std::abs(getPriority(first) - getPriority(second)) <= 1;
}
// To simplify handling of Left/Right hand turns, we can mirror turns and write an intersection // To simplify handling of Left/Right hand turns, we can mirror turns and write an intersection
// handler only for one side. The mirror function turns a left-hand turn in a equivalent right-hand // handler only for one side. The mirror function turns a left-hand turn in a equivalent right-hand
// turn and vice versa. // turn and vice versa.

View File

@ -7,7 +7,7 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include "extractor/guidance/classification_data.hpp" #include "extractor/guidance/road_classification.hpp"
#include "osrm/coordinate.hpp" #include "osrm/coordinate.hpp"
#include <utility> #include <utility>
@ -51,7 +51,7 @@ struct InternalExtractorEdge
TRAVEL_MODE_INACCESSIBLE, TRAVEL_MODE_INACCESSIBLE,
false, false,
guidance::TurnLaneType::empty, guidance::TurnLaneType::empty,
guidance::RoadClassificationData()) guidance::RoadClassification())
{ {
} }
@ -67,7 +67,7 @@ struct InternalExtractorEdge
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
LaneDescriptionID lane_description, LaneDescriptionID lane_description,
guidance::RoadClassificationData road_classification) guidance::RoadClassification road_classification)
: result(source, : result(source,
target, target,
name_id, name_id,
@ -107,7 +107,7 @@ struct InternalExtractorEdge
TRAVEL_MODE_INACCESSIBLE, TRAVEL_MODE_INACCESSIBLE,
false, false,
INVALID_LANE_DESCRIPTIONID, INVALID_LANE_DESCRIPTIONID,
guidance::RoadClassificationData()); guidance::RoadClassification());
} }
static InternalExtractorEdge max_osm_value() static InternalExtractorEdge max_osm_value()
{ {
@ -123,7 +123,7 @@ struct InternalExtractorEdge
TRAVEL_MODE_INACCESSIBLE, TRAVEL_MODE_INACCESSIBLE,
false, false,
INVALID_LANE_DESCRIPTIONID, INVALID_LANE_DESCRIPTIONID,
guidance::RoadClassificationData()); guidance::RoadClassification());
} }
static InternalExtractorEdge min_internal_value() static InternalExtractorEdge min_internal_value()

View File

@ -4,7 +4,7 @@
#include "extractor/travel_mode.hpp" #include "extractor/travel_mode.hpp"
#include "util/typedefs.hpp" #include "util/typedefs.hpp"
#include "extractor/guidance/classification_data.hpp" #include "extractor/guidance/road_classification.hpp"
namespace osrm namespace osrm
{ {
@ -27,7 +27,7 @@ struct NodeBasedEdge
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
const LaneDescriptionID lane_description_id, const LaneDescriptionID lane_description_id,
guidance::RoadClassificationData road_classification); guidance::RoadClassification road_classification);
bool operator<(const NodeBasedEdge &other) const; bool operator<(const NodeBasedEdge &other) const;
@ -43,7 +43,7 @@ struct NodeBasedEdge
bool is_split : 1; bool is_split : 1;
TravelMode travel_mode : 4; TravelMode travel_mode : 4;
LaneDescriptionID lane_description_id; LaneDescriptionID lane_description_id;
guidance::RoadClassificationData road_classification; guidance::RoadClassification road_classification;
}; };
struct NodeBasedEdgeWithOSM : NodeBasedEdge struct NodeBasedEdgeWithOSM : NodeBasedEdge
@ -60,7 +60,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
const LaneDescriptionID lane_description_id, const LaneDescriptionID lane_description_id,
guidance::RoadClassificationData road_classification); guidance::RoadClassification road_classification);
OSMNodeID osm_source_id; OSMNodeID osm_source_id;
OSMNodeID osm_target_id; OSMNodeID osm_target_id;
@ -87,7 +87,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
const LaneDescriptionID lane_description_id, const LaneDescriptionID lane_description_id,
guidance::RoadClassificationData road_classification) guidance::RoadClassification road_classification)
: source(source), target(target), name_id(name_id), weight(weight), forward(forward), : source(source), target(target), name_id(name_id), weight(weight), forward(forward),
backward(backward), roundabout(roundabout), access_restricted(access_restricted), backward(backward), roundabout(roundabout), access_restricted(access_restricted),
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode), startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
@ -125,7 +125,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(
TravelMode travel_mode, TravelMode travel_mode,
bool is_split, bool is_split,
const LaneDescriptionID lane_description_id, const LaneDescriptionID lane_description_id,
guidance::RoadClassificationData road_classification) guidance::RoadClassification road_classification)
: NodeBasedEdge(SPECIAL_NODEID, : NodeBasedEdge(SPECIAL_NODEID,
SPECIAL_NODEID, SPECIAL_NODEID,
name_id, name_id,

View File

@ -54,6 +54,15 @@ inline void print(const std::vector<engine::guidance::RouteStep> &steps)
} }
} }
inline void print( const extractor::guidance::Intersection & intersection )
{
std::cout << " Intersection:\n";
for (const auto &road : intersection)
std::cout << "\t" << toString(road) << "\n";
std::cout << std::flush;
}
inline void print(const extractor::guidance::lanes::LaneDataVector &turn_lane_data) inline void print(const extractor::guidance::lanes::LaneDataVector &turn_lane_data)
{ {
std::cout << " Tags:\n"; std::cout << " Tags:\n";
@ -76,10 +85,7 @@ printTurnAssignmentData(const NodeID at,
std::cout << std::setprecision(12) << toFloating(coordinate.lat) << " " std::cout << std::setprecision(12) << toFloating(coordinate.lat) << " "
<< toFloating(coordinate.lon) << "\n"; << toFloating(coordinate.lon) << "\n";
std::cout << " Intersection:\n"; print(intersection);
for (const auto &road : intersection)
std::cout << "\t" << toString(road) << "\n";
// flushes as well // flushes as well
print(turn_lane_data); print(turn_lane_data);
} }

View File

@ -1,7 +1,7 @@
#ifndef NODE_BASED_GRAPH_HPP #ifndef NODE_BASED_GRAPH_HPP
#define NODE_BASED_GRAPH_HPP #define NODE_BASED_GRAPH_HPP
#include "extractor/guidance/classification_data.hpp" #include "extractor/guidance/road_classification.hpp"
#include "extractor/node_based_edge.hpp" #include "extractor/node_based_edge.hpp"
#include "util/dynamic_graph.hpp" #include "util/dynamic_graph.hpp"
#include "util/graph_utils.hpp" #include "util/graph_utils.hpp"
@ -49,7 +49,7 @@ struct NodeBasedEdgeData
bool startpoint : 1; bool startpoint : 1;
extractor::TravelMode travel_mode : 4; extractor::TravelMode travel_mode : 4;
LaneDescriptionID lane_description_id; LaneDescriptionID lane_description_id;
extractor::guidance::RoadClassificationData road_classification; extractor::guidance::RoadClassification road_classification;
bool IsCompatibleTo(const NodeBasedEdgeData &other) const bool IsCompatibleTo(const NodeBasedEdgeData &other) const
{ {

View File

@ -2,6 +2,7 @@
local find_access_tag = require("lib/access").find_access_tag local find_access_tag = require("lib/access").find_access_tag
local limit = require("lib/maxspeed").limit local limit = require("lib/maxspeed").limit
local set_classification = require("lib/guidance").set_classification
-- Begin of globals -- Begin of globals
barrier_whitelist = { [""] = true, ["cycle_barrier"] = true, ["bollard"] = true, ["entrance"] = true, ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true, ["block"] = true } barrier_whitelist = { [""] = true, ["cycle_barrier"] = true, ["bollard"] = true, ["entrance"] = true, ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true, ["block"] = true }
@ -392,6 +393,9 @@ function way_function (way, result)
result.backward_speed = math.min(surface_speeds[surface], result.backward_speed) result.backward_speed = math.min(surface_speeds[surface], result.backward_speed)
end end
-- set the road classification based on guidance globals configuration
set_classification(highway,result)
-- maxspeed -- maxspeed
limit( result, maxspeed, maxspeed_forward, maxspeed_backward ) limit( result, maxspeed, maxspeed_forward, maxspeed_backward )
end end

View File

@ -1,7 +1,8 @@
-- Car profile -- Car profile
local find_access_tag = require("lib/access").find_access_tag local find_access_tag = require("lib/access").find_access_tag
local get_destination = require("lib/destination").get_destination local get_destination = require("lib/destination").get_destination
local set_classification = require("lib/guidance").set_classification
local get_turn_lanes = require("lib/guidance").get_turn_lanes
-- Begin of globals -- Begin of globals
barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["checkpoint"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["lift_gate"] = true, ["no"] = true, ["entrance"] = true } barrier_whitelist = { ["cattle_grid"] = true, ["border_control"] = true, ["checkpoint"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["lift_gate"] = true, ["no"] = true, ["entrance"] = true }
@ -166,62 +167,6 @@ function get_exceptions(vector)
end end
end end
-- returns forward,backward psv lane count
local function getPSVCounts(way)
local psv = way:get_value_by_key("lanes:psv")
local psv_forward = way:get_value_by_key("lanes:psv:forward");
local psv_backward = way:get_value_by_key("lanes:psv:backward");
local fw = 0;
local bw = 0;
if( psv and psv ~= "" ) then
fw = tonumber(psv)
if( fw == nil ) then
fw = 0
end
end
if( psv_forward and psv_forward ~= "" ) then
fw = tonumber(psv_forward)
if( fw == nil ) then
fw = 0
end
end
if( psv_backward and psv_backward ~= "" ) then
bw = tonumber(psv_backward);
if( bw == nil ) then
bw = 0
end
end
return fw, bw
end
-- this is broken for left-sided driving. It needs to switch left and right in case of left-sided driving
local function getTurnLanes(way)
local fw_psv = 0
local bw_psv = 0
fw_psv, bw_psv = getPSVCounts(way)
local turn_lanes = way:get_value_by_key("turn:lanes")
local turn_lanes_fw = way:get_value_by_key("turn:lanes:forward")
local turn_lanes_bw = way:get_value_by_key("turn:lanes:backward")
if( fw_psv ~= 0 or bw_psv ~= 0 ) then
if turn_lanes and turn_lanes ~= "" then
turn_lanes = trimLaneString(turn_lanes, bw_psv, fw_psv )
end
if turn_lanes_fw and turn_lanes_fw ~= "" then
turn_lanes_fw = trimLaneString(turn_lanes_fw, bw_psv, fw_psv )
end
--backwards turn lanes need to treat bw_psv as fw_psv and vice versa
if turn_lanes_bw and turn_lanes_bw ~= "" then
turn_lanes_bw = trimLaneString(turn_lanes_bw, fw_psv, bw_psv )
end
end
return turn_lanes, turn_lanes_fw, turn_lanes_bw
end
local function parse_maxspeed(source) local function parse_maxspeed(source)
if not source then if not source then
return 0 return 0
@ -340,7 +285,7 @@ function way_function (way, result)
result.backward_speed = bridge_speed result.backward_speed = bridge_speed
end end
-- leave early of this way is not accessible -- leave early if this way is not accessible
if "" == highway then if "" == highway then
return return
end end
@ -402,6 +347,9 @@ function way_function (way, result)
result.backward_speed = math.min(smoothness_speeds[smoothness], result.backward_speed) result.backward_speed = math.min(smoothness_speeds[smoothness], result.backward_speed)
end end
-- set the road classification based on guidance globals configuration
set_classification(highway,result)
-- parse the remaining tags -- parse the remaining tags
local name = way:get_value_by_key("name") local name = way:get_value_by_key("name")
local pronunciation = way:get_value_by_key("name:pronunciation") local pronunciation = way:get_value_by_key("name:pronunciation")
@ -432,7 +380,7 @@ function way_function (way, result)
local turn_lanes_forward = "" local turn_lanes_forward = ""
local turn_lanes_backward = "" local turn_lanes_backward = ""
turn_lanes, turn_lanes_forward, turn_lanes_backward = getTurnLanes(way) turn_lanes, turn_lanes_forward, turn_lanes_backward = get_turn_lanes(way)
if turn_lanes and turn_lanes ~= "" then if turn_lanes and turn_lanes ~= "" then
result.turn_lanes_forward = turn_lanes; result.turn_lanes_forward = turn_lanes;
result.turn_lanes_backward = turn_lanes; result.turn_lanes_backward = turn_lanes;

113
profiles/lib/guidance.lua Normal file
View File

@ -0,0 +1,113 @@
local Guidance = {}
-- Guidance: Default Mapping from roads to types/priorities
highway_classes = { ["motorway"] = road_priority_class.motorway,
["motorway_link"] = road_priority_class.link_road,
["trunk"] = road_priority_class.trunk,
["trunk_link"] = road_priority_class.link_road,
["primary"] = road_priority_class.primary,
["primary_link"] = road_priority_class.link_road,
["secondary"] = road_priority_class.secondary,
["secondary_link"] = road_priority_class.link_road,
["tertiary"] = road_priority_class.tertiary,
["tertiary_link"] = road_priority_class.link_road,
["unclassified"] = road_priority_class.side_residential,
["residential"] = road_priority_class.side_residential,
["service"] = road_priority_class.connectivity,
["living_street"] = road_priority_class.main_residential,
["track"] = road_priority_class.bike_path,
["path"] = road_priority_class.bike_path,
["footway"] = road_priority_class.foot_path,
["pedestrian"] = road_priority_class.foot_path,
["steps"] = road_priority_class.foot_path}
default_highway_class = road_priority_class.connectivity;
motorway_types = { ["motorway"] = true, ["motorway_link"] = true, ["trunk"] = true, ["trunk_link"] = true }
-- these road types are set with a car in mind. For bicycle/walk we probably need different ones
road_types = { ["motorway"] = true,
["motorway_link"] = true,
["trunk"] = true,
["trunk_link"] = true,
["primary"] = true,
["primary_link"] = true,
["secondary"] = true,
["secondary_link"] = true,
["tertiary"] = true,
["tertiary_link"] = true,
["unclassified"] = true,
["residential"] = true,
["living_street"] = true }
link_types = { ["motorway_link"] = true, ["trunk_link"] = true, ["primary_link"] = true, ["secondary_link"] = true, ["tertiary_link"] = true }
function Guidance.set_classification (highway, result)
if motorway_types[highway] then
result.road_classification.motorway_class = true;
end
if link_types[highway] then
result.road_classification.link_class = true;
end
if highway_classes[highway] ~= nil then
result.road_classification.road_priority_class = highway_classes[highway]
else
result.road_classification.road_priority_class = default_highway_class
end
if road_types[highway] then
result.road_classification.may_be_ignored = false;
else
result.road_classification.may_be_ignored = true;
end
end
-- returns forward,backward psv lane count
local function get_psv_counts(way)
local psv = way:get_value_by_key("lanes:psv")
local psv_forward = way:get_value_by_key("lanes:psv:forward");
local psv_backward = way:get_value_by_key("lanes:psv:backward");
local fw = 0;
local bw = 0;
if( psv and psv ~= "" ) then
fw = tonumber(psv)
if( fw == nil ) then
fw = 0
end
end
if( psv_forward and psv_forward ~= "" ) then
fw = tonumber(psv_forward)
if( fw == nil ) then
fw = 0
end
end
if( psv_backward and psv_backward ~= "" ) then
bw = tonumber(psv_backward);
if( bw == nil ) then
fw = 0
end
end
return fw, bw
end
-- this is broken for left-sided driving. It needs to switch left and right in case of left-sided driving
function Guidance.get_turn_lanes(way)
local fw_psv = 0
local bw_psv = 0
fw_psv, bw_psv = get_psv_counts(way)
local turn_lanes = way:get_value_by_key("turn:lanes")
local turn_lanes_fw = way:get_value_by_key("turn:lanes:forward")
local turn_lanes_bw = way:get_value_by_key("turn:lanes:backward")
if( fw_psv ~= 0 or bw_psv ~= 0 ) then
turn_lanes = trimLaneString(turn_lanes, bw_psv, fw_psv )
turn_lanes_fw = trimLaneString(turn_lanes_fw, bw_psv, fw_psv )
--backwards turn lanes need to treat bw_psv as fw_psv and vice versa
turn_lanes_bw = trimLaneString(turn_lanes_bw, fw_psv, bw_psv )
end
return turn_lanes, turn_lanes_fw, turn_lanes_bw
end
return Guidance

View File

@ -425,7 +425,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
const int32_t turn_penalty = scripting_environment.GetTurnPenalty(180. - turn.angle); const int32_t turn_penalty = scripting_environment.GetTurnPenalty(180. - turn.angle);
const auto turn_instruction = turn.instruction; const auto turn_instruction = turn.instruction;
if (guidance::isUturn(turn_instruction)) if (turn_instruction.direction_modifier == guidance::DirectionModifier::UTurn)
{ {
distance += profile_properties.u_turn_penalty; distance += profile_properties.u_turn_penalty;
} }

View File

@ -1,8 +1,9 @@
#include "extractor/extractor_callbacks.hpp"
#include "extractor/external_memory_node.hpp" #include "extractor/external_memory_node.hpp"
#include "extractor/extraction_containers.hpp" #include "extractor/extraction_containers.hpp"
#include "extractor/extraction_node.hpp" #include "extractor/extraction_node.hpp"
#include "extractor/extraction_way.hpp" #include "extractor/extraction_way.hpp"
#include "extractor/extractor_callbacks.hpp"
#include "extractor/guidance/road_classification.hpp"
#include "extractor/restriction.hpp" #include "extractor/restriction.hpp"
#include "util/for_each_pair.hpp" #include "util/for_each_pair.hpp"
@ -140,13 +141,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti
} }
// FIXME this need to be moved into the profiles // FIXME this need to be moved into the profiles
const char *data = input_way.get_value_by_key("highway"); const guidance::RoadClassification road_classification = parsed_way.road_classification;
guidance::RoadClassificationData road_classification;
if (data)
{
road_classification.road_class = guidance::functionalRoadClassFromTag(data);
}
const auto laneStringToDescription = [](std::string lane_string) -> TurnLaneDescription { const auto laneStringToDescription = [](std::string lane_string) -> TurnLaneDescription {
if (lane_string.empty()) if (lane_string.empty())
return {}; return {};

View File

@ -1,53 +0,0 @@
#include "extractor/guidance/classification_data.hpp"
#include "util/simple_logger.hpp"
#include <unordered_map>
namespace osrm
{
namespace extractor
{
namespace guidance
{
FunctionalRoadClass functionalRoadClassFromTag(std::string const &value)
{
// FIXME at some point this should be part of the profiles
const static auto class_hash = [] {
std::unordered_map<std::string, FunctionalRoadClass> hash;
hash["motorway"] = FunctionalRoadClass::MOTORWAY;
hash["motorway_link"] = FunctionalRoadClass::MOTORWAY_LINK;
hash["trunk"] = FunctionalRoadClass::TRUNK;
hash["trunk_link"] = FunctionalRoadClass::TRUNK_LINK;
hash["primary"] = FunctionalRoadClass::PRIMARY;
hash["primary_link"] = FunctionalRoadClass::PRIMARY_LINK;
hash["secondary"] = FunctionalRoadClass::SECONDARY;
hash["secondary_link"] = FunctionalRoadClass::SECONDARY_LINK;
hash["tertiary"] = FunctionalRoadClass::TERTIARY;
hash["tertiary_link"] = FunctionalRoadClass::TERTIARY_LINK;
hash["unclassified"] = FunctionalRoadClass::UNCLASSIFIED;
hash["residential"] = FunctionalRoadClass::RESIDENTIAL;
hash["service"] = FunctionalRoadClass::SERVICE;
hash["living_street"] = FunctionalRoadClass::LIVING_STREET;
hash["track"] = FunctionalRoadClass::LOW_PRIORITY_ROAD;
hash["road"] = FunctionalRoadClass::LOW_PRIORITY_ROAD;
hash["path"] = FunctionalRoadClass::LOW_PRIORITY_ROAD;
hash["driveway"] = FunctionalRoadClass::LOW_PRIORITY_ROAD;
return hash;
}();
if (class_hash.find(value) != class_hash.end())
{
return class_hash.find(value)->second;
}
else
{
// TODO activate again, when road classes are moved to the profile
// util::SimpleLogger().Write(logDEBUG) << "Unknown road class encountered: " << value;
return FunctionalRoadClass::UNKNOWN;
}
}
} // ns guidance
} // ns extractor
} // ns osrm

View File

@ -48,9 +48,9 @@ TurnType::Enum IntersectionHandler::findBasicTurnType(const EdgeID via_edge,
const auto &in_data = node_based_graph.GetEdgeData(via_edge); const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid); const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
bool on_ramp = isRampClass(in_data.road_classification.road_class); bool on_ramp = in_data.road_classification.IsRampClass();
bool onto_ramp = isRampClass(out_data.road_classification.road_class); bool onto_ramp = out_data.road_classification.IsRampClass();
if (!on_ramp && onto_ramp) if (!on_ramp && onto_ramp)
return TurnType::OnRamp; return TurnType::OnRamp;
@ -130,10 +130,10 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
ConnectedRoad &right) const ConnectedRoad &right) const
{ {
const auto &in_data = node_based_graph.GetEdgeData(via_edge); const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const bool low_priority_left = isLowPriorityRoadClass( const bool low_priority_left =
node_based_graph.GetEdgeData(left.turn.eid).road_classification.road_class); node_based_graph.GetEdgeData(left.turn.eid).road_classification.IsLowPriorityRoadClass();
const bool low_priority_right = isLowPriorityRoadClass( const bool low_priority_right =
node_based_graph.GetEdgeData(right.turn.eid).road_classification.road_class); node_based_graph.GetEdgeData(right.turn.eid).road_classification.IsLowPriorityRoadClass();
if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION && if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
angularDeviation(right.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE)) angularDeviation(right.turn.angle, STRAIGHT_ANGLE) > FUZZY_ANGLE_DIFFERENCE))
{ {
@ -339,6 +339,7 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
double best_continue_deviation = 180; double best_continue_deviation = 180;
const EdgeData &in_data = node_based_graph.GetEdgeData(via_edge); const EdgeData &in_data = node_based_graph.GetEdgeData(via_edge);
const auto in_classification = in_data.road_classification;
for (std::size_t i = 1; i < intersection.size(); ++i) for (std::size_t i = 1; i < intersection.size(); ++i)
{ {
const double deviation = angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE); const double deviation = angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE);
@ -349,12 +350,16 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
} }
const auto out_data = node_based_graph.GetEdgeData(intersection[i].turn.eid); const auto out_data = node_based_graph.GetEdgeData(intersection[i].turn.eid);
auto continue_class = node_based_graph.GetEdgeData(intersection[best_continue].turn.eid) auto continue_class =
.road_classification.road_class; node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification;
if (intersection[i].entry_allowed && out_data.name_id == in_data.name_id && if (intersection[i].entry_allowed && out_data.name_id == in_data.name_id &&
(best_continue == 0 || continue_class > out_data.road_classification.road_class || (best_continue == 0 ||
(continue_class.GetPriority() > out_data.road_classification.GetPriority() &&
in_classification != continue_class) ||
(deviation < best_continue_deviation && (deviation < best_continue_deviation &&
out_data.road_classification.road_class == continue_class))) out_data.road_classification == continue_class) ||
(continue_class != in_classification &&
out_data.road_classification == continue_class)))
{ {
best_continue_deviation = deviation; best_continue_deviation = deviation;
best_continue = i; best_continue = i;
@ -368,10 +373,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
return 0; return 0;
// has no obvious continued road // has no obvious continued road
if (best_continue == 0 || best_continue_deviation >= 2 * NARROW_TURN_ANGLE || if (best_continue == 0 || best_continue_deviation >= 2 * NARROW_TURN_ANGLE ||
(node_based_graph.GetEdgeData(intersection[best_continue].turn.eid) (node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification ==
.road_classification.road_class == node_based_graph.GetEdgeData(intersection[best].turn.eid).road_classification &&
node_based_graph.GetEdgeData(intersection[best].turn.eid)
.road_classification.road_class &&
std::abs(best_continue_deviation) > 1 && best_deviation / best_continue_deviation < 0.75)) std::abs(best_continue_deviation) > 1 && best_deviation / best_continue_deviation < 0.75))
{ {
// Find left/right deviation // Find left/right deviation
@ -418,9 +421,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
continue; continue;
if (angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE) / deviation < 1.1 && if (angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE) / deviation < 1.1 &&
continue_data.road_classification.road_class == continue_data.road_classification ==
node_based_graph.GetEdgeData(intersection[i].turn.eid) node_based_graph.GetEdgeData(intersection[i].turn.eid).road_classification)
.road_classification.road_class)
return 0; return 0;
} }
return best_continue; // no obvious turn return best_continue; // no obvious turn

View File

@ -1,6 +1,6 @@
#include "extractor/guidance/motorway_handler.hpp"
#include "extractor/guidance/classification_data.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/motorway_handler.hpp"
#include "extractor/guidance/road_classification.hpp"
#include "extractor/guidance/toolkit.hpp" #include "extractor/guidance/toolkit.hpp"
#include "util/guidance/toolkit.hpp" #include "util/guidance/toolkit.hpp"
@ -20,25 +20,26 @@ namespace extractor
{ {
namespace guidance namespace guidance
{ {
namespace detail namespace
{ {
inline bool isMotorwayClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph) inline bool isMotorwayClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
{ {
return isMotorwayClass(node_based_graph.GetEdgeData(eid).road_classification.road_class); return node_based_graph.GetEdgeData(eid).road_classification.IsMotorwayClass();
} }
inline FunctionalRoadClass roadClass(const ConnectedRoad &road, inline RoadClassification roadClass(const ConnectedRoad &road,
const util::NodeBasedDynamicGraph &graph) const util::NodeBasedDynamicGraph &graph)
{ {
return graph.GetEdgeData(road.turn.eid).road_classification.road_class; return graph.GetEdgeData(road.turn.eid).road_classification;
} }
inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph) inline bool isRampClass(EdgeID eid, const util::NodeBasedDynamicGraph &node_based_graph)
{ {
return isRampClass(node_based_graph.GetEdgeData(eid).road_classification.road_class); return node_based_graph.GetEdgeData(eid).road_classification.IsRampClass();
}
} }
} // namespace
MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph, MotorwayHandler::MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
const std::vector<QueryNode> &node_info_list, const std::vector<QueryNode> &node_info_list,
const util::NameTable &name_table, const util::NameTable &name_table,
@ -56,36 +57,29 @@ bool MotorwayHandler::canProcess(const NodeID,
for (const auto &road : intersection) for (const auto &road : intersection)
{ {
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
// not merging or forking? // not merging or forking?
if (road.entry_allowed && angularDeviation(road.turn.angle, STRAIGHT_ANGLE) > 60) if (road.entry_allowed && angularDeviation(road.turn.angle, STRAIGHT_ANGLE) > 60)
return false; return false;
else if (out_data.road_classification.road_class == FunctionalRoadClass::MOTORWAY || else if (isMotorwayClass(road.turn.eid, node_based_graph))
out_data.road_classification.road_class == FunctionalRoadClass::TRUNK)
{ {
if (road.entry_allowed) if (road.entry_allowed)
has_motorway = true; has_motorway = true;
} }
else if (!isRampClass(out_data.road_classification.road_class)) else if (!isRampClass(road.turn.eid, node_based_graph))
has_normal_roads = true; has_normal_roads = true;
} }
if (has_normal_roads) if (has_normal_roads)
return false; return false;
const auto &in_data = node_based_graph.GetEdgeData(via_eid); return has_motorway || isMotorwayClass(via_eid, node_based_graph);
return has_motorway ||
in_data.road_classification.road_class == FunctionalRoadClass::MOTORWAY ||
in_data.road_classification.road_class == FunctionalRoadClass::TRUNK;
} }
Intersection MotorwayHandler:: Intersection MotorwayHandler::
operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const
{ {
const auto &in_data = node_based_graph.GetEdgeData(via_eid);
// coming from motorway // coming from motorway
if (isMotorwayClass(in_data.road_classification.road_class)) if (isMotorwayClass(via_eid, node_based_graph))
{ {
intersection = fromMotorway(via_eid, std::move(intersection)); intersection = fromMotorway(via_eid, std::move(intersection));
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) { std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
@ -104,13 +98,13 @@ operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const
Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection intersection) const Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection intersection) const
{ {
const auto &in_data = node_based_graph.GetEdgeData(via_eid); const auto &in_data = node_based_graph.GetEdgeData(via_eid);
BOOST_ASSERT(isMotorwayClass(in_data.road_classification.road_class)); BOOST_ASSERT(isMotorwayClass(via_eid, node_based_graph));
const auto countExitingMotorways = [this](const Intersection &intersection) { const auto countExitingMotorways = [this](const Intersection &intersection) {
unsigned count = 0; unsigned count = 0;
for (const auto &road : intersection) for (const auto &road : intersection)
{ {
if (road.entry_allowed && detail::isMotorwayClass(road.turn.eid, node_based_graph)) if (road.entry_allowed && isMotorwayClass(road.turn.eid, node_based_graph))
++count; ++count;
} }
return count; return count;
@ -122,8 +116,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
{ {
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid); const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
if (road.turn.angle != 0 && in_data.name_id == out_data.name_id && if (road.turn.angle != 0 && in_data.name_id == out_data.name_id &&
in_data.name_id != EMPTY_NAMEID && in_data.name_id != EMPTY_NAMEID && isMotorwayClass(road.turn.eid, node_based_graph))
isMotorwayClass(out_data.road_classification.road_class))
return road.turn.angle; return road.turn.angle;
} }
return intersection[0].turn.angle; return intersection[0].turn.angle;
@ -134,8 +127,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
double best = 180; double best = 180;
for (const auto &road : intersection) for (const auto &road : intersection)
{ {
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid); if (isMotorwayClass(road.turn.eid, node_based_graph) &&
if (isMotorwayClass(out_data.road_classification.road_class) &&
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < best) angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < best)
{ {
best = angularDeviation(road.turn.angle, STRAIGHT_ANGLE); best = angularDeviation(road.turn.angle, STRAIGHT_ANGLE);
@ -183,10 +175,10 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
} }
} }
else if (intersection.size() == 4 && else if (intersection.size() == 4 &&
detail::roadClass(intersection[1], node_based_graph) == roadClass(intersection[1], node_based_graph) ==
detail::roadClass(intersection[2], node_based_graph) && roadClass(intersection[2], node_based_graph) &&
detail::roadClass(intersection[2], node_based_graph) == roadClass(intersection[2], node_based_graph) ==
detail::roadClass(intersection[3], node_based_graph)) roadClass(intersection[3], node_based_graph))
{ {
// tripple fork at the end // tripple fork at the end
assignFork(via_eid, intersection[3], intersection[2], intersection[1]); assignFork(via_eid, intersection[3], intersection[2], intersection[1]);
@ -212,7 +204,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
{ {
if (road.entry_allowed) if (road.entry_allowed)
{ {
BOOST_ASSERT(detail::isRampClass(road.turn.eid, node_based_graph)); BOOST_ASSERT(isRampClass(road.turn.eid, node_based_graph));
road.turn.instruction = road.turn.instruction =
TurnInstruction::SUPPRESSED(getTurnDirection(road.turn.angle)); TurnInstruction::SUPPRESSED(getTurnDirection(road.turn.angle));
} }
@ -223,7 +215,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
// normal motorway passing some ramps or mering onto another motorway // normal motorway passing some ramps or mering onto another motorway
if (intersection.size() == 2) if (intersection.size() == 2)
{ {
BOOST_ASSERT(!detail::isRampClass(intersection[1].turn.eid, node_based_graph)); BOOST_ASSERT(!isRampClass(intersection[1].turn.eid, node_based_graph));
intersection[1].turn.instruction = intersection[1].turn.instruction =
getInstructionForObvious(intersection.size(), getInstructionForObvious(intersection.size(),
@ -248,16 +240,16 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
else if (road.turn.angle < continue_angle) else if (road.turn.angle < continue_angle)
{ {
road.turn.instruction = { road.turn.instruction = {
detail::isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp
: TurnType::Turn, : TurnType::Turn,
(road.turn.angle < 145) ? DirectionModifier::Right (road.turn.angle < 145) ? DirectionModifier::Right
: DirectionModifier::SlightRight}; : DirectionModifier::SlightRight};
} }
else if (road.turn.angle > continue_angle) else if (road.turn.angle > continue_angle)
{ {
road.turn.instruction = { road.turn.instruction = {
detail::isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp
: TurnType::Turn, : TurnType::Turn,
(road.turn.angle > 215) ? DirectionModifier::Left (road.turn.angle > 215) ? DirectionModifier::Left
: DirectionModifier::SlightLeft}; : DirectionModifier::SlightLeft};
} }
@ -285,7 +277,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
for (std::size_t i = 0; i < intersection.size(); ++i) for (std::size_t i = 0; i < intersection.size(); ++i)
{ {
if (intersection[i].entry_allowed && if (intersection[i].entry_allowed &&
detail::isMotorwayClass(intersection[i].turn.eid, node_based_graph)) isMotorwayClass(intersection[i].turn.eid, node_based_graph))
{ {
if (first_valid < intersection.size()) if (first_valid < intersection.size())
{ {
@ -309,7 +301,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
for (std::size_t i = 0; i < intersection.size(); ++i) for (std::size_t i = 0; i < intersection.size(); ++i)
{ {
if (intersection[i].entry_allowed && if (intersection[i].entry_allowed &&
detail::isMotorwayClass(intersection[i].turn.eid, node_based_graph)) isMotorwayClass(intersection[i].turn.eid, node_based_graph))
{ {
if (second_valid < intersection.size()) if (second_valid < intersection.size())
{ {
@ -349,7 +341,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
if (intersection.size() == 2 && num_valid_turns == 1) if (intersection.size() == 2 && num_valid_turns == 1)
{ {
BOOST_ASSERT(!intersection[0].entry_allowed); BOOST_ASSERT(!intersection[0].entry_allowed);
BOOST_ASSERT(detail::isMotorwayClass(intersection[1].turn.eid, node_based_graph)); BOOST_ASSERT(isMotorwayClass(intersection[1].turn.eid, node_based_graph));
intersection[1].turn.instruction = getInstructionForObvious( intersection[1].turn.instruction = getInstructionForObvious(
intersection.size(), via_eid, isThroughStreet(1, intersection), intersection[1]); intersection.size(), via_eid, isThroughStreet(1, intersection), intersection[1]);
@ -370,7 +362,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
// 0 // 0
if (intersection[1].entry_allowed) if (intersection[1].entry_allowed)
{ {
if (detail::isMotorwayClass(intersection[1].turn.eid, node_based_graph) && if (isMotorwayClass(intersection[1].turn.eid, node_based_graph) &&
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id != node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id !=
EMPTY_NAMEID && EMPTY_NAMEID &&
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id == node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id ==
@ -397,7 +389,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
else else
{ {
BOOST_ASSERT(intersection[2].entry_allowed); BOOST_ASSERT(intersection[2].entry_allowed);
if (detail::isMotorwayClass(intersection[2].turn.eid, node_based_graph) && if (isMotorwayClass(intersection[2].turn.eid, node_based_graph) &&
node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id != node_based_graph.GetEdgeData(intersection[1].turn.eid).name_id !=
EMPTY_NAMEID && EMPTY_NAMEID &&
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id == node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id ==
@ -434,8 +426,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
// \ / // \ /
// | // |
// R // R
if (detail::isMotorwayClass(intersection[1].turn.eid, node_based_graph) && if (isMotorwayClass(intersection[1].turn.eid, node_based_graph) &&
detail::isMotorwayClass(intersection[2].turn.eid, node_based_graph)) isMotorwayClass(intersection[2].turn.eid, node_based_graph))
{ {
assignFork(via_eid, intersection[2], intersection[1]); assignFork(via_eid, intersection[2], intersection[1]);
} }
@ -446,8 +438,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
// M R // M R
// | / // | /
// R // R
if (isMotorwayClass(node_based_graph.GetEdgeData(intersection[1].turn.eid) if (isMotorwayClass(intersection[1].turn.eid, node_based_graph))
.road_classification.road_class))
{ {
intersection[1].turn.instruction = {TurnType::Turn, intersection[1].turn.instruction = {TurnType::Turn,
DirectionModifier::SlightRight}; DirectionModifier::SlightRight};
@ -467,12 +458,11 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
bool passed_highway_entry = false; bool passed_highway_entry = false;
for (auto &road : intersection) for (auto &road : intersection)
{ {
const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid); if (!road.entry_allowed && isMotorwayClass(road.turn.eid, node_based_graph))
if (!road.entry_allowed && isMotorwayClass(edge_data.road_classification.road_class))
{ {
passed_highway_entry = true; passed_highway_entry = true;
} }
else if (isMotorwayClass(edge_data.road_classification.road_class)) else if (isMotorwayClass(road.turn.eid, node_based_graph))
{ {
road.turn.instruction = {TurnType::Merge, road.turn.instruction = {TurnType::Merge,
passed_highway_entry ? DirectionModifier::SlightRight passed_highway_entry ? DirectionModifier::SlightRight
@ -480,7 +470,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
} }
else else
{ {
BOOST_ASSERT(isRampClass(edge_data.road_classification.road_class)); BOOST_ASSERT(isRampClass(road.turn.eid, node_based_graph));
road.turn.instruction = {TurnType::OffRamp, getTurnDirection(road.turn.angle)}; road.turn.instruction = {TurnType::OffRamp, getTurnDirection(road.turn.angle)};
} }
} }
@ -503,13 +493,13 @@ Intersection MotorwayHandler::fallback(Intersection intersection) const
util::SimpleLogger().Write(logDEBUG) util::SimpleLogger().Write(logDEBUG)
<< "road: " << toString(road) << " Name: " << out_data.name_id << "road: " << toString(road) << " Name: " << out_data.name_id
<< " Road Class: " << (int)out_data.road_classification.road_class; << " Road Class: " << out_data.road_classification.ToString();
if (!road.entry_allowed) if (!road.entry_allowed)
continue; continue;
const auto type = isMotorwayClass(out_data.road_classification.road_class) ? TurnType::Merge const auto type =
: TurnType::Turn; isMotorwayClass(road.turn.eid, node_based_graph) ? TurnType::Merge : TurnType::Turn;
if (type == TurnType::Turn) if (type == TurnType::Turn)
{ {

View File

@ -74,8 +74,8 @@ operator()(const NodeID, const EdgeID source_edge_id, Intersection intersection)
const auto check_valid = [this, source_edge_data](const ConnectedRoad &road) { const auto check_valid = [this, source_edge_data](const ConnectedRoad &road) {
const auto road_edge_data = node_based_graph.GetEdgeData(road.turn.eid); const auto road_edge_data = node_based_graph.GetEdgeData(road.turn.eid);
// Test to see if the source edge and the one we're looking at are the same road // Test to see if the source edge and the one we're looking at are the same road
return road_edge_data.road_classification.road_class == return road_edge_data.road_classification ==
source_edge_data.road_classification.road_class && source_edge_data.road_classification &&
road_edge_data.name_id != EMPTY_NAMEID && road_edge_data.name_id != EMPTY_NAMEID &&
road_edge_data.name_id == source_edge_data.name_id && road.entry_allowed; road_edge_data.name_id == source_edge_data.name_id && road.entry_allowed;
}; };

View File

@ -1,4 +1,4 @@
#include "extractor/guidance/classification_data.hpp" #include "extractor/guidance/road_classification.hpp"
#include "extractor/guidance/constants.hpp" #include "extractor/guidance/constants.hpp"
#include "extractor/guidance/turn_analysis.hpp" #include "extractor/guidance/turn_analysis.hpp"
@ -86,7 +86,8 @@ Intersection TurnAnalysis::assignTurnTypes(const NodeID from_nid,
intersection = sliproad_handler(from_nid, via_eid, std::move(intersection)); intersection = sliproad_handler(from_nid, via_eid, std::move(intersection));
// Turn On Ramps Into Off Ramps, if we come from a motorway-like road // Turn On Ramps Into Off Ramps, if we come from a motorway-like road
if (isMotorwayClass(node_based_graph.GetEdgeData(via_eid).road_classification.road_class)) if (node_based_graph.GetEdgeData(via_eid)
.road_classification.IsMotorwayClass())
{ {
std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) { std::for_each(intersection.begin(), intersection.end(), [](ConnectedRoad &road) {
if (road.turn.instruction.type == TurnType::OnRamp) if (road.turn.instruction.type == TurnType::OnRamp)

View File

@ -75,25 +75,28 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
const ConnectedRoad &other) const const ConnectedRoad &other) const
{ {
const auto &in_data = node_based_graph.GetEdgeData(via_edge); const auto &in_data = node_based_graph.GetEdgeData(via_edge);
const auto first_class =
node_based_graph.GetEdgeData(road.turn.eid).road_classification.road_class;
const auto second_class = const auto &first_data = node_based_graph.GetEdgeData(road.turn.eid);
node_based_graph.GetEdgeData(other.turn.eid).road_classification.road_class; const auto &second_data = node_based_graph.GetEdgeData(other.turn.eid);
const auto &first_classification = first_data.road_classification;
const bool is_ramp = isRampClass(first_class); const auto &second_classification = second_data.road_classification;
const bool is_ramp = first_classification.IsRampClass();
const bool is_obvious_by_road_class = const bool is_obvious_by_road_class =
(!is_ramp && (2 * getPriority(first_class) < getPriority(second_class)) && (!is_ramp &&
in_data.road_classification.road_class == first_class) || (2 * first_classification.GetPriority() < second_classification.GetPriority()) &&
(!isLowPriorityRoadClass(first_class) && isLowPriorityRoadClass(second_class)); in_data.road_classification == first_classification) ||
(!first_classification.IsLowPriorityRoadClass() &&
second_classification.IsLowPriorityRoadClass());
if (is_obvious_by_road_class) if (is_obvious_by_road_class)
return true; return true;
const bool other_is_obvious_by_road_class = const bool other_is_obvious_by_road_class =
(!isRampClass(second_class) && (2 * getPriority(second_class) < getPriority(first_class)) && (!second_classification.IsRampClass() &&
in_data.road_classification.road_class == second_class) || (2 * second_classification.GetPriority() < first_classification.GetPriority()) &&
(!isLowPriorityRoadClass(second_class) && isLowPriorityRoadClass(first_class)); in_data.road_classification == second_classification) ||
(!second_classification.IsLowPriorityRoadClass() &&
first_classification.IsLowPriorityRoadClass());
if (other_is_obvious_by_road_class) if (other_is_obvious_by_road_class)
return false; return false;
@ -114,7 +117,7 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
FUZZY_ANGLE_DIFFERENCE; FUZZY_ANGLE_DIFFERENCE;
return is_much_narrower_than_other; return is_much_narrower_than_other;
}; }
Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection intersection) const Intersection TurnHandler::handleThreeWayTurn(const EdgeID via_edge, Intersection intersection) const
{ {
@ -256,13 +259,13 @@ Intersection TurnHandler::handleComplexTurn(const EdgeID via_edge, Intersection
{ {
auto &left = intersection[fork_range.second]; auto &left = intersection[fork_range.second];
auto &right = intersection[fork_range.first]; auto &right = intersection[fork_range.first];
const auto left_class = const auto left_classification =
node_based_graph.GetEdgeData(left.turn.eid).road_classification.road_class; node_based_graph.GetEdgeData(left.turn.eid).road_classification;
const auto right_class = const auto right_classification =
node_based_graph.GetEdgeData(right.turn.eid).road_classification.road_class; node_based_graph.GetEdgeData(right.turn.eid).road_classification;
if (canBeSeenAsFork(left_class, right_class)) if (canBeSeenAsFork(left_classification, right_classification))
assignFork(via_edge, left, right); assignFork(via_edge, left, right);
else if (getPriority(left_class) > getPriority(right_class)) else if (left_classification.GetPriority() > right_classification.GetPriority())
{ {
right.turn.instruction = right.turn.instruction =
getInstructionForObvious(intersection.size(), via_edge, false, right); getInstructionForObvious(intersection.size(), via_edge, false, right);
@ -541,13 +544,12 @@ std::pair<std::size_t, std::size_t> TurnHandler::findFork(const EdgeID via_edge,
}(); }();
const bool has_compatible_classes = [&]() { const bool has_compatible_classes = [&]() {
const bool ramp_class = const bool ramp_class = node_based_graph.GetEdgeData(intersection[right].turn.eid)
isLinkClass(node_based_graph.GetEdgeData(intersection[right].turn.eid) .road_classification.IsLinkClass();
.road_classification.road_class);
for (std::size_t index = right + 1; index <= left; ++index) for (std::size_t index = right + 1; index <= left; ++index)
if (ramp_class != if (ramp_class !=
isLinkClass(node_based_graph.GetEdgeData(intersection[index].turn.eid) node_based_graph.GetEdgeData(intersection[index].turn.eid)
.road_classification.road_class)) .road_classification.IsLinkClass())
return false; return false;
return true; return true;
}(); }();
@ -581,13 +583,13 @@ void TurnHandler::handleDistinctConflict(const EdgeID via_edge,
getTurnDirection(left.turn.angle) == DirectionModifier::SlightLeft || getTurnDirection(left.turn.angle) == DirectionModifier::SlightLeft ||
getTurnDirection(right.turn.angle) == DirectionModifier::SlightRight) getTurnDirection(right.turn.angle) == DirectionModifier::SlightRight)
{ {
const auto left_class = const auto left_classification =
node_based_graph.GetEdgeData(left.turn.eid).road_classification.road_class; node_based_graph.GetEdgeData(left.turn.eid).road_classification;
const auto right_class = const auto right_classification =
node_based_graph.GetEdgeData(right.turn.eid).road_classification.road_class; node_based_graph.GetEdgeData(right.turn.eid).road_classification;
if (canBeSeenAsFork(left_class, right_class)) if (canBeSeenAsFork(left_classification, right_classification))
assignFork(via_edge, left, right); assignFork(via_edge, left, right);
else if (getPriority(left_class) > getPriority(right_class)) else if (left_classification.GetPriority() > right_classification.GetPriority())
{ {
// FIXME this should possibly know about the actual roads? // FIXME this should possibly know about the actual roads?
// here we don't know about the intersection size. To be on the save side, // here we don't know about the intersection size. To be on the save side,

View File

@ -95,6 +95,24 @@ void LuaScriptingEnvironment::InitContext(LuaScriptingContext &context)
luabind::value("river_up", TRAVEL_MODE_RIVER_UP), luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN), luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN),
luabind::value("route", TRAVEL_MODE_ROUTE)], luabind::value("route", TRAVEL_MODE_ROUTE)],
luabind::class_<extractor::guidance::RoadPriorityClass::Enum>("road_priority_class")
.enum_("enums")
[luabind::value("motorway", extractor::guidance::RoadPriorityClass::MOTORWAY),
luabind::value("trunk", extractor::guidance::RoadPriorityClass::TRUNK),
luabind::value("primary", extractor::guidance::RoadPriorityClass::PRIMARY),
luabind::value("secondary", extractor::guidance::RoadPriorityClass::SECONDARY),
luabind::value("tertiary", extractor::guidance::RoadPriorityClass::TERTIARY),
luabind::value("main_residential",
extractor::guidance::RoadPriorityClass::MAIN_RESIDENTIAL),
luabind::value("side_residential",
extractor::guidance::RoadPriorityClass::SIDE_RESIDENTIAL),
luabind::value("link_road", extractor::guidance::RoadPriorityClass::LINK_ROAD),
luabind::value("bike_path", extractor::guidance::RoadPriorityClass::BIKE_PATH),
luabind::value("foot_path", extractor::guidance::RoadPriorityClass::FOOT_PATH),
luabind::value("connectivity",
extractor::guidance::RoadPriorityClass::CONNECTIVITY)],
luabind::class_<SourceContainer>("sources") luabind::class_<SourceContainer>("sources")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
.def("load", &SourceContainer::LoadRasterSource) .def("load", &SourceContainer::LoadRasterSource)
@ -135,6 +153,21 @@ void LuaScriptingEnvironment::InitContext(LuaScriptingContext &context)
.def_readwrite("traffic_lights", &ExtractionNode::traffic_lights) .def_readwrite("traffic_lights", &ExtractionNode::traffic_lights)
.def_readwrite("barrier", &ExtractionNode::barrier), .def_readwrite("barrier", &ExtractionNode::barrier),
// road classification to be set in profile
luabind::class_<guidance::RoadClassification>("RoadClassification")
.property("motorway_class",
&guidance::RoadClassification::IsMotorwayClass,
&guidance::RoadClassification::SetMotorwayFlag)
.property("link_class",
&guidance::RoadClassification::IsLinkClass,
&guidance::RoadClassification::SetLinkClass)
.property("may_be_ignored",
&guidance::RoadClassification::IsLowPriorityRoadClass,
&guidance::RoadClassification::SetLowPriorityFlag)
.property("road_priority_class",
&guidance::RoadClassification::GetClass,
&guidance::RoadClassification::SetClass),
luabind::class_<ExtractionWay>("ResultWay") luabind::class_<ExtractionWay>("ResultWay")
// .def(luabind::constructor<>()) // .def(luabind::constructor<>())
.def_readwrite("forward_speed", &ExtractionWay::forward_speed) .def_readwrite("forward_speed", &ExtractionWay::forward_speed)
@ -148,6 +181,7 @@ void LuaScriptingEnvironment::InitContext(LuaScriptingContext &context)
.def_readwrite("duration", &ExtractionWay::duration) .def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("turn_lanes_forward", &ExtractionWay::turn_lanes_forward) .def_readwrite("turn_lanes_forward", &ExtractionWay::turn_lanes_forward)
.def_readwrite("turn_lanes_backward", &ExtractionWay::turn_lanes_backward) .def_readwrite("turn_lanes_backward", &ExtractionWay::turn_lanes_backward)
.def_readwrite("road_classification", &ExtractionWay::road_classification)
.property( .property(
"forward_mode", &ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode) "forward_mode", &ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode)
.property("backward_mode", .property("backward_mode",