osrm-backend/include/engine/internal_route_result.hpp

160 lines
6.0 KiB
C++
Raw Normal View History

#ifndef RAW_ROUTE_DATA_H
#define RAW_ROUTE_DATA_H
2011-07-07 13:03:32 -04:00
2017-07-21 08:59:54 -04:00
#include "extractor/class_data.hpp"
#include "extractor/travel_mode.hpp"
#include "guidance/turn_bearing.hpp"
#include "guidance/turn_instruction.hpp"
2017-07-21 08:59:54 -04:00
2016-05-27 15:05:04 -04:00
#include "engine/phantom_node.hpp"
2017-07-21 08:59:54 -04:00
#include "util/coordinate.hpp"
2017-06-19 09:27:46 -04:00
#include "util/guidance/entry_class.hpp"
2016-06-15 08:38:24 -04:00
#include "util/guidance/turn_lanes.hpp"
#include "util/integer_range.hpp"
2016-06-15 08:38:24 -04:00
#include "util/typedefs.hpp"
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 <boost/optional.hpp>
#include <vector>
2016-01-05 10:51:13 -05:00
namespace osrm
{
namespace engine
{
2014-05-07 12:39:16 -04:00
struct PathData
{
2018-02-09 13:32:09 -05:00
// from edge-based-node id
NodeID from_edge_based_node;
// the internal OSRM id of the OSM node id that is the via node of the turn
2016-01-28 10:28:44 -05:00
NodeID turn_via_node;
// weight that is traveled on the segment until the turn is reached
// including the turn weight, if one exists
EdgeWeight weight_until_turn;
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 this segment immediately precedes a turn, then duration_of_turn
// will contain the weight of the turn. Otherwise it will be 0.
EdgeWeight weight_of_turn;
// duration that is traveled on the segment until the turn is reached,
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
// including a turn if the segment precedes one.
2016-01-28 10:28:44 -05:00
EdgeWeight duration_until_turn;
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 this segment immediately precedes a turn, then duration_of_turn
// will contain the duration of the turn. Otherwise it will be 0.
EdgeWeight duration_of_turn;
// Source of the speed value on this road segment
DatasourceID datasource_id;
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 segment precedes a turn, ID of the turn itself
boost::optional<EdgeID> turn_edge;
2012-08-27 11:40:59 -04:00
};
struct InternalRouteResult
2014-05-07 12:39:16 -04:00
{
std::vector<std::vector<PathData>> unpacked_path_segments;
std::vector<PhantomNodes> segment_end_coordinates;
std::vector<bool> source_traversed_in_reverse;
std::vector<bool> target_traversed_in_reverse;
EdgeWeight shortest_path_weight = INVALID_EDGE_WEIGHT;
bool is_valid() const { return INVALID_EDGE_WEIGHT != shortest_path_weight; }
2016-01-04 04:19:25 -05:00
bool is_via_leg(const std::size_t leg) const
{
return (leg != unpacked_path_segments.size() - 1);
}
2017-04-06 08:28:43 -04:00
// Note: includes duration for turns, except for at start and end node.
EdgeWeight duration() const
{
EdgeWeight ret{0};
for (const auto &leg : unpacked_path_segments)
for (const auto &segment : leg)
ret += segment.duration_until_turn;
return ret;
}
2011-07-07 13:03:32 -04:00
};
struct InternalManyRoutesResult
{
InternalManyRoutesResult() = default;
InternalManyRoutesResult(InternalRouteResult route) : routes{std::move(route)} {}
InternalManyRoutesResult(std::vector<InternalRouteResult> routes_) : routes{std::move(routes_)}
{
}
std::vector<InternalRouteResult> routes;
};
inline InternalRouteResult CollapseInternalRouteResult(const InternalRouteResult &leggy_result,
const std::vector<bool> &is_waypoint)
{
BOOST_ASSERT(leggy_result.is_valid());
BOOST_ASSERT(is_waypoint[0]); // first and last coords
BOOST_ASSERT(is_waypoint.back()); // should always be waypoints
// Nothing to collapse! return result as is
if (leggy_result.unpacked_path_segments.size() == 1)
return leggy_result;
BOOST_ASSERT(leggy_result.segment_end_coordinates.size() > 1);
InternalRouteResult collapsed;
collapsed.shortest_path_weight = leggy_result.shortest_path_weight;
for (auto i : util::irange<std::size_t>(0, leggy_result.unpacked_path_segments.size()))
{
if (is_waypoint[i])
{
// start another leg vector
collapsed.unpacked_path_segments.push_back(leggy_result.unpacked_path_segments[i]);
// save new phantom node pair
collapsed.segment_end_coordinates.push_back(leggy_result.segment_end_coordinates[i]);
// save data about phantom nodes
collapsed.source_traversed_in_reverse.push_back(
leggy_result.source_traversed_in_reverse[i]);
collapsed.target_traversed_in_reverse.push_back(
leggy_result.target_traversed_in_reverse[i]);
}
else
// no new leg, collapse the next segment into the last leg
{
BOOST_ASSERT(!collapsed.unpacked_path_segments.empty());
auto &last_segment = collapsed.unpacked_path_segments.back();
BOOST_ASSERT(!collapsed.segment_end_coordinates.empty());
collapsed.segment_end_coordinates.back().target_phantom =
leggy_result.segment_end_coordinates[i].target_phantom;
collapsed.target_traversed_in_reverse.back() =
leggy_result.target_traversed_in_reverse[i];
// copy path segments into current leg
if (!leggy_result.unpacked_path_segments[i].empty())
{
auto old_size = last_segment.size();
last_segment.insert(last_segment.end(),
leggy_result.unpacked_path_segments[i].begin(),
leggy_result.unpacked_path_segments[i].end());
// The first segment of the unpacked path is missing the weight of the
// source phantom. We need to add those values back so that the total
// edge weight is correct
last_segment[old_size].weight_until_turn +=
leggy_result.source_traversed_in_reverse[i]
? leggy_result.segment_end_coordinates[i].source_phantom.reverse_weight
: leggy_result.segment_end_coordinates[i].source_phantom.forward_weight;
last_segment[old_size].duration_until_turn +=
leggy_result.source_traversed_in_reverse[i]
? leggy_result.segment_end_coordinates[i].source_phantom.reverse_duration
: leggy_result.segment_end_coordinates[i].source_phantom.forward_duration;
}
}
}
BOOST_ASSERT(collapsed.segment_end_coordinates.size() ==
collapsed.unpacked_path_segments.size());
return collapsed;
}
} // namespace engine
} // namespace osrm
2016-01-05 10:51:13 -05:00
#endif // RAW_ROUTE_DATA_H