move hardcoded road priorities into profiles, change road classification
This commit is contained in:
parent
fd6bb5ec1f
commit
1fc63e1e72
@ -1,3 +1,7 @@
|
||||
# 5.4.0
|
||||
- Profiles
|
||||
- includes library guidance.lua that offers preliminary configuration on guidance.
|
||||
|
||||
# 5.3.0
|
||||
Changes from 5.3.0-rc.3
|
||||
- Guidance
|
||||
|
@ -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)
|
||||
|
||||
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.
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define EXTRACTION_WAY_HPP
|
||||
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "util/guidance/turn_lanes.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
@ -38,6 +39,7 @@ struct ExtractionWay
|
||||
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
|
||||
turn_lanes_forward.clear();
|
||||
turn_lanes_backward.clear();
|
||||
road_classification = guidance::RoadClassification();
|
||||
}
|
||||
|
||||
// These accessors exists because it's not possible to take the address of a bitfield,
|
||||
@ -60,6 +62,7 @@ struct ExtractionWay
|
||||
bool is_startpoint;
|
||||
TravelMode forward_travel_mode : 4;
|
||||
TravelMode backward_travel_mode : 4;
|
||||
guidance::RoadClassification road_classification;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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_
|
130
include/extractor/guidance/road_classification.hpp
Normal file
130
include/extractor/guidance/road_classification.hpp
Normal 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_
|
@ -12,7 +12,6 @@
|
||||
#include "extractor/query_node.hpp"
|
||||
#include "extractor/suffix_table.hpp"
|
||||
|
||||
#include "extractor/guidance/classification_data.hpp"
|
||||
#include "extractor/guidance/discrete_angle.hpp"
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/turn_instruction.hpp"
|
||||
@ -46,12 +45,6 @@ using util::guidance::leavesRoundabout;
|
||||
namespace detail
|
||||
{
|
||||
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>
|
||||
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)
|
||||
{
|
||||
const auto suffix_pos = data.find_last_of(' ');
|
||||
@ -422,26 +258,6 @@ inline bool requiresNameAnnounced(const std::string &from,
|
||||
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
|
||||
// handler only for one side. The mirror function turns a left-hand turn in a equivalent right-hand
|
||||
// turn and vice versa.
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include "extractor/guidance/classification_data.hpp"
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "osrm/coordinate.hpp"
|
||||
#include <utility>
|
||||
|
||||
@ -51,7 +51,7 @@ struct InternalExtractorEdge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
guidance::TurnLaneType::empty,
|
||||
guidance::RoadClassificationData())
|
||||
guidance::RoadClassification())
|
||||
{
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ struct InternalExtractorEdge
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
LaneDescriptionID lane_description,
|
||||
guidance::RoadClassificationData road_classification)
|
||||
guidance::RoadClassification road_classification)
|
||||
: result(source,
|
||||
target,
|
||||
name_id,
|
||||
@ -107,7 +107,7 @@ struct InternalExtractorEdge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassificationData());
|
||||
guidance::RoadClassification());
|
||||
}
|
||||
static InternalExtractorEdge max_osm_value()
|
||||
{
|
||||
@ -123,7 +123,7 @@ struct InternalExtractorEdge
|
||||
TRAVEL_MODE_INACCESSIBLE,
|
||||
false,
|
||||
INVALID_LANE_DESCRIPTIONID,
|
||||
guidance::RoadClassificationData());
|
||||
guidance::RoadClassification());
|
||||
}
|
||||
|
||||
static InternalExtractorEdge min_internal_value()
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "extractor/travel_mode.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include "extractor/guidance/classification_data.hpp"
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@ -27,7 +27,7 @@ struct NodeBasedEdge
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassificationData road_classification);
|
||||
guidance::RoadClassification road_classification);
|
||||
|
||||
bool operator<(const NodeBasedEdge &other) const;
|
||||
|
||||
@ -43,7 +43,7 @@ struct NodeBasedEdge
|
||||
bool is_split : 1;
|
||||
TravelMode travel_mode : 4;
|
||||
LaneDescriptionID lane_description_id;
|
||||
guidance::RoadClassificationData road_classification;
|
||||
guidance::RoadClassification road_classification;
|
||||
};
|
||||
|
||||
struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
@ -60,7 +60,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassificationData road_classification);
|
||||
guidance::RoadClassification road_classification);
|
||||
|
||||
OSMNodeID osm_source_id;
|
||||
OSMNodeID osm_target_id;
|
||||
@ -87,7 +87,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
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),
|
||||
backward(backward), roundabout(roundabout), access_restricted(access_restricted),
|
||||
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
|
||||
@ -125,7 +125,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(
|
||||
TravelMode travel_mode,
|
||||
bool is_split,
|
||||
const LaneDescriptionID lane_description_id,
|
||||
guidance::RoadClassificationData road_classification)
|
||||
guidance::RoadClassification road_classification)
|
||||
: NodeBasedEdge(SPECIAL_NODEID,
|
||||
SPECIAL_NODEID,
|
||||
name_id,
|
||||
|
@ -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)
|
||||
{
|
||||
std::cout << " Tags:\n";
|
||||
@ -76,10 +85,7 @@ printTurnAssignmentData(const NodeID at,
|
||||
std::cout << std::setprecision(12) << toFloating(coordinate.lat) << " "
|
||||
<< toFloating(coordinate.lon) << "\n";
|
||||
|
||||
std::cout << " Intersection:\n";
|
||||
for (const auto &road : intersection)
|
||||
std::cout << "\t" << toString(road) << "\n";
|
||||
|
||||
print(intersection);
|
||||
// flushes as well
|
||||
print(turn_lane_data);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef 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 "util/dynamic_graph.hpp"
|
||||
#include "util/graph_utils.hpp"
|
||||
@ -49,7 +49,7 @@ struct NodeBasedEdgeData
|
||||
bool startpoint : 1;
|
||||
extractor::TravelMode travel_mode : 4;
|
||||
LaneDescriptionID lane_description_id;
|
||||
extractor::guidance::RoadClassificationData road_classification;
|
||||
extractor::guidance::RoadClassification road_classification;
|
||||
|
||||
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
local find_access_tag = require("lib/access").find_access_tag
|
||||
local limit = require("lib/maxspeed").limit
|
||||
local set_classification = require("lib/guidance").set_classification
|
||||
|
||||
-- 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 }
|
||||
@ -392,6 +393,9 @@ function way_function (way, result)
|
||||
result.backward_speed = math.min(surface_speeds[surface], result.backward_speed)
|
||||
end
|
||||
|
||||
-- set the road classification based on guidance globals configuration
|
||||
set_classification(highway,result)
|
||||
|
||||
-- maxspeed
|
||||
limit( result, maxspeed, maxspeed_forward, maxspeed_backward )
|
||||
end
|
||||
|
@ -1,7 +1,8 @@
|
||||
-- Car profile
|
||||
|
||||
local find_access_tag = require("lib/access").find_access_tag
|
||||
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
|
||||
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
|
||||
|
||||
-- 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)
|
||||
if not source then
|
||||
return 0
|
||||
@ -340,7 +285,7 @@ function way_function (way, result)
|
||||
result.backward_speed = bridge_speed
|
||||
end
|
||||
|
||||
-- leave early of this way is not accessible
|
||||
-- leave early if this way is not accessible
|
||||
if "" == highway then
|
||||
return
|
||||
end
|
||||
@ -402,6 +347,9 @@ function way_function (way, result)
|
||||
result.backward_speed = math.min(smoothness_speeds[smoothness], result.backward_speed)
|
||||
end
|
||||
|
||||
-- set the road classification based on guidance globals configuration
|
||||
set_classification(highway,result)
|
||||
|
||||
-- parse the remaining tags
|
||||
local name = way:get_value_by_key("name")
|
||||
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_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
|
||||
result.turn_lanes_forward = turn_lanes;
|
||||
result.turn_lanes_backward = turn_lanes;
|
||||
|
113
profiles/lib/guidance.lua
Normal file
113
profiles/lib/guidance.lua
Normal 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
|
@ -425,7 +425,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const int32_t turn_penalty = scripting_environment.GetTurnPenalty(180. - turn.angle);
|
||||
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;
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include "extractor/extractor_callbacks.hpp"
|
||||
#include "extractor/external_memory_node.hpp"
|
||||
#include "extractor/extraction_containers.hpp"
|
||||
#include "extractor/extraction_node.hpp"
|
||||
#include "extractor/extraction_way.hpp"
|
||||
#include "extractor/extractor_callbacks.hpp"
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/restriction.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
|
||||
const char *data = input_way.get_value_by_key("highway");
|
||||
guidance::RoadClassificationData road_classification;
|
||||
if (data)
|
||||
{
|
||||
road_classification.road_class = guidance::functionalRoadClassFromTag(data);
|
||||
}
|
||||
|
||||
const guidance::RoadClassification road_classification = parsed_way.road_classification;
|
||||
const auto laneStringToDescription = [](std::string lane_string) -> TurnLaneDescription {
|
||||
if (lane_string.empty())
|
||||
return {};
|
||||
|
@ -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
|
@ -48,9 +48,9 @@ TurnType::Enum IntersectionHandler::findBasicTurnType(const EdgeID via_edge,
|
||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||
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)
|
||||
return TurnType::OnRamp;
|
||||
@ -130,10 +130,10 @@ void IntersectionHandler::assignFork(const EdgeID via_edge,
|
||||
ConnectedRoad &right) const
|
||||
{
|
||||
const auto &in_data = node_based_graph.GetEdgeData(via_edge);
|
||||
const bool low_priority_left = isLowPriorityRoadClass(
|
||||
node_based_graph.GetEdgeData(left.turn.eid).road_classification.road_class);
|
||||
const bool low_priority_right = isLowPriorityRoadClass(
|
||||
node_based_graph.GetEdgeData(right.turn.eid).road_classification.road_class);
|
||||
const bool low_priority_left =
|
||||
node_based_graph.GetEdgeData(left.turn.eid).road_classification.IsLowPriorityRoadClass();
|
||||
const bool low_priority_right =
|
||||
node_based_graph.GetEdgeData(right.turn.eid).road_classification.IsLowPriorityRoadClass();
|
||||
if ((angularDeviation(left.turn.angle, STRAIGHT_ANGLE) < MAXIMAL_ALLOWED_NO_TURN_DEVIATION &&
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
auto continue_class = node_based_graph.GetEdgeData(intersection[best_continue].turn.eid)
|
||||
.road_classification.road_class;
|
||||
auto continue_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 &&
|
||||
(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 &&
|
||||
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 = i;
|
||||
@ -368,10 +373,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
||||
return 0;
|
||||
// has no obvious continued road
|
||||
if (best_continue == 0 || best_continue_deviation >= 2 * NARROW_TURN_ANGLE ||
|
||||
(node_based_graph.GetEdgeData(intersection[best_continue].turn.eid)
|
||||
.road_classification.road_class ==
|
||||
node_based_graph.GetEdgeData(intersection[best].turn.eid)
|
||||
.road_classification.road_class &&
|
||||
(node_based_graph.GetEdgeData(intersection[best_continue].turn.eid).road_classification ==
|
||||
node_based_graph.GetEdgeData(intersection[best].turn.eid).road_classification &&
|
||||
std::abs(best_continue_deviation) > 1 && best_deviation / best_continue_deviation < 0.75))
|
||||
{
|
||||
// Find left/right deviation
|
||||
@ -418,9 +421,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
||||
continue;
|
||||
|
||||
if (angularDeviation(intersection[i].turn.angle, STRAIGHT_ANGLE) / deviation < 1.1 &&
|
||||
continue_data.road_classification.road_class ==
|
||||
node_based_graph.GetEdgeData(intersection[i].turn.eid)
|
||||
.road_classification.road_class)
|
||||
continue_data.road_classification ==
|
||||
node_based_graph.GetEdgeData(intersection[i].turn.eid).road_classification)
|
||||
return 0;
|
||||
}
|
||||
return best_continue; // no obvious turn
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "extractor/guidance/motorway_handler.hpp"
|
||||
#include "extractor/guidance/classification_data.hpp"
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/motorway_handler.hpp"
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
@ -20,25 +20,26 @@ namespace extractor
|
||||
{
|
||||
namespace guidance
|
||||
{
|
||||
namespace detail
|
||||
namespace
|
||||
{
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const util::NameTable &name_table,
|
||||
@ -56,36 +57,29 @@ bool MotorwayHandler::canProcess(const NodeID,
|
||||
|
||||
for (const auto &road : intersection)
|
||||
{
|
||||
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
// not merging or forking?
|
||||
if (road.entry_allowed && angularDeviation(road.turn.angle, STRAIGHT_ANGLE) > 60)
|
||||
return false;
|
||||
else if (out_data.road_classification.road_class == FunctionalRoadClass::MOTORWAY ||
|
||||
out_data.road_classification.road_class == FunctionalRoadClass::TRUNK)
|
||||
else if (isMotorwayClass(road.turn.eid, node_based_graph))
|
||||
{
|
||||
if (road.entry_allowed)
|
||||
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;
|
||||
}
|
||||
|
||||
if (has_normal_roads)
|
||||
return false;
|
||||
|
||||
const auto &in_data = node_based_graph.GetEdgeData(via_eid);
|
||||
return has_motorway ||
|
||||
in_data.road_classification.road_class == FunctionalRoadClass::MOTORWAY ||
|
||||
in_data.road_classification.road_class == FunctionalRoadClass::TRUNK;
|
||||
return has_motorway || isMotorwayClass(via_eid, node_based_graph);
|
||||
}
|
||||
|
||||
Intersection MotorwayHandler::
|
||||
operator()(const NodeID, const EdgeID via_eid, Intersection intersection) const
|
||||
{
|
||||
const auto &in_data = node_based_graph.GetEdgeData(via_eid);
|
||||
|
||||
// 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));
|
||||
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
|
||||
{
|
||||
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) {
|
||||
unsigned count = 0;
|
||||
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;
|
||||
}
|
||||
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);
|
||||
if (road.turn.angle != 0 && in_data.name_id == out_data.name_id &&
|
||||
in_data.name_id != EMPTY_NAMEID &&
|
||||
isMotorwayClass(out_data.road_classification.road_class))
|
||||
in_data.name_id != EMPTY_NAMEID && isMotorwayClass(road.turn.eid, node_based_graph))
|
||||
return road.turn.angle;
|
||||
}
|
||||
return intersection[0].turn.angle;
|
||||
@ -134,8 +127,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
||||
double best = 180;
|
||||
for (const auto &road : intersection)
|
||||
{
|
||||
const auto &out_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
if (isMotorwayClass(out_data.road_classification.road_class) &&
|
||||
if (isMotorwayClass(road.turn.eid, node_based_graph) &&
|
||||
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) < best)
|
||||
{
|
||||
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 &&
|
||||
detail::roadClass(intersection[1], node_based_graph) ==
|
||||
detail::roadClass(intersection[2], node_based_graph) &&
|
||||
detail::roadClass(intersection[2], node_based_graph) ==
|
||||
detail::roadClass(intersection[3], node_based_graph))
|
||||
roadClass(intersection[1], node_based_graph) ==
|
||||
roadClass(intersection[2], node_based_graph) &&
|
||||
roadClass(intersection[2], node_based_graph) ==
|
||||
roadClass(intersection[3], node_based_graph))
|
||||
{
|
||||
// tripple fork at the end
|
||||
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)
|
||||
{
|
||||
BOOST_ASSERT(detail::isRampClass(road.turn.eid, node_based_graph));
|
||||
BOOST_ASSERT(isRampClass(road.turn.eid, node_based_graph));
|
||||
road.turn.instruction =
|
||||
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
|
||||
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 =
|
||||
getInstructionForObvious(intersection.size(),
|
||||
@ -248,7 +240,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
||||
else if (road.turn.angle < continue_angle)
|
||||
{
|
||||
road.turn.instruction = {
|
||||
detail::isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp
|
||||
isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp
|
||||
: TurnType::Turn,
|
||||
(road.turn.angle < 145) ? DirectionModifier::Right
|
||||
: DirectionModifier::SlightRight};
|
||||
@ -256,7 +248,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
||||
else if (road.turn.angle > continue_angle)
|
||||
{
|
||||
road.turn.instruction = {
|
||||
detail::isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp
|
||||
isRampClass(road.turn.eid, node_based_graph) ? TurnType::OffRamp
|
||||
: TurnType::Turn,
|
||||
(road.turn.angle > 215) ? DirectionModifier::Left
|
||||
: 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)
|
||||
{
|
||||
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())
|
||||
{
|
||||
@ -309,7 +301,7 @@ Intersection MotorwayHandler::fromMotorway(const EdgeID via_eid, Intersection in
|
||||
for (std::size_t i = 0; i < intersection.size(); ++i)
|
||||
{
|
||||
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())
|
||||
{
|
||||
@ -349,7 +341,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
if (intersection.size() == 2 && num_valid_turns == 1)
|
||||
{
|
||||
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.size(), via_eid, isThroughStreet(1, intersection), intersection[1]);
|
||||
@ -370,7 +362,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
// 0
|
||||
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 !=
|
||||
EMPTY_NAMEID &&
|
||||
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id ==
|
||||
@ -397,7 +389,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
else
|
||||
{
|
||||
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 !=
|
||||
EMPTY_NAMEID &&
|
||||
node_based_graph.GetEdgeData(intersection[2].turn.eid).name_id ==
|
||||
@ -434,8 +426,8 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
// \ /
|
||||
// |
|
||||
// R
|
||||
if (detail::isMotorwayClass(intersection[1].turn.eid, node_based_graph) &&
|
||||
detail::isMotorwayClass(intersection[2].turn.eid, node_based_graph))
|
||||
if (isMotorwayClass(intersection[1].turn.eid, node_based_graph) &&
|
||||
isMotorwayClass(intersection[2].turn.eid, node_based_graph))
|
||||
{
|
||||
assignFork(via_eid, intersection[2], intersection[1]);
|
||||
}
|
||||
@ -446,8 +438,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
// M R
|
||||
// | /
|
||||
// R
|
||||
if (isMotorwayClass(node_based_graph.GetEdgeData(intersection[1].turn.eid)
|
||||
.road_classification.road_class))
|
||||
if (isMotorwayClass(intersection[1].turn.eid, node_based_graph))
|
||||
{
|
||||
intersection[1].turn.instruction = {TurnType::Turn,
|
||||
DirectionModifier::SlightRight};
|
||||
@ -467,12 +458,11 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
bool passed_highway_entry = false;
|
||||
for (auto &road : intersection)
|
||||
{
|
||||
const auto &edge_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
if (!road.entry_allowed && isMotorwayClass(edge_data.road_classification.road_class))
|
||||
if (!road.entry_allowed && isMotorwayClass(road.turn.eid, node_based_graph))
|
||||
{
|
||||
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,
|
||||
passed_highway_entry ? DirectionModifier::SlightRight
|
||||
@ -480,7 +470,7 @@ Intersection MotorwayHandler::fromRamp(const EdgeID via_eid, Intersection inters
|
||||
}
|
||||
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)};
|
||||
}
|
||||
}
|
||||
@ -503,13 +493,13 @@ Intersection MotorwayHandler::fallback(Intersection intersection) const
|
||||
|
||||
util::SimpleLogger().Write(logDEBUG)
|
||||
<< "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)
|
||||
continue;
|
||||
|
||||
const auto type = isMotorwayClass(out_data.road_classification.road_class) ? TurnType::Merge
|
||||
: TurnType::Turn;
|
||||
const auto type =
|
||||
isMotorwayClass(road.turn.eid, node_based_graph) ? TurnType::Merge : TurnType::Turn;
|
||||
|
||||
if (type == TurnType::Turn)
|
||||
{
|
||||
|
@ -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 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
|
||||
return road_edge_data.road_classification.road_class ==
|
||||
source_edge_data.road_classification.road_class &&
|
||||
return road_edge_data.road_classification ==
|
||||
source_edge_data.road_classification &&
|
||||
road_edge_data.name_id != EMPTY_NAMEID &&
|
||||
road_edge_data.name_id == source_edge_data.name_id && road.entry_allowed;
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "extractor/guidance/classification_data.hpp"
|
||||
#include "extractor/guidance/road_classification.hpp"
|
||||
#include "extractor/guidance/constants.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));
|
||||
|
||||
// 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) {
|
||||
if (road.turn.instruction.type == TurnType::OnRamp)
|
||||
|
@ -75,25 +75,28 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
|
||||
const ConnectedRoad &other) const
|
||||
{
|
||||
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 =
|
||||
node_based_graph.GetEdgeData(other.turn.eid).road_classification.road_class;
|
||||
|
||||
const bool is_ramp = isRampClass(first_class);
|
||||
const auto &first_data = node_based_graph.GetEdgeData(road.turn.eid);
|
||||
const auto &second_data = node_based_graph.GetEdgeData(other.turn.eid);
|
||||
const auto &first_classification = first_data.road_classification;
|
||||
const auto &second_classification = second_data.road_classification;
|
||||
const bool is_ramp = first_classification.IsRampClass();
|
||||
const bool is_obvious_by_road_class =
|
||||
(!is_ramp && (2 * getPriority(first_class) < getPriority(second_class)) &&
|
||||
in_data.road_classification.road_class == first_class) ||
|
||||
(!isLowPriorityRoadClass(first_class) && isLowPriorityRoadClass(second_class));
|
||||
(!is_ramp &&
|
||||
(2 * first_classification.GetPriority() < second_classification.GetPriority()) &&
|
||||
in_data.road_classification == first_classification) ||
|
||||
(!first_classification.IsLowPriorityRoadClass() &&
|
||||
second_classification.IsLowPriorityRoadClass());
|
||||
|
||||
if (is_obvious_by_road_class)
|
||||
return true;
|
||||
|
||||
const bool other_is_obvious_by_road_class =
|
||||
(!isRampClass(second_class) && (2 * getPriority(second_class) < getPriority(first_class)) &&
|
||||
in_data.road_classification.road_class == second_class) ||
|
||||
(!isLowPriorityRoadClass(second_class) && isLowPriorityRoadClass(first_class));
|
||||
(!second_classification.IsRampClass() &&
|
||||
(2 * second_classification.GetPriority() < first_classification.GetPriority()) &&
|
||||
in_data.road_classification == second_classification) ||
|
||||
(!second_classification.IsLowPriorityRoadClass() &&
|
||||
first_classification.IsLowPriorityRoadClass());
|
||||
|
||||
if (other_is_obvious_by_road_class)
|
||||
return false;
|
||||
@ -114,7 +117,7 @@ bool TurnHandler::isObviousOfTwo(const EdgeID via_edge,
|
||||
FUZZY_ANGLE_DIFFERENCE;
|
||||
|
||||
return is_much_narrower_than_other;
|
||||
};
|
||||
}
|
||||
|
||||
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 &right = intersection[fork_range.first];
|
||||
const auto left_class =
|
||||
node_based_graph.GetEdgeData(left.turn.eid).road_classification.road_class;
|
||||
const auto right_class =
|
||||
node_based_graph.GetEdgeData(right.turn.eid).road_classification.road_class;
|
||||
if (canBeSeenAsFork(left_class, right_class))
|
||||
const auto left_classification =
|
||||
node_based_graph.GetEdgeData(left.turn.eid).road_classification;
|
||||
const auto right_classification =
|
||||
node_based_graph.GetEdgeData(right.turn.eid).road_classification;
|
||||
if (canBeSeenAsFork(left_classification, right_classification))
|
||||
assignFork(via_edge, left, right);
|
||||
else if (getPriority(left_class) > getPriority(right_class))
|
||||
else if (left_classification.GetPriority() > right_classification.GetPriority())
|
||||
{
|
||||
right.turn.instruction =
|
||||
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 ramp_class =
|
||||
isLinkClass(node_based_graph.GetEdgeData(intersection[right].turn.eid)
|
||||
.road_classification.road_class);
|
||||
const bool ramp_class = node_based_graph.GetEdgeData(intersection[right].turn.eid)
|
||||
.road_classification.IsLinkClass();
|
||||
for (std::size_t index = right + 1; index <= left; ++index)
|
||||
if (ramp_class !=
|
||||
isLinkClass(node_based_graph.GetEdgeData(intersection[index].turn.eid)
|
||||
.road_classification.road_class))
|
||||
node_based_graph.GetEdgeData(intersection[index].turn.eid)
|
||||
.road_classification.IsLinkClass())
|
||||
return false;
|
||||
return true;
|
||||
}();
|
||||
@ -581,13 +583,13 @@ void TurnHandler::handleDistinctConflict(const EdgeID via_edge,
|
||||
getTurnDirection(left.turn.angle) == DirectionModifier::SlightLeft ||
|
||||
getTurnDirection(right.turn.angle) == DirectionModifier::SlightRight)
|
||||
{
|
||||
const auto left_class =
|
||||
node_based_graph.GetEdgeData(left.turn.eid).road_classification.road_class;
|
||||
const auto right_class =
|
||||
node_based_graph.GetEdgeData(right.turn.eid).road_classification.road_class;
|
||||
if (canBeSeenAsFork(left_class, right_class))
|
||||
const auto left_classification =
|
||||
node_based_graph.GetEdgeData(left.turn.eid).road_classification;
|
||||
const auto right_classification =
|
||||
node_based_graph.GetEdgeData(right.turn.eid).road_classification;
|
||||
if (canBeSeenAsFork(left_classification, right_classification))
|
||||
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?
|
||||
// here we don't know about the intersection size. To be on the save side,
|
||||
|
@ -95,6 +95,24 @@ void LuaScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
luabind::value("river_up", TRAVEL_MODE_RIVER_UP),
|
||||
luabind::value("river_down", TRAVEL_MODE_RIVER_DOWN),
|
||||
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")
|
||||
.def(luabind::constructor<>())
|
||||
.def("load", &SourceContainer::LoadRasterSource)
|
||||
@ -135,6 +153,21 @@ void LuaScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
.def_readwrite("traffic_lights", &ExtractionNode::traffic_lights)
|
||||
.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")
|
||||
// .def(luabind::constructor<>())
|
||||
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
|
||||
@ -148,6 +181,7 @@ void LuaScriptingEnvironment::InitContext(LuaScriptingContext &context)
|
||||
.def_readwrite("duration", &ExtractionWay::duration)
|
||||
.def_readwrite("turn_lanes_forward", &ExtractionWay::turn_lanes_forward)
|
||||
.def_readwrite("turn_lanes_backward", &ExtractionWay::turn_lanes_backward)
|
||||
.def_readwrite("road_classification", &ExtractionWay::road_classification)
|
||||
.property(
|
||||
"forward_mode", &ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode)
|
||||
.property("backward_mode",
|
||||
|
Loading…
Reference in New Issue
Block a user