Merge branch 'master' into sf-stop-sign
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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]; }
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user