osrm-backend/include/engine/guidance/assemble_steps.hpp

367 lines
19 KiB
C++
Raw Normal View History

2016-01-28 10:28:44 -05:00
#ifndef ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
#define ENGINE_GUIDANCE_ASSEMBLE_STEPS_HPP_
2016-07-21 08:34:32 -04:00
#include "extractor/travel_mode.hpp"
#include "extractor/turn_lane_types.hpp"
#include "guidance/turn_instruction.hpp"
#include "engine/datafacade/datafacade_base.hpp"
2016-03-23 08:04:23 -04:00
#include "engine/guidance/leg_geometry.hpp"
2016-01-28 10:28:44 -05:00
#include "engine/guidance/route_step.hpp"
#include "engine/guidance/step_maneuver.hpp"
#include "engine/internal_route_result.hpp"
#include "engine/phantom_node.hpp"
2016-03-23 08:04:23 -04:00
#include "util/bearing.hpp"
#include "util/coordinate.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/guidance/entry_class.hpp"
2016-06-15 08:38:24 -04:00
#include "util/guidance/turn_lanes.hpp"
#include "util/typedefs.hpp"
2016-01-28 10:28:44 -05:00
2016-02-25 04:01:16 -05:00
#include <boost/optional.hpp>
#include <cstddef>
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
#include <guidance/turn_bearing.hpp>
2016-03-23 08:04:23 -04:00
#include <vector>
2016-01-28 10:28:44 -05:00
namespace osrm::engine::guidance
2016-01-28 10:28:44 -05:00
{
namespace detail
{
2017-08-28 12:03:51 -04:00
std::pair<short, short> getDepartBearings(const LegGeometry &leg_geometry,
const PhantomNode &source_node,
const bool traversed_in_reverse);
std::pair<short, short> getArriveBearings(const LegGeometry &leg_geometry,
const PhantomNode &target_node,
const bool traversed_in_reverse);
} // namespace detail
2016-01-28 10:28:44 -05:00
inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &facade,
const std::vector<PathData> &leg_data,
const LegGeometry &leg_geometry,
const PhantomNode &source_node,
const PhantomNode &target_node,
const bool source_traversed_in_reverse,
const bool target_traversed_in_reverse)
2016-01-28 10:28:44 -05:00
{
const double weight_multiplier = facade.GetWeightMultiplier();
const double constexpr ZERO_DURATION = 0., ZERO_DISTANCE = 0., ZERO_WEIGHT = 0;
2016-03-23 08:04:23 -04:00
const constexpr char *NO_ROTARY_NAME = "";
const EdgeWeight source_weight =
2016-03-18 11:14:48 -04:00
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const EdgeDuration source_duration =
source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration;
2017-05-11 03:13:59 -04:00
const auto source_node_id = source_traversed_in_reverse ? source_node.reverse_segment_id.id
: source_node.forward_segment_id.id;
const auto source_name_id = facade.GetNameIndex(source_node_id);
bool is_segregated = facade.IsSegregated(source_node_id);
2017-05-11 03:13:59 -04:00
const auto source_mode = facade.GetTravelMode(source_node_id);
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
2016-01-28 10:28:44 -05:00
const EdgeDuration target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const EdgeWeight target_weight =
2016-03-18 11:14:48 -04:00
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
2017-05-11 03:13:59 -04:00
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
: target_node.forward_segment_id.id;
const auto target_name_id = facade.GetNameIndex(target_node_id);
const auto target_mode = facade.GetTravelMode(target_node_id);
2016-01-28 10:28:44 -05:00
const auto number_of_segments = leg_geometry.GetNumberOfSegments();
std::vector<RouteStep> steps;
steps.reserve(number_of_segments);
std::size_t segment_index = 0;
BOOST_ASSERT(leg_geometry.locations.size() >= 2);
2017-08-28 12:03:51 -04:00
auto bearings =
detail::getDepartBearings(leg_geometry, source_node, source_traversed_in_reverse);
2016-02-25 04:01:16 -05:00
2016-05-27 15:05:04 -04:00
StepManeuver maneuver{source_node.location,
bearings.first,
bearings.second,
osrm::guidance::TurnInstruction::NO_TURN(),
2016-05-27 15:05:04 -04:00
WaypointType::Depart,
2016-07-21 08:34:32 -04:00
0};
IntermediateIntersection intersection{source_node.location,
std::vector<short>({bearings.second}),
std::vector<bool>({true}),
IntermediateIntersection::NO_INDEX,
0,
util::guidance::LaneTuple(),
{},
source_classes};
2016-01-28 10:28:44 -05:00
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
if (!leg_data.empty())
{
2016-01-28 10:28:44 -05:00
// PathData saves the information we need of the segment _before_ the turn,
// but a RouteStep is with regard to the segment after the turn.
// We need to skip the first segment because it is already covered by the
2016-02-24 04:29:23 -05:00
// initial start of a route
EdgeDuration segment_duration = {0};
EdgeWeight segment_weight = {0};
// some name changes are not announced in our processing. For these, we have to keep the
// first name on the segment
2017-05-11 03:13:59 -04:00
auto step_name_id = source_name_id;
for (std::size_t leg_data_index = 0; leg_data_index < leg_data.size(); ++leg_data_index)
2016-01-28 10:28:44 -05:00
{
const auto &path_point = leg_data[leg_data_index];
segment_duration += path_point.duration_until_turn;
segment_weight += path_point.weight_until_turn;
2016-03-22 08:40:13 -04:00
// all changes to this check have to be matched with assemble_geometry
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
const auto turn_instruction =
path_point.turn_edge ? facade.GetTurnInstructionForEdgeID(*path_point.turn_edge)
: osrm::guidance::TurnInstruction::NO_TURN();
if (turn_instruction.type != osrm::guidance::TurnType::NoTurn)
2016-01-28 10:28:44 -05:00
{
BOOST_ASSERT(segment_weight >= EdgeWeight{0});
const auto name = facade.GetNameForID(step_name_id);
2016-09-05 09:01:51 -04:00
const auto ref = facade.GetRefForID(step_name_id);
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
2016-05-26 18:47:46 -04:00
const auto destinations = facade.GetDestinationsForID(step_name_id);
const auto exits = facade.GetExitsForID(step_name_id);
2016-01-28 10:28:44 -05:00
const auto distance = leg_geometry.segment_distances[segment_index];
// intersections contain the classes of exiting road
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
intersection.classes =
facade.GetClasses(facade.GetClassData(path_point.from_edge_based_node));
const auto is_left_hand_driving =
facade.IsLeftHandDriving(path_point.from_edge_based_node);
const auto travel_mode = facade.GetTravelMode(path_point.from_edge_based_node);
BOOST_ASSERT(travel_mode > 0);
2018-02-09 13:32:09 -05:00
steps.push_back(RouteStep{path_point.from_edge_based_node,
step_name_id,
is_segregated,
std::string(name),
std::string(ref),
std::string(pronunciation),
std::string(destinations),
std::string(exits),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
from_alias<double>(segment_duration) / 10.,
distance,
from_alias<double>(segment_weight) / weight_multiplier,
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
travel_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1,
{intersection},
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
is_left_hand_driving});
if (leg_data_index + 1 < leg_data.size())
{
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
step_name_id =
facade.GetNameIndex(leg_data[leg_data_index + 1].from_edge_based_node);
is_segregated =
facade.IsSegregated(leg_data[leg_data_index + 1].from_edge_based_node);
}
else
{
2017-05-11 03:13:59 -04:00
step_name_id = facade.GetNameIndex(target_node_id);
is_segregated = facade.IsSegregated(target_node_id);
}
// extract bearings
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
auto pre_turn_bearing = path_point.turn_edge
? facade.PreTurnBearing(*path_point.turn_edge)
: osrm::guidance::TurnBearing(0);
auto post_turn_bearing = path_point.turn_edge
? facade.PostTurnBearing(*path_point.turn_edge)
: osrm::guidance::TurnBearing(0);
bearings = std::make_pair<std::uint16_t, std::uint16_t>(pre_turn_bearing.Get(),
post_turn_bearing.Get());
2017-06-19 09:27:46 -04:00
const auto bearing_class = facade.GetBearingClass(path_point.turn_via_node);
auto bearing_data = bearing_class.getAvailableBearings();
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
util::guidance::LaneTupleIdPair lane_data = {{0, INVALID_LANEID},
INVALID_LANE_DESCRIPTIONID};
if (path_point.turn_edge && facade.HasLaneData(*path_point.turn_edge))
{
lane_data = facade.GetLaneData(*path_point.turn_edge);
}
intersection.in = bearing_class.findMatchingBearing(bearings.first);
intersection.out = bearing_class.findMatchingBearing(bearings.second);
intersection.location = facade.GetCoordinateOfNode(path_point.turn_via_node);
intersection.bearings.clear();
2016-12-13 05:48:21 -05:00
intersection.bearings.reserve(bearing_data.size());
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
intersection.lanes = lane_data.first;
intersection.lane_description = lane_data.second != INVALID_LANE_DESCRIPTIONID
? facade.GetTurnDescription(lane_data.second)
: extractor::TurnLaneDescription();
// Lanes in turn are bound by total number of lanes at the location
BOOST_ASSERT(intersection.lanes.lanes_in_turn <=
intersection.lane_description.size());
// No lanes at location and no turn lane or lanes at location and lanes in turn
BOOST_ASSERT((intersection.lane_description.empty() &&
intersection.lanes.lanes_in_turn == 0) ||
(!intersection.lane_description.empty() &&
intersection.lanes.lanes_in_turn != 0));
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
auto entry_class = path_point.turn_edge
? facade.GetEntryClass(*path_point.turn_edge)
: EMPTY_ENTRY_CLASS;
2016-12-13 05:48:21 -05:00
std::copy(bearing_data.begin(),
bearing_data.end(),
std::back_inserter(intersection.bearings));
intersection.entry.clear();
for (auto idx : util::irange<std::size_t>(0, intersection.bearings.size()))
{
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
intersection.entry.push_back(entry_class.allowsEntry(idx));
}
std::int16_t bearing_in_driving_direction =
util::bearing::reverse(std::round(bearings.first));
2016-05-27 15:05:04 -04:00
maneuver = {intersection.location,
bearing_in_driving_direction,
2016-05-27 15:05:04 -04:00
bearings.second,
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
turn_instruction,
2016-05-27 15:05:04 -04:00
WaypointType::None,
2016-07-21 08:34:32 -04:00
0};
2016-01-28 10:28:44 -05:00
segment_index++;
segment_duration = {0};
segment_weight = {0};
2016-01-28 10:28:44 -05:00
}
}
const auto distance = leg_geometry.segment_distances[segment_index];
const EdgeDuration duration = segment_duration + target_duration;
const EdgeWeight weight = segment_weight + target_weight;
// intersections contain the classes of exiting road
intersection.classes = facade.GetClasses(facade.GetClassData(target_node_id));
BOOST_ASSERT(duration >= EdgeDuration{0});
2018-02-09 13:32:09 -05:00
steps.push_back(RouteStep{leg_data[leg_data.size() - 1].from_edge_based_node,
step_name_id,
is_segregated,
std::string(facade.GetNameForID(step_name_id)),
std::string(facade.GetRefForID(step_name_id)),
std::string(facade.GetPronunciationForID(step_name_id)),
std::string(facade.GetDestinationsForID(step_name_id)),
std::string(facade.GetExitsForID(step_name_id)),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
from_alias<double>(duration) / 10.,
distance,
from_alias<double>(weight) / weight_multiplier,
target_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1,
{intersection},
facade.IsLeftHandDriving(target_node_id)});
2016-01-28 10:28:44 -05:00
}
// In this case the source + target are on the same edge segment
2016-01-28 10:28:44 -05:00
else
{
BOOST_ASSERT(source_node.fwd_segment_position == target_node.fwd_segment_position);
BOOST_ASSERT(source_traversed_in_reverse == target_traversed_in_reverse);
// The difference (target-source) should handle
// all variants for similar directions u-v and s-t (and opposite)
// s(t) t(s) source_traversed_in_reverse = target_traversed_in_reverse = false
// u-------------v
// |---| source_weight
// |---------| target_weight
// s(t) t(s) source_traversed_in_reverse = target_traversed_in_reverse = true
// u-------------v
// | |---------| source_weight
// | |---| target_weight
BOOST_ASSERT(target_weight >= source_weight);
const EdgeWeight weight = target_weight - source_weight;
// use rectified linear unit function to avoid negative duration values
// due to flooring errors in phantom snapping
BOOST_ASSERT(target_duration >= source_duration || weight == EdgeWeight{0});
const EdgeDuration duration =
std::max<EdgeDuration>({0}, target_duration - source_duration);
2016-02-24 04:29:23 -05:00
2018-02-09 13:32:09 -05:00
steps.push_back(RouteStep{source_node_id,
source_name_id,
is_segregated,
std::string(facade.GetNameForID(source_name_id)),
std::string(facade.GetRefForID(source_name_id)),
std::string(facade.GetPronunciationForID(source_name_id)),
std::string(facade.GetDestinationsForID(source_name_id)),
std::string(facade.GetExitsForID(source_name_id)),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
from_alias<double>(duration) / 10.,
leg_geometry.segment_distances[segment_index],
from_alias<double>(weight) / weight_multiplier,
source_mode,
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
maneuver,
leg_geometry.FrontIndex(segment_index),
leg_geometry.BackIndex(segment_index) + 1,
{intersection},
facade.IsLeftHandDriving(source_node_id)});
2016-01-28 10:28:44 -05:00
}
BOOST_ASSERT(segment_index == number_of_segments - 1);
2017-08-28 12:03:51 -04:00
bearings = detail::getArriveBearings(leg_geometry, target_node, target_traversed_in_reverse);
2016-07-21 08:34:32 -04:00
intersection = {
target_node.location,
std::vector<short>({static_cast<short>(util::bearing::reverse(bearings.first))}),
std::vector<bool>({true}),
0,
IntermediateIntersection::NO_INDEX,
util::guidance::LaneTuple(),
{},
{}};
2016-04-06 10:47:16 -04:00
// This step has length zero, the only reason we need it is the target location
maneuver = {intersection.location,
bearings.first,
bearings.second,
osrm::guidance::TurnInstruction::NO_TURN(),
WaypointType::Arrive,
0};
2016-04-06 10:47:16 -04:00
BOOST_ASSERT(!leg_geometry.locations.empty());
2018-02-09 13:32:09 -05:00
steps.push_back(RouteStep{target_node_id,
target_name_id,
facade.IsSegregated(target_node_id),
std::string(facade.GetNameForID(target_name_id)),
std::string(facade.GetRefForID(target_name_id)),
std::string(facade.GetPronunciationForID(target_name_id)),
std::string(facade.GetDestinationsForID(target_name_id)),
std::string(facade.GetExitsForID(target_name_id)),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
ZERO_DURATION,
ZERO_DISTANCE,
ZERO_WEIGHT,
target_mode,
Lazily generate optional route path data (#6045) Currently route results are annotated with additional path information, such as geometries, turn-by-turn steps and other metadata. These annotations are generated if they are not requested or returned in the response. Datasets needed to generate these annotations are loaded and available to the OSRM process even when unused. This commit is a first step towards making the loading of these datasets optional. We refactor the code so that route annotations are only generated if explicitly requested and needed in the response. Specifically, we change the following annotations to be lazily generated: - Turn-by-turn steps - Route Overview geometry - Route segment metadata For example. a /route/v1 request with steps=false&overview=false&annotations=false would no longer call the following data facade methods: - GetOSMNodeIDOfNode - GetTurnInstructionForEdgeID - GetNameIndex - GetNameForID - GetRefForID - GetTurnInstructionForEdgeID - GetClassData - IsLeftHandDriving - GetTravelMode - IsSegregated - PreTurnBearing - PostTurnBearing - HasLaneData - GetLaneData - GetEntryClass Requests that include segment metadata and/or overview geometry but not turn-by-turn instructions will also benefit from this, although there is some interdependency with the step instructions - a call to GetTurnInstructionForEdgeID is still required. Requests for OSM annotations will understandably still need to call GetOSMNodeIDOfNode. Making these changes unlocks the optional loading of data contained in the following OSRM files: - osrm.names - osrm.icd - osrm.nbg_nodes (partial) - osrm.ebg_nodes (partial) - osrm.edges
2022-08-22 07:59:20 -04:00
maneuver,
leg_geometry.locations.size() - 1,
leg_geometry.locations.size(),
{intersection},
facade.IsLeftHandDriving(target_node_id)});
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);
BOOST_ASSERT(steps.front().maneuver.waypoint_type == WaypointType::Depart);
2016-01-28 10:28:44 -05:00
BOOST_ASSERT(steps.back().intersections.size() == 1);
BOOST_ASSERT(steps.back().intersections.front().bearings.size() == 1);
BOOST_ASSERT(steps.back().intersections.front().entry.size() == 1);
BOOST_ASSERT(steps.back().maneuver.waypoint_type == WaypointType::Arrive);
2016-07-21 08:34:32 -04:00
BOOST_ASSERT(steps.back().intersections.front().lanes.lanes_in_turn == 0);
2016-07-26 09:00:58 -04:00
BOOST_ASSERT(steps.back().intersections.front().lanes.first_lane_from_the_right ==
INVALID_LANEID);
2016-07-21 08:34:32 -04:00
BOOST_ASSERT(steps.back().intersections.front().lane_description.empty());
// depart and arrive need to be trivial
BOOST_ASSERT(steps.front().maneuver.exit == 0 && steps.back().maneuver.exit == 0);
2016-01-28 10:28:44 -05:00
return steps;
}
2022-12-20 12:00:11 -05:00
} // namespace osrm::engine::guidance
2016-01-28 10:28:44 -05:00
#endif // ENGINE_GUIDANCE_SEGMENT_LIST_HPP_