Distinguish between offramps and sliproads.
This commit is contained in:
committed by
Patrick Niklaus
parent
089e60fa1e
commit
3d03797e53
@@ -12,8 +12,8 @@
|
||||
#include "util/bearing.hpp"
|
||||
#include "util/coordinate.hpp"
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
#include "util/guidance/entry_class.hpp"
|
||||
#include "util/guidance/toolkit.hpp"
|
||||
#include "util/typedefs.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
@@ -68,10 +68,8 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
StepManeuver maneuver{source_node.location, bearings.first,
|
||||
bearings.second, extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Depart, 0};
|
||||
Intersection intersection{
|
||||
source_node.location,
|
||||
std::vector<short>({bearings.second}),
|
||||
std::vector<bool>({true}), Intersection::NO_INDEX, 0};
|
||||
Intersection intersection{source_node.location, std::vector<short>({bearings.second}),
|
||||
std::vector<bool>({true}), Intersection::NO_INDEX, 0};
|
||||
|
||||
if (leg_data.size() > 0)
|
||||
{
|
||||
@@ -96,6 +94,17 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
const auto name = facade.GetNameForID(step_name_id);
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
name,
|
||||
NO_ROTARY_NAME,
|
||||
segment_duration / 10.0,
|
||||
distance,
|
||||
path_point.travel_mode,
|
||||
maneuver,
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
|
||||
if (leg_data_index + 1 < leg_data.size())
|
||||
{
|
||||
step_name_id = leg_data[leg_data_index + 1].name_id;
|
||||
@@ -104,26 +113,26 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
{
|
||||
step_name_id = target_node.name_id;
|
||||
}
|
||||
steps.push_back(RouteStep{
|
||||
step_name_id, name, NO_ROTARY_NAME, segment_duration / 10.0, distance,
|
||||
path_point.travel_mode, maneuver, leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
|
||||
|
||||
bearings = detail::getIntermediateBearings(leg_geometry, segment_index);
|
||||
const auto entry_class = facade.GetEntryClass(path_point.entry_classid);
|
||||
const auto bearing_class = facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
|
||||
intersection.in = bearing_class.findMatchingBearing(util::bearing::reverseBearing(bearings.first));
|
||||
const auto bearing_class =
|
||||
facade.GetBearingClass(facade.GetBearingClassID(path_point.turn_via_node));
|
||||
intersection.in = bearing_class.findMatchingBearing(
|
||||
util::bearing::reverseBearing(bearings.first));
|
||||
intersection.out = bearing_class.findMatchingBearing(bearings.second);
|
||||
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
|
||||
intersection.bearings.clear();
|
||||
std::copy(bearing_class.getAvailableBearings().begin(), bearing_class.getAvailableBearings().end(),
|
||||
std::copy(bearing_class.getAvailableBearings().begin(),
|
||||
bearing_class.getAvailableBearings().end(),
|
||||
std::back_inserter(intersection.bearings));
|
||||
intersection.entry.clear();
|
||||
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
|
||||
{
|
||||
intersection.entry.push_back(entry_class.allowsEntry(idx));
|
||||
}
|
||||
maneuver = {intersection.location, bearings.first, bearings.second, path_point.turn_instruction, WaypointType::None, 0};
|
||||
maneuver = {intersection.location, bearings.first, bearings.second,
|
||||
path_point.turn_instruction, WaypointType::None, 0};
|
||||
segment_index++;
|
||||
segment_duration = 0;
|
||||
}
|
||||
@@ -131,10 +140,16 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
const auto distance = leg_geometry.segment_distances[segment_index];
|
||||
const int duration = segment_duration + target_duration;
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
steps.push_back(RouteStep{
|
||||
step_name_id, facade.GetNameForID(step_name_id), NO_ROTARY_NAME, duration / 10.,
|
||||
distance, target_mode, maneuver, leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
|
||||
steps.push_back(RouteStep{step_name_id,
|
||||
facade.GetNameForID(step_name_id),
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
distance,
|
||||
target_mode,
|
||||
maneuver,
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
}
|
||||
// In this case the source + target are on the same edge segment
|
||||
else
|
||||
@@ -148,30 +163,41 @@ std::vector<RouteStep> assembleSteps(const DataFacadeT &facade,
|
||||
int duration = target_duration - source_duration;
|
||||
BOOST_ASSERT(duration >= 0);
|
||||
|
||||
steps.push_back(RouteStep{
|
||||
source_node.name_id, facade.GetNameForID(source_node.name_id), NO_ROTARY_NAME,
|
||||
duration / 10., leg_geometry.segment_distances[segment_index], source_mode,
|
||||
std::move(maneuver), leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1, {intersection}});
|
||||
steps.push_back(RouteStep{source_node.name_id,
|
||||
facade.GetNameForID(source_node.name_id),
|
||||
NO_ROTARY_NAME,
|
||||
duration / 10.,
|
||||
leg_geometry.segment_distances[segment_index],
|
||||
source_mode,
|
||||
std::move(maneuver),
|
||||
leg_geometry.FrontIndex(segment_index),
|
||||
leg_geometry.BackIndex(segment_index) + 1,
|
||||
{intersection}});
|
||||
}
|
||||
|
||||
BOOST_ASSERT(segment_index == number_of_segments - 1);
|
||||
bearings = detail::getArriveBearings(leg_geometry);
|
||||
// This step has length zero, the only reason we need it is the target location
|
||||
maneuver = {intersection.location, bearings.first, bearings.second, extractor::guidance::TurnInstruction::NO_TURN(), WaypointType::Arrive, 0};
|
||||
maneuver = {intersection.location, bearings.first,
|
||||
bearings.second, extractor::guidance::TurnInstruction::NO_TURN(),
|
||||
WaypointType::Arrive, 0};
|
||||
intersection = {
|
||||
target_node.location,
|
||||
std::vector<short>({static_cast<short>(util::bearing::reverseBearing(bearings.first))}),
|
||||
std::vector<bool>({true}), 0, Intersection::NO_INDEX};
|
||||
|
||||
BOOST_ASSERT(!leg_geometry.locations.empty());
|
||||
steps.push_back(RouteStep{target_node.name_id, facade.GetNameForID(target_node.name_id),
|
||||
NO_ROTARY_NAME, ZERO_DURATION, ZERO_DISTANCE, target_mode,
|
||||
std::move(maneuver), leg_geometry.locations.size() - 1,
|
||||
steps.push_back(RouteStep{target_node.name_id,
|
||||
facade.GetNameForID(target_node.name_id),
|
||||
NO_ROTARY_NAME,
|
||||
ZERO_DURATION,
|
||||
ZERO_DISTANCE,
|
||||
target_mode,
|
||||
std::move(maneuver),
|
||||
leg_geometry.locations.size() - 1,
|
||||
leg_geometry.locations.size(),
|
||||
{intersection}});
|
||||
|
||||
|
||||
BOOST_ASSERT(steps.front().intersections.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1);
|
||||
BOOST_ASSERT(steps.front().intersections.front().entry.size() == 1);
|
||||
|
||||
@@ -47,6 +47,17 @@ inline bool isRampClass(const FunctionalRoadClass road_class)
|
||||
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;
|
||||
}
|
||||
|
||||
// TODO augment this with all data required for guidance generation
|
||||
struct RoadClassificationData
|
||||
{
|
||||
|
||||
@@ -22,10 +22,12 @@ const double constexpr FUZZY_ANGLE_DIFFERENCE = 20.;
|
||||
const double constexpr DISTINCTION_RATIO = 2;
|
||||
const unsigned constexpr INVALID_NAME_ID = 0;
|
||||
|
||||
const double constexpr MAX_ROUNDABOUT_INTERSECTION_RADIUS = 5;
|
||||
const double constexpr MAX_ROUNDABOUT_INTERSECTION_RADIUS = 5;
|
||||
const double constexpr MAX_ROUNDABOUT_RADIUS = 15; // 30 m diameter as final distinction
|
||||
const double constexpr INCREASES_BY_FOURTY_PERCENT = 1.4;
|
||||
|
||||
const unsigned constexpr MAX_SLIPROAD_THRESHOLD = 250;
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define OSRM_EXTRACTOR_GUIDANCE_MOTORWAY_HANDLER_HPP_
|
||||
|
||||
#include "extractor/guidance/intersection.hpp"
|
||||
#include "extractor/guidance/intersection_generator.hpp"
|
||||
#include "extractor/guidance/intersection_handler.hpp"
|
||||
#include "extractor/query_node.hpp"
|
||||
|
||||
@@ -25,7 +26,8 @@ class MotorwayHandler : public IntersectionHandler
|
||||
MotorwayHandler(const util::NodeBasedDynamicGraph &node_based_graph,
|
||||
const std::vector<QueryNode> &node_info_list,
|
||||
const util::NameTable &name_table,
|
||||
const SuffixTable &street_name_suffix_table);
|
||||
const SuffixTable &street_name_suffix_table,
|
||||
const IntersectionGenerator &intersection_generator);
|
||||
~MotorwayHandler() override final;
|
||||
|
||||
// check whether the handler can actually handle the intersection
|
||||
@@ -39,10 +41,14 @@ class MotorwayHandler : public IntersectionHandler
|
||||
Intersection intersection) const override final;
|
||||
|
||||
private:
|
||||
Intersection handleSliproads(const NodeID intersection_node_id,
|
||||
Intersection intersection) const;
|
||||
Intersection fromMotorway(const EdgeID via_edge, Intersection intersection) const;
|
||||
Intersection fromRamp(const EdgeID via_edge, Intersection intersection) const;
|
||||
|
||||
Intersection fallback(Intersection intersection) const;
|
||||
|
||||
const IntersectionGenerator &intersection_generator;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -59,6 +59,9 @@ class TurnAnalysis
|
||||
// Utility function, setting basic turn types. Prepares for normal turn handling.
|
||||
Intersection
|
||||
setTurnTypes(const NodeID from, const EdgeID via_edge, Intersection intersection) const;
|
||||
|
||||
Intersection handleSliproads(const NodeID intersection_node_id,
|
||||
Intersection intersection) const;
|
||||
}; // class TurnAnalysis
|
||||
|
||||
} // namespace guidance
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace detail
|
||||
const constexpr uint8_t num_direction_modifiers = 8;
|
||||
} // detail
|
||||
|
||||
|
||||
// direction modifiers based on angle
|
||||
namespace DirectionModifier
|
||||
{
|
||||
@@ -38,31 +37,36 @@ const constexpr Enum SharpLeft = 7;
|
||||
namespace TurnType
|
||||
{
|
||||
typedef std::uint8_t Enum;
|
||||
const constexpr Enum Invalid = 0; // no valid turn instruction
|
||||
const constexpr Enum NewName = 1; // no turn, but name changes
|
||||
const constexpr Enum Continue = 2; // remain on a street
|
||||
const constexpr Enum Turn = 3; // basic turn
|
||||
const constexpr Enum Merge = 4; // merge onto a street
|
||||
const constexpr Enum OnRamp = 5; // special turn (highway ramp on-ramps)
|
||||
const constexpr Enum OffRamp = 6; // special turn, highway exit
|
||||
const constexpr Enum Fork = 7; // fork road splitting up
|
||||
const constexpr Enum EndOfRoad = 8; // T intersection
|
||||
const constexpr Enum Notification = 9; // Travel Mode Changes, Restrictions apply...
|
||||
const constexpr Enum EnterRoundabout = 10; // Entering a small Roundabout
|
||||
const constexpr Enum EnterAndExitRoundabout = 11; // Touching a roundabout
|
||||
const constexpr Enum EnterRotary = 12; // Enter a rotary
|
||||
const constexpr Enum EnterAndExitRotary = 13; // Touching a rotary
|
||||
const constexpr Enum EnterRoundaboutIntersection = 14; // Entering a small Roundabout
|
||||
const constexpr Enum Invalid = 0; // no valid turn instruction
|
||||
const constexpr Enum NewName = 1; // no turn, but name changes
|
||||
const constexpr Enum Continue = 2; // remain on a street
|
||||
const constexpr Enum Turn = 3; // basic turn
|
||||
const constexpr Enum Merge = 4; // merge onto a street
|
||||
const constexpr Enum OnRamp = 5; // special turn (highway ramp on-ramps)
|
||||
const constexpr Enum OffRamp = 6; // special turn, highway exit
|
||||
const constexpr Enum Fork = 7; // fork road splitting up
|
||||
const constexpr Enum EndOfRoad = 8; // T intersection
|
||||
const constexpr Enum Notification = 9; // Travel Mode Changes, Restrictions apply...
|
||||
const constexpr Enum EnterRoundabout = 10; // Entering a small Roundabout
|
||||
const constexpr Enum EnterAndExitRoundabout = 11; // Touching a roundabout
|
||||
const constexpr Enum EnterRotary = 12; // Enter a rotary
|
||||
const constexpr Enum EnterAndExitRotary = 13; // Touching a rotary
|
||||
const constexpr Enum EnterRoundaboutIntersection = 14; // Entering a small Roundabout
|
||||
const constexpr Enum EnterAndExitRoundaboutIntersection = 15; // Touching a roundabout
|
||||
const constexpr Enum NoTurn = 16; // end of segment without turn/middle of a segment
|
||||
const constexpr Enum Suppressed = 17; // location that suppresses a turn
|
||||
const constexpr Enum EnterRoundaboutAtExit = 18; // Entering a small Roundabout at a countable exit
|
||||
const constexpr Enum ExitRoundabout = 19; // Exiting a small Roundabout
|
||||
const constexpr Enum EnterRotaryAtExit = 20; // Enter A Rotary at a countable exit
|
||||
const constexpr Enum ExitRotary = 21; // Exit a rotary
|
||||
const constexpr Enum EnterRoundaboutIntersectionAtExit = 22; // Entering a small Roundabout at a countable exit
|
||||
const constexpr Enum ExitRoundaboutIntersection = 23; // Exiting a small Roundabout
|
||||
const constexpr Enum StayOnRoundabout = 24; // Continue on Either a small or a large Roundabout
|
||||
|
||||
// Values below here are silent instructions
|
||||
const constexpr Enum NoTurn = 16; // end of segment without turn/middle of a segment
|
||||
const constexpr Enum Suppressed = 17; // location that suppresses a turn
|
||||
const constexpr Enum EnterRoundaboutAtExit = 18; // Entering a small Roundabout at a countable exit
|
||||
const constexpr Enum ExitRoundabout = 19; // Exiting a small Roundabout
|
||||
const constexpr Enum EnterRotaryAtExit = 20; // Enter A Rotary at a countable exit
|
||||
const constexpr Enum ExitRotary = 21; // Exit a rotary
|
||||
const constexpr Enum EnterRoundaboutIntersectionAtExit =
|
||||
22; // Entering a small Roundabout at a countable exit
|
||||
const constexpr Enum ExitRoundaboutIntersection = 23; // Exiting a small Roundabout
|
||||
const constexpr Enum StayOnRoundabout = 24; // Continue on Either a small or a large Roundabout
|
||||
const constexpr Enum Sliproad =
|
||||
25; // Something that looks like a ramp, but is actually just a small sliproad
|
||||
}
|
||||
|
||||
// turn angle in 1.40625 degree -> 128 == 180 degree
|
||||
@@ -87,7 +91,8 @@ struct TurnInstruction
|
||||
return TurnInstruction(TurnType::NoTurn, DirectionModifier::UTurn);
|
||||
}
|
||||
|
||||
static TurnInstruction REMAIN_ROUNDABOUT(const RoundaboutType, const DirectionModifier::Enum modifier)
|
||||
static TurnInstruction REMAIN_ROUNDABOUT(const RoundaboutType,
|
||||
const DirectionModifier::Enum modifier)
|
||||
{
|
||||
return TurnInstruction(TurnType::StayOnRoundabout, modifier);
|
||||
}
|
||||
@@ -104,9 +109,9 @@ struct TurnInstruction
|
||||
static TurnInstruction EXIT_ROUNDABOUT(const RoundaboutType roundabout_type,
|
||||
const DirectionModifier::Enum modifier)
|
||||
{
|
||||
const constexpr TurnType::Enum exit_instruction[] = {TurnType::Invalid, TurnType::ExitRoundabout,
|
||||
TurnType::ExitRotary,
|
||||
TurnType::ExitRoundaboutIntersection};
|
||||
const constexpr TurnType::Enum exit_instruction[] = {
|
||||
TurnType::Invalid, TurnType::ExitRoundabout, TurnType::ExitRotary,
|
||||
TurnType::ExitRoundaboutIntersection};
|
||||
return {exit_instruction[static_cast<int>(roundabout_type)], modifier};
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
// OpenStreetMap node ids are higher than 2^32
|
||||
OSRM_STRONG_TYPEDEF(std::uint64_t, OSMNodeID)
|
||||
@@ -56,6 +56,7 @@ using OSMEdgeID_weak = std::uint64_t;
|
||||
|
||||
using NodeID = unsigned int;
|
||||
using EdgeID = unsigned int;
|
||||
using NameID = std::uint32_t;
|
||||
using EdgeWeight = int;
|
||||
|
||||
using BearingClassID = std::uint32_t;
|
||||
@@ -80,8 +81,8 @@ struct SegmentID
|
||||
BOOST_ASSERT(!enabled || id != SPECIAL_SEGMENTID);
|
||||
}
|
||||
|
||||
NodeID id : 31;
|
||||
std::uint32_t enabled : 1;
|
||||
NodeID id : 31;
|
||||
std::uint32_t enabled : 1;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SegmentID) == 4, "SegmentID needs to be 4 bytes big");
|
||||
|
||||
Reference in New Issue
Block a user