Merge branch 'master' into sf-stop-sign

This commit is contained in:
Siarhei Fedartsou
2022-10-31 21:47:36 +01:00
78 changed files with 934 additions and 846 deletions
+3 -3
View File
@@ -12,12 +12,12 @@ namespace contractor
struct ContractorEdgeData
{
ContractorEdgeData()
: weight(0), duration(0), distance(0), id(0), originalEdges(0), shortcut(0), forward(0),
: weight{0}, duration{0}, distance{0}, id(0), originalEdges(0), shortcut(0), forward(0),
backward(0)
{
}
ContractorEdgeData(EdgeWeight weight,
EdgeWeight duration,
EdgeDuration duration,
EdgeDistance distance,
unsigned original_edges,
unsigned id,
@@ -30,7 +30,7 @@ struct ContractorEdgeData
{
}
EdgeWeight weight;
EdgeWeight duration;
EdgeDuration duration;
EdgeDistance distance;
unsigned id;
unsigned originalEdges : 29;
@@ -29,18 +29,20 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
#ifndef NDEBUG
const unsigned int constexpr DAY_IN_DECI_SECONDS = 24 * 60 * 60 * 10;
if (static_cast<unsigned int>(std::max(input_edge.data.weight, 1)) > DAY_IN_DECI_SECONDS)
if (from_alias<unsigned int>(std::max(input_edge.data.weight, EdgeWeight{1})) >
DAY_IN_DECI_SECONDS)
{
util::Log(logWARNING) << "Edge weight large -> "
<< static_cast<unsigned int>(std::max(input_edge.data.weight, 1))
<< from_alias<unsigned int>(
std::max(input_edge.data.weight, EdgeWeight{1}))
<< " : " << static_cast<unsigned int>(input_edge.source) << " -> "
<< static_cast<unsigned int>(input_edge.target);
}
#endif
edges.emplace_back(input_edge.source,
input_edge.target,
std::max(input_edge.data.weight, 1),
input_edge.data.duration,
std::max(input_edge.data.weight, {1}),
to_alias<EdgeDuration>(input_edge.data.duration),
input_edge.data.distance,
1,
input_edge.data.turn_id,
@@ -50,8 +52,8 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
edges.emplace_back(input_edge.target,
input_edge.source,
std::max(input_edge.data.weight, 1),
input_edge.data.duration,
std::max(input_edge.data.weight, {1}),
to_alias<EdgeDuration>(input_edge.data.duration),
input_edge.data.distance,
1,
input_edge.data.turn_id,
@@ -109,7 +111,7 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.weight == reverse_edge.data.weight)
{
if ((int)forward_edge.data.weight != INVALID_EDGE_WEIGHT)
if (forward_edge.data.weight != INVALID_EDGE_WEIGHT)
{
forward_edge.data.backward = true;
edges[edge++] = forward_edge;
@@ -117,11 +119,11 @@ ContractorGraph toContractorGraph(NodeID number_of_nodes, InputEdgeContainer inp
}
else
{ // insert seperate edges
if (((int)forward_edge.data.weight) != INVALID_EDGE_WEIGHT)
if (forward_edge.data.weight != INVALID_EDGE_WEIGHT)
{
edges[edge++] = forward_edge;
}
if ((int)reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
if (reverse_edge.data.weight != INVALID_EDGE_WEIGHT)
{
edges[edge++] = reverse_edge;
}
@@ -157,7 +159,7 @@ template <class Edge, typename GraphT> inline std::vector<Edge> toEdges(GraphT g
new_edge.target = target;
BOOST_ASSERT_MSG(SPECIAL_NODEID != new_edge.target, "Target id invalid");
new_edge.data.weight = data.weight;
new_edge.data.duration = data.duration;
new_edge.data.duration = from_alias<EdgeDuration::value_type>(data.duration);
new_edge.data.distance = data.distance;
new_edge.data.shortcut = data.shortcut;
new_edge.data.turn_id = data.id;
+4 -4
View File
@@ -17,15 +17,15 @@ struct QueryEdge
struct EdgeData
{
explicit EdgeData()
: turn_id(0), shortcut(false), weight(0), duration(0), forward(false), backward(false),
distance(0)
: turn_id(0), shortcut(false), weight{0}, duration(0), forward(false),
backward(false), distance{0}
{
}
EdgeData(const NodeID turn_id,
const bool shortcut,
const EdgeWeight weight,
const EdgeWeight duration,
const EdgeDuration duration,
const EdgeDistance distance,
const bool forward,
const bool backward)
@@ -50,7 +50,7 @@ struct QueryEdge
NodeID turn_id : 31;
bool shortcut : 1;
EdgeWeight weight;
EdgeWeight duration : 30;
EdgeDuration::value_type duration : 30;
std::uint32_t forward : 1;
std::uint32_t backward : 1;
EdgeDistance distance;
+3 -4
View File
@@ -61,7 +61,7 @@ class CellCustomizer
}
}
heap.Clear();
heap.Insert(source, 0, {false, 0, 0});
heap.Insert(source, {0}, {false, {0}, {0}});
// explore search space
while (!heap.Empty() && !destinations_set.empty())
@@ -216,12 +216,11 @@ class CellCustomizer
partition.GetCell(level - 1, to)))
{
const EdgeWeight to_weight = weight + data.weight;
const EdgeDuration to_duration = duration + data.duration;
const EdgeDuration to_duration = duration + to_alias<EdgeDuration>(data.duration);
const EdgeDistance to_distance = distance + data.distance;
if (!heap.WasInserted(to))
{
heap.Insert(
to, to_weight, {false, duration + data.duration, distance + data.distance});
heap.Insert(to, to_weight, {false, to_duration, to_distance});
}
else if (std::tie(to_weight, to_duration, to_distance) <
std::tie(
+1 -1
View File
@@ -97,7 +97,7 @@ class MultiLevelGraph : public partitioner::MultiLevelGraph<EdgeDataT, Ownership
EdgeWeight GetNodeWeight(NodeID node) const { return node_weights[node]; }
EdgeWeight GetNodeDuration(NodeID node) const { return node_durations[node]; }
EdgeDuration GetNodeDuration(NodeID node) const { return node_durations[node]; }
EdgeDistance GetNodeDistance(NodeID node) const { return node_distances[node]; }
+14 -11
View File
@@ -133,7 +133,8 @@ class TableAPI final : public BaseAPI
}
bool have_speed_cells =
parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0;
parameters.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
parameters.fallback_speed > 0;
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> speed_cells;
if (have_speed_cells)
{
@@ -223,7 +224,8 @@ class TableAPI final : public BaseAPI
MakeDistanceTable(tables.second, number_of_sources, number_of_destinations);
}
if (parameters.fallback_speed != INVALID_FALLBACK_SPEED && parameters.fallback_speed > 0)
if (parameters.fallback_speed != from_alias<double>(INVALID_FALLBACK_SPEED) &&
parameters.fallback_speed > 0)
{
response.values["fallback_speed_cells"] = MakeEstimatesTable(fallback_speed_cells);
}
@@ -272,17 +274,17 @@ class TableAPI final : public BaseAPI
virtual flatbuffers::Offset<flatbuffers::Vector<float>>
MakeDurationTable(flatbuffers::FlatBufferBuilder &builder,
const std::vector<EdgeWeight> &values) const
const std::vector<EdgeDuration> &values) const
{
std::vector<float> distance_table;
distance_table.resize(values.size());
std::transform(
values.begin(), values.end(), distance_table.begin(), [](const EdgeWeight duration) {
values.begin(), values.end(), distance_table.begin(), [](const EdgeDuration duration) {
if (duration == MAXIMAL_EDGE_DURATION)
{
return 0.;
}
return duration / 10.;
return from_alias<double>(duration) / 10.;
});
return builder.CreateVector(distance_table);
}
@@ -299,7 +301,7 @@ class TableAPI final : public BaseAPI
{
return 0.;
}
return std::round(distance * 10) / 10.;
return std::round(from_alias<double>(distance) * 10) / 10.;
});
return builder.CreateVector(duration_table);
}
@@ -347,7 +349,7 @@ class TableAPI final : public BaseAPI
return json_waypoints;
}
virtual util::json::Array MakeDurationTable(const std::vector<EdgeWeight> &values,
virtual util::json::Array MakeDurationTable(const std::vector<EdgeDuration> &values,
std::size_t number_of_rows,
std::size_t number_of_columns) const
{
@@ -361,13 +363,14 @@ class TableAPI final : public BaseAPI
std::transform(row_begin_iterator,
row_end_iterator,
json_row.values.begin(),
[](const EdgeWeight duration) {
[](const EdgeDuration duration) {
if (duration == MAXIMAL_EDGE_DURATION)
{
return util::json::Value(util::json::Null());
}
// division by 10 because the duration is in deciseconds (10s)
return util::json::Value(util::json::Number(duration / 10.));
return util::json::Value(
util::json::Number(from_alias<double>(duration) / 10.));
});
json_table.values.push_back(std::move(json_row));
}
@@ -394,8 +397,8 @@ class TableAPI final : public BaseAPI
return util::json::Value(util::json::Null());
}
// round to single decimal place
return util::json::Value(
util::json::Number(std::round(distance * 10) / 10.));
return util::json::Value(util::json::Number(
std::round(from_alias<double>(distance) * 10) / 10.));
});
json_table.values.push_back(std::move(json_row));
}
+1 -1
View File
@@ -59,7 +59,7 @@ struct TableParameters : public BaseParameters
{
std::vector<std::size_t> sources;
std::vector<std::size_t> destinations;
double fallback_speed = INVALID_FALLBACK_SPEED;
double fallback_speed = from_alias<double>(INVALID_FALLBACK_SPEED);
enum class FallbackCoordinateType
{
@@ -83,7 +83,7 @@ template <> class AlgorithmDataFacade<MLD>
virtual EdgeWeight GetNodeWeight(const NodeID edge_based_node_id) const = 0;
virtual EdgeWeight
virtual EdgeDuration
GetNodeDuration(const NodeID edge_based_node_id) const = 0; // TODO: to be removed
virtual EdgeDistance GetNodeDistance(const NodeID edge_based_node_id) const = 0;
+43 -34
View File
@@ -320,75 +320,84 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
const auto forward_weight_offset =
// NOLINTNEXTLINE(bugprone-fold-init-type)
std::accumulate(forward_weights.begin(),
forward_weights.begin() + data.fwd_segment_position,
EdgeWeight{0});
alias_cast<EdgeWeight>(
std::accumulate(forward_weights.begin(),
forward_weights.begin() + data.fwd_segment_position,
SegmentWeight{0}));
const auto forward_duration_offset =
// NOLINTNEXTLINE(bugprone-fold-init-type)
std::accumulate(forward_durations.begin(),
forward_durations.begin() + data.fwd_segment_position,
EdgeDuration{0});
alias_cast<EdgeDuration>(
std::accumulate(forward_durations.begin(),
forward_durations.begin() + data.fwd_segment_position,
SegmentDuration{0}));
EdgeDistance forward_distance_offset = 0;
EdgeDistance forward_distance_offset = {0};
// Sum up the distance from the start to the fwd_segment_position
for (auto current = forward_geometry.begin();
current < forward_geometry.begin() + data.fwd_segment_position;
++current)
{
forward_distance_offset += util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current)));
forward_distance_offset +=
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current))));
}
BOOST_ASSERT(data.fwd_segment_position <
std::distance(forward_durations.begin(), forward_durations.end()));
EdgeWeight forward_weight = forward_weights[data.fwd_segment_position];
EdgeDuration forward_duration = forward_durations[data.fwd_segment_position];
EdgeDistance forward_distance = util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
point_on_segment);
EdgeWeight forward_weight =
alias_cast<EdgeWeight>(forward_weights[data.fwd_segment_position]);
EdgeDuration forward_duration =
alias_cast<EdgeDuration>(forward_durations[data.fwd_segment_position]);
EdgeDistance forward_distance =
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
point_on_segment));
const auto reverse_weight_offset =
const auto reverse_weight_offset = alias_cast<EdgeWeight>(
std::accumulate(reverse_weights.begin(),
reverse_weights.end() - data.fwd_segment_position - 1,
EdgeWeight{0});
SegmentWeight{0}));
const auto reverse_duration_offset =
const auto reverse_duration_offset = alias_cast<EdgeDuration>(
std::accumulate(reverse_durations.begin(),
reverse_durations.end() - data.fwd_segment_position - 1,
EdgeDuration{0});
SegmentDuration{0}));
EdgeDistance reverse_distance_offset = 0;
EdgeDistance reverse_distance_offset = {0};
// Sum up the distance from just after the fwd_segment_position to the end
for (auto current = forward_geometry.begin() + data.fwd_segment_position + 1;
current != std::prev(forward_geometry.end());
++current)
{
reverse_distance_offset += util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current)));
reverse_distance_offset +=
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
datafacade.GetCoordinateOfNode(*current),
datafacade.GetCoordinateOfNode(*std::next(current))));
}
EdgeWeight reverse_weight =
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
EdgeDuration reverse_duration =
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1];
EdgeDistance reverse_distance = util::coordinate_calculation::greatCircleDistance(
point_on_segment,
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
EdgeWeight reverse_weight = alias_cast<EdgeWeight>(
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1]);
EdgeDuration reverse_duration = alias_cast<EdgeDuration>(
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1]);
EdgeDistance reverse_distance =
to_alias<EdgeDistance>(util::coordinate_calculation::greatCircleDistance(
point_on_segment,
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1))));
ratio = std::min(1.0, std::max(0.0, ratio));
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
{
forward_weight = static_cast<EdgeWeight>(forward_weight * ratio);
forward_duration = static_cast<EdgeDuration>(forward_duration * ratio);
forward_weight = to_alias<EdgeWeight>(from_alias<double>(forward_weight) * ratio);
forward_duration = to_alias<EdgeDuration>(from_alias<double>(forward_duration) * ratio);
}
if (data.reverse_segment_id.id != SPECIAL_SEGMENTID)
{
reverse_weight -= static_cast<EdgeWeight>(reverse_weight * ratio);
reverse_duration -= static_cast<EdgeDuration>(reverse_duration * ratio);
reverse_weight -= to_alias<EdgeWeight>(from_alias<double>(reverse_weight) * ratio);
reverse_duration -=
to_alias<EdgeDuration>(from_alias<double>(reverse_duration) * ratio);
}
// check phantom node segments validity
+13 -8
View File
@@ -95,8 +95,9 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
// the duration_of_turn/weight_of_turn value, which is 0 for
// non-preceeding-turn segments, but contains the turn value
// for segments before a turn.
(path_point.duration_until_turn - path_point.duration_of_turn) / 10.,
(path_point.weight_until_turn - path_point.weight_of_turn) /
from_alias<double>(path_point.duration_until_turn - path_point.duration_of_turn) /
10.,
from_alias<double>(path_point.weight_until_turn - path_point.weight_of_turn) /
facade.GetWeightMultiplier(),
path_point.datasource_id});
geometry.locations.push_back(coordinate);
@@ -121,14 +122,15 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
if (geometry.annotations.empty())
{
auto duration =
std::abs(
std::abs(from_alias<EdgeDuration::value_type>(
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) -
(reversed_source ? source_node.reverse_duration : source_node.forward_duration)) /
(reversed_source ? source_node.reverse_duration : source_node.forward_duration))) /
10.;
BOOST_ASSERT(duration >= 0);
auto weight =
std::abs((reversed_target ? target_node.reverse_weight : target_node.forward_weight) -
(reversed_source ? source_node.reverse_weight : source_node.forward_weight)) /
std::abs(from_alias<EdgeWeight::value_type>(
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) -
(reversed_source ? source_node.reverse_weight : source_node.forward_weight))) /
facade.GetWeightMultiplier();
BOOST_ASSERT(weight >= 0);
@@ -142,8 +144,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade,
{
geometry.annotations.emplace_back(LegGeometry::Annotation{
current_distance,
(reversed_target ? target_node.reverse_duration : target_node.forward_duration) / 10.,
(reversed_target ? target_node.reverse_weight : target_node.forward_weight) /
from_alias<double>(reversed_target ? target_node.reverse_duration
: target_node.forward_duration) /
10.,
from_alias<double>(reversed_target ? target_node.reverse_weight
: target_node.forward_weight) /
facade.GetWeightMultiplier(),
forward_datasources(target_node.fwd_segment_position)});
}
+10 -10
View File
@@ -34,7 +34,7 @@ namespace detail
const constexpr std::size_t MAX_USED_SEGMENTS = 2;
struct NamedSegment
{
EdgeWeight duration;
EdgeDuration duration;
std::uint32_t position;
std::uint32_t name_id;
};
@@ -88,7 +88,7 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const auto target_node_id = target_traversed_in_reverse ? target_node.reverse_segment_id.id
: target_node.forward_segment_id.id;
if (target_duration > 1)
if (target_duration > EdgeDuration{1})
segments.push_back({target_duration, index++, facade.GetNameIndex(target_node_id)});
// this makes sure that the segment with the lowest position comes first
std::sort(
@@ -184,11 +184,11 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
auto duration = std::accumulate(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + data.duration_until_turn;
return sum + from_alias<double>(data.duration_until_turn);
});
auto weight = std::accumulate(
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
return sum + data.weight_until_turn;
return sum + from_alias<double>(data.weight_until_turn);
});
// s
@@ -212,14 +212,14 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
// caputed by the phantom node. So we need to add the target duration here.
// On local segments, the target duration is already part of the duration, however.
duration = duration + target_duration;
weight = weight + target_weight;
duration = duration + from_alias<double>(target_duration);
weight = weight + from_alias<double>(target_weight);
if (route_data.empty())
{
weight -=
(target_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight);
duration -= (target_traversed_in_reverse ? source_node.reverse_duration
: source_node.forward_duration);
weight -= from_alias<double>(target_traversed_in_reverse ? source_node.reverse_weight
: source_node.forward_weight);
duration -= from_alias<double>(target_traversed_in_reverse ? source_node.reverse_duration
: source_node.forward_duration);
// use rectified linear unit function to avoid negative duration values
// due to flooring errors in phantom snapping
duration = std::max(0, duration);
+18 -17
View File
@@ -52,7 +52,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const constexpr char *NO_ROTARY_NAME = "";
const EdgeWeight source_weight =
source_traversed_in_reverse ? source_node.reverse_weight : source_node.forward_weight;
const EdgeWeight source_duration =
const EdgeDuration source_duration =
source_traversed_in_reverse ? source_node.reverse_duration : source_node.forward_duration;
const auto source_node_id = source_traversed_in_reverse ? source_node.reverse_segment_id.id
: source_node.forward_segment_id.id;
@@ -61,7 +61,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
const auto source_mode = facade.GetTravelMode(source_node_id);
auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id));
const EdgeWeight target_duration =
const EdgeDuration target_duration =
target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration;
const EdgeWeight target_weight =
target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight;
@@ -103,8 +103,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
// 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
// initial start of a route
EdgeWeight segment_duration = 0;
EdgeWeight segment_weight = 0;
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
@@ -121,7 +121,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
: osrm::guidance::TurnInstruction::NO_TURN();
if (turn_instruction.type != osrm::guidance::TurnType::NoTurn)
{
BOOST_ASSERT(segment_weight >= 0);
BOOST_ASSERT(segment_weight >= EdgeWeight{0});
const auto name = facade.GetNameForID(step_name_id);
const auto ref = facade.GetRefForID(step_name_id);
const auto pronunciation = facade.GetPronunciationForID(step_name_id);
@@ -147,9 +147,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
exits.to_string(),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
segment_duration / 10.,
from_alias<double>(segment_duration) / 10.,
distance,
segment_weight / weight_multiplier,
from_alias<double>(segment_weight) / weight_multiplier,
travel_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
@@ -228,16 +228,16 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
WaypointType::None,
0};
segment_index++;
segment_duration = 0;
segment_weight = 0;
segment_duration = {0};
segment_weight = {0};
}
}
const auto distance = leg_geometry.segment_distances[segment_index];
const EdgeWeight duration = segment_duration + target_duration;
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 >= 0);
BOOST_ASSERT(duration >= EdgeDuration{0});
steps.push_back(RouteStep{leg_data[leg_data.size() - 1].from_edge_based_node,
step_name_id,
is_segregated,
@@ -248,9 +248,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
facade.GetExitsForID(step_name_id).to_string(),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
duration / 10.,
from_alias<double>(duration) / 10.,
distance,
weight / weight_multiplier,
from_alias<double>(weight) / weight_multiplier,
target_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
@@ -280,8 +280,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
// use rectified linear unit function to avoid negative duration values
// due to flooring errors in phantom snapping
BOOST_ASSERT(target_duration >= source_duration || weight == 0);
const EdgeWeight duration = std::max(0, target_duration - source_duration);
BOOST_ASSERT(target_duration >= source_duration || weight == EdgeWeight{0});
const EdgeDuration duration =
std::max<EdgeDuration>({0}, target_duration - source_duration);
steps.push_back(RouteStep{source_node_id,
source_name_id,
@@ -293,9 +294,9 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa
facade.GetExitsForID(source_name_id).to_string(),
NO_ROTARY_NAME,
NO_ROTARY_NAME,
duration / 10.,
from_alias<double>(duration) / 10.,
leg_geometry.segment_distances[segment_index],
weight / weight_multiplier,
from_alias<double>(weight) / weight_multiplier,
source_mode,
maneuver,
leg_geometry.FrontIndex(segment_index),
+4 -4
View File
@@ -37,10 +37,10 @@ struct PathData
EdgeWeight weight_of_turn;
// duration that is traveled on the segment until the turn is reached,
// including a turn if the segment precedes one.
EdgeWeight duration_until_turn;
EdgeDuration duration_until_turn;
// 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;
EdgeDuration duration_of_turn;
// Source of the speed value on this road segment
DatasourceID datasource_id;
// If segment precedes a turn, ID of the turn itself
@@ -63,9 +63,9 @@ struct InternalRouteResult
}
// Note: includes duration for turns, except for at start and end node.
EdgeWeight duration() const
EdgeDuration duration() const
{
EdgeWeight ret{0};
EdgeDuration ret{0};
for (const auto &leg : unpacked_path_segments)
for (const auto &segment : leg)
+14 -14
View File
@@ -48,12 +48,12 @@ struct PhantomNode
PhantomNode()
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID,
false},
forward_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT),
forward_weight_offset(0), reverse_weight_offset(0),
forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset{0}, reverse_weight_offset{0},
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
forward_distance_offset(0), reverse_distance_offset(0),
forward_distance_offset{0}, reverse_distance_offset{0},
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
forward_duration_offset(0), reverse_duration_offset(0),
forward_duration_offset{0}, reverse_duration_offset{0},
component({INVALID_COMPONENTID, 0}),
fwd_segment_position(0), is_valid_forward_source{false}, is_valid_forward_target{false},
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
@@ -73,13 +73,13 @@ struct PhantomNode
return reverse_weight_offset + reverse_weight;
}
EdgeWeight GetForwardDuration() const
EdgeDuration GetForwardDuration() const
{
BOOST_ASSERT(forward_segment_id.enabled);
return forward_duration + forward_duration_offset;
}
EdgeWeight GetReverseDuration() const
EdgeDuration GetReverseDuration() const
{
BOOST_ASSERT(reverse_segment_id.enabled);
return reverse_duration + reverse_duration_offset;
@@ -168,10 +168,10 @@ struct PhantomNode
EdgeDistance reverse_distance,
EdgeDistance forward_distance_offset,
EdgeDistance reverse_distance_offset,
EdgeWeight forward_duration,
EdgeWeight reverse_duration,
EdgeWeight forward_duration_offset,
EdgeWeight reverse_duration_offset,
EdgeDuration forward_duration,
EdgeDuration reverse_duration,
EdgeDuration forward_duration_offset,
EdgeDuration reverse_duration_offset,
bool is_valid_forward_source,
bool is_valid_forward_target,
bool is_valid_reverse_source,
@@ -206,10 +206,10 @@ struct PhantomNode
EdgeDistance reverse_distance;
EdgeDistance forward_distance_offset; // TODO: try to remove -> requires path unpacking changes
EdgeDistance reverse_distance_offset; // TODO: try to remove -> requires path unpacking changes
EdgeWeight forward_duration;
EdgeWeight reverse_duration;
EdgeWeight forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeWeight reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeDuration forward_duration;
EdgeDuration reverse_duration;
EdgeDuration forward_duration_offset; // TODO: try to remove -> requires path unpacking changes
EdgeDuration reverse_duration_offset; // TODO: try to remove -> requires path unpacking changes
ComponentID component;
util::Coordinate location; // this is the coordinate of x
@@ -43,14 +43,14 @@ void insertSourceInForwardHeap(Heap &forward_heap, const PhantomNode &source)
if (source.IsValidForwardSource())
{
forward_heap.Insert(source.forward_segment_id.id,
-source.GetForwardWeightPlusOffset(),
EdgeWeight{0} - source.GetForwardWeightPlusOffset(),
source.forward_segment_id.id);
}
if (source.IsValidReverseSource())
{
forward_heap.Insert(source.reverse_segment_id.id,
-source.GetReverseWeightPlusOffset(),
EdgeWeight{0} - source.GetReverseWeightPlusOffset(),
source.reverse_segment_id.id);
}
}
@@ -127,18 +127,18 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNodeCandidates &
if (phantom_node.IsValidForwardSource())
{
heap.Insert(phantom_node.forward_segment_id.id,
-phantom_node.GetForwardWeightPlusOffset(),
EdgeWeight{0} - phantom_node.GetForwardWeightPlusOffset(),
{phantom_node.forward_segment_id.id,
-phantom_node.GetForwardDuration(),
-phantom_node.GetForwardDistance()});
EdgeDuration{0} - phantom_node.GetForwardDuration(),
EdgeDistance{0} - phantom_node.GetForwardDistance()});
}
if (phantom_node.IsValidReverseSource())
{
heap.Insert(phantom_node.reverse_segment_id.id,
-phantom_node.GetReverseWeightPlusOffset(),
EdgeWeight{0} - phantom_node.GetReverseWeightPlusOffset(),
{phantom_node.reverse_segment_id.id,
-phantom_node.GetReverseDuration(),
-phantom_node.GetReverseDistance()});
EdgeDuration{0} - phantom_node.GetReverseDuration(),
EdgeDistance{0} - phantom_node.GetReverseDistance()});
}
}
}
@@ -251,25 +251,24 @@ void annotatePath(const FacadeT &facade,
BOOST_ASSERT(start_index < end_index);
for (std::size_t segment_idx = start_index; segment_idx < end_index; ++segment_idx)
{
unpacked_path.push_back(
PathData{node_id,
id_vector[segment_idx + 1],
static_cast<EdgeWeight>(weight_vector[segment_idx]),
0,
static_cast<EdgeDuration>(duration_vector[segment_idx]),
0,
datasource_vector[segment_idx],
boost::none});
unpacked_path.push_back(PathData{node_id,
id_vector[segment_idx + 1],
alias_cast<EdgeWeight>(weight_vector[segment_idx]),
{0},
alias_cast<EdgeDuration>(duration_vector[segment_idx]),
{0},
datasource_vector[segment_idx],
boost::none});
}
BOOST_ASSERT(!unpacked_path.empty());
const auto turn_duration = facade.GetDurationPenaltyForEdgeID(turn_id);
const auto turn_weight = facade.GetWeightPenaltyForEdgeID(turn_id);
unpacked_path.back().duration_until_turn += turn_duration;
unpacked_path.back().duration_of_turn = turn_duration;
unpacked_path.back().weight_until_turn += turn_weight;
unpacked_path.back().weight_of_turn = turn_weight;
unpacked_path.back().duration_until_turn += alias_cast<EdgeDuration>(turn_duration);
unpacked_path.back().duration_of_turn = alias_cast<EdgeDuration>(turn_duration);
unpacked_path.back().weight_until_turn += alias_cast<EdgeWeight>(turn_weight);
unpacked_path.back().weight_of_turn = alias_cast<EdgeWeight>(turn_weight);
unpacked_path.back().turn_edge = turn_id;
}
@@ -311,10 +310,10 @@ void annotatePath(const FacadeT &facade,
unpacked_path.push_back(
PathData{target_node_id,
id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1],
static_cast<EdgeWeight>(weight_vector[segment_idx]),
0,
static_cast<EdgeDuration>(duration_vector[segment_idx]),
0,
alias_cast<EdgeWeight>(weight_vector[segment_idx]),
{0},
alias_cast<EdgeDuration>(duration_vector[segment_idx]),
{0},
datasource_vector[segment_idx],
boost::none});
}
@@ -341,9 +340,9 @@ void annotatePath(const FacadeT &facade,
// node to the first turn would be the same as from end to end of a segment,
// which is obviously incorrect and not ideal...
unpacked_path.front().weight_until_turn =
std::max(unpacked_path.front().weight_until_turn - source_weight, 0);
std::max(unpacked_path.front().weight_until_turn - source_weight, {0});
unpacked_path.front().duration_until_turn =
std::max(unpacked_path.front().duration_until_turn - source_duration, 0);
std::max(unpacked_path.front().duration_until_turn - source_duration, {0});
}
}
@@ -410,7 +409,7 @@ template <typename FacadeT> EdgeDistance computeEdgeDistance(const FacadeT &faca
{
const auto geometry_index = facade.GetGeometryIndex(node_id);
EdgeDistance total_distance = 0.0;
EdgeDistance total_distance = {0};
auto geometry_range = facade.GetUncompressedForwardGeometry(geometry_index.id);
for (auto current = geometry_range.begin(); current < geometry_range.end() - 1; ++current)
@@ -34,7 +34,7 @@ bool stallAtNode(const DataFacade<Algorithm> &facade,
{
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
BOOST_ASSERT_MSG(edge_weight > EdgeWeight{0}, "edge_weight invalid");
const auto toHeapNode = query_heap.GetHeapNodeIfWasInserted(to);
if (toHeapNode)
{
@@ -61,7 +61,7 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
const NodeID to = facade.GetTarget(edge);
const EdgeWeight edge_weight = data.weight;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
BOOST_ASSERT_MSG(edge_weight > EdgeWeight{0}, "edge_weight invalid");
const EdgeWeight to_weight = heapNode.weight + edge_weight;
const auto toHeapNode = heap.GetHeapNodeIfWasInserted(to);
@@ -135,7 +135,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
force_loop(force_loop_reverse_nodes, heapNode) ||
// in this case we are looking at a bi-directional way where the source
// and target phantom are on the same edge based node
new_weight < 0)
new_weight < EdgeWeight{0})
{
// check whether there is a loop present at the node
for (const auto edge : facade.GetAdjacentEdgeRange(heapNode.node))
@@ -148,7 +148,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
{
const EdgeWeight edge_weight = data.weight;
const EdgeWeight loop_weight = new_weight + edge_weight;
if (loop_weight >= 0 && loop_weight < upper_bound)
if (loop_weight >= EdgeWeight{0} && loop_weight < upper_bound)
{
middle_node_id = heapNode.node;
upper_bound = loop_weight;
@@ -159,7 +159,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
}
else
{
BOOST_ASSERT(new_weight >= 0);
BOOST_ASSERT(new_weight >= EdgeWeight{0});
middle_node_id = heapNode.node;
upper_bound = new_weight;
@@ -169,7 +169,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
// make sure we don't terminate too early if we initialize the weight
// for the nodes in the forward heap with the forward/reverse offset
BOOST_ASSERT(min_edge_offset <= 0);
BOOST_ASSERT(min_edge_offset <= EdgeWeight{0});
if (heapNode.weight + min_edge_offset > upper_bound)
{
forward_heap.DeleteAll();
@@ -185,31 +185,6 @@ void routingStep(const DataFacade<Algorithm> &facade,
relaxOutgoingEdges<DIRECTION>(facade, heapNode, forward_heap);
}
template <bool UseDuration>
std::tuple<EdgeWeight, EdgeDistance> getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
{
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
EdgeDistance loop_distance = MAXIMAL_EDGE_DISTANCE;
for (auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
if (data.forward)
{
const NodeID to = facade.GetTarget(edge);
if (to == node)
{
const auto value = UseDuration ? data.duration : data.weight;
if (value < loop_weight)
{
loop_weight = value;
loop_distance = data.distance;
}
}
}
}
return std::make_tuple(loop_weight, loop_distance);
}
/**
* Given a sequence of connected `NodeID`s in the CH graph, performs a depth-first unpacking of
* the shortcut
@@ -301,7 +276,7 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
// Make sure we have at least something to unpack
if (packed_path_begin == packed_path_end ||
std::distance(packed_path_begin, packed_path_end) <= 1)
return 0;
return {0};
std::stack<std::tuple<NodeID, NodeID, bool>> recursion_stack;
std::stack<EdgeDistance> distance_stack;
@@ -383,7 +358,7 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
}
}
EdgeDistance total_distance = 0;
EdgeDistance total_distance = {0};
while (!distance_stack.empty())
{
total_distance += distance_stack.top();
@@ -505,8 +480,48 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
SearchEngineData<Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
int duration_upper_bound = INVALID_EDGE_WEIGHT);
EdgeWeight duration_upper_bound = INVALID_EDGE_WEIGHT);
template <typename EdgeMetric>
std::tuple<EdgeMetric, EdgeDistance> getLoopMetric(const DataFacade<Algorithm> &facade, NodeID node)
{
EdgeMetric loop_metric;
if constexpr (std::is_same<EdgeMetric, EdgeDuration>::value)
{
loop_metric = INVALID_EDGE_DURATION;
}
else
{
loop_metric = INVALID_EDGE_WEIGHT;
}
EdgeDistance loop_distance = MAXIMAL_EDGE_DISTANCE;
for (auto edge : facade.GetAdjacentEdgeRange(node))
{
const auto &data = facade.GetEdgeData(edge);
if (data.forward)
{
const NodeID to = facade.GetTarget(edge);
if (to == node)
{
EdgeMetric value;
if constexpr (std::is_same<EdgeMetric, EdgeDuration>::value)
{
value = to_alias<EdgeDuration>(data.duration);
}
else
{
value = data.weight;
}
if (value < loop_metric)
{
loop_metric = value;
loop_distance = data.distance;
}
}
}
}
return std::make_tuple(loop_metric, loop_distance);
}
} // namespace ch
} // namespace routing_algorithms
} // namespace engine
@@ -363,7 +363,8 @@ void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
// TODO: BOOST_ASSERT(edge_data.weight == node_weight + turn_penalty);
const EdgeWeight to_weight = heapNode.weight + node_weight + turn_penalty;
const EdgeWeight to_weight =
heapNode.weight + node_weight + alias_cast<EdgeWeight>(turn_penalty);
const auto toHeapNode = forward_heap.GetHeapNodeIfWasInserted(to);
if (!toHeapNode)
@@ -410,7 +411,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
// MLD uses loops forcing only to prune single node paths in forward and/or
// backward direction (there is no need to force loops in MLD but in CH)
if (!force_loop(force_loop_forward_nodes, heapNode) &&
!force_loop(force_loop_reverse_nodes, heapNode) && (path_weight >= 0) &&
!force_loop(force_loop_reverse_nodes, heapNode) && (path_weight >= EdgeWeight{0}) &&
(path_weight < path_upper_bound))
{
middle_node = heapNode.node;
@@ -529,8 +530,8 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
// Here heaps can be reused, let's go deeper!
forward_heap.Clear();
reverse_heap.Clear();
forward_heap.Insert(source, 0, {source});
reverse_heap.Insert(target, 0, {target});
forward_heap.Insert(source, {0}, {source});
reverse_heap.Insert(target, {0}, {target});
// TODO: when structured bindings will be allowed change to
// auto [subpath_weight, subpath_source, subpath_target, subpath] = ...
@@ -292,7 +292,7 @@ shortestPathWithWaypointUTurns(SearchEngineData<Algorithm> &engine_working_data,
const std::vector<PhantomNodeCandidates> &waypoint_candidates)
{
EdgeWeight total_weight = 0;
EdgeWeight total_weight = {0};
std::vector<NodeID> total_packed_path;
std::vector<std::size_t> packed_leg_begin;
@@ -467,8 +467,8 @@ struct route_state
route_state(const PhantomNodeCandidates &init_candidates)
: current_leg(0), previous_leg_path_offset(0)
{
last.total_weight_to_forward.resize(init_candidates.size(), 0);
last.total_weight_to_reverse.resize(init_candidates.size(), 0);
last.total_weight_to_forward.resize(init_candidates.size(), {0});
last.total_weight_to_reverse.resize(init_candidates.size(), {0});
// Initialize routability from source validity.
std::transform(
init_candidates.begin(),
@@ -23,7 +23,7 @@ struct TurnData final
const int in_angle;
const int turn_angle;
const EdgeWeight weight;
const EdgeWeight duration;
const EdgeDuration duration;
const guidance::TurnInstruction turn_instruction;
};
+5 -5
View File
@@ -29,9 +29,9 @@ struct HeapData
struct ManyToManyHeapData : HeapData
{
EdgeWeight duration;
EdgeDuration duration;
EdgeDistance distance;
ManyToManyHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
ManyToManyHeapData(NodeID p, EdgeDuration duration, EdgeDistance distance)
: HeapData(p), duration(duration), distance(distance)
{
}
@@ -78,15 +78,15 @@ struct MultiLayerDijkstraHeapData
struct ManyToManyMultiLayerDijkstraHeapData : MultiLayerDijkstraHeapData
{
EdgeWeight duration;
EdgeDuration duration;
EdgeDistance distance;
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeWeight duration, EdgeDistance distance)
ManyToManyMultiLayerDijkstraHeapData(NodeID p, EdgeDuration duration, EdgeDistance distance)
: MultiLayerDijkstraHeapData(p), duration(duration), distance(distance)
{
}
ManyToManyMultiLayerDijkstraHeapData(NodeID p,
bool from,
EdgeWeight duration,
EdgeDuration duration,
EdgeDistance distance)
: MultiLayerDijkstraHeapData(p, from), duration(duration), distance(distance)
{
+14 -13
View File
@@ -23,12 +23,12 @@ namespace trip
{
// computes the distance of a given permutation
inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_table,
const std::vector<NodeID> &location_order,
const EdgeWeight min_route_dist,
const std::size_t number_of_locations)
inline EdgeDuration ReturnDistance(const util::DistTableWrapper<EdgeDuration> &dist_table,
const std::vector<NodeID> &location_order,
const EdgeDuration min_route_dist,
const std::size_t number_of_locations)
{
EdgeWeight route_dist = 0;
EdgeDuration route_dist = {0};
std::size_t current_index = 0;
while (current_index < location_order.size() && (route_dist < min_route_dist))
{
@@ -36,12 +36,13 @@ inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_
std::size_t next_index = (current_index + 1) % number_of_locations;
auto edge_weight = dist_table(location_order[current_index], location_order[next_index]);
// If the edge_weight is very large (INVALID_EDGE_WEIGHT) then the algorithm will not choose
// this edge in final minimal path. So instead of computing all the permutations after this
// large edge, discard this edge right here and don't consider the path after this edge.
if (edge_weight == INVALID_EDGE_WEIGHT)
// If the edge_weight is very large (INVALID_EDGE_DURATION) then the algorithm will not
// choose this edge in final minimal path. So instead of computing all the permutations
// after this large edge, discard this edge right here and don't consider the path after
// this edge.
if (edge_weight == INVALID_EDGE_DURATION)
{
return INVALID_EDGE_WEIGHT;
return INVALID_EDGE_DURATION;
}
else
{
@@ -50,7 +51,7 @@ inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_
// This boost assert should not be reached if TFSE table
BOOST_ASSERT_MSG(dist_table(location_order[current_index], location_order[next_index]) !=
INVALID_EDGE_WEIGHT,
INVALID_EDGE_DURATION,
"invalid route found");
++current_index;
}
@@ -60,14 +61,14 @@ inline EdgeWeight ReturnDistance(const util::DistTableWrapper<EdgeWeight> &dist_
// computes the route by computing all permutations and selecting the shortest
inline std::vector<NodeID> BruteForceTrip(const std::size_t number_of_locations,
const util::DistTableWrapper<EdgeWeight> &dist_table)
const util::DistTableWrapper<EdgeDuration> &dist_table)
{
// set initial order in which nodes are visited to 0, 1, 2, 3, ...
std::vector<NodeID> node_order(number_of_locations);
std::iota(std::begin(node_order), std::end(node_order), 0);
std::vector<NodeID> route = node_order;
EdgeWeight min_route_dist = INVALID_EDGE_WEIGHT;
EdgeDuration min_route_dist = INVALID_EDGE_DURATION;
// check length of all possible permutation of the component ids
BOOST_ASSERT_MSG(node_order.size() > 0, "no order permutation given");
+13 -12
View File
@@ -23,15 +23,15 @@ namespace trip
// given a route and a new location, find the best place of insertion and
// check the distance of roundtrip when the new location is additionally visited
using NodeIDIter = std::vector<NodeID>::iterator;
inline std::pair<EdgeWeight, NodeIDIter>
inline std::pair<EdgeDuration, NodeIDIter>
GetShortestRoundTrip(const NodeID new_loc,
const util::DistTableWrapper<EdgeWeight> &dist_table,
const util::DistTableWrapper<EdgeDuration> &dist_table,
const std::size_t number_of_locations,
std::vector<NodeID> &route)
{
(void)number_of_locations; // unused
auto min_trip_distance = INVALID_EDGE_WEIGHT;
auto min_trip_distance = INVALID_EDGE_DURATION;
NodeIDIter next_insert_point_candidate;
// for all nodes in the current trip find the best insertion resulting in the shortest path
@@ -48,10 +48,11 @@ GetShortestRoundTrip(const NodeID new_loc,
const auto dist_from = dist_table(*from_node, new_loc);
const auto dist_to = dist_table(new_loc, *to_node);
// If the edge_weight is very large (INVALID_EDGE_WEIGHT) then the algorithm will not choose
// this edge in final minimal path. So instead of computing all the permutations after this
// large edge, discard this edge right here and don't consider the path after this edge.
if (dist_from == INVALID_EDGE_WEIGHT || dist_to == INVALID_EDGE_WEIGHT)
// If the edge_weight is very large (INVALID_EDGE_DURATION) then the algorithm will not
// choose this edge in final minimal path. So instead of computing all the permutations
// after this large edge, discard this edge right here and don't consider the path after
// this edge.
if (dist_from == INVALID_EDGE_DURATION || dist_to == INVALID_EDGE_DURATION)
continue;
const auto trip_dist = dist_from + dist_to - dist_table(*from_node, *to_node);
@@ -71,14 +72,14 @@ GetShortestRoundTrip(const NodeID new_loc,
next_insert_point_candidate = to_node;
}
}
BOOST_ASSERT_MSG(min_trip_distance != INVALID_EDGE_WEIGHT, "trip has invalid edge weight");
BOOST_ASSERT_MSG(min_trip_distance != INVALID_EDGE_DURATION, "trip has invalid edge weight");
return std::make_pair(min_trip_distance, next_insert_point_candidate);
}
// given two initial start nodes, find a roundtrip route using the farthest insertion algorithm
inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
const util::DistTableWrapper<EdgeWeight> &dist_table,
const util::DistTableWrapper<EdgeDuration> &dist_table,
const NodeID &start1,
const NodeID &start2)
{
@@ -99,7 +100,7 @@ inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
// two nodes are already in the initial start trip, so we need to add all other nodes
for (std::size_t added_nodes = 2; added_nodes < number_of_locations; ++added_nodes)
{
auto farthest_distance = std::numeric_limits<int>::min();
auto farthest_distance = EdgeDuration{std::numeric_limits<EdgeDuration::value_type>::min()};
auto next_node = -1;
NodeIDIter next_insert_point;
@@ -112,7 +113,7 @@ inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
const auto insert_candidate =
GetShortestRoundTrip(id, dist_table, number_of_locations, route);
BOOST_ASSERT_MSG(insert_candidate.first != INVALID_EDGE_WEIGHT,
BOOST_ASSERT_MSG(insert_candidate.first != INVALID_EDGE_DURATION,
"shortest round trip is invalid");
// add the location to the current trip such that it results in the shortest total
@@ -137,7 +138,7 @@ inline std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
inline std::vector<NodeID>
FarthestInsertionTrip(const std::size_t number_of_locations,
const util::DistTableWrapper<EdgeWeight> &dist_table)
const util::DistTableWrapper<EdgeDuration> &dist_table)
{
//////////////////////////////////////////////////////////////////////////////////////////////////
// START FARTHEST INSERTION HERE
@@ -44,8 +44,8 @@ class CompressedEdgeContainer
void AddUncompressedEdge(const EdgeID edge_id,
const NodeID target_node,
const SegmentWeight weight,
const SegmentWeight duration);
const EdgeWeight weight,
const EdgeDuration duration);
void InitializeBothwayVector();
unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos);
@@ -67,8 +67,8 @@ class CompressedEdgeContainer
std::unique_ptr<SegmentDataContainer> ToSegmentData();
private:
SegmentWeight ClipWeight(const SegmentWeight weight);
SegmentDuration ClipDuration(const SegmentDuration duration);
SegmentWeight ClipWeight(const EdgeWeight weight);
SegmentDuration ClipDuration(const EdgeDuration duration);
int free_list_maximum = 0;
std::atomic_size_t clipped_weights{0};
+5 -5
View File
@@ -16,14 +16,14 @@ struct EdgeBasedEdge
struct EdgeData
{
EdgeData()
: turn_id(0), weight(0), distance(0), duration(0), forward(false), backward(false)
: turn_id(0), weight{0}, distance{0}, duration(0), forward(false), backward(false)
{
}
EdgeData(const NodeID turn_id,
const EdgeWeight weight,
const EdgeDistance distance,
const EdgeWeight duration,
const EdgeDuration duration,
const bool forward,
const bool backward)
: turn_id(turn_id), weight(weight), distance(distance), duration(duration),
@@ -34,7 +34,7 @@ struct EdgeBasedEdge
NodeID turn_id; // ID of the edge based node (node based edge)
EdgeWeight weight;
EdgeDistance distance;
EdgeWeight duration : 30;
EdgeDuration::value_type duration : 30;
std::uint32_t forward : 1;
std::uint32_t backward : 1;
@@ -47,7 +47,7 @@ struct EdgeBasedEdge
const NodeID target,
const NodeID edge_id,
const EdgeWeight weight,
const EdgeWeight duration,
const EdgeDuration duration,
const EdgeDistance distance,
const bool forward,
const bool backward);
@@ -72,7 +72,7 @@ inline EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
const NodeID target,
const NodeID turn_id,
const EdgeWeight weight,
const EdgeWeight duration,
const EdgeDuration duration,
const EdgeDistance distance,
const bool forward,
const bool backward)
@@ -93,7 +93,7 @@ class EdgeBasedGraphFactory
void GetEdgeBasedEdges(util::DeallocatingVector<EdgeBasedEdge> &edges);
void GetEdgeBasedNodeSegments(std::vector<EdgeBasedNodeSegment> &nodes);
void GetEdgeBasedNodeWeights(std::vector<EdgeWeight> &output_node_weights);
void GetEdgeBasedNodeDurations(std::vector<EdgeWeight> &output_node_durations);
void GetEdgeBasedNodeDurations(std::vector<EdgeDuration> &output_node_durations);
void GetEdgeBasedNodeDistances(std::vector<EdgeDistance> &output_node_distances);
std::uint32_t GetConnectivityChecksum() const;
@@ -63,7 +63,7 @@ struct InternalExtractorEdge
WeightData weight_data,
DurationData duration_data,
util::Coordinate source_coordinate)
: result(source, target, 0, 0, 0, {}, -1, {}), weight_data(weight_data),
: result(source, target, {0}, {0}, {0}, {}, -1, {}), weight_data(weight_data),
duration_data(duration_data), source_coordinate(source_coordinate)
{
}
+1 -1
View File
@@ -141,7 +141,7 @@ inline NodeBasedEdgeClassification::NodeBasedEdgeClassification()
}
inline NodeBasedEdge::NodeBasedEdge()
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), weight(0), duration(0), distance(0),
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), weight{0}, duration{0}, distance{0},
annotation_data(-1)
{
}
+1 -1
View File
@@ -6,8 +6,8 @@
#include "util/typedefs.hpp"
#include <boost/range/adaptor/filtered.hpp>
#include <boost/unordered_map.hpp>
#include <unordered_map>
#include <utility>
#include <vector>
+1 -1
View File
@@ -114,7 +114,7 @@ struct ProfileProperties
double GetMaxTurnWeight() const
{
return std::numeric_limits<TurnPenalty>::max() / GetWeightMultiplier();
return from_alias<double>(MAXIMAL_TURN_PENALTY) / GetWeightMultiplier();
}
//! penalty to cross a traffic light in deci-seconds
+5 -3
View File
@@ -2,11 +2,13 @@
#define OSRM_EXTRACTOR_RESTRICTION_GRAPH_HPP_
#include <boost/assert.hpp>
#include <boost/unordered_map.hpp>
#include "util/node_based_graph.hpp"
#include "util/std_hash.hpp"
#include "util/typedefs.hpp"
#include <unordered_map>
namespace osrm
{
namespace extractor
@@ -112,10 +114,10 @@ struct RestrictionGraph
RestrictionRange GetRestrictions(RestrictionID id) const;
// A compressed node-based edge can only have one start node in the restriction graph.
boost::unordered_map<EdgeKey, RestrictionID> start_edge_to_node{};
std::unordered_map<EdgeKey, RestrictionID> start_edge_to_node{};
// A compressed node-based edge can have multiple via nodes in the restriction graph
// (as the compressed edge can appear in paths with different prefixes).
boost::unordered_multimap<EdgeKey, RestrictionID> via_edge_to_node{};
std::unordered_multimap<EdgeKey, RestrictionID> via_edge_to_node{};
std::vector<RestrictionNode> nodes;
// TODO: Investigate reusing DynamicGraph. Currently it requires specific attributes
// (e.g. reversed, weight) that would not make sense for restrictions.
@@ -2,9 +2,9 @@
#define OSRM_EXTRACTOR_TRAFFIC_SIGNALS_HPP
#include "util/typedefs.hpp"
#include <unordered_set>
#include <boost/unordered_set.hpp>
#include <boost/functional/hash.hpp>
#include <unordered_set>
namespace osrm
{
+4 -4
View File
@@ -3,7 +3,7 @@
#include "util/typedefs.hpp"
#include <boost/unordered_map.hpp>
#include <unordered_map>
#include <vector>
namespace osrm
@@ -43,9 +43,9 @@ class TurnPathCompressor
// via nodes are the same.
// Similarly, we do not compress the instruction via node in a maneuver override, as we need
// this to identify the location of the maneuver during routing path-processing.
boost::unordered_multimap<NodeID, TurnPath *> starts;
boost::unordered_multimap<NodeID, TurnPath *> vias;
boost::unordered_multimap<NodeID, TurnPath *> ends;
std::unordered_multimap<NodeID, TurnPath *> starts;
std::unordered_multimap<NodeID, TurnPath *> vias;
std::unordered_multimap<NodeID, TurnPath *> ends;
};
} // namespace extractor
+5 -6
View File
@@ -1,17 +1,16 @@
#ifndef OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
#define OSRM_EXTRACTOR_WAY_RESTRICTION_MAP_HPP_
#include <utility>
#include <vector>
// to access the turn restrictions
#include <boost/unordered_map.hpp>
#include "extractor/restriction.hpp"
#include "extractor/restriction_graph.hpp"
#include "util/integer_range.hpp"
#include "util/typedefs.hpp"
// to access the turn restrictions
#include <unordered_map>
#include <utility>
#include <vector>
namespace osrm
{
namespace extractor
@@ -41,8 +41,8 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
directed.emplace_back(edge.source,
edge.target,
edge.data.turn_id,
std::max(edge.data.weight, 1),
edge.data.duration,
std::max(edge.data.weight, {1}),
to_alias<EdgeDuration>(edge.data.duration),
edge.data.distance,
edge.data.forward,
edge.data.backward);
@@ -50,8 +50,8 @@ splitBidirectionalEdges(const std::vector<extractor::EdgeBasedEdge> &edges)
directed.emplace_back(edge.target,
edge.source,
edge.data.turn_id,
std::max(edge.data.weight, 1),
edge.data.duration,
std::max(edge.data.weight, {1}),
to_alias<EdgeDuration>(edge.data.duration),
edge.data.distance,
edge.data.backward,
edge.data.forward);
+35
View File
@@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OSRM_UTIL_ALIAS_HPP
#define OSRM_UTIL_ALIAS_HPP
#include <boost/numeric/conversion/cast.hpp>
#include <functional>
#include <iostream>
#include <type_traits>
@@ -125,6 +126,40 @@ template <typename From, typename Tag> struct Alias final
}
};
template <typename ToAlias, typename FromAlias> inline ToAlias alias_cast(const FromAlias &from)
{
static_assert(std::is_arithmetic<typename FromAlias::value_type>::value,
"Alias From needs to be based on an arithmetic type");
static_assert(std::is_arithmetic<typename ToAlias::value_type>::value,
"Alias Other needs to be based on an arithmetic type");
return {static_cast<typename ToAlias::value_type>(
static_cast<const typename FromAlias::value_type>(from))};
}
template <typename ToNumeric, typename FromAlias> inline ToNumeric from_alias(const FromAlias &from)
{
static_assert(std::is_arithmetic<typename FromAlias::value_type>::value,
"Alias From needs to be based on an arithmetic type");
static_assert(std::is_arithmetic<ToNumeric>::value, "Numeric needs to be an arithmetic type");
return {static_cast<ToNumeric>(static_cast<const typename FromAlias::value_type>(from))};
}
template <typename ToAlias,
typename FromNumeric,
typename = std::enable_if_t<!std::is_same<ToAlias, FromNumeric>::value>>
inline ToAlias to_alias(const FromNumeric &from)
{
static_assert(std::is_arithmetic<FromNumeric>::value, "Numeric needs to be an arithmetic type");
static_assert(std::is_arithmetic<typename ToAlias::value_type>::value,
"Alias needs to be based on an arithmetic type");
return {static_cast<typename ToAlias::value_type>(from)};
}
// Sometimes metrics are stored either as bitfields or the alias itself.
// So we'll try to convert to alias without knowing which is the case.
// Therefore, we need this no-op overload, otherwise it will fail on the arithmetic requirement.
template <typename ToAlias> inline ToAlias to_alias(const ToAlias &from) { return from; }
template <typename From, typename Tag>
inline std::ostream &operator<<(std::ostream &stream, const Alias<From, Tag> &inst)
{
+2 -2
View File
@@ -34,7 +34,7 @@ template <typename T> class DistTableWrapper
std::size_t size() const { return table_.size(); }
EdgeWeight operator()(NodeID from, NodeID to) const
T operator()(NodeID from, NodeID to) const
{
BOOST_ASSERT_MSG(from < number_of_nodes_, "from ID is out of bound");
BOOST_ASSERT_MSG(to < number_of_nodes_, "to ID is out of bound");
@@ -46,7 +46,7 @@ template <typename T> class DistTableWrapper
return table_[index];
}
void SetValue(NodeID from, NodeID to, EdgeWeight value)
void SetValue(NodeID from, NodeID to, T value)
{
BOOST_ASSERT_MSG(from < number_of_nodes_, "from ID is out of bound");
BOOST_ASSERT_MSG(to < number_of_nodes_, "to ID is out of bound");
+6 -6
View File
@@ -21,14 +21,14 @@ namespace util
struct NodeBasedEdgeData
{
NodeBasedEdgeData()
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_WEIGHT),
: weight(INVALID_EDGE_WEIGHT), duration(INVALID_EDGE_DURATION),
distance(INVALID_EDGE_DISTANCE), geometry_id({0, false}), reversed(false),
annotation_data(-1)
{
}
NodeBasedEdgeData(EdgeWeight weight,
EdgeWeight duration,
EdgeDuration duration,
EdgeDistance distance,
GeometryID geometry_id,
bool reversed,
@@ -40,7 +40,7 @@ struct NodeBasedEdgeData
}
EdgeWeight weight;
EdgeWeight duration;
EdgeDuration duration;
EdgeDistance distance;
GeometryID geometry_id;
bool reversed : 1;
@@ -88,9 +88,9 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
output_edge.data.flags = input_edge.flags;
output_edge.data.annotation_data = input_edge.annotation_data;
BOOST_ASSERT(output_edge.data.weight > 0);
BOOST_ASSERT(output_edge.data.duration > 0);
BOOST_ASSERT(output_edge.data.distance >= 0);
BOOST_ASSERT(output_edge.data.weight > EdgeWeight{0});
BOOST_ASSERT(output_edge.data.duration > EdgeDuration{0});
BOOST_ASSERT(output_edge.data.distance >= EdgeDistance{0});
});
tbb::parallel_sort(edges_list.begin(), edges_list.end());
+34 -2
View File
@@ -83,19 +83,45 @@ inline T get_upper_half_value(WordT word,
}
template <typename WordT, typename T>
inline WordT set_lower_value(WordT word, WordT mask, std::uint8_t offset, T value)
inline WordT set_lower_value(WordT word,
WordT mask,
std::uint8_t offset,
T value,
typename std::enable_if_t<std::is_integral<T>::value> * = nullptr)
{
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
return (word & ~mask) | ((static_cast<WordT>(value) << offset) & mask);
}
template <typename WordT, typename T>
inline WordT set_upper_value(WordT word, WordT mask, std::uint8_t offset, T value)
inline WordT set_upper_value(WordT word,
WordT mask,
std::uint8_t offset,
T value,
typename std::enable_if_t<std::is_integral<T>::value> * = nullptr)
{
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
return (word & ~mask) | ((static_cast<WordT>(value) >> offset) & mask);
}
template <typename WordT, typename T>
inline WordT set_lower_value(
WordT word, WordT mask, std::uint8_t offset, T value, typename T::value_type * = nullptr)
{
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
return (word & ~mask) |
((static_cast<WordT>(static_cast<typename T::value_type>(value)) << offset) & mask);
}
template <typename WordT, typename T>
inline WordT set_upper_value(
WordT word, WordT mask, std::uint8_t offset, T value, typename T::value_type * = nullptr)
{
static_assert(std::is_unsigned<WordT>::value, "Only unsigned word types supported for now.");
return (word & ~mask) |
((static_cast<WordT>(static_cast<typename T::value_type>(value)) >> offset) & mask);
}
inline bool compare_and_swap(uint64_t *ptr, uint64_t old_value, uint64_t new_value)
{
#if defined(_MSC_VER)
@@ -287,6 +313,12 @@ template <typename T, std::size_t Bits, storage::Ownership Ownership> class Pack
return &container == &other.container && internal_index == other.internal_index;
}
// FIXME: This is needed for tests on Boost ranges to correctly compare Alias values.
template <typename F, typename U> bool operator!=(const osrm::Alias<F, U> value) const
{
return container.get_value(internal_index) != value;
}
friend std::ostream &operator<<(std::ostream &os, const internal_reference &rhs)
{
return os << static_cast<T>(rhs);
+50 -16
View File
@@ -48,7 +48,26 @@ struct osm_way_id
struct duplicated_node
{
};
struct edge_weight
{
};
struct edge_duration
{
};
struct edge_distance
{
};
struct segment_weight
{
};
struct segment_duration
{
};
struct turn_penalty
{
};
} // namespace tag
using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
// clang-tidy fires `bugprone-throw-keyword-missing` here for unknown reason
// NOLINTNEXTLINE(bugprone-throw-keyword-missing)
@@ -77,12 +96,13 @@ using EdgeID = std::uint32_t;
using NameID = std::uint32_t;
using AnnotationID = std::uint32_t;
using PackedGeometryID = std::uint32_t;
using EdgeWeight = std::int32_t;
using EdgeDuration = std::int32_t;
using EdgeDistance = float;
using SegmentWeight = std::uint32_t;
using SegmentDuration = std::uint32_t;
using TurnPenalty = std::int16_t; // turn penalty in 100ms units
using EdgeWeight = osrm::Alias<std::int32_t, tag::edge_weight>;
using EdgeDuration = osrm::Alias<std::int32_t, tag::edge_duration>;
using EdgeDistance = osrm::Alias<float, tag::edge_distance>;
using SegmentWeight = osrm::Alias<std::uint32_t, tag::segment_weight>;
using SegmentDuration = osrm::Alias<std::uint32_t, tag::segment_duration>;
using TurnPenalty = osrm::Alias<std::int16_t, tag::turn_penalty>; // turn penalty in 100ms units
static const std::size_t INVALID_INDEX = std::numeric_limits<std::size_t>::max();
@@ -109,16 +129,30 @@ static const NameID EMPTY_NAMEID = 0;
static const unsigned INVALID_COMPONENTID = 0;
static const std::size_t SEGMENT_WEIGHT_BITS = 22;
static const std::size_t SEGMENT_DURATION_BITS = 22;
static const SegmentWeight INVALID_SEGMENT_WEIGHT = (1u << SEGMENT_WEIGHT_BITS) - 1;
static const SegmentDuration INVALID_SEGMENT_DURATION = (1u << SEGMENT_DURATION_BITS) - 1;
static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - 1;
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - 1;
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<EdgeWeight>::max();
static const EdgeDuration MAXIMAL_EDGE_DURATION = std::numeric_limits<EdgeDuration>::max();
static const EdgeDistance MAXIMAL_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
static const TurnPenalty INVALID_TURN_PENALTY = std::numeric_limits<TurnPenalty>::max();
static const EdgeDistance INVALID_EDGE_DISTANCE = std::numeric_limits<EdgeDistance>::max();
static const EdgeDistance INVALID_FALLBACK_SPEED = std::numeric_limits<EdgeDistance>::max();
static const SegmentWeight INVALID_SEGMENT_WEIGHT = SegmentWeight{(1u << SEGMENT_WEIGHT_BITS) - 1};
static const SegmentDuration INVALID_SEGMENT_DURATION =
SegmentDuration{(1u << SEGMENT_DURATION_BITS) - 1};
static const SegmentWeight MAX_SEGMENT_WEIGHT = INVALID_SEGMENT_WEIGHT - SegmentWeight{1};
static const SegmentDuration MAX_SEGMENT_DURATION = INVALID_SEGMENT_DURATION - SegmentDuration{1};
static const EdgeWeight INVALID_EDGE_WEIGHT =
EdgeWeight{std::numeric_limits<EdgeWeight::value_type>::max()};
static const EdgeDuration INVALID_EDGE_DURATION =
EdgeDuration{std::numeric_limits<EdgeDuration::value_type>::max()};
static const EdgeDistance INVALID_EDGE_DISTANCE =
EdgeDistance{std::numeric_limits<EdgeDistance::value_type>::max()};
static const TurnPenalty INVALID_TURN_PENALTY =
TurnPenalty{std::numeric_limits<TurnPenalty::value_type>::max()};
static const EdgeDistance INVALID_FALLBACK_SPEED =
EdgeDistance{std::numeric_limits<EdgeDistance::value_type>::max()};
// TODO: These are the same as the invalid values. Do we need both?
static const EdgeWeight MAXIMAL_EDGE_WEIGHT =
EdgeWeight{std::numeric_limits<EdgeWeight::value_type>::max()};
static const EdgeDuration MAXIMAL_EDGE_DURATION =
EdgeDuration{std::numeric_limits<EdgeDuration::value_type>::max()};
static const EdgeDistance MAXIMAL_EDGE_DISTANCE =
EdgeDistance{std::numeric_limits<EdgeDistance::value_type>::max()};
static const TurnPenalty MAXIMAL_TURN_PENALTY =
TurnPenalty{std::numeric_limits<TurnPenalty::value_type>::max()};
using DatasourceID = std::uint8_t;