Upgrade clang-format to version 15 (#6859)
This commit is contained in:
parent
b503e96a98
commit
7f9d591ab7
4
.github/workflows/osrm-backend.yml
vendored
4
.github/workflows/osrm-backend.yml
vendored
@ -71,7 +71,7 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
format-taginfo-docs:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js
|
||||
@ -88,7 +88,7 @@ jobs:
|
||||
- name: Prepare environment
|
||||
run: |
|
||||
npm ci --ignore-scripts
|
||||
clang-format-10 --version
|
||||
clang-format-15 --version
|
||||
- name: Run checks
|
||||
run: |
|
||||
./scripts/check_taginfo.py taginfo.json profiles/car.lua
|
||||
|
@ -13,6 +13,7 @@
|
||||
- REMOVED: Drop support of Node 12 & 14. [#6431](https://github.com/Project-OSRM/osrm-backend/pull/6431)
|
||||
- ADDED: Add 'load directly' mode to default Cucumber test suite. [#6663](https://github.com/Project-OSRM/osrm-backend/pull/6663)
|
||||
- CHANGED: Drop support for Node 16 [#6855](https://github.com/Project-OSRM/osrm-backend/pull/6855)
|
||||
- CHANGED: Upgrade clang-format to version 15 [#6859](https://github.com/Project-OSRM/osrm-backend/pull/6859)
|
||||
- NodeJS:
|
||||
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
|
||||
- Misc:
|
||||
|
@ -10,7 +10,7 @@ You can add a :+1: emoji reaction to the issue if you want to express interest i
|
||||
|
||||
# Developer
|
||||
|
||||
We use `clang-format` version `3.8` to consistently format the code base. There is a helper script under `scripts/format.sh`.
|
||||
We use `clang-format` version `15` to consistently format the code base. There is a helper script under `scripts/format.sh`.
|
||||
The format is automatically checked by the `mason-linux-release` job of a Travis CI build.
|
||||
To save development time a local hook `.git/hooks/pre-push`
|
||||
```
|
||||
|
@ -61,10 +61,12 @@ inline auto contractExcludableGraph(ContractorGraph contractor_graph_,
|
||||
// Add all non-core edges to container
|
||||
{
|
||||
auto non_core_edges = toEdges<QueryEdge>(contractor_graph);
|
||||
auto new_end =
|
||||
std::remove_if(non_core_edges.begin(), non_core_edges.end(), [&](const auto &edge) {
|
||||
return is_shared_core[edge.source] && is_shared_core[edge.target];
|
||||
});
|
||||
auto new_end = std::remove_if(non_core_edges.begin(),
|
||||
non_core_edges.end(),
|
||||
[&](const auto &edge) {
|
||||
return is_shared_core[edge.source] &&
|
||||
is_shared_core[edge.target];
|
||||
});
|
||||
non_core_edges.resize(new_end - non_core_edges.begin());
|
||||
edge_container.Insert(std::move(non_core_edges));
|
||||
|
||||
@ -75,8 +77,8 @@ inline auto contractExcludableGraph(ContractorGraph contractor_graph_,
|
||||
}
|
||||
|
||||
// Extract core graph for further contraction
|
||||
shared_core_graph = contractor_graph.Filter(
|
||||
[&is_shared_core](const NodeID node) { return is_shared_core[node]; });
|
||||
shared_core_graph = contractor_graph.Filter([&is_shared_core](const NodeID node)
|
||||
{ return is_shared_core[node]; });
|
||||
}
|
||||
|
||||
for (const auto &filter : filters)
|
||||
|
@ -89,37 +89,40 @@ struct ContractedEdgeContainer
|
||||
|
||||
// Remove all edges that are contained in the old set of edges and set the appropriate flag.
|
||||
auto new_end =
|
||||
std::remove_if(new_edges.begin(), new_edges.end(), [&](const QueryEdge &edge) {
|
||||
// check if the new edge would be sorted before the currend old edge
|
||||
// if so it is not contained yet in the set of old edges
|
||||
if (edge_iter == edge_end || mergeCompare(edge, *edge_iter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::remove_if(new_edges.begin(),
|
||||
new_edges.end(),
|
||||
[&](const QueryEdge &edge)
|
||||
{
|
||||
// check if the new edge would be sorted before the currend old edge
|
||||
// if so it is not contained yet in the set of old edges
|
||||
if (edge_iter == edge_end || mergeCompare(edge, *edge_iter))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// find the first old edge that is equal or greater then the new edge
|
||||
while (edge_iter != edge_end && mergeCompare(*edge_iter, edge))
|
||||
{
|
||||
BOOST_ASSERT(flags_iter != flags.end());
|
||||
edge_iter++;
|
||||
flags_iter++;
|
||||
}
|
||||
// find the first old edge that is equal or greater then the new edge
|
||||
while (edge_iter != edge_end && mergeCompare(*edge_iter, edge))
|
||||
{
|
||||
BOOST_ASSERT(flags_iter != flags.end());
|
||||
edge_iter++;
|
||||
flags_iter++;
|
||||
}
|
||||
|
||||
// all new edges will be sorted after the old edges
|
||||
if (edge_iter == edge_end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// all new edges will be sorted after the old edges
|
||||
if (edge_iter == edge_end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(edge_iter != edge_end);
|
||||
if (mergable(edge, *edge_iter))
|
||||
{
|
||||
*flags_iter = *flags_iter | flag;
|
||||
return true;
|
||||
}
|
||||
BOOST_ASSERT(mergeCompare(edge, *edge_iter));
|
||||
return false;
|
||||
});
|
||||
BOOST_ASSERT(edge_iter != edge_end);
|
||||
if (mergable(edge, *edge_iter))
|
||||
{
|
||||
*flags_iter = *flags_iter | flag;
|
||||
return true;
|
||||
}
|
||||
BOOST_ASSERT(mergeCompare(edge, *edge_iter));
|
||||
return false;
|
||||
});
|
||||
|
||||
// append new edges
|
||||
edges.insert(edges.end(), new_edges.begin(), new_end);
|
||||
@ -132,10 +135,10 @@ struct ContractedEdgeContainer
|
||||
// enforce sorting for next merge step
|
||||
std::vector<unsigned> ordering(edges_size);
|
||||
std::iota(ordering.begin(), ordering.end(), 0);
|
||||
tbb::parallel_sort(
|
||||
ordering.begin(), ordering.end(), [&](const auto lhs_idx, const auto rhs_idx) {
|
||||
return mergeCompare(edges[lhs_idx], edges[rhs_idx]);
|
||||
});
|
||||
tbb::parallel_sort(ordering.begin(),
|
||||
ordering.end(),
|
||||
[&](const auto lhs_idx, const auto rhs_idx)
|
||||
{ return mergeCompare(edges[lhs_idx], edges[rhs_idx]); });
|
||||
auto permutation = util::orderingToPermutation(ordering);
|
||||
|
||||
util::inplacePermutation(edges.begin(), edges.end(), permutation);
|
||||
|
@ -122,7 +122,8 @@ class CellCustomizer
|
||||
for (std::size_t level = 1; level < partition.GetNumberOfLevels(); ++level)
|
||||
{
|
||||
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, partition.GetNumberOfCells(level)),
|
||||
[&](const tbb::blocked_range<std::size_t> &range) {
|
||||
[&](const tbb::blocked_range<std::size_t> &range)
|
||||
{
|
||||
auto &heap = heaps.local();
|
||||
for (auto id = range.begin(), end = range.end(); id != end; ++id)
|
||||
{
|
||||
|
@ -40,10 +40,10 @@ class BaseAPI
|
||||
util::json::Array waypoints;
|
||||
waypoints.values.resize(parameters.coordinates.size());
|
||||
|
||||
boost::range::transform(
|
||||
waypoint_candidates,
|
||||
waypoints.values.begin(),
|
||||
[this](const PhantomNodeCandidates &candidates) { return MakeWaypoint(candidates); });
|
||||
boost::range::transform(waypoint_candidates,
|
||||
waypoints.values.begin(),
|
||||
[this](const PhantomNodeCandidates &candidates)
|
||||
{ return MakeWaypoint(candidates); });
|
||||
return waypoints;
|
||||
}
|
||||
|
||||
@ -104,9 +104,8 @@ class BaseAPI
|
||||
std::transform(waypoint_candidates.begin(),
|
||||
waypoint_candidates.end(),
|
||||
waypoints.begin(),
|
||||
[this, builder](const PhantomNodeCandidates &candidates) {
|
||||
return MakeWaypoint(builder, candidates)->Finish();
|
||||
});
|
||||
[this, builder](const PhantomNodeCandidates &candidates)
|
||||
{ return MakeWaypoint(builder, candidates)->Finish(); });
|
||||
return builder->CreateVector(waypoints);
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,8 @@ struct BaseParameters
|
||||
(approaches.empty() || approaches.size() == coordinates.size()) &&
|
||||
std::all_of(bearings.begin(),
|
||||
bearings.end(),
|
||||
[](const boost::optional<Bearing> &bearing_and_range) {
|
||||
[](const boost::optional<Bearing> &bearing_and_range)
|
||||
{
|
||||
if (bearing_and_range)
|
||||
{
|
||||
return bearing_and_range->IsValid();
|
||||
|
@ -52,9 +52,10 @@ class MatchAPI final : public RouteAPI
|
||||
data_version_string = fb_result.CreateString(data_timestamp);
|
||||
}
|
||||
|
||||
auto response = MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_matchings]() {
|
||||
return MakeTracepoints(fb_result, sub_matchings);
|
||||
});
|
||||
auto response = MakeFBResponse(sub_routes,
|
||||
fb_result,
|
||||
[this, &fb_result, &sub_matchings]()
|
||||
{ return MakeTracepoints(fb_result, sub_matchings); });
|
||||
|
||||
if (!data_timestamp.empty())
|
||||
{
|
||||
|
@ -67,7 +67,7 @@ struct MatchParameters : public RouteParameters
|
||||
MatchParameters(const std::vector<unsigned> ×tamps_,
|
||||
GapsType gaps_,
|
||||
bool tidy_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: MatchParameters(timestamps_, gaps_, tidy_, {}, std::forward<Args>(args_)...)
|
||||
{
|
||||
}
|
||||
@ -77,7 +77,7 @@ struct MatchParameters : public RouteParameters
|
||||
GapsType gaps_,
|
||||
bool tidy_,
|
||||
const std::vector<std::size_t> &waypoints_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: RouteParameters{std::forward<Args>(args_)..., waypoints_}, timestamps{std::move(
|
||||
timestamps_)},
|
||||
gaps(gaps_), tidy(tidy_)
|
||||
|
@ -57,20 +57,20 @@ class NearestAPI final : public BaseAPI
|
||||
{
|
||||
std::vector<flatbuffers::Offset<fbresult::Waypoint>> waypoints;
|
||||
waypoints.resize(phantom_nodes.front().size());
|
||||
std::transform(
|
||||
phantom_nodes.front().begin(),
|
||||
phantom_nodes.front().end(),
|
||||
waypoints.begin(),
|
||||
[this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance) {
|
||||
auto &phantom_node = phantom_with_distance.phantom_node;
|
||||
std::transform(phantom_nodes.front().begin(),
|
||||
phantom_nodes.front().end(),
|
||||
waypoints.begin(),
|
||||
[this, &fb_result](const PhantomNodeWithDistance &phantom_with_distance)
|
||||
{
|
||||
auto &phantom_node = phantom_with_distance.phantom_node;
|
||||
|
||||
auto node_values = MakeNodes(phantom_node);
|
||||
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
|
||||
auto node_values = MakeNodes(phantom_node);
|
||||
fbresult::Uint64Pair nodes{node_values.first, node_values.second};
|
||||
|
||||
auto waypoint = MakeWaypoint(&fb_result, {phantom_node});
|
||||
waypoint->add_nodes(&nodes);
|
||||
return waypoint->Finish();
|
||||
});
|
||||
auto waypoint = MakeWaypoint(&fb_result, {phantom_node});
|
||||
waypoint->add_nodes(&nodes);
|
||||
return waypoint->Finish();
|
||||
});
|
||||
|
||||
waypoints_vector = fb_result.CreateVector(waypoints);
|
||||
}
|
||||
@ -94,7 +94,8 @@ class NearestAPI final : public BaseAPI
|
||||
std::transform(phantom_nodes.front().begin(),
|
||||
phantom_nodes.front().end(),
|
||||
waypoints.values.begin(),
|
||||
[this](const PhantomNodeWithDistance &phantom_with_distance) {
|
||||
[this](const PhantomNodeWithDistance &phantom_with_distance)
|
||||
{
|
||||
auto &phantom_node = phantom_with_distance.phantom_node;
|
||||
auto waypoint = MakeWaypoint({phantom_node});
|
||||
|
||||
|
@ -77,9 +77,10 @@ class RouteAPI : public BaseAPI
|
||||
}
|
||||
|
||||
auto response =
|
||||
MakeFBResponse(raw_routes, fb_result, [this, &waypoint_candidates, &fb_result]() {
|
||||
return BaseAPI::MakeWaypoints(&fb_result, waypoint_candidates);
|
||||
});
|
||||
MakeFBResponse(raw_routes,
|
||||
fb_result,
|
||||
[this, &waypoint_candidates, &fb_result]()
|
||||
{ return BaseAPI::MakeWaypoints(&fb_result, waypoint_candidates); });
|
||||
|
||||
if (!data_timestamp.empty())
|
||||
{
|
||||
@ -171,10 +172,15 @@ class RouteAPI : public BaseAPI
|
||||
}
|
||||
std::vector<fbresult::Position> coordinates;
|
||||
coordinates.resize(std::distance(begin, end));
|
||||
std::transform(begin, end, coordinates.begin(), [](const Coordinate &c) {
|
||||
return fbresult::Position{static_cast<float>(util::toFloating(c.lon).__value),
|
||||
static_cast<float>(util::toFloating(c.lat).__value)};
|
||||
});
|
||||
std::transform(begin,
|
||||
end,
|
||||
coordinates.begin(),
|
||||
[](const Coordinate &c)
|
||||
{
|
||||
return fbresult::Position{
|
||||
static_cast<float>(util::toFloating(c.lon).__value),
|
||||
static_cast<float>(util::toFloating(c.lat).__value)};
|
||||
});
|
||||
return builder.CreateVectorOfStructs(coordinates);
|
||||
}
|
||||
|
||||
@ -354,9 +360,8 @@ class RouteAPI : public BaseAPI
|
||||
std::transform(leg.steps.begin(),
|
||||
leg.steps.end(),
|
||||
legSteps.begin(),
|
||||
[this, &fb_result, &leg_geometry](auto &step) {
|
||||
return this->MakeFBStep(fb_result, leg_geometry, step);
|
||||
});
|
||||
[this, &fb_result, &leg_geometry](auto &step)
|
||||
{ return this->MakeFBStep(fb_result, leg_geometry, step); });
|
||||
}
|
||||
auto steps_vector = fb_result.CreateVector(legSteps);
|
||||
|
||||
@ -441,7 +446,8 @@ class RouteAPI : public BaseAPI
|
||||
speed =
|
||||
GetAnnotations<float>(fb_result,
|
||||
leg_geometry,
|
||||
[&prev_speed](const guidance::LegGeometry::Annotation &anno) {
|
||||
[&prev_speed](const guidance::LegGeometry::Annotation &anno)
|
||||
{
|
||||
if (anno.duration < std::numeric_limits<float>::min())
|
||||
{
|
||||
return prev_speed;
|
||||
@ -459,37 +465,37 @@ class RouteAPI : public BaseAPI
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration;
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
||||
{
|
||||
duration = GetAnnotations<uint32_t>(
|
||||
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.duration;
|
||||
});
|
||||
duration = GetAnnotations<uint32_t>(fb_result,
|
||||
leg_geometry,
|
||||
[](const guidance::LegGeometry::Annotation &anno)
|
||||
{ return anno.duration; });
|
||||
}
|
||||
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> distance;
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
||||
{
|
||||
distance = GetAnnotations<uint32_t>(
|
||||
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.distance;
|
||||
});
|
||||
distance = GetAnnotations<uint32_t>(fb_result,
|
||||
leg_geometry,
|
||||
[](const guidance::LegGeometry::Annotation &anno)
|
||||
{ return anno.distance; });
|
||||
}
|
||||
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> weight;
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
||||
{
|
||||
weight = GetAnnotations<uint32_t>(
|
||||
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.weight;
|
||||
});
|
||||
weight = GetAnnotations<uint32_t>(fb_result,
|
||||
leg_geometry,
|
||||
[](const guidance::LegGeometry::Annotation &anno)
|
||||
{ return anno.weight; });
|
||||
}
|
||||
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> datasources;
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
||||
{
|
||||
datasources = GetAnnotations<uint32_t>(
|
||||
fb_result, leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.datasource;
|
||||
});
|
||||
datasources = GetAnnotations<uint32_t>(fb_result,
|
||||
leg_geometry,
|
||||
[](const guidance::LegGeometry::Annotation &anno)
|
||||
{ return anno.datasource; });
|
||||
}
|
||||
std::vector<uint32_t> nodes;
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
||||
@ -653,7 +659,8 @@ class RouteAPI : public BaseAPI
|
||||
step.intersections.begin(),
|
||||
step.intersections.end(),
|
||||
intersections.begin(),
|
||||
[&fb_result, this](const guidance::IntermediateIntersection &intersection) {
|
||||
[&fb_result, this](const guidance::IntermediateIntersection &intersection)
|
||||
{
|
||||
std::vector<flatbuffers::Offset<fbresult::Lane>> lanes;
|
||||
if (json::detail::hasValidLanes(intersection))
|
||||
{
|
||||
@ -681,11 +688,11 @@ class RouteAPI : public BaseAPI
|
||||
auto bearings_vector = fb_result.CreateVector(intersection.bearings);
|
||||
std::vector<flatbuffers::Offset<flatbuffers::String>> classes;
|
||||
classes.resize(intersection.classes.size());
|
||||
std::transform(
|
||||
intersection.classes.begin(),
|
||||
intersection.classes.end(),
|
||||
classes.begin(),
|
||||
[&fb_result](const std::string &cls) { return fb_result.CreateString(cls); });
|
||||
std::transform(intersection.classes.begin(),
|
||||
intersection.classes.end(),
|
||||
classes.begin(),
|
||||
[&fb_result](const std::string &cls)
|
||||
{ return fb_result.CreateString(cls); });
|
||||
auto classes_vector = fb_result.CreateVector(classes);
|
||||
auto entry_vector = fb_result.CreateVector(intersection.entry);
|
||||
|
||||
@ -720,9 +727,10 @@ class RouteAPI : public BaseAPI
|
||||
|
||||
std::vector<util::json::Value> step_geometries;
|
||||
const auto total_step_count =
|
||||
std::accumulate(legs.begin(), legs.end(), 0, [](const auto &v, const auto &leg) {
|
||||
return v + leg.steps.size();
|
||||
});
|
||||
std::accumulate(legs.begin(),
|
||||
legs.end(),
|
||||
0,
|
||||
[](const auto &v, const auto &leg) { return v + leg.steps.size(); });
|
||||
step_geometries.reserve(total_step_count);
|
||||
|
||||
for (const auto idx : util::irange<std::size_t>(0UL, legs.size()))
|
||||
@ -733,7 +741,8 @@ class RouteAPI : public BaseAPI
|
||||
legs[idx].steps.begin(),
|
||||
legs[idx].steps.end(),
|
||||
std::back_inserter(step_geometries),
|
||||
[this, &leg_geometry](const guidance::RouteStep &step) {
|
||||
[this, &leg_geometry](const guidance::RouteStep &step)
|
||||
{
|
||||
if (parameters.geometries == RouteParameters::GeometriesType::Polyline)
|
||||
{
|
||||
return static_cast<util::json::Value>(json::makePolyline<100000>(
|
||||
@ -778,7 +787,9 @@ class RouteAPI : public BaseAPI
|
||||
{
|
||||
double prev_speed = 0;
|
||||
annotation.values["speed"] = GetAnnotations(
|
||||
leg_geometry, [&prev_speed](const guidance::LegGeometry::Annotation &anno) {
|
||||
leg_geometry,
|
||||
[&prev_speed](const guidance::LegGeometry::Annotation &anno)
|
||||
{
|
||||
if (anno.duration < std::numeric_limits<double>::min())
|
||||
{
|
||||
return prev_speed;
|
||||
@ -794,17 +805,17 @@ class RouteAPI : public BaseAPI
|
||||
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Duration)
|
||||
{
|
||||
annotation.values["duration"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.duration;
|
||||
});
|
||||
annotation.values["duration"] =
|
||||
GetAnnotations(leg_geometry,
|
||||
[](const guidance::LegGeometry::Annotation &anno)
|
||||
{ return anno.duration; });
|
||||
}
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Distance)
|
||||
{
|
||||
annotation.values["distance"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.distance;
|
||||
});
|
||||
annotation.values["distance"] =
|
||||
GetAnnotations(leg_geometry,
|
||||
[](const guidance::LegGeometry::Annotation &anno)
|
||||
{ return anno.distance; });
|
||||
}
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Weight)
|
||||
{
|
||||
@ -814,10 +825,10 @@ class RouteAPI : public BaseAPI
|
||||
}
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Datasources)
|
||||
{
|
||||
annotation.values["datasources"] = GetAnnotations(
|
||||
leg_geometry, [](const guidance::LegGeometry::Annotation &anno) {
|
||||
return anno.datasource;
|
||||
});
|
||||
annotation.values["datasources"] =
|
||||
GetAnnotations(leg_geometry,
|
||||
[](const guidance::LegGeometry::Annotation &anno)
|
||||
{ return anno.datasource; });
|
||||
}
|
||||
if (requested_annotations & RouteParameters::AnnotationsType::Nodes)
|
||||
{
|
||||
|
@ -83,7 +83,7 @@ struct RouteParameters : public BaseParameters
|
||||
const GeometriesType geometries_,
|
||||
const OverviewType overview_,
|
||||
const boost::optional<bool> continue_straight_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
// Once we perfectly-forward `args` (see #2990) this constructor can delegate to the one
|
||||
// below.
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
@ -101,7 +101,7 @@ struct RouteParameters : public BaseParameters
|
||||
const GeometriesType geometries_,
|
||||
const OverviewType overview_,
|
||||
const boost::optional<bool> continue_straight_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
||||
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
||||
@ -119,7 +119,7 @@ struct RouteParameters : public BaseParameters
|
||||
const GeometriesType geometries_,
|
||||
const OverviewType overview_,
|
||||
const boost::optional<bool> continue_straight_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
number_of_alternatives{alternatives_ ? 1u : 0u},
|
||||
annotations{annotations_ != AnnotationsType::None}, annotations_type{annotations_},
|
||||
@ -137,7 +137,7 @@ struct RouteParameters : public BaseParameters
|
||||
const OverviewType overview_,
|
||||
const boost::optional<bool> continue_straight_,
|
||||
std::vector<std::size_t> waypoints_,
|
||||
const Args &&... args_)
|
||||
const Args &&...args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_},
|
||||
annotations_type{annotations_ ? AnnotationsType::All : AnnotationsType::None},
|
||||
@ -155,7 +155,7 @@ struct RouteParameters : public BaseParameters
|
||||
const OverviewType overview_,
|
||||
const boost::optional<bool> continue_straight_,
|
||||
std::vector<std::size_t> waypoints_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, steps{steps_}, alternatives{alternatives_},
|
||||
number_of_alternatives{alternatives_ ? 1u : 0u}, annotations{annotations_ !=
|
||||
AnnotationsType::None},
|
||||
@ -180,9 +180,9 @@ struct RouteParameters : public BaseParameters
|
||||
const auto coordinates_ok = coordinates.size() >= 2;
|
||||
const auto base_params_ok = BaseParameters::IsValid();
|
||||
const auto valid_waypoints =
|
||||
std::all_of(waypoints.begin(), waypoints.end(), [this](const auto &w) {
|
||||
return w < coordinates.size();
|
||||
});
|
||||
std::all_of(waypoints.begin(),
|
||||
waypoints.end(),
|
||||
[this](const auto &w) { return w < coordinates.size(); });
|
||||
return coordinates_ok && base_params_ok && valid_waypoints;
|
||||
}
|
||||
};
|
||||
|
@ -245,9 +245,8 @@ class TableAPI final : public BaseAPI
|
||||
|
||||
boost::range::transform(candidates,
|
||||
std::back_inserter(waypoints),
|
||||
[this, &builder](const PhantomNodeCandidates &candidates) {
|
||||
return BaseAPI::MakeWaypoint(&builder, candidates)->Finish();
|
||||
});
|
||||
[this, &builder](const PhantomNodeCandidates &candidates)
|
||||
{ return BaseAPI::MakeWaypoint(&builder, candidates)->Finish(); });
|
||||
return builder.CreateVector(waypoints);
|
||||
}
|
||||
|
||||
@ -261,7 +260,8 @@ class TableAPI final : public BaseAPI
|
||||
boost::range::transform(
|
||||
indices,
|
||||
std::back_inserter(waypoints),
|
||||
[this, &builder, &candidates](const std::size_t idx) {
|
||||
[this, &builder, &candidates](const std::size_t idx)
|
||||
{
|
||||
BOOST_ASSERT(idx < candidates.size());
|
||||
return BaseAPI::MakeWaypoint(&builder, candidates[idx])->Finish();
|
||||
});
|
||||
@ -274,14 +274,17 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
std::vector<float> distance_table;
|
||||
distance_table.resize(values.size());
|
||||
std::transform(
|
||||
values.begin(), values.end(), distance_table.begin(), [](const EdgeDuration duration) {
|
||||
if (duration == MAXIMAL_EDGE_DURATION)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
return from_alias<double>(duration) / 10.;
|
||||
});
|
||||
std::transform(values.begin(),
|
||||
values.end(),
|
||||
distance_table.begin(),
|
||||
[](const EdgeDuration duration)
|
||||
{
|
||||
if (duration == MAXIMAL_EDGE_DURATION)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
return from_alias<double>(duration) / 10.;
|
||||
});
|
||||
return builder.CreateVector(distance_table);
|
||||
}
|
||||
|
||||
@ -291,14 +294,17 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
std::vector<float> duration_table;
|
||||
duration_table.resize(values.size());
|
||||
std::transform(
|
||||
values.begin(), values.end(), duration_table.begin(), [](const EdgeDistance distance) {
|
||||
if (distance == INVALID_EDGE_DISTANCE)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
return std::round(from_alias<double>(distance) * 10) / 10.;
|
||||
});
|
||||
std::transform(values.begin(),
|
||||
values.end(),
|
||||
duration_table.begin(),
|
||||
[](const EdgeDistance distance)
|
||||
{
|
||||
if (distance == INVALID_EDGE_DISTANCE)
|
||||
{
|
||||
return 0.;
|
||||
}
|
||||
return std::round(from_alias<double>(distance) * 10) / 10.;
|
||||
});
|
||||
return builder.CreateVector(duration_table);
|
||||
}
|
||||
|
||||
@ -308,11 +314,13 @@ class TableAPI final : public BaseAPI
|
||||
{
|
||||
std::vector<uint32_t> fb_table;
|
||||
fb_table.reserve(fallback_speed_cells.size());
|
||||
std::for_each(
|
||||
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
|
||||
fb_table.push_back(cell.row);
|
||||
fb_table.push_back(cell.column);
|
||||
});
|
||||
std::for_each(fallback_speed_cells.begin(),
|
||||
fallback_speed_cells.end(),
|
||||
[&](const auto &cell)
|
||||
{
|
||||
fb_table.push_back(cell.row);
|
||||
fb_table.push_back(cell.column);
|
||||
});
|
||||
return builder.CreateVector(fb_table);
|
||||
}
|
||||
|
||||
@ -325,9 +333,8 @@ class TableAPI final : public BaseAPI
|
||||
|
||||
boost::range::transform(candidates,
|
||||
std::back_inserter(json_waypoints.values),
|
||||
[this](const PhantomNodeCandidates &candidates) {
|
||||
return BaseAPI::MakeWaypoint(candidates);
|
||||
});
|
||||
[this](const PhantomNodeCandidates &candidates)
|
||||
{ return BaseAPI::MakeWaypoint(candidates); });
|
||||
return json_waypoints;
|
||||
}
|
||||
|
||||
@ -338,7 +345,8 @@ class TableAPI final : public BaseAPI
|
||||
json_waypoints.values.reserve(indices.size());
|
||||
boost::range::transform(indices,
|
||||
std::back_inserter(json_waypoints.values),
|
||||
[this, &candidates](const std::size_t idx) {
|
||||
[this, &candidates](const std::size_t idx)
|
||||
{
|
||||
BOOST_ASSERT(idx < candidates.size());
|
||||
return BaseAPI::MakeWaypoint(candidates[idx]);
|
||||
});
|
||||
@ -359,7 +367,8 @@ class TableAPI final : public BaseAPI
|
||||
std::transform(row_begin_iterator,
|
||||
row_end_iterator,
|
||||
json_row.values.begin(),
|
||||
[](const EdgeDuration duration) {
|
||||
[](const EdgeDuration duration)
|
||||
{
|
||||
if (duration == MAXIMAL_EDGE_DURATION)
|
||||
{
|
||||
return util::json::Value(util::json::Null());
|
||||
@ -387,7 +396,8 @@ class TableAPI final : public BaseAPI
|
||||
std::transform(row_begin_iterator,
|
||||
row_end_iterator,
|
||||
json_row.values.begin(),
|
||||
[](const EdgeDistance distance) {
|
||||
[](const EdgeDistance distance)
|
||||
{
|
||||
if (distance == INVALID_EDGE_DISTANCE)
|
||||
{
|
||||
return util::json::Value(util::json::Null());
|
||||
@ -405,13 +415,15 @@ class TableAPI final : public BaseAPI
|
||||
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
|
||||
{
|
||||
util::json::Array json_table;
|
||||
std::for_each(
|
||||
fallback_speed_cells.begin(), fallback_speed_cells.end(), [&](const auto &cell) {
|
||||
util::json::Array row;
|
||||
row.values.push_back(util::json::Number(cell.row));
|
||||
row.values.push_back(util::json::Number(cell.column));
|
||||
json_table.values.push_back(std::move(row));
|
||||
});
|
||||
std::for_each(fallback_speed_cells.begin(),
|
||||
fallback_speed_cells.end(),
|
||||
[&](const auto &cell)
|
||||
{
|
||||
util::json::Array row;
|
||||
row.values.push_back(util::json::Number(cell.row));
|
||||
row.values.push_back(util::json::Number(cell.column));
|
||||
json_table.values.push_back(std::move(row));
|
||||
});
|
||||
return json_table;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ struct TableParameters : public BaseParameters
|
||||
template <typename... Args>
|
||||
TableParameters(std::vector<std::size_t> sources_,
|
||||
std::vector<std::size_t> destinations_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||
destinations{std::move(destinations_)}
|
||||
{
|
||||
@ -91,7 +91,7 @@ struct TableParameters : public BaseParameters
|
||||
TableParameters(std::vector<std::size_t> sources_,
|
||||
std::vector<std::size_t> destinations_,
|
||||
const AnnotationsType annotations_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||
destinations{std::move(destinations_)}, annotations{annotations_}
|
||||
{
|
||||
@ -104,7 +104,7 @@ struct TableParameters : public BaseParameters
|
||||
double fallback_speed_,
|
||||
FallbackCoordinateType fallback_coordinate_type_,
|
||||
double scale_factor_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: BaseParameters{std::forward<Args>(args_)...}, sources{std::move(sources_)},
|
||||
destinations{std::move(destinations_)}, fallback_speed{fallback_speed_},
|
||||
fallback_coordinate_type{fallback_coordinate_type_}, annotations{annotations_},
|
||||
|
@ -50,10 +50,10 @@ class TripAPI final : public RouteAPI
|
||||
data_version_string = fb_result.CreateString(data_timestamp);
|
||||
}
|
||||
|
||||
auto response =
|
||||
MakeFBResponse(sub_routes, fb_result, [this, &fb_result, &sub_trips, &candidates]() {
|
||||
return MakeWaypoints(fb_result, sub_trips, candidates);
|
||||
});
|
||||
auto response = MakeFBResponse(sub_routes,
|
||||
fb_result,
|
||||
[this, &fb_result, &sub_trips, &candidates]()
|
||||
{ return MakeWaypoints(fb_result, sub_trips, candidates); });
|
||||
|
||||
if (!data_timestamp.empty())
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ struct TripParameters : public RouteParameters
|
||||
TripParameters(SourceType source_,
|
||||
DestinationType destination_,
|
||||
bool roundtrip_,
|
||||
Args &&... args_)
|
||||
Args &&...args_)
|
||||
: RouteParameters{std::forward<Args>(args_)...}, source{source_},
|
||||
destination{destination_}, roundtrip{roundtrip_}
|
||||
{
|
||||
|
@ -440,9 +440,11 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
{
|
||||
auto indexes = extractor::getClassIndexes(class_data);
|
||||
std::vector<std::string> classes(indexes.size());
|
||||
std::transform(indexes.begin(), indexes.end(), classes.begin(), [this](const auto index) {
|
||||
return m_profile_properties->GetClassName(index);
|
||||
});
|
||||
std::transform(indexes.begin(),
|
||||
indexes.end(),
|
||||
classes.begin(),
|
||||
[this](const auto index)
|
||||
{ return m_profile_properties->GetClassName(index); });
|
||||
|
||||
return classes;
|
||||
}
|
||||
@ -600,15 +602,19 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade
|
||||
auto found_range = std::equal_range(
|
||||
m_maneuver_overrides.begin(), m_maneuver_overrides.end(), edge_based_node_id, Comp{});
|
||||
|
||||
std::for_each(found_range.first, found_range.second, [&](const auto &override) {
|
||||
std::vector<NodeID> sequence(
|
||||
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_begin,
|
||||
m_maneuver_override_node_sequences.begin() + override.node_sequence_offset_end);
|
||||
results.push_back(extractor::ManeuverOverride{std::move(sequence),
|
||||
override.instruction_node,
|
||||
override.override_type,
|
||||
override.direction});
|
||||
});
|
||||
std::for_each(found_range.first,
|
||||
found_range.second,
|
||||
[&](const auto &override)
|
||||
{
|
||||
std::vector<NodeID> sequence(m_maneuver_override_node_sequences.begin() +
|
||||
override.node_sequence_offset_begin,
|
||||
m_maneuver_override_node_sequences.begin() +
|
||||
override.node_sequence_offset_end);
|
||||
results.push_back(extractor::ManeuverOverride{std::move(sequence),
|
||||
override.instruction_node,
|
||||
override.override_type,
|
||||
override.direction});
|
||||
});
|
||||
return results;
|
||||
}
|
||||
};
|
||||
|
@ -60,7 +60,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[this, approach, &input_coordinate, &bearing_with_range, &use_all_edges](
|
||||
const CandidateSegment &segment) {
|
||||
const CandidateSegment &segment)
|
||||
{
|
||||
auto valid = CheckSegmentExclude(segment) &&
|
||||
CheckApproach(input_coordinate, segment, approach) &&
|
||||
(use_all_edges ? HasValidEdge(segment, *use_all_edges)
|
||||
@ -70,7 +71,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
return valid;
|
||||
},
|
||||
[this, &max_distance, &max_results, input_coordinate](const std::size_t num_results,
|
||||
const CandidateSegment &segment) {
|
||||
const CandidateSegment &segment)
|
||||
{
|
||||
return (max_results && num_results >= *max_results) ||
|
||||
(max_distance && max_distance != -1.0 &&
|
||||
CheckSegmentDistance(input_coordinate, segment, *max_distance));
|
||||
@ -107,7 +109,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
&big_component_coord,
|
||||
&big_component_distance,
|
||||
&use_all_edges,
|
||||
&bearing_with_range](const CandidateSegment &segment) {
|
||||
&bearing_with_range](const CandidateSegment &segment)
|
||||
{
|
||||
auto is_big_component = !IsTinyComponent(segment);
|
||||
auto not_nearest =
|
||||
has_nearest && segment.fixed_projected_coordinate != nearest_coord;
|
||||
@ -159,7 +162,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
return use_candidate;
|
||||
},
|
||||
[this, &has_big_component, &max_distance, input_coordinate, &big_component_distance](
|
||||
const std::size_t /*num_results*/, const CandidateSegment &segment) {
|
||||
const std::size_t /*num_results*/, const CandidateSegment &segment)
|
||||
{
|
||||
auto distance = GetSegmentDistance(input_coordinate, segment);
|
||||
auto further_than_big_component = distance > big_component_distance;
|
||||
auto no_more_candidates = has_big_component && further_than_big_component;
|
||||
@ -190,13 +194,17 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
PhantomNodeCandidates nearest_phantoms;
|
||||
PhantomNodeCandidates big_component_phantoms;
|
||||
|
||||
const auto add_to_candidates = [this, &input_coordinate](PhantomNodeCandidates &candidates,
|
||||
const EdgeData data) {
|
||||
const auto add_to_candidates =
|
||||
[this, &input_coordinate](PhantomNodeCandidates &candidates, const EdgeData data)
|
||||
{
|
||||
auto candidate_it =
|
||||
std::find_if(candidates.begin(), candidates.end(), [&](const PhantomNode &node) {
|
||||
return data.forward_segment_id.id == node.forward_segment_id.id &&
|
||||
data.reverse_segment_id.id == node.reverse_segment_id.id;
|
||||
});
|
||||
std::find_if(candidates.begin(),
|
||||
candidates.end(),
|
||||
[&](const PhantomNode &node)
|
||||
{
|
||||
return data.forward_segment_id.id == node.forward_segment_id.id &&
|
||||
data.reverse_segment_id.id == node.reverse_segment_id.id;
|
||||
});
|
||||
if (candidate_it == candidates.end())
|
||||
{
|
||||
// First candidate from this segment
|
||||
@ -259,17 +267,20 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
}
|
||||
};
|
||||
|
||||
std::for_each(results.begin(), results.end(), [&](const CandidateSegment &segment) {
|
||||
if (segment.fixed_projected_coordinate == nearest_coord)
|
||||
{
|
||||
add_to_candidates(nearest_phantoms, segment.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can only be from a big component for the alternative candidates
|
||||
add_to_candidates(big_component_phantoms, segment.data);
|
||||
}
|
||||
});
|
||||
std::for_each(results.begin(),
|
||||
results.end(),
|
||||
[&](const CandidateSegment &segment)
|
||||
{
|
||||
if (segment.fixed_projected_coordinate == nearest_coord)
|
||||
{
|
||||
add_to_candidates(nearest_phantoms, segment.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can only be from a big component for the alternative candidates
|
||||
add_to_candidates(big_component_phantoms, segment.data);
|
||||
}
|
||||
});
|
||||
return std::make_pair(std::move(nearest_phantoms), std::move(big_component_phantoms));
|
||||
}
|
||||
|
||||
@ -281,9 +292,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
std::transform(results.begin(),
|
||||
results.end(),
|
||||
distance_and_phantoms.begin(),
|
||||
[this, &input_coordinate](const CandidateSegment &segment) {
|
||||
return MakePhantomNode(input_coordinate, segment.data);
|
||||
});
|
||||
[this, &input_coordinate](const CandidateSegment &segment)
|
||||
{ return MakePhantomNode(input_coordinate, segment.data); });
|
||||
return distance_and_phantoms;
|
||||
}
|
||||
|
||||
@ -400,9 +410,8 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
}
|
||||
|
||||
// check phantom node segments validity
|
||||
auto areSegmentsValid = [](auto first, auto last) -> bool {
|
||||
return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last;
|
||||
};
|
||||
auto areSegmentsValid = [](auto first, auto last) -> bool
|
||||
{ return std::find(first, last, INVALID_SEGMENT_WEIGHT) == last; };
|
||||
bool is_forward_valid_source =
|
||||
areSegmentsValid(forward_weights.begin(), forward_weights.end());
|
||||
bool is_forward_valid_target = areSegmentsValid(
|
||||
|
@ -43,7 +43,8 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
||||
const bool target_traversed_in_reverse)
|
||||
{
|
||||
// merges segments with same name id
|
||||
const auto collapse_segments = [](std::vector<NamedSegment> &segments) {
|
||||
const auto collapse_segments = [](std::vector<NamedSegment> &segments)
|
||||
{
|
||||
auto out = segments.begin();
|
||||
auto end = segments.end();
|
||||
|
||||
@ -75,7 +76,8 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
||||
std::transform(route_data.begin(),
|
||||
route_data.end(),
|
||||
segments.begin(),
|
||||
[&index, &facade](const PathData &point) {
|
||||
[&index, &facade](const PathData &point)
|
||||
{
|
||||
return NamedSegment{point.duration_until_turn,
|
||||
index++,
|
||||
facade.GetNameIndex(point.from_edge_based_node)};
|
||||
@ -87,33 +89,37 @@ std::array<std::uint32_t, SegmentNumber> summarizeRoute(const datafacade::BaseDa
|
||||
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(
|
||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
||||
return lhs.name_id < rhs.name_id ||
|
||||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
|
||||
});
|
||||
std::sort(segments.begin(),
|
||||
segments.end(),
|
||||
[](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||
{
|
||||
return lhs.name_id < rhs.name_id ||
|
||||
(lhs.name_id == rhs.name_id && lhs.position < rhs.position);
|
||||
});
|
||||
auto new_end = collapse_segments(segments);
|
||||
segments.resize(new_end - segments.begin());
|
||||
|
||||
// Filter out segments with an empty name (name_id == 0)
|
||||
new_end = std::remove_if(segments.begin(), segments.end(), [](const NamedSegment &segment) {
|
||||
return segment.name_id == 0;
|
||||
});
|
||||
new_end = std::remove_if(segments.begin(),
|
||||
segments.end(),
|
||||
[](const NamedSegment &segment) { return segment.name_id == 0; });
|
||||
segments.resize(new_end - segments.begin());
|
||||
|
||||
// sort descending
|
||||
std::sort(
|
||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
||||
return lhs.duration > rhs.duration ||
|
||||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
|
||||
});
|
||||
std::sort(segments.begin(),
|
||||
segments.end(),
|
||||
[](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||
{
|
||||
return lhs.duration > rhs.duration ||
|
||||
(lhs.duration == rhs.duration && lhs.position < rhs.position);
|
||||
});
|
||||
|
||||
// make sure the segments are sorted by position
|
||||
segments.resize(std::min(segments.size(), SegmentNumber));
|
||||
std::sort(
|
||||
segments.begin(), segments.end(), [](const NamedSegment &lhs, const NamedSegment &rhs) {
|
||||
return lhs.position < rhs.position;
|
||||
});
|
||||
std::sort(segments.begin(),
|
||||
segments.end(),
|
||||
[](const NamedSegment &lhs, const NamedSegment &rhs)
|
||||
{ return lhs.position < rhs.position; });
|
||||
|
||||
std::array<std::uint32_t, SegmentNumber> summary;
|
||||
std::fill(summary.begin(), summary.end(), EMPTY_NAMEID);
|
||||
@ -138,7 +144,8 @@ inline std::string assembleSummary(const datafacade::BaseDataFacade &facade,
|
||||
|
||||
// transform a name_id into a string containing either the name, or -if the name is empty-
|
||||
// the reference.
|
||||
const auto name_id_to_string = [&](const NameID name_id) {
|
||||
const auto name_id_to_string = [&](const NameID name_id)
|
||||
{
|
||||
const auto name = facade.GetNameForID(name_id);
|
||||
if (!name.empty())
|
||||
return std::string(name);
|
||||
@ -178,14 +185,16 @@ inline RouteLeg assembleLeg(const datafacade::BaseDataFacade &facade,
|
||||
const auto target_weight =
|
||||
(target_traversed_in_reverse ? target_node.reverse_weight : target_node.forward_weight);
|
||||
|
||||
auto duration = std::accumulate(
|
||||
route_data.begin(), route_data.end(), 0, [](const double sum, const PathData &data) {
|
||||
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 + from_alias<double>(data.weight_until_turn);
|
||||
});
|
||||
auto duration = std::accumulate(route_data.begin(),
|
||||
route_data.end(),
|
||||
0,
|
||||
[](const double sum, const PathData &data)
|
||||
{ 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 + from_alias<double>(data.weight_until_turn); });
|
||||
|
||||
// s
|
||||
// |
|
||||
|
@ -16,7 +16,7 @@ bool basicCollapsePreconditions(const RouteStepIterator first,
|
||||
|
||||
// Staggered intersection are very short zig-zags of a few meters.
|
||||
// We do not want to announce these short left-rights or right-lefts:
|
||||
//
|
||||
//
|
||||
// * -> b a -> *
|
||||
// | or | becomes a -> b
|
||||
// a -> * * -> b
|
||||
@ -26,7 +26,7 @@ bool isStaggeredIntersection(const RouteStepIterator step_prior_to_intersection,
|
||||
|
||||
// Two two turns following close after another, we can announce them as a U-Turn if both end up
|
||||
// involving the same (segregated) road.
|
||||
//
|
||||
//
|
||||
// b < - y
|
||||
// | will be represented by at x, turn around instead of turn left at x, turn left at y
|
||||
// a - > x
|
||||
@ -42,11 +42,11 @@ bool isNameOszillation(const RouteStepIterator step_prior_to_intersection,
|
||||
|
||||
// Sometimes, segments names don't match the perceived turns. We try to detect these additional
|
||||
// name changes and issue a combined turn.
|
||||
//
|
||||
//
|
||||
// | e |
|
||||
// a - b - c
|
||||
// d
|
||||
//
|
||||
//
|
||||
// can have `a-b` as one name, `b-c-d` as a second. At `b` we would issue a new name, even though
|
||||
// the road turns right after. The offset would only be there due to the broad road at `e`
|
||||
bool maneuverPreceededByNameChange(const RouteStepIterator step_prior_to_intersection,
|
||||
@ -73,11 +73,11 @@ bool doubleChoiceless(const RouteStepIterator step_entering_intersection,
|
||||
|
||||
// Due to obvious detection, sometimes we can have straight turns followed by a different turn right
|
||||
// next to each other. We combine both turns into one, if the second turn is without choice
|
||||
//
|
||||
// e
|
||||
//
|
||||
// e
|
||||
// a - b - c
|
||||
// ' d
|
||||
//
|
||||
//
|
||||
// with a main road `abd`, the turn `continue straight` at `b` and `turn left at `c` will become a
|
||||
// `turn left` at `b`
|
||||
bool straightTurnFollowedByChoiceless(const RouteStepIterator step_entering_intersection,
|
||||
|
@ -122,9 +122,8 @@ inline bool haveSameMode(const RouteStep &first, const RouteStep &second, const
|
||||
// alias for readability
|
||||
inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
|
||||
{
|
||||
const auto has_name_or_ref = [](auto const &step) {
|
||||
return !step.name.empty() || !step.ref.empty();
|
||||
};
|
||||
const auto has_name_or_ref = [](auto const &step)
|
||||
{ return !step.name.empty() || !step.ref.empty(); };
|
||||
|
||||
// make sure empty is not involved
|
||||
if (!has_name_or_ref(lhs) || !has_name_or_ref(rhs))
|
||||
@ -151,12 +150,14 @@ inline bool haveSameName(const RouteStep &lhs, const RouteStep &rhs)
|
||||
// alias for readability, both turn right | left
|
||||
inline bool areSameSide(const RouteStep &lhs, const RouteStep &rhs)
|
||||
{
|
||||
const auto is_left = [](const RouteStep &step) {
|
||||
const auto is_left = [](const RouteStep &step)
|
||||
{
|
||||
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
|
||||
hasLeftModifier(step.maneuver.instruction);
|
||||
};
|
||||
|
||||
const auto is_right = [](const RouteStep &step) {
|
||||
const auto is_right = [](const RouteStep &step)
|
||||
{
|
||||
return hasModifier(step, osrm::guidance::DirectionModifier::Straight) ||
|
||||
hasRightModifier(step.maneuver.instruction);
|
||||
};
|
||||
@ -174,7 +175,8 @@ inline std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> st
|
||||
// Two valid NO_TURNs exist in each leg in the form of Depart/Arrive
|
||||
|
||||
// keep valid instructions
|
||||
const auto not_is_valid = [](const RouteStep &step) {
|
||||
const auto not_is_valid = [](const RouteStep &step)
|
||||
{
|
||||
return step.maneuver.instruction == osrm::guidance::TurnInstruction::NO_TURN() &&
|
||||
step.maneuver.waypoint_type == WaypointType::None;
|
||||
};
|
||||
@ -225,7 +227,8 @@ inline double totalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_
|
||||
inline bool bearingsAreReversed(const double bearing_in, const double bearing_out)
|
||||
{
|
||||
// Nearly perfectly reversed angles have a difference close to 180 degrees (straight)
|
||||
const double left_turn_angle = [&]() {
|
||||
const double left_turn_angle = [&]()
|
||||
{
|
||||
if (0 <= bearing_out && bearing_out <= bearing_in)
|
||||
return bearing_in - bearing_out;
|
||||
return bearing_in + 360 - bearing_out;
|
||||
|
@ -20,14 +20,16 @@ template <typename Iter, typename Fn> inline Fn forEachRoundabout(Iter first, It
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
const auto enter = std::find_if(first, last, [](const RouteStep &step) {
|
||||
return entersRoundabout(step.maneuver.instruction);
|
||||
});
|
||||
const auto enter = std::find_if(first,
|
||||
last,
|
||||
[](const RouteStep &step)
|
||||
{ return entersRoundabout(step.maneuver.instruction); });
|
||||
|
||||
// enter has to come before leave, otherwise: faulty data / partial roundabout, skip those
|
||||
const auto leave = std::find_if(enter, last, [](const RouteStep &step) {
|
||||
return leavesRoundabout(step.maneuver.instruction);
|
||||
});
|
||||
const auto leave = std::find_if(enter,
|
||||
last,
|
||||
[](const RouteStep &step)
|
||||
{ return leavesRoundabout(step.maneuver.instruction); });
|
||||
|
||||
// No roundabouts, or partial one (like start / end inside a roundabout)
|
||||
if (enter == last || leave == last)
|
||||
|
@ -259,10 +259,10 @@ inline util::Coordinate candidatesInputLocation(const PhantomNodeCandidates &can
|
||||
|
||||
inline bool candidatesHaveComponent(const PhantomNodeCandidates &candidates, uint32_t component_id)
|
||||
{
|
||||
return std::any_of(
|
||||
candidates.begin(), candidates.end(), [component_id](const PhantomNode &node) {
|
||||
return node.component.id == component_id;
|
||||
});
|
||||
return std::any_of(candidates.begin(),
|
||||
candidates.end(),
|
||||
[component_id](const PhantomNode &node)
|
||||
{ return node.component.id == component_id; });
|
||||
}
|
||||
|
||||
struct PhantomEndpoints
|
||||
|
@ -33,10 +33,10 @@ class BasePlugin
|
||||
|
||||
bool CheckAllCoordinates(const std::vector<util::Coordinate> &coordinates) const
|
||||
{
|
||||
return !std::any_of(
|
||||
std::begin(coordinates), std::end(coordinates), [](const util::Coordinate coordinate) {
|
||||
return !coordinate.IsValid();
|
||||
});
|
||||
return !std::any_of(std::begin(coordinates),
|
||||
std::end(coordinates),
|
||||
[](const util::Coordinate coordinate)
|
||||
{ return !coordinate.IsValid(); });
|
||||
}
|
||||
|
||||
bool CheckAlgorithms(const api::BaseParameters ¶ms,
|
||||
@ -105,45 +105,45 @@ class BasePlugin
|
||||
{
|
||||
// are all phantoms from a tiny cc?
|
||||
const auto all_in_same_tiny_component =
|
||||
[](const std::vector<PhantomCandidateAlternatives> &alts_list) {
|
||||
return std::any_of(
|
||||
alts_list.front().first.begin(),
|
||||
alts_list.front().first.end(),
|
||||
// For each of the first possible phantoms, check if all other
|
||||
// positions in the list have a phantom from the same small component.
|
||||
[&](const PhantomNode &phantom) {
|
||||
if (!phantom.component.is_tiny)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const auto component_id = phantom.component.id;
|
||||
return std::all_of(
|
||||
std::next(alts_list.begin()),
|
||||
std::end(alts_list),
|
||||
[component_id](const PhantomCandidateAlternatives &alternatives) {
|
||||
return candidatesHaveComponent(alternatives.first, component_id);
|
||||
});
|
||||
});
|
||||
};
|
||||
[](const std::vector<PhantomCandidateAlternatives> &alts_list)
|
||||
{
|
||||
return std::any_of(
|
||||
alts_list.front().first.begin(),
|
||||
alts_list.front().first.end(),
|
||||
// For each of the first possible phantoms, check if all other
|
||||
// positions in the list have a phantom from the same small component.
|
||||
[&](const PhantomNode &phantom)
|
||||
{
|
||||
if (!phantom.component.is_tiny)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const auto component_id = phantom.component.id;
|
||||
return std::all_of(
|
||||
std::next(alts_list.begin()),
|
||||
std::end(alts_list),
|
||||
[component_id](const PhantomCandidateAlternatives &alternatives)
|
||||
{ return candidatesHaveComponent(alternatives.first, component_id); });
|
||||
});
|
||||
};
|
||||
|
||||
// Move the alternative into the final list
|
||||
const auto fallback_to_big_component = [](PhantomCandidateAlternatives &alternatives) {
|
||||
const auto fallback_to_big_component = [](PhantomCandidateAlternatives &alternatives)
|
||||
{
|
||||
auto no_big_alternative = alternatives.second.empty();
|
||||
return no_big_alternative ? std::move(alternatives.first)
|
||||
: std::move(alternatives.second);
|
||||
};
|
||||
|
||||
// Move the alternative into the final list
|
||||
const auto use_closed_phantom = [](PhantomCandidateAlternatives &alternatives) {
|
||||
return std::move(alternatives.first);
|
||||
};
|
||||
const auto use_closed_phantom = [](PhantomCandidateAlternatives &alternatives)
|
||||
{ return std::move(alternatives.first); };
|
||||
|
||||
const auto no_alternatives =
|
||||
std::all_of(alternatives_list.begin(),
|
||||
alternatives_list.end(),
|
||||
[](const PhantomCandidateAlternatives &alternatives) {
|
||||
return alternatives.second.empty();
|
||||
});
|
||||
[](const PhantomCandidateAlternatives &alternatives)
|
||||
{ return alternatives.second.empty(); });
|
||||
|
||||
std::vector<PhantomNodeCandidates> snapped_phantoms;
|
||||
snapped_phantoms.reserve(alternatives_list.size());
|
||||
@ -313,12 +313,12 @@ class BasePlugin
|
||||
alternatives.end(),
|
||||
coordinates.begin(),
|
||||
coordinates.end(),
|
||||
[](const auto &candidates_pair, const auto &coordinate) {
|
||||
[](const auto &candidates_pair, const auto &coordinate)
|
||||
{
|
||||
return std::any_of(candidates_pair.first.begin(),
|
||||
candidates_pair.first.end(),
|
||||
[&](const auto &phantom) {
|
||||
return phantom.input_location == coordinate;
|
||||
});
|
||||
[&](const auto &phantom)
|
||||
{ return phantom.input_location == coordinate; });
|
||||
});
|
||||
std::size_t missing_index = std::distance(alternatives.begin(), mismatch.first);
|
||||
return std::string("Could not find a matching segment for coordinate ") +
|
||||
|
@ -39,7 +39,8 @@ std::string encodePolyline(CoordVectorForwardIter begin, CoordVectorForwardIter
|
||||
begin,
|
||||
end,
|
||||
[&delta_numbers, ¤t_lat, ¤t_lon, coordinate_to_polyline](
|
||||
const util::Coordinate loc) {
|
||||
const util::Coordinate loc)
|
||||
{
|
||||
const int lat_diff =
|
||||
std::round(static_cast<int>(loc.lat) * coordinate_to_polyline) - current_lat;
|
||||
const int lon_diff =
|
||||
|
@ -190,8 +190,10 @@ void annotatePath(const FacadeT &facade,
|
||||
std::vector<SegmentDuration> duration_vector;
|
||||
std::vector<DatasourceID> datasource_vector;
|
||||
|
||||
const auto get_segment_geometry = [&](const auto geometry_index) {
|
||||
const auto copy = [](auto &vector, const auto range) {
|
||||
const auto get_segment_geometry = [&](const auto geometry_index)
|
||||
{
|
||||
const auto copy = [](auto &vector, const auto range)
|
||||
{
|
||||
vector.resize(range.size());
|
||||
std::copy(range.begin(), range.end(), vector.begin());
|
||||
};
|
||||
|
@ -294,9 +294,9 @@ EdgeDistance calculateEBGNodeAnnotations(const DataFacade<Algorithm> &facade,
|
||||
|
||||
// Look for an edge on the forward CH graph (.forward)
|
||||
EdgeID smaller_edge_id =
|
||||
facade.FindSmallestEdge(std::get<0>(edge), std::get<1>(edge), [](const auto &data) {
|
||||
return data.forward;
|
||||
});
|
||||
facade.FindSmallestEdge(std::get<0>(edge),
|
||||
std::get<1>(edge),
|
||||
[](const auto &data) { return data.forward; });
|
||||
|
||||
// If we didn't find one there, the we might be looking at a part of the path that
|
||||
// was found using the backward search. Here, we flip the node order (.second,
|
||||
@ -381,7 +381,8 @@ void unpackPath(const FacadeT &facade,
|
||||
unpackPath(facade,
|
||||
packed_path_begin,
|
||||
packed_path_end,
|
||||
[&](std::pair<NodeID, NodeID> &edge, const auto &edge_id) {
|
||||
[&](std::pair<NodeID, NodeID> &edge, const auto &edge_id)
|
||||
{
|
||||
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
||||
unpacked_nodes.push_back(edge.second);
|
||||
unpacked_edges.push_back(edge_id);
|
||||
|
@ -30,7 +30,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
const PhantomNode &source,
|
||||
const PhantomNode &target)
|
||||
{
|
||||
auto level = [&partition, node](const SegmentID &source, const SegmentID &target) {
|
||||
auto level = [&partition, node](const SegmentID &source, const SegmentID &target)
|
||||
{
|
||||
if (source.enabled && target.enabled)
|
||||
return partition.GetQueryLevel(source.id, target.id, node);
|
||||
return INVALID_LEVEL_ID;
|
||||
@ -59,7 +60,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
endpoint_candidates.source_phantoms.begin(),
|
||||
endpoint_candidates.source_phantoms.end(),
|
||||
INVALID_LEVEL_ID,
|
||||
[&](LevelID current_level, const PhantomNode &source) {
|
||||
[&](LevelID current_level, const PhantomNode &source)
|
||||
{
|
||||
return std::min(
|
||||
current_level,
|
||||
getNodeQueryLevel(partition, node, source, endpoint_candidates.target_phantom));
|
||||
@ -76,7 +78,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
endpoint_candidates.source_phantoms.begin(),
|
||||
endpoint_candidates.source_phantoms.end(),
|
||||
INVALID_LEVEL_ID,
|
||||
[&](LevelID level_1, const PhantomNode &source) {
|
||||
[&](LevelID level_1, const PhantomNode &source)
|
||||
{
|
||||
return std::min(
|
||||
level_1,
|
||||
std::accumulate(endpoint_candidates.target_phantoms.begin(),
|
||||
@ -119,7 +122,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
const NodeID node,
|
||||
const PhantomNodeCandidates &candidates)
|
||||
{
|
||||
auto highest_different_level = [&partition, node](const SegmentID &segment) {
|
||||
auto highest_different_level = [&partition, node](const SegmentID &segment)
|
||||
{
|
||||
return segment.enabled ? partition.GetHighestDifferentLevel(segment.id, node)
|
||||
: INVALID_LEVEL_ID;
|
||||
};
|
||||
@ -128,7 +132,8 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
std::accumulate(candidates.begin(),
|
||||
candidates.end(),
|
||||
INVALID_LEVEL_ID,
|
||||
[&](LevelID current_level, const PhantomNode &phantom_node) {
|
||||
[&](LevelID current_level, const PhantomNode &phantom_node)
|
||||
{
|
||||
auto highest_level =
|
||||
std::min(highest_different_level(phantom_node.forward_segment_id),
|
||||
highest_different_level(phantom_node.reverse_segment_id));
|
||||
@ -151,9 +156,11 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
||||
// This is equivalent to min_{∀ source, target} partition.GetQueryLevel(source, node, target)
|
||||
auto init = getNodeQueryLevel(partition, node, candidates_list[phantom_index]);
|
||||
auto result = std::accumulate(
|
||||
phantom_indices.begin(), phantom_indices.end(), init, [&](LevelID level, size_t index) {
|
||||
return std::min(level, getNodeQueryLevel(partition, node, candidates_list[index]));
|
||||
});
|
||||
phantom_indices.begin(),
|
||||
phantom_indices.end(),
|
||||
init,
|
||||
[&](LevelID level, size_t index)
|
||||
{ return std::min(level, getNodeQueryLevel(partition, node, candidates_list[index])); });
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
@ -266,7 +273,7 @@ template <bool DIRECTION, typename Algorithm, typename... Args>
|
||||
void relaxOutgoingEdges(const DataFacade<Algorithm> &facade,
|
||||
typename SearchEngineData<Algorithm>::QueryHeap &forward_heap,
|
||||
const typename SearchEngineData<Algorithm>::QueryHeap::HeapNode &heapNode,
|
||||
const Args &... args)
|
||||
const Args &...args)
|
||||
{
|
||||
const auto &partition = facade.GetMultiLevelPartition();
|
||||
const auto &cells = facade.GetCellStorage();
|
||||
@ -384,7 +391,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
||||
EdgeWeight &path_upper_bound,
|
||||
const std::vector<NodeID> &force_loop_forward_nodes,
|
||||
const std::vector<NodeID> &force_loop_reverse_nodes,
|
||||
const Args &... args)
|
||||
const Args &...args)
|
||||
{
|
||||
const auto heapNode = forward_heap.DeleteMinGetHeapNode();
|
||||
const auto weight = heapNode.weight;
|
||||
@ -434,7 +441,7 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
||||
const std::vector<NodeID> &force_loop_forward_nodes,
|
||||
const std::vector<NodeID> &force_loop_reverse_nodes,
|
||||
EdgeWeight weight_upper_bound,
|
||||
const Args &... args)
|
||||
const Args &...args)
|
||||
{
|
||||
if (forward_heap.Empty() || reverse_heap.Empty())
|
||||
{
|
||||
@ -601,7 +608,8 @@ void unpackPath(const FacadeT &facade,
|
||||
util::for_each_pair(
|
||||
packed_path_begin,
|
||||
packed_path_end,
|
||||
[&facade, &unpacked_nodes, &unpacked_edges](const auto from, const auto to) {
|
||||
[&facade, &unpacked_nodes, &unpacked_edges](const auto from, const auto to)
|
||||
{
|
||||
unpacked_nodes.push_back(to);
|
||||
unpacked_edges.push_back(facade.FindEdge(from, to));
|
||||
});
|
||||
|
@ -247,7 +247,8 @@ constructRouteResult(const DataFacade<Algorithm> &facade,
|
||||
auto source_it =
|
||||
std::find_if(source_candidates.begin(),
|
||||
source_candidates.end(),
|
||||
[&start_node](const auto &source_phantom) {
|
||||
[&start_node](const auto &source_phantom)
|
||||
{
|
||||
return (start_node == source_phantom.forward_segment_id.id ||
|
||||
start_node == source_phantom.reverse_segment_id.id);
|
||||
});
|
||||
@ -256,7 +257,8 @@ constructRouteResult(const DataFacade<Algorithm> &facade,
|
||||
auto target_it =
|
||||
std::find_if(target_candidates.begin(),
|
||||
target_candidates.end(),
|
||||
[&end_node](const auto &target_phantom) {
|
||||
[&end_node](const auto &target_phantom)
|
||||
{
|
||||
return (end_node == target_phantom.forward_segment_id.id ||
|
||||
end_node == target_phantom.reverse_segment_id.id);
|
||||
});
|
||||
@ -464,16 +466,16 @@ struct route_state
|
||||
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(),
|
||||
init_candidates.end(),
|
||||
std::back_inserter(last.reached_forward_node_target),
|
||||
[](const PhantomNode &phantom_node) { return phantom_node.IsValidForwardSource(); });
|
||||
std::transform(
|
||||
init_candidates.begin(),
|
||||
init_candidates.end(),
|
||||
std::back_inserter(last.reached_reverse_node_target),
|
||||
[](const PhantomNode &phantom_node) { return phantom_node.IsValidReverseSource(); });
|
||||
std::transform(init_candidates.begin(),
|
||||
init_candidates.end(),
|
||||
std::back_inserter(last.reached_forward_node_target),
|
||||
[](const PhantomNode &phantom_node)
|
||||
{ return phantom_node.IsValidForwardSource(); });
|
||||
std::transform(init_candidates.begin(),
|
||||
init_candidates.end(),
|
||||
std::back_inserter(last.reached_reverse_node_target),
|
||||
[](const PhantomNode &phantom_node)
|
||||
{ return phantom_node.IsValidReverseSource(); });
|
||||
}
|
||||
|
||||
bool completeLeg()
|
||||
@ -611,15 +613,21 @@ struct route_state
|
||||
{
|
||||
// Find the segment from final leg with the shortest path
|
||||
auto forward_range = util::irange<std::size_t>(0UL, last.total_weight_to_forward.size());
|
||||
auto forward_min =
|
||||
std::min_element(forward_range.begin(), forward_range.end(), [&](size_t a, size_t b) {
|
||||
auto forward_min = std::min_element(
|
||||
forward_range.begin(),
|
||||
forward_range.end(),
|
||||
[&](size_t a, size_t b)
|
||||
{
|
||||
return (last.total_weight_to_forward[a] < last.total_weight_to_forward[b] ||
|
||||
(last.total_weight_to_forward[a] == last.total_weight_to_forward[b] &&
|
||||
last.total_nodes_to_forward[a] < last.total_nodes_to_forward[b]));
|
||||
});
|
||||
auto reverse_range = util::irange<std::size_t>(0UL, last.total_weight_to_reverse.size());
|
||||
auto reverse_min =
|
||||
std::min_element(reverse_range.begin(), reverse_range.end(), [&](size_t a, size_t b) {
|
||||
auto reverse_min = std::min_element(
|
||||
reverse_range.begin(),
|
||||
reverse_range.end(),
|
||||
[&](size_t a, size_t b)
|
||||
{
|
||||
return (last.total_weight_to_reverse[a] < last.total_weight_to_reverse[b] ||
|
||||
(last.total_weight_to_reverse[a] == last.total_weight_to_reverse[b] &&
|
||||
last.total_nodes_to_reverse[a] < last.total_nodes_to_reverse[b]));
|
||||
|
@ -27,9 +27,9 @@ inline auto getClassData(const std::size_t index)
|
||||
|
||||
inline bool isValidClassName(const std::string &name)
|
||||
{
|
||||
return std::find_if_not(name.begin(), name.end(), [](const auto c) {
|
||||
return std::isalnum(c);
|
||||
}) == name.end();
|
||||
return std::find_if_not(name.begin(),
|
||||
name.end(),
|
||||
[](const auto c) { return std::isalnum(c); }) == name.end();
|
||||
}
|
||||
} // namespace osrm::extractor
|
||||
|
||||
|
@ -125,9 +125,8 @@ inline std::string canonicalizeStringList(std::string strlist, const std::string
|
||||
|
||||
// collapse spaces; this is needed in case we expand "; X" => "; X" above
|
||||
// but also makes sense to do irregardless of the fact - canonicalizing strings.
|
||||
const auto spaces = [](unsigned char lhs, unsigned char rhs) {
|
||||
return ::isspace(lhs) && ::isspace(rhs);
|
||||
};
|
||||
const auto spaces = [](unsigned char lhs, unsigned char rhs)
|
||||
{ return ::isspace(lhs) && ::isspace(rhs); };
|
||||
auto it = std::unique(begin(strlist), end(strlist), spaces);
|
||||
strlist.erase(it, end(strlist));
|
||||
|
||||
|
@ -133,7 +133,8 @@ class ExtractionRelationContainer
|
||||
(void)res; // prevent unused warning in release
|
||||
}
|
||||
|
||||
auto MergeRefMap = [&](RelationRefMap &source, RelationRefMap &target) {
|
||||
auto MergeRefMap = [&](RelationRefMap &source, RelationRefMap &target)
|
||||
{
|
||||
for (auto it : source)
|
||||
{
|
||||
auto &v = target[it.first];
|
||||
@ -151,7 +152,8 @@ class ExtractionRelationContainer
|
||||
const RelationIDList &GetRelations(const OsmIDTyped &member_id) const
|
||||
{
|
||||
auto getFromMap = [this](std::uint64_t id,
|
||||
const RelationRefMap &map) -> const RelationIDList & {
|
||||
const RelationRefMap &map) -> const RelationIDList &
|
||||
{
|
||||
auto it = map.find(id);
|
||||
if (it != map.end())
|
||||
return it->second;
|
||||
|
@ -453,7 +453,8 @@ void readRawNBGraph(const boost::filesystem::path &path,
|
||||
coordinates.resize(number_of_nodes);
|
||||
osm_node_ids.reserve(number_of_nodes);
|
||||
auto index = 0;
|
||||
auto decode = [&](const auto ¤t_node) {
|
||||
auto decode = [&](const auto ¤t_node)
|
||||
{
|
||||
coordinates[index].lon = current_node.lon;
|
||||
coordinates[index].lat = current_node.lat;
|
||||
osm_node_ids.push_back(current_node.node_id);
|
||||
|
@ -26,16 +26,14 @@ namespace osrm::extractor::intersection
|
||||
|
||||
inline auto makeCompareAngularDeviation(const double angle)
|
||||
{
|
||||
return [angle](const auto &lhs, const auto &rhs) {
|
||||
return util::angularDeviation(lhs.angle, angle) < util::angularDeviation(rhs.angle, angle);
|
||||
};
|
||||
return [angle](const auto &lhs, const auto &rhs)
|
||||
{ return util::angularDeviation(lhs.angle, angle) < util::angularDeviation(rhs.angle, angle); };
|
||||
}
|
||||
|
||||
inline auto makeExtractLanesForRoad(const util::NodeBasedDynamicGraph &node_based_graph)
|
||||
{
|
||||
return [&node_based_graph](const auto &road) {
|
||||
return node_based_graph.GetEdgeData(road.eid).road_classification.GetNumberOfLanes();
|
||||
};
|
||||
return [&node_based_graph](const auto &road)
|
||||
{ return node_based_graph.GetEdgeData(road.eid).road_classification.GetNumberOfLanes(); };
|
||||
}
|
||||
|
||||
// When viewing an intersection from an incoming edge, we can transform a shape into a view which
|
||||
@ -63,7 +61,10 @@ template <typename Self> struct EnableShapeOps
|
||||
auto FindClosestBearing(double base_bearing) const
|
||||
{
|
||||
return std::min_element(
|
||||
self()->begin(), self()->end(), [base_bearing](const auto &lhs, const auto &rhs) {
|
||||
self()->begin(),
|
||||
self()->end(),
|
||||
[base_bearing](const auto &lhs, const auto &rhs)
|
||||
{
|
||||
return util::angularDeviation(lhs.perceived_bearing, base_bearing) <
|
||||
util::angularDeviation(rhs.perceived_bearing, base_bearing);
|
||||
});
|
||||
@ -81,7 +82,8 @@ template <typename Self> struct EnableShapeOps
|
||||
BOOST_ASSERT(!self()->empty());
|
||||
auto initial = converter(self()->front());
|
||||
|
||||
const auto extract_maximal_value = [&initial, converter](const auto &road) {
|
||||
const auto extract_maximal_value = [&initial, converter](const auto &road)
|
||||
{
|
||||
initial = std::max(initial, converter(road));
|
||||
return false;
|
||||
};
|
||||
@ -191,8 +193,10 @@ template <typename Self> struct EnableIntersectionOps
|
||||
auto findClosestTurn(const double angle, const UnaryPredicate filter) const
|
||||
{
|
||||
BOOST_ASSERT(!self()->empty());
|
||||
const auto candidate =
|
||||
boost::range::min_element(*self(), [angle, &filter](const auto &lhs, const auto &rhs) {
|
||||
const auto candidate = boost::range::min_element(
|
||||
*self(),
|
||||
[angle, &filter](const auto &lhs, const auto &rhs)
|
||||
{
|
||||
const auto filtered_lhs = filter(lhs), filtered_rhs = filter(rhs);
|
||||
const auto deviation_lhs = util::angularDeviation(lhs.angle, angle),
|
||||
deviation_rhs = util::angularDeviation(rhs.angle, angle);
|
||||
|
@ -32,9 +32,8 @@ template <typename RestrictionFilter> class NodeRestrictionMap
|
||||
// Find all restrictions applicable to (from,via,to) turns
|
||||
auto Restrictions(NodeID from, NodeID via, NodeID to) const
|
||||
{
|
||||
const auto turnFilter = [this, to](const auto &restriction) {
|
||||
return index_filter(restriction) && restriction->IsTurnRestricted(to);
|
||||
};
|
||||
const auto turnFilter = [this, to](const auto &restriction)
|
||||
{ return index_filter(restriction) && restriction->IsTurnRestricted(to); };
|
||||
return getRange(from, via) | boost::adaptors::filtered(turnFilter);
|
||||
};
|
||||
|
||||
|
@ -187,11 +187,11 @@ IntersectionHandler::IsDistinctNarrowTurn(const EdgeID via_edge,
|
||||
node_data_container.GetAnnotation(candidate_data.annotation_data);
|
||||
auto const candidate_deviation = util::angularDeviation(candidate->angle, STRAIGHT_ANGLE);
|
||||
|
||||
auto const num_lanes = [](auto const &data) {
|
||||
return data.flags.road_classification.GetNumberOfLanes();
|
||||
};
|
||||
auto const num_lanes = [](auto const &data)
|
||||
{ return data.flags.road_classification.GetNumberOfLanes(); };
|
||||
|
||||
auto const lanes_number_equal = [&](auto const &compare_data) {
|
||||
auto const lanes_number_equal = [&](auto const &compare_data)
|
||||
{
|
||||
// Check if the lanes number is the same going from the inbound edge to the compare road
|
||||
return num_lanes(compare_data) > 0 && num_lanes(compare_data) == num_lanes(via_edge_data);
|
||||
};
|
||||
@ -210,7 +210,8 @@ IntersectionHandler::IsDistinctNarrowTurn(const EdgeID via_edge,
|
||||
|
||||
// check if there are other narrow turns are not considered passing a low category or simply
|
||||
// a link of the same type as the potentially obvious turn
|
||||
auto const is_similar_turn = [&](auto const &road) {
|
||||
auto const is_similar_turn = [&](auto const &road)
|
||||
{
|
||||
// 1. Skip the candidate road
|
||||
if (road.eid == candidate->eid)
|
||||
{
|
||||
@ -405,7 +406,8 @@ IntersectionHandler::IsDistinctWideTurn(const EdgeID via_edge,
|
||||
// Deviation is larger than NARROW_TURN_ANGLE0 here for the candidate
|
||||
// check if there is any turn, that might look just as obvious, even though it might not
|
||||
// be allowed. Entry-allowed isn't considered a valid distinction criterion here
|
||||
auto const is_similar_turn = [&](auto const &road) {
|
||||
auto const is_similar_turn = [&](auto const &road)
|
||||
{
|
||||
// 1. Skip over our candidate
|
||||
if (road.eid == candidate->eid)
|
||||
return false;
|
||||
@ -503,7 +505,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
||||
node_data_container.GetAnnotation(via_edge_data.annotation_data);
|
||||
|
||||
// implement a filter, taking out all roads of lower class or different names
|
||||
auto const continues_on_name_with_higher_class = [&](auto const &road) {
|
||||
auto const continues_on_name_with_higher_class = [&](auto const &road)
|
||||
{
|
||||
// it needs to be possible to enter the road
|
||||
if (!road.entry_allowed)
|
||||
return true;
|
||||
@ -550,7 +553,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
||||
|
||||
// this check is not part of the main conditions, so that if the turn looks obvious from all
|
||||
// other perspectives, a mode change will not result in different classification
|
||||
auto const to_index_if_valid = [&](auto const iterator) -> std::size_t {
|
||||
auto const to_index_if_valid = [&](auto const iterator) -> std::size_t
|
||||
{
|
||||
auto const &from_data = node_based_graph.GetEdgeData(via_edge);
|
||||
auto const &to_data = node_based_graph.GetEdgeData(iterator->eid);
|
||||
|
||||
@ -577,7 +581,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
||||
|
||||
// opposed to before, we do not care about name changes, again: this is a filter, so internal
|
||||
// false/true will be negated for selection
|
||||
auto const valid_of_higher_or_same_category = [&](auto const &road) {
|
||||
auto const valid_of_higher_or_same_category = [&](auto const &road)
|
||||
{
|
||||
if (!road.entry_allowed)
|
||||
return true;
|
||||
|
||||
@ -640,7 +645,8 @@ std::size_t IntersectionHandler::findObviousTurn(const EdgeID via_edge,
|
||||
const auto all_roads_have_same_name =
|
||||
std::all_of(intersection.begin(),
|
||||
intersection.end(),
|
||||
[id = via_edge_annotation.name_id, this](auto const &road) {
|
||||
[id = via_edge_annotation.name_id, this](auto const &road)
|
||||
{
|
||||
auto const data_id = node_based_graph.GetEdgeData(road.eid).annotation_data;
|
||||
auto const name_id = node_data_container.GetAnnotation(data_id).name_id;
|
||||
return (name_id != EMPTY_NAMEID) && (name_id == id);
|
||||
|
@ -65,8 +65,8 @@ inline BisectionGraph makeBisectionGraph(const std::vector<util::Coordinate> &co
|
||||
result_edges.reserve(edges.size());
|
||||
|
||||
// find the end of edges that belong to node_id
|
||||
const auto advance_edge_itr = [&edges, &result_edges](const std::size_t node_id,
|
||||
auto edge_itr) {
|
||||
const auto advance_edge_itr = [&edges, &result_edges](const std::size_t node_id, auto edge_itr)
|
||||
{
|
||||
while (edge_itr != edges.end() && edge_itr->source == node_id)
|
||||
{
|
||||
result_edges.push_back(edge_itr->Reduce());
|
||||
@ -76,9 +76,9 @@ inline BisectionGraph makeBisectionGraph(const std::vector<util::Coordinate> &co
|
||||
};
|
||||
|
||||
// create a bisection node, requires the ID of the node as well as the lower bound to its edges
|
||||
const auto make_bisection_node = [&edges, &coordinates](const std::size_t node_id,
|
||||
const auto begin_itr,
|
||||
const auto end_itr) {
|
||||
const auto make_bisection_node =
|
||||
[&edges, &coordinates](const std::size_t node_id, const auto begin_itr, const auto end_itr)
|
||||
{
|
||||
std::size_t range_begin = std::distance(edges.begin(), begin_itr);
|
||||
std::size_t range_end = std::distance(edges.begin(), end_itr);
|
||||
return BisectionGraph::NodeT(range_begin, range_end, coordinates[node_id], node_id);
|
||||
@ -102,9 +102,12 @@ std::vector<BisectionInputEdge> adaptToBisectionEdge(std::vector<InputEdge> edge
|
||||
std::vector<BisectionInputEdge> result;
|
||||
result.reserve(edges.size());
|
||||
|
||||
std::transform(begin(edges), end(edges), std::back_inserter(result), [](const auto &edge) {
|
||||
return BisectionInputEdge{edge.source, edge.target};
|
||||
});
|
||||
std::transform(begin(edges),
|
||||
end(edges),
|
||||
std::back_inserter(result),
|
||||
[](const auto &edge) {
|
||||
return BisectionInputEdge{edge.source, edge.target};
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -298,7 +298,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
auto set_num_nodes_fn,
|
||||
auto set_boundary_offset_fn,
|
||||
auto begin,
|
||||
auto end) {
|
||||
auto end)
|
||||
{
|
||||
BOOST_ASSERT(std::distance(begin, end) > 0);
|
||||
|
||||
const auto cell_id = begin->first;
|
||||
@ -316,7 +317,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
util::for_each_range(
|
||||
level_source_boundary.begin(),
|
||||
level_source_boundary.end(),
|
||||
[this, insert_cell_boundary](auto begin, auto end) {
|
||||
[this, insert_cell_boundary](auto begin, auto end)
|
||||
{
|
||||
insert_cell_boundary(
|
||||
source_boundary,
|
||||
[](auto &cell, auto value) { cell.num_source_nodes = value; },
|
||||
@ -327,7 +329,8 @@ template <storage::Ownership Ownership> class CellStorageImpl
|
||||
util::for_each_range(
|
||||
level_destination_boundary.begin(),
|
||||
level_destination_boundary.end(),
|
||||
[this, insert_cell_boundary](auto begin, auto end) {
|
||||
[this, insert_cell_boundary](auto begin, auto end)
|
||||
{
|
||||
insert_cell_boundary(
|
||||
destination_boundary,
|
||||
[](auto &cell, auto value) { cell.num_destination_nodes = value; },
|
||||
|
@ -64,10 +64,13 @@ std::vector<OutputEdgeT> prepareEdgesForUsageInGraph(std::vector<extractor::Edge
|
||||
// sort into blocks of edges with same source + target
|
||||
// the we partition by the forward flag to sort all edges with a forward direction first.
|
||||
// the we sort by weight to ensure the first forward edge is the smallest forward edge
|
||||
std::sort(begin(edges), end(edges), [](const auto &lhs, const auto &rhs) {
|
||||
return std::tie(lhs.source, lhs.target, rhs.data.forward, lhs.data.weight) <
|
||||
std::tie(rhs.source, rhs.target, lhs.data.forward, rhs.data.weight);
|
||||
});
|
||||
std::sort(begin(edges),
|
||||
end(edges),
|
||||
[](const auto &lhs, const auto &rhs)
|
||||
{
|
||||
return std::tie(lhs.source, lhs.target, rhs.data.forward, lhs.data.weight) <
|
||||
std::tie(rhs.source, rhs.target, lhs.data.forward, rhs.data.weight);
|
||||
});
|
||||
|
||||
std::vector<OutputEdgeT> output_edges;
|
||||
output_edges.reserve(edges.size());
|
||||
@ -77,10 +80,11 @@ std::vector<OutputEdgeT> prepareEdgesForUsageInGraph(std::vector<extractor::Edge
|
||||
const NodeID source = begin_interval->source;
|
||||
const NodeID target = begin_interval->target;
|
||||
|
||||
auto end_interval =
|
||||
std::find_if_not(begin_interval, edges.end(), [source, target](const auto &edge) {
|
||||
return std::tie(edge.source, edge.target) == std::tie(source, target);
|
||||
});
|
||||
auto end_interval = std::find_if_not(
|
||||
begin_interval,
|
||||
edges.end(),
|
||||
[source, target](const auto &edge)
|
||||
{ return std::tie(edge.source, edge.target) == std::tie(source, target); });
|
||||
BOOST_ASSERT(begin_interval != end_interval);
|
||||
|
||||
// remove eigenloops
|
||||
@ -144,7 +148,8 @@ graphToEdges(const DynamicEdgeBasedGraph &edge_based_graph)
|
||||
auto max_turn_id = tbb::parallel_reduce(
|
||||
range,
|
||||
NodeID{0},
|
||||
[&edge_based_graph](const auto range, NodeID initial) {
|
||||
[&edge_based_graph](const auto range, NodeID initial)
|
||||
{
|
||||
NodeID max_turn_id = initial;
|
||||
for (auto node = range.begin(); node < range.end(); ++node)
|
||||
{
|
||||
@ -159,26 +164,29 @@ graphToEdges(const DynamicEdgeBasedGraph &edge_based_graph)
|
||||
[](const NodeID lhs, const NodeID rhs) { return std::max(lhs, rhs); });
|
||||
|
||||
std::vector<extractor::EdgeBasedEdge> edges(max_turn_id + 1);
|
||||
tbb::parallel_for(range, [&](const auto range) {
|
||||
for (auto node = range.begin(); node < range.end(); ++node)
|
||||
tbb::parallel_for(
|
||||
range,
|
||||
[&](const auto range)
|
||||
{
|
||||
for (auto edge : edge_based_graph.GetAdjacentEdgeRange(node))
|
||||
for (auto node = range.begin(); node < range.end(); ++node)
|
||||
{
|
||||
const auto &data = edge_based_graph.GetEdgeData(edge);
|
||||
// we only need to save the forward edges, since the read method will
|
||||
// convert from forward to bi-directional edges again
|
||||
if (data.forward)
|
||||
for (auto edge : edge_based_graph.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
auto target = edge_based_graph.GetTarget(edge);
|
||||
BOOST_ASSERT(data.turn_id <= max_turn_id);
|
||||
edges[data.turn_id] = extractor::EdgeBasedEdge{node, target, data};
|
||||
// only save the forward edge
|
||||
edges[data.turn_id].data.forward = true;
|
||||
edges[data.turn_id].data.backward = false;
|
||||
const auto &data = edge_based_graph.GetEdgeData(edge);
|
||||
// we only need to save the forward edges, since the read method will
|
||||
// convert from forward to bi-directional edges again
|
||||
if (data.forward)
|
||||
{
|
||||
auto target = edge_based_graph.GetTarget(edge);
|
||||
BOOST_ASSERT(data.turn_id <= max_turn_id);
|
||||
edges[data.turn_id] = extractor::EdgeBasedEdge{node, target, data};
|
||||
// only save the forward edge
|
||||
edges[data.turn_id].data.forward = true;
|
||||
edges[data.turn_id].data.backward = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
@ -159,10 +159,11 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
|
||||
auto GetHighestBorderLevel(const MultiLevelPartition &mlp, const ContainerT &edges) const
|
||||
{
|
||||
std::vector<LevelID> highest_border_level(edges.size());
|
||||
std::transform(
|
||||
edges.begin(), edges.end(), highest_border_level.begin(), [&mlp](const auto &edge) {
|
||||
return mlp.GetHighestDifferentLevel(edge.source, edge.target);
|
||||
});
|
||||
std::transform(edges.begin(),
|
||||
edges.end(),
|
||||
highest_border_level.begin(),
|
||||
[&mlp](const auto &edge)
|
||||
{ return mlp.GetHighestDifferentLevel(edge.source, edge.target); });
|
||||
return highest_border_level;
|
||||
}
|
||||
|
||||
@ -175,7 +176,8 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
|
||||
tbb::parallel_sort(
|
||||
permutation.begin(),
|
||||
permutation.end(),
|
||||
[&edges, &highest_border_level](const auto &lhs, const auto &rhs) {
|
||||
[&edges, &highest_border_level](const auto &lhs, const auto &rhs)
|
||||
{
|
||||
// sort by source node and then by level in ascending order
|
||||
return std::tie(edges[lhs].source, highest_border_level[lhs], edges[lhs].target) <
|
||||
std::tie(edges[rhs].source, highest_border_level[rhs], edges[rhs].target);
|
||||
@ -201,11 +203,12 @@ class MultiLevelGraph : public util::StaticGraph<EdgeDataT, Ownership>
|
||||
auto level_begin = iter;
|
||||
for (auto level : util::irange<LevelID>(0, mlp.GetNumberOfLevels()))
|
||||
{
|
||||
iter = std::find_if(
|
||||
iter, edge_and_level_end, [node, level](const auto &edge_and_level) {
|
||||
return boost::get<0>(edge_and_level).source != node ||
|
||||
boost::get<1>(edge_and_level) != level;
|
||||
});
|
||||
iter = std::find_if(iter,
|
||||
edge_and_level_end,
|
||||
[node, level](const auto &edge_and_level) {
|
||||
return boost::get<0>(edge_and_level).source != node ||
|
||||
boost::get<1>(edge_and_level) != level;
|
||||
});
|
||||
EdgeOffset offset = std::distance(level_begin, iter);
|
||||
node_to_edge_offset.push_back(offset);
|
||||
}
|
||||
|
@ -207,7 +207,8 @@ template <storage::Ownership Ownership> class MultiLevelPartitionImpl final
|
||||
auto lidx = 0UL;
|
||||
util::for_each_pair(level_offsets.begin(),
|
||||
level_offsets.begin() + num_level,
|
||||
[&](const auto offset, const auto next_offset) {
|
||||
[&](const auto offset, const auto next_offset)
|
||||
{
|
||||
// create mask that has `bits` ones at its LSBs.
|
||||
// 000011
|
||||
BOOST_ASSERT(offset <= NUM_PARTITION_BITS);
|
||||
@ -274,9 +275,8 @@ template <storage::Ownership Ownership> class MultiLevelPartitionImpl final
|
||||
{
|
||||
std::stable_sort(permutation.begin(),
|
||||
permutation.end(),
|
||||
[&partition](const auto lhs, const auto rhs) {
|
||||
return partition[lhs] < partition[rhs];
|
||||
});
|
||||
[&partition](const auto lhs, const auto rhs)
|
||||
{ return partition[lhs] < partition[rhs]; });
|
||||
}
|
||||
|
||||
// top down assign new cell ids
|
||||
|
@ -21,7 +21,7 @@ template <typename Base> class NodeEntryWrapper : public Base
|
||||
{
|
||||
public:
|
||||
template <typename... Args>
|
||||
NodeEntryWrapper(std::size_t edges_begin_, std::size_t edges_end_, Args &&... args)
|
||||
NodeEntryWrapper(std::size_t edges_begin_, std::size_t edges_end_, Args &&...args)
|
||||
: Base(std::forward<Args>(args)...), edges_begin(edges_begin_), edges_end(edges_end_)
|
||||
{
|
||||
}
|
||||
@ -41,7 +41,7 @@ template <typename Base> class GraphConstructionWrapper : public Base
|
||||
{
|
||||
public:
|
||||
template <typename... Args>
|
||||
GraphConstructionWrapper(const NodeID source_, Args &&... args)
|
||||
GraphConstructionWrapper(const NodeID source_, Args &&...args)
|
||||
: Base(std::forward<Args>(args)...), source(source_)
|
||||
{
|
||||
}
|
||||
|
@ -59,11 +59,13 @@ std::size_t removeUnconnectedBoundaryNodes(const GraphT &edge_based_graph,
|
||||
|
||||
if (level_index < static_cast<int>(partitions.size() - 1))
|
||||
{
|
||||
auto new_end = std::remove_if(
|
||||
witnesses.begin(), witnesses.end(), [&](const auto &witness) {
|
||||
return partitions[level_index + 1][node] !=
|
||||
partitions[level_index + 1][witness.id];
|
||||
});
|
||||
auto new_end =
|
||||
std::remove_if(witnesses.begin(),
|
||||
witnesses.end(),
|
||||
[&](const auto &witness) {
|
||||
return partitions[level_index + 1][node] !=
|
||||
partitions[level_index + 1][witness.id];
|
||||
});
|
||||
witnesses.resize(new_end - witnesses.begin());
|
||||
}
|
||||
if (witnesses.size() == 0)
|
||||
@ -87,10 +89,12 @@ std::size_t removeUnconnectedBoundaryNodes(const GraphT &edge_based_graph,
|
||||
}
|
||||
}
|
||||
|
||||
auto best_witness = std::min_element(
|
||||
witnesses.begin(), witnesses.end(), [](const auto &lhs, const auto &rhs) {
|
||||
return lhs.induced_border_edges < rhs.induced_border_edges;
|
||||
});
|
||||
auto best_witness =
|
||||
std::min_element(witnesses.begin(),
|
||||
witnesses.end(),
|
||||
[](const auto &lhs, const auto &rhs) {
|
||||
return lhs.induced_border_edges < rhs.induced_border_edges;
|
||||
});
|
||||
BOOST_ASSERT(best_witness != witnesses.end());
|
||||
|
||||
// assign `node` to same subcells as `best_witness`
|
||||
|
@ -30,10 +30,10 @@ void reorderFirstLast(RandomIt first, RandomIt last, std::size_t n, Comparator c
|
||||
// requirements.
|
||||
std::reverse_iterator<RandomIt> rfirst{last}, rlast{first + n};
|
||||
|
||||
const auto flipped = [](auto fn) {
|
||||
return [fn](auto &&lhs, auto &&rhs) {
|
||||
return fn(std::forward<decltype(lhs)>(rhs), std::forward<decltype(rhs)>(lhs));
|
||||
};
|
||||
const auto flipped = [](auto fn)
|
||||
{
|
||||
return [fn](auto &&lhs, auto &&rhs)
|
||||
{ return fn(std::forward<decltype(lhs)>(rhs), std::forward<decltype(rhs)>(lhs)); };
|
||||
};
|
||||
|
||||
std::nth_element(rfirst, rfirst + (n - 1), rlast, flipped(comp));
|
||||
|
@ -74,16 +74,16 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
||||
: BaseParametersGrammar::base_type(root_rule)
|
||||
{
|
||||
const auto add_hint = [](engine::api::BaseParameters &base_parameters,
|
||||
const std::vector<std::string> &hint_strings) {
|
||||
const std::vector<std::string> &hint_strings)
|
||||
{
|
||||
if (!hint_strings.empty())
|
||||
{
|
||||
std::vector<engine::SegmentHint> location_hints(hint_strings.size());
|
||||
std::transform(hint_strings.begin(),
|
||||
hint_strings.end(),
|
||||
location_hints.begin(),
|
||||
[](const auto &hint_string) {
|
||||
return engine::SegmentHint::FromBase64(hint_string);
|
||||
});
|
||||
[](const auto &hint_string)
|
||||
{ return engine::SegmentHint::FromBase64(hint_string); });
|
||||
base_parameters.hints.push_back(engine::Hint{std::move(location_hints)});
|
||||
}
|
||||
else
|
||||
@ -94,15 +94,16 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
||||
|
||||
const auto add_bearing =
|
||||
[](engine::api::BaseParameters &base_parameters,
|
||||
boost::optional<boost::fusion::vector2<short, short>> bearing_range) {
|
||||
boost::optional<engine::Bearing> bearing;
|
||||
if (bearing_range)
|
||||
{
|
||||
bearing = engine::Bearing{boost::fusion::at_c<0>(*bearing_range),
|
||||
boost::fusion::at_c<1>(*bearing_range)};
|
||||
}
|
||||
base_parameters.bearings.push_back(std::move(bearing));
|
||||
};
|
||||
boost::optional<boost::fusion::vector2<short, short>> bearing_range)
|
||||
{
|
||||
boost::optional<engine::Bearing> bearing;
|
||||
if (bearing_range)
|
||||
{
|
||||
bearing = engine::Bearing{boost::fusion::at_c<0>(*bearing_range),
|
||||
boost::fusion::at_c<1>(*bearing_range)};
|
||||
}
|
||||
base_parameters.bearings.push_back(std::move(bearing));
|
||||
};
|
||||
|
||||
polyline_chars = qi::char_("a-zA-Z0-9_.--[]{}@?|\\%~`^");
|
||||
base64_char = qi::char_("a-zA-Z0-9--_=");
|
||||
@ -118,7 +119,8 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
||||
|
||||
location_rule = (double_ > qi::lit(',') >
|
||||
double_)[qi::_val = ph::bind(
|
||||
[](double lon, double lat) {
|
||||
[](double lon, double lat)
|
||||
{
|
||||
return util::Coordinate(
|
||||
util::toFixed(util::UnsafeFloatLongitude{lon}),
|
||||
util::toFixed(util::UnsafeFloatLatitude{lat}));
|
||||
@ -126,19 +128,17 @@ struct BaseParametersGrammar : boost::spirit::qi::grammar<Iterator, Signature>
|
||||
qi::_1,
|
||||
qi::_2)];
|
||||
|
||||
polyline_rule = qi::as_string[qi::lit("polyline(") > +polyline_chars > ')']
|
||||
[qi::_val = ph::bind(
|
||||
[](const std::string &polyline) {
|
||||
return engine::decodePolyline(polyline);
|
||||
},
|
||||
qi::_1)];
|
||||
polyline_rule =
|
||||
qi::as_string[qi::lit("polyline(") > +polyline_chars > ')']
|
||||
[qi::_val = ph::bind([](const std::string &polyline)
|
||||
{ return engine::decodePolyline(polyline); },
|
||||
qi::_1)];
|
||||
|
||||
polyline6_rule = qi::as_string[qi::lit("polyline6(") > +polyline_chars > ')']
|
||||
[qi::_val = ph::bind(
|
||||
[](const std::string &polyline) {
|
||||
return engine::decodePolyline<1000000>(polyline);
|
||||
},
|
||||
qi::_1)];
|
||||
polyline6_rule =
|
||||
qi::as_string[qi::lit("polyline6(") > +polyline_chars > ')']
|
||||
[qi::_val = ph::bind([](const std::string &polyline)
|
||||
{ return engine::decodePolyline<1000000>(polyline); },
|
||||
qi::_1)];
|
||||
|
||||
query_rule =
|
||||
((location_rule % ';') | polyline_rule |
|
||||
|
@ -54,8 +54,9 @@ struct RouteParametersGrammar : public BaseParametersGrammar<Iterator, Signature
|
||||
#endif
|
||||
using AnnotationsType = engine::api::RouteParameters::AnnotationsType;
|
||||
|
||||
const auto add_annotation = [](engine::api::RouteParameters &route_parameters,
|
||||
AnnotationsType route_param) {
|
||||
const auto add_annotation =
|
||||
[](engine::api::RouteParameters &route_parameters, AnnotationsType route_param)
|
||||
{
|
||||
route_parameters.annotations_type = route_parameters.annotations_type | route_param;
|
||||
route_parameters.annotations =
|
||||
route_parameters.annotations_type != AnnotationsType::None;
|
||||
|
@ -66,7 +66,8 @@ void readBoolVector(tar::FileReader &reader, const std::string &name, VectorT &d
|
||||
using BlockType = std::uint64_t;
|
||||
constexpr std::uint64_t BLOCK_BITS = CHAR_BIT * sizeof(BlockType);
|
||||
|
||||
const auto decode = [&](const BlockType block) {
|
||||
const auto decode = [&](const BlockType block)
|
||||
{
|
||||
auto read_size = std::min<std::size_t>(count - index, BLOCK_BITS);
|
||||
unpackBits<VectorT, BlockType>(data, index, read_size, block);
|
||||
index += BLOCK_BITS;
|
||||
@ -87,7 +88,8 @@ void writeBoolVector(tar::FileWriter &writer, const std::string &name, const Vec
|
||||
|
||||
// FIXME on old boost version the function_input_iterator does not work with lambdas
|
||||
// so we need to wrap it in a function here.
|
||||
const std::function<BlockType()> encode_function = [&]() -> BlockType {
|
||||
const std::function<BlockType()> encode_function = [&]() -> BlockType
|
||||
{
|
||||
auto write_size = std::min<std::size_t>(count - index, BLOCK_BITS);
|
||||
auto packed = packBits<VectorT, BlockType>(data, index, write_size);
|
||||
index += BLOCK_BITS;
|
||||
|
@ -28,10 +28,10 @@ class SharedDataIndex
|
||||
// Build mapping from block name to region
|
||||
for (auto index : util::irange<std::uint32_t>(0, regions.size()))
|
||||
{
|
||||
regions[index].layout->List("",
|
||||
boost::make_function_output_iterator([&](const auto &name) {
|
||||
block_to_region[name] = index;
|
||||
}));
|
||||
regions[index].layout->List(
|
||||
"",
|
||||
boost::make_function_output_iterator([&](const auto &name)
|
||||
{ block_to_region[name] = index; }));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,9 +223,12 @@ struct SharedRegionRegister
|
||||
// Returns the key of the region with the given name
|
||||
RegionID Find(const std::string &name) const
|
||||
{
|
||||
auto iter = std::find_if(regions.begin(), regions.end(), [&](const auto ®ion) {
|
||||
return std::strncmp(region.name, name.c_str(), SharedRegion::MAX_NAME_LENGTH) == 0;
|
||||
});
|
||||
auto iter = std::find_if(
|
||||
regions.begin(),
|
||||
regions.end(),
|
||||
[&](const auto ®ion) {
|
||||
return std::strncmp(region.name, name.c_str(), SharedRegion::MAX_NAME_LENGTH) == 0;
|
||||
});
|
||||
|
||||
if (iter == regions.end())
|
||||
{
|
||||
|
@ -113,7 +113,8 @@ class SharedMemory
|
||||
{
|
||||
auto shmid = shm.get_shmid();
|
||||
::shmid_ds xsi_ds;
|
||||
const auto errorToMessage = [](int error) -> std::string {
|
||||
const auto errorToMessage = [](int error) -> std::string
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case EPERM:
|
||||
|
@ -241,9 +241,9 @@ inline auto make_contracted_metric_view(const SharedDataIndex &index, const std:
|
||||
|
||||
std::vector<util::vector_view<bool>> edge_filter;
|
||||
index.List(name + "/exclude",
|
||||
boost::make_function_output_iterator([&](const auto &filter_name) {
|
||||
edge_filter.push_back(make_vector_view<bool>(index, filter_name));
|
||||
}));
|
||||
boost::make_function_output_iterator(
|
||||
[&](const auto &filter_name)
|
||||
{ edge_filter.push_back(make_vector_view<bool>(index, filter_name)); }));
|
||||
|
||||
return contractor::ContractedMetricView{{node_list, edge_list}, std::move(edge_filter)};
|
||||
}
|
||||
|
@ -46,31 +46,36 @@ template <typename Key, typename Value> struct CSVFilesParser
|
||||
{
|
||||
tbb::spin_mutex mutex;
|
||||
std::vector<std::pair<Key, Value>> lookup;
|
||||
tbb::parallel_for(std::size_t{0}, csv_filenames.size(), [&](const std::size_t idx) {
|
||||
auto local = ParseCSVFile(csv_filenames[idx], start_index + idx);
|
||||
tbb::parallel_for(std::size_t{0},
|
||||
csv_filenames.size(),
|
||||
[&](const std::size_t idx)
|
||||
{
|
||||
auto local = ParseCSVFile(csv_filenames[idx], start_index + idx);
|
||||
|
||||
{ // Merge local CSV results into a flat global vector
|
||||
tbb::spin_mutex::scoped_lock _{mutex};
|
||||
lookup.insert(end(lookup),
|
||||
std::make_move_iterator(begin(local)),
|
||||
std::make_move_iterator(end(local)));
|
||||
}
|
||||
});
|
||||
{ // Merge local CSV results into a flat global vector
|
||||
tbb::spin_mutex::scoped_lock _{mutex};
|
||||
lookup.insert(end(lookup),
|
||||
std::make_move_iterator(begin(local)),
|
||||
std::make_move_iterator(end(local)));
|
||||
}
|
||||
});
|
||||
|
||||
// With flattened map-ish view of all the files, make a stable sort on key and source
|
||||
// and unique them on key to keep only the value with the largest file index
|
||||
// and the largest line number in a file.
|
||||
// The operands order is swapped to make descending ordering on (key, source)
|
||||
tbb::parallel_sort(begin(lookup), end(lookup), [](const auto &lhs, const auto &rhs) {
|
||||
return std::tie(rhs.first, rhs.second.source) <
|
||||
std::tie(lhs.first, lhs.second.source);
|
||||
});
|
||||
tbb::parallel_sort(begin(lookup),
|
||||
end(lookup),
|
||||
[](const auto &lhs, const auto &rhs) {
|
||||
return std::tie(rhs.first, rhs.second.source) <
|
||||
std::tie(lhs.first, lhs.second.source);
|
||||
});
|
||||
|
||||
// Unique only on key to take the source precedence into account and remove duplicates.
|
||||
const auto it =
|
||||
std::unique(begin(lookup), end(lookup), [](const auto &lhs, const auto &rhs) {
|
||||
return lhs.first == rhs.first;
|
||||
});
|
||||
const auto it = std::unique(begin(lookup),
|
||||
end(lookup),
|
||||
[](const auto &lhs, const auto &rhs)
|
||||
{ return lhs.first == rhs.first; });
|
||||
lookup.erase(it, end(lookup));
|
||||
|
||||
util::Log() << "In total loaded " << csv_filenames.size() << " file(s) with a total of "
|
||||
|
@ -15,10 +15,11 @@ template <typename Key, typename Value> struct LookupTable
|
||||
boost::optional<Value> operator()(const Key &key) const
|
||||
{
|
||||
using Result = boost::optional<Value>;
|
||||
const auto it = std::lower_bound(
|
||||
lookup.begin(), lookup.end(), key, [](const auto &lhs, const auto &rhs) {
|
||||
return rhs < lhs.first;
|
||||
});
|
||||
const auto it =
|
||||
std::lower_bound(lookup.begin(),
|
||||
lookup.end(),
|
||||
key,
|
||||
[](const auto &lhs, const auto &rhs) { return rhs < lhs.first; });
|
||||
return it != std::end(lookup) && !(it->first < key) ? Result(it->second) : Result();
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ template <typename From, typename Tag> struct Alias final
|
||||
static_assert(std::is_arithmetic<From>::value, "Needs to be based on an arithmetic type");
|
||||
|
||||
From __value;
|
||||
friend std::ostream &operator<<<From, Tag>(std::ostream &stream, const Alias &inst);
|
||||
friend std::ostream &operator<< <From, Tag>(std::ostream &stream, const Alias &inst);
|
||||
|
||||
explicit operator From &() { return __value; }
|
||||
explicit operator From() const { return __value; }
|
||||
|
@ -179,7 +179,8 @@ template <class BinaryOperation, typename iterator_type>
|
||||
double getLength(iterator_type begin, const iterator_type end, BinaryOperation op)
|
||||
{
|
||||
double result = 0;
|
||||
const auto functor = [&result, op](const Coordinate lhs, const Coordinate rhs) {
|
||||
const auto functor = [&result, op](const Coordinate lhs, const Coordinate rhs)
|
||||
{
|
||||
result += op(lhs, rhs);
|
||||
return false;
|
||||
};
|
||||
@ -197,8 +198,9 @@ findClosestDistance(const Coordinate coordinate, const iterator_type begin, cons
|
||||
double current_min = std::numeric_limits<double>::max();
|
||||
|
||||
// comparator updating current_min without ever finding an element
|
||||
const auto compute_minimum_distance = [¤t_min, coordinate](const Coordinate lhs,
|
||||
const Coordinate rhs) {
|
||||
const auto compute_minimum_distance =
|
||||
[¤t_min, coordinate](const Coordinate lhs, const Coordinate rhs)
|
||||
{
|
||||
current_min = std::min(current_min, findClosestDistance(coordinate, lhs, rhs));
|
||||
return false;
|
||||
};
|
||||
@ -216,8 +218,9 @@ double findClosestDistance(const iterator_type lhs_begin,
|
||||
{
|
||||
double current_min = std::numeric_limits<double>::max();
|
||||
|
||||
const auto compute_minimum_distance_in_rhs = [¤t_min, rhs_begin, rhs_end](
|
||||
const Coordinate coordinate) {
|
||||
const auto compute_minimum_distance_in_rhs =
|
||||
[¤t_min, rhs_begin, rhs_end](const Coordinate coordinate)
|
||||
{
|
||||
current_min = std::min(current_min, findClosestDistance(coordinate, rhs_begin, rhs_end));
|
||||
return false;
|
||||
};
|
||||
@ -233,13 +236,11 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
|
||||
// following the formulas of https://faculty.elgin.edu/dkernler/statistics/ch04/4-2.html
|
||||
const auto number_of_coordinates = std::distance(begin, end);
|
||||
BOOST_ASSERT(number_of_coordinates >= 2);
|
||||
const auto extract_lon = [](const Coordinate coordinate) {
|
||||
return static_cast<double>(toFloating(coordinate.lon));
|
||||
};
|
||||
const auto extract_lon = [](const Coordinate coordinate)
|
||||
{ return static_cast<double>(toFloating(coordinate.lon)); };
|
||||
|
||||
const auto extract_lat = [](const Coordinate coordinate) {
|
||||
return static_cast<double>(toFloating(coordinate.lat));
|
||||
};
|
||||
const auto extract_lat = [](const Coordinate coordinate)
|
||||
{ return static_cast<double>(toFloating(coordinate.lat)); };
|
||||
|
||||
double min_lon = extract_lon(*begin);
|
||||
double max_lon = extract_lon(*begin);
|
||||
@ -262,19 +263,21 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
|
||||
{
|
||||
std::vector<util::Coordinate> rotated_coordinates(number_of_coordinates);
|
||||
// rotate all coordinates to the right
|
||||
std::transform(begin, end, rotated_coordinates.begin(), [](const auto coordinate) {
|
||||
return rotateCCWAroundZero(coordinate, detail::degToRad(-90));
|
||||
});
|
||||
std::transform(begin,
|
||||
end,
|
||||
rotated_coordinates.begin(),
|
||||
[](const auto coordinate)
|
||||
{ return rotateCCWAroundZero(coordinate, detail::degToRad(-90)); });
|
||||
const auto rotated_regression =
|
||||
leastSquareRegression(rotated_coordinates.begin(), rotated_coordinates.end());
|
||||
return {rotateCCWAroundZero(rotated_regression.first, detail::degToRad(90)),
|
||||
rotateCCWAroundZero(rotated_regression.second, detail::degToRad(90))};
|
||||
}
|
||||
|
||||
const auto make_accumulate = [](const auto extraction_function) {
|
||||
return [extraction_function](const double sum_so_far, const Coordinate coordinate) {
|
||||
return sum_so_far + extraction_function(coordinate);
|
||||
};
|
||||
const auto make_accumulate = [](const auto extraction_function)
|
||||
{
|
||||
return [extraction_function](const double sum_so_far, const Coordinate coordinate)
|
||||
{ return sum_so_far + extraction_function(coordinate); };
|
||||
};
|
||||
|
||||
const auto accumulated_lon = std::accumulate(begin, end, 0., make_accumulate(extract_lon));
|
||||
@ -283,8 +286,10 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
|
||||
|
||||
const auto mean_lon = accumulated_lon / number_of_coordinates;
|
||||
const auto mean_lat = accumulated_lat / number_of_coordinates;
|
||||
const auto make_variance = [](const auto mean, const auto extraction_function) {
|
||||
return [extraction_function, mean](const double sum_so_far, const Coordinate coordinate) {
|
||||
const auto make_variance = [](const auto mean, const auto extraction_function)
|
||||
{
|
||||
return [extraction_function, mean](const double sum_so_far, const Coordinate coordinate)
|
||||
{
|
||||
const auto difference = extraction_function(coordinate) - mean;
|
||||
return sum_so_far + difference * difference;
|
||||
};
|
||||
@ -312,7 +317,8 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
|
||||
std::accumulate(begin,
|
||||
end,
|
||||
0.,
|
||||
[&](const auto sum_so_far, const auto current_coordinate) {
|
||||
[&](const auto sum_so_far, const auto current_coordinate)
|
||||
{
|
||||
return sum_so_far + (extract_lon(current_coordinate) - mean_lon) *
|
||||
(extract_lat(current_coordinate) - mean_lat) /
|
||||
(sample_variance_lon * sample_variance_lat);
|
||||
@ -323,9 +329,8 @@ std::pair<Coordinate, Coordinate> leastSquareRegression(const iterator_type begi
|
||||
const auto intercept = mean_lat - slope * mean_lon;
|
||||
|
||||
const auto GetLatAtLon = [intercept,
|
||||
slope](const util::FloatLongitude longitude) -> util::FloatLatitude {
|
||||
return {intercept + slope * static_cast<double>((longitude))};
|
||||
};
|
||||
slope](const util::FloatLongitude longitude) -> util::FloatLatitude
|
||||
{ return {intercept + slope * static_cast<double>((longitude))}; };
|
||||
|
||||
const double offset = 0.00001;
|
||||
const Coordinate regression_first = {
|
||||
@ -359,7 +364,8 @@ bool areParallel(const iterator_type lhs_begin,
|
||||
const auto rotation_angle_radians = detail::degToRad(bearing_lhs - 90);
|
||||
const auto rotated_difference_rhs = rotateCCWAroundZero(difference_rhs, rotation_angle_radians);
|
||||
|
||||
const auto get_slope = [](const Coordinate from, const Coordinate to) {
|
||||
const auto get_slope = [](const Coordinate from, const Coordinate to)
|
||||
{
|
||||
const auto diff_lat = static_cast<int>(from.lat) - static_cast<int>(to.lat);
|
||||
const auto diff_lon = static_cast<int>(from.lon) - static_cast<int>(to.lon);
|
||||
if (diff_lon == 0)
|
||||
|
@ -254,7 +254,7 @@ template <typename ElementT> class DeallocatingVector
|
||||
++current_size;
|
||||
}
|
||||
|
||||
template <typename... Ts> void emplace_back(Ts &&... element)
|
||||
template <typename... Ts> void emplace_back(Ts &&...element)
|
||||
{
|
||||
const std::size_t current_capacity = capacity();
|
||||
if (current_size == current_capacity)
|
||||
|
@ -68,7 +68,7 @@ template <typename EdgeDataT> class DynamicGraph
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
InputEdge(NodeIterator source, NodeIterator target, Ts &&... data)
|
||||
InputEdge(NodeIterator source, NodeIterator target, Ts &&...data)
|
||||
: source(source), target(target), data(std::forward<Ts>(data)...)
|
||||
{
|
||||
}
|
||||
@ -189,25 +189,28 @@ template <typename EdgeDataT> class DynamicGraph
|
||||
other.node_array.resize(node_array.size());
|
||||
|
||||
NodeID node_id = 0;
|
||||
std::transform(
|
||||
node_array.begin(), node_array.end(), other.node_array.begin(), [&](const Node &node) {
|
||||
const EdgeIterator first_edge = other.edge_list.size();
|
||||
std::transform(node_array.begin(),
|
||||
node_array.end(),
|
||||
other.node_array.begin(),
|
||||
[&](const Node &node)
|
||||
{
|
||||
const EdgeIterator first_edge = other.edge_list.size();
|
||||
|
||||
BOOST_ASSERT(node_id < number_of_nodes);
|
||||
if (filter(node_id++))
|
||||
{
|
||||
std::copy_if(edge_list.begin() + node.first_edge,
|
||||
edge_list.begin() + node.first_edge + node.edges,
|
||||
std::back_inserter(other.edge_list),
|
||||
[&](const auto &edge) { return filter(edge.target); });
|
||||
const unsigned num_edges = other.edge_list.size() - first_edge;
|
||||
return Node{first_edge, num_edges};
|
||||
}
|
||||
else
|
||||
{
|
||||
return Node{first_edge, 0};
|
||||
}
|
||||
});
|
||||
BOOST_ASSERT(node_id < number_of_nodes);
|
||||
if (filter(node_id++))
|
||||
{
|
||||
std::copy_if(edge_list.begin() + node.first_edge,
|
||||
edge_list.begin() + node.first_edge + node.edges,
|
||||
std::back_inserter(other.edge_list),
|
||||
[&](const auto &edge) { return filter(edge.target); });
|
||||
const unsigned num_edges = other.edge_list.size() - first_edge;
|
||||
return Node{first_edge, num_edges};
|
||||
}
|
||||
else
|
||||
{
|
||||
return Node{first_edge, 0};
|
||||
}
|
||||
});
|
||||
|
||||
return other;
|
||||
}
|
||||
|
@ -37,9 +37,9 @@ class FilteredGraphImpl<util::StaticGraph<EdgeDataT, Ownership>, Ownership>
|
||||
unsigned GetOutDegree(const NodeIterator n) const
|
||||
{
|
||||
auto range = graph.GetAdjacentEdgeRange(n);
|
||||
return std::count_if(range.begin(), range.end(), [this](const EdgeIterator edge) {
|
||||
return edge_filter[edge];
|
||||
});
|
||||
return std::count_if(range.begin(),
|
||||
range.end(),
|
||||
[this](const EdgeIterator edge) { return edge_filter[edge]; });
|
||||
}
|
||||
|
||||
inline NodeIterator GetTarget(const EdgeIterator e) const
|
||||
|
@ -58,7 +58,7 @@ class GeojsonLogger
|
||||
}
|
||||
|
||||
// writes a single feature into the Geojson file
|
||||
template <typename... Args> static bool Write(Args &&... args)
|
||||
template <typename... Args> static bool Write(Args &&...args)
|
||||
{
|
||||
// make sure to syncronize logging output, our writing should be sequential
|
||||
std::lock_guard<std::mutex> guard(lock);
|
||||
@ -146,7 +146,7 @@ class ScopedGeojsonLoggerGuard
|
||||
{
|
||||
public:
|
||||
template <typename... Args>
|
||||
ScopedGeojsonLoggerGuard(const std::string &logfile, Args &&... args)
|
||||
ScopedGeojsonLoggerGuard(const std::string &logfile, Args &&...args)
|
||||
: policy(std::forward<Args>(args)...)
|
||||
{
|
||||
GeojsonLogger<geojson_conversion_policy, scenario>::Open(logfile);
|
||||
@ -159,7 +159,7 @@ class ScopedGeojsonLoggerGuard
|
||||
GeojsonLogger<geojson_conversion_policy, scenario>::SetPolicy(nullptr);
|
||||
}
|
||||
|
||||
template <typename... Args> static bool Write(Args &&... args)
|
||||
template <typename... Args> static bool Write(Args &&...args)
|
||||
{
|
||||
return GeojsonLogger<geojson_conversion_policy, scenario>::Write(
|
||||
std::forward<Args>(args)...);
|
||||
|
@ -63,14 +63,16 @@ template <typename StringView> inline auto decompose(const StringView &lhs, cons
|
||||
auto const lcs = longest_common_substring(lhs, rhs);
|
||||
|
||||
// trim spaces, transform to lower
|
||||
const auto trim = [](StringView view) {
|
||||
const auto trim = [](StringView view)
|
||||
{
|
||||
// we compare suffixes based on this value, it might break UTF chars, but as long as we are
|
||||
// consistent in handling, we do not create bad results
|
||||
std::string str;
|
||||
str.reserve(view.size());
|
||||
std::transform(view.begin(), view.end(), std::back_inserter(str), [](unsigned char c) {
|
||||
return std::tolower(c);
|
||||
});
|
||||
std::transform(view.begin(),
|
||||
view.end(),
|
||||
std::back_inserter(str),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
auto front = str.find_first_not_of(' ');
|
||||
|
||||
if (front == std::string::npos)
|
||||
@ -131,13 +133,13 @@ inline bool requiresNameAnnounced(const StringView &from_name,
|
||||
|
||||
const auto checkForPrefixOrSuffixChange = [](const std::string_view first,
|
||||
const std::string_view second,
|
||||
const SuffixTable &suffix_table) {
|
||||
const SuffixTable &suffix_table)
|
||||
{
|
||||
std::string first_prefix, first_suffix, second_prefix, second_suffix;
|
||||
std::tie(first_prefix, first_suffix, second_prefix, second_suffix) =
|
||||
decompose(first, second);
|
||||
const auto checkTable = [&](const std::string &str) {
|
||||
return str.empty() || suffix_table.isSuffix(str);
|
||||
};
|
||||
const auto checkTable = [&](const std::string &str)
|
||||
{ return str.empty() || suffix_table.isSuffix(str); };
|
||||
|
||||
return checkTable(first_prefix) && checkTable(first_suffix) && checkTable(second_prefix) &&
|
||||
checkTable(second_suffix);
|
||||
|
@ -315,9 +315,8 @@ template <typename GroupBlockPolicy, storage::Ownership Ownership> struct Indexe
|
||||
values_byte_iter = block.WriteBlockPrefix(curr, next, values_byte_iter);
|
||||
std::advance(next, std::min<diff_type>(1, std::distance(next, sentinel)));
|
||||
|
||||
auto to_bytes = [&](const auto &data) {
|
||||
values_byte_iter = std::copy_n(&data, sizeof(ValueType), values_byte_iter);
|
||||
};
|
||||
auto to_bytes = [&](const auto &data)
|
||||
{ values_byte_iter = std::copy_n(&data, sizeof(ValueType), values_byte_iter); };
|
||||
std::copy(data + *curr,
|
||||
data + *next,
|
||||
boost::make_function_output_iterator(std::cref(to_bytes)));
|
||||
|
@ -43,11 +43,10 @@ class integer_iterator : public boost::iterator_facade<integer_iterator<Integer>
|
||||
|
||||
difference_type distance_to(const integer_iterator &other) const
|
||||
{
|
||||
return std::is_signed<value_type>::value
|
||||
? (other.m_value - m_value)
|
||||
: (other.m_value >= m_value)
|
||||
? static_cast<difference_type>(other.m_value - m_value)
|
||||
: -static_cast<difference_type>(m_value - other.m_value);
|
||||
return std::is_signed<value_type>::value ? (other.m_value - m_value)
|
||||
: (other.m_value >= m_value)
|
||||
? static_cast<difference_type>(other.m_value - m_value)
|
||||
: -static_cast<difference_type>(m_value - other.m_value);
|
||||
}
|
||||
|
||||
friend class ::boost::iterator_core_access;
|
||||
|
@ -79,7 +79,8 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
||||
auto edges_list = directedEdgesFromCompressed<NodeBasedDynamicGraph::InputEdge>(
|
||||
input_edge_list,
|
||||
[](NodeBasedDynamicGraph::InputEdge &output_edge,
|
||||
const extractor::NodeBasedEdge &input_edge) {
|
||||
const extractor::NodeBasedEdge &input_edge)
|
||||
{
|
||||
output_edge.data.weight = input_edge.weight;
|
||||
output_edge.data.duration = input_edge.duration;
|
||||
output_edge.data.distance = input_edge.distance;
|
||||
|
@ -193,23 +193,20 @@ struct OpeningHours
|
||||
&& (times.empty() ||
|
||||
std::any_of(times.begin(),
|
||||
times.end(),
|
||||
[&time, &use_curr_day, &use_next_day](const auto &x) {
|
||||
return x.IsInRange(time, use_curr_day, use_next_day);
|
||||
}))
|
||||
[&time, &use_curr_day, &use_next_day](const auto &x)
|
||||
{ return x.IsInRange(time, use_curr_day, use_next_day); }))
|
||||
// .. and if weekdays are not specified or matches weekdays range
|
||||
&& (weekdays.empty() ||
|
||||
std::any_of(weekdays.begin(),
|
||||
weekdays.end(),
|
||||
[&time, use_curr_day, use_next_day](const auto &x) {
|
||||
return x.IsInRange(time, use_curr_day, use_next_day);
|
||||
}))
|
||||
[&time, use_curr_day, use_next_day](const auto &x)
|
||||
{ return x.IsInRange(time, use_curr_day, use_next_day); }))
|
||||
// .. and if month-day ranges are not specified or is in any month-day range
|
||||
&& (monthdays.empty() ||
|
||||
std::any_of(monthdays.begin(),
|
||||
monthdays.end(),
|
||||
[&time, use_curr_day, use_next_day](const auto &x) {
|
||||
return x.IsInRange(time, use_curr_day, use_next_day);
|
||||
}));
|
||||
[&time, use_curr_day, use_next_day](const auto &x)
|
||||
{ return x.IsInRange(time, use_curr_day, use_next_day); }));
|
||||
}
|
||||
|
||||
std::vector<TimeSpan> times;
|
||||
|
@ -345,9 +345,9 @@ class QueryHeap
|
||||
void DeleteAll()
|
||||
{
|
||||
auto const none_handle = heap.s_handle_from_iterator(heap.end());
|
||||
std::for_each(inserted_nodes.begin(), inserted_nodes.end(), [&none_handle](auto &node) {
|
||||
node.handle = none_handle;
|
||||
});
|
||||
std::for_each(inserted_nodes.begin(),
|
||||
inserted_nodes.end(),
|
||||
[&none_handle](auto &node) { node.handle = none_handle; });
|
||||
heap.clear();
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,8 @@ template <unsigned BLOCK_SIZE, storage::Ownership Ownership> class RangeTable
|
||||
// construct table from length vector
|
||||
template <typename VectorT> explicit RangeTable(const VectorT &lengths)
|
||||
{
|
||||
const unsigned number_of_blocks = [&lengths]() {
|
||||
const unsigned number_of_blocks = [&lengths]()
|
||||
{
|
||||
unsigned num = (lengths.size() + 1) / (BLOCK_SIZE + 1);
|
||||
if ((lengths.size() + 1) % (BLOCK_SIZE + 1) != 0)
|
||||
{
|
||||
|
@ -94,7 +94,7 @@ template <typename EdgeDataT> struct SortableEdgeWithData : SortableEdgeWithData
|
||||
SortableEdgeWithData() = default;
|
||||
|
||||
template <typename... Ts>
|
||||
SortableEdgeWithData(NodeIterator source, NodeIterator target, Ts &&... data)
|
||||
SortableEdgeWithData(NodeIterator source, NodeIterator target, Ts &&...data)
|
||||
: Base{source, target}, data{std::forward<Ts>(data)...}
|
||||
{
|
||||
}
|
||||
@ -304,10 +304,14 @@ class StaticGraph
|
||||
BOOST_ASSERT(node_array.size() == number_of_nodes + 1);
|
||||
|
||||
edge_array.resize(number_of_edges);
|
||||
std::transform(begin, end, edge_array.begin(), [](const auto &from) {
|
||||
return static_graph_details::edgeToEntry<EdgeArrayEntry>(
|
||||
from, traits::HasDataMember<EdgeArrayEntry>{});
|
||||
});
|
||||
std::transform(begin,
|
||||
end,
|
||||
edge_array.begin(),
|
||||
[](const auto &from)
|
||||
{
|
||||
return static_graph_details::edgeToEntry<EdgeArrayEntry>(
|
||||
from, traits::HasDataMember<EdgeArrayEntry>{});
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -281,7 +281,8 @@ class StaticRTree
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<uint64_t>(0, element_count),
|
||||
[&input_data_vector, &input_wrapper_vector, this](
|
||||
const tbb::blocked_range<uint64_t> &range) {
|
||||
const tbb::blocked_range<uint64_t> &range)
|
||||
{
|
||||
for (uint64_t element_counter = range.begin(), end = range.end();
|
||||
element_counter != end;
|
||||
++element_counter)
|
||||
@ -560,9 +561,8 @@ class StaticRTree
|
||||
return Nearest(
|
||||
input_coordinate,
|
||||
[](const CandidateSegment &) { return std::make_pair(true, true); },
|
||||
[max_results](const std::size_t num_results, const CandidateSegment &) {
|
||||
return num_results >= max_results;
|
||||
});
|
||||
[max_results](const std::size_t num_results, const CandidateSegment &)
|
||||
{ return num_results >= max_results; });
|
||||
}
|
||||
|
||||
// Return edges in distance order with the coordinate of the closest point on the edge.
|
||||
|
@ -14,13 +14,13 @@ template <typename T> void hash_combine(std::size_t &seed, const T &val)
|
||||
template <typename T> void hash_val(std::size_t &seed, const T &val) { hash_combine(seed, val); }
|
||||
|
||||
template <typename T, typename... Types>
|
||||
void hash_val(std::size_t &seed, const T &val, const Types &... args)
|
||||
void hash_val(std::size_t &seed, const T &val, const Types &...args)
|
||||
{
|
||||
hash_combine(seed, val);
|
||||
hash_val(seed, args...);
|
||||
}
|
||||
|
||||
template <typename... Types> std::size_t hash_val(const Types &... args)
|
||||
template <typename... Types> std::size_t hash_val(const Types &...args)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
hash_val(seed, args...);
|
||||
|
@ -18,7 +18,8 @@ template <int length, int precision> char *printInt(char *buffer, int value)
|
||||
static_assert(length > 0, "length must be positive");
|
||||
static_assert(precision > 0, "precision must be positive");
|
||||
|
||||
const bool minus = [&value] {
|
||||
const bool minus = [&value]
|
||||
{
|
||||
if (value >= 0)
|
||||
{
|
||||
value = -value;
|
||||
|
@ -51,16 +51,20 @@ template <std::size_t TimeBinSize = 1000, std::size_t IndexBinSize = 1000> class
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
const auto print_bins = [&out](auto frame_index, auto begin, auto end) {
|
||||
const auto print_bins = [&out](auto frame_index, auto begin, auto end)
|
||||
{
|
||||
auto bin_index = 0;
|
||||
std::for_each(begin, end, [&](const auto count) {
|
||||
if (count > 0)
|
||||
{
|
||||
out << (frame_index * TimeBinSize) << "," << (bin_index * IndexBinSize) << ","
|
||||
<< count << std::endl;
|
||||
}
|
||||
bin_index++;
|
||||
});
|
||||
std::for_each(begin,
|
||||
end,
|
||||
[&](const auto count)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
out << (frame_index * TimeBinSize) << ","
|
||||
<< (bin_index * IndexBinSize) << "," << count << std::endl;
|
||||
}
|
||||
bin_index++;
|
||||
});
|
||||
};
|
||||
|
||||
if (frame_offsets.size() == 0)
|
||||
|
@ -19,18 +19,18 @@ elif [[ ${OS} = "Darwin" ]] ; then
|
||||
fi
|
||||
|
||||
# Discover clang-format
|
||||
if type clang-format-10 2> /dev/null ; then
|
||||
CLANG_FORMAT=clang-format-10
|
||||
if type clang-format-15 2> /dev/null ; then
|
||||
CLANG_FORMAT=clang-format-15
|
||||
elif type clang-format 2> /dev/null ; then
|
||||
# Clang format found, but need to check version
|
||||
CLANG_FORMAT=clang-format
|
||||
V=$(clang-format --version)
|
||||
if [[ $V != *10.0* ]] ; then
|
||||
echo "clang-format is not 10.0 (returned ${V})"
|
||||
if [[ $V != *15.0* ]] ; then
|
||||
echo "clang-format is not 15.0 (returned ${V})"
|
||||
#exit 1
|
||||
fi
|
||||
else
|
||||
echo "No appropriate clang-format found (expected clang-format-10, or clang-format)"
|
||||
echo "No appropriate clang-format found (expected clang-format-15, or clang-format)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -65,12 +65,12 @@ void benchmark(BenchStaticRTree &rtree, unsigned num_queries)
|
||||
util::FixedLatitude{lat_udist(mt_rand)});
|
||||
}
|
||||
|
||||
benchmarkQuery(queries, "raw RTree queries (1 result)", [&rtree](const util::Coordinate &q) {
|
||||
return rtree.Nearest(q, 1);
|
||||
});
|
||||
benchmarkQuery(queries, "raw RTree queries (10 results)", [&rtree](const util::Coordinate &q) {
|
||||
return rtree.Nearest(q, 10);
|
||||
});
|
||||
benchmarkQuery(queries,
|
||||
"raw RTree queries (1 result)",
|
||||
[&rtree](const util::Coordinate &q) { return rtree.Nearest(q, 1); });
|
||||
benchmarkQuery(queries,
|
||||
"raw RTree queries (10 results)",
|
||||
[&rtree](const util::Coordinate &q) { return rtree.Nearest(q, 10); });
|
||||
}
|
||||
} // namespace osrm::benchmarks
|
||||
|
||||
|
@ -619,7 +619,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
|
||||
util::UnbufferedLog log;
|
||||
log << "initializing node priorities...";
|
||||
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, remaining_nodes.size(), PQGrainSize),
|
||||
[&](const auto &range) {
|
||||
[&](const auto &range)
|
||||
{
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (auto x = range.begin(), end = range.end(); x != end; ++x)
|
||||
{
|
||||
@ -656,7 +657,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
|
||||
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<NodeID>(0, remaining_nodes.size(), IndependentGrainSize),
|
||||
[&](const auto &range) {
|
||||
[&](const auto &range)
|
||||
{
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
// determine independent node set
|
||||
for (auto i = range.begin(), end = range.end(); i != end; ++i)
|
||||
@ -669,9 +671,9 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
|
||||
|
||||
// sort all remaining nodes to the beginning of the sequence
|
||||
const auto begin_independent_nodes = std::stable_partition(
|
||||
remaining_nodes.begin(), remaining_nodes.end(), [](RemainingNodeData node_data) {
|
||||
return !node_data.is_independent;
|
||||
});
|
||||
remaining_nodes.begin(),
|
||||
remaining_nodes.end(),
|
||||
[](RemainingNodeData node_data) { return !node_data.is_independent; });
|
||||
auto begin_independent_nodes_idx =
|
||||
std::distance(remaining_nodes.begin(), begin_independent_nodes);
|
||||
auto end_independent_nodes_idx = remaining_nodes.size();
|
||||
@ -680,7 +682,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<NodeID>(
|
||||
begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
|
||||
[&](const auto &range) {
|
||||
[&](const auto &range)
|
||||
{
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (auto position = range.begin(), end = range.end(); position != end; ++position)
|
||||
{
|
||||
@ -699,7 +702,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<NodeID>(
|
||||
begin_independent_nodes_idx, end_independent_nodes_idx, DeleteGrainSize),
|
||||
[&](const auto &range) {
|
||||
[&](const auto &range)
|
||||
{
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (auto position = range.begin(), end = range.end(); position != end; ++position)
|
||||
{
|
||||
@ -709,10 +713,13 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
|
||||
});
|
||||
|
||||
// make sure we really sort each block
|
||||
tbb::parallel_for(thread_data_list.data.range(), [&](const auto &range) {
|
||||
for (auto &data : range)
|
||||
tbb::parallel_sort(data->inserted_edges.begin(), data->inserted_edges.end());
|
||||
});
|
||||
tbb::parallel_for(thread_data_list.data.range(),
|
||||
[&](const auto &range)
|
||||
{
|
||||
for (auto &data : range)
|
||||
tbb::parallel_sort(data->inserted_edges.begin(),
|
||||
data->inserted_edges.end());
|
||||
});
|
||||
|
||||
// insert new edges
|
||||
for (auto &data : thread_data_list.data)
|
||||
@ -743,7 +750,8 @@ std::vector<bool> contractGraph(ContractorGraph &graph,
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<NodeID>(
|
||||
begin_independent_nodes_idx, end_independent_nodes_idx, NeighboursGrainSize),
|
||||
[&](const auto &range) {
|
||||
[&](const auto &range)
|
||||
{
|
||||
ContractorThreadData *data = thread_data_list.GetThreadData();
|
||||
for (auto position = range.begin(), end = range.end(); position != end; ++position)
|
||||
{
|
||||
|
@ -47,17 +47,18 @@ void printUnreachableStatistics(const Partition &partition,
|
||||
for (auto node : cell.GetSourceNodes())
|
||||
{
|
||||
const auto &weights = cell.GetOutWeight(node);
|
||||
invalid_sources += std::all_of(weights.begin(), weights.end(), [](auto weight) {
|
||||
return weight == INVALID_EDGE_WEIGHT;
|
||||
});
|
||||
invalid_sources +=
|
||||
std::all_of(weights.begin(),
|
||||
weights.end(),
|
||||
[](auto weight) { return weight == INVALID_EDGE_WEIGHT; });
|
||||
}
|
||||
for (auto node : cell.GetDestinationNodes())
|
||||
{
|
||||
const auto &weights = cell.GetInWeight(node);
|
||||
invalid_destinations +=
|
||||
std::all_of(weights.begin(), weights.end(), [](auto weight) {
|
||||
return weight == INVALID_EDGE_WEIGHT;
|
||||
});
|
||||
std::all_of(weights.begin(),
|
||||
weights.end(),
|
||||
[](auto weight) { return weight == INVALID_EDGE_WEIGHT; });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,8 @@ util::json::Object makeIntersection(const guidance::IntermediateIntersection &in
|
||||
std::transform(intersection.entry.begin(),
|
||||
intersection.entry.end(),
|
||||
std::back_inserter(entry.values),
|
||||
[](const bool has_entry) -> util::json::Value {
|
||||
[](const bool has_entry) -> util::json::Value
|
||||
{
|
||||
if (has_entry)
|
||||
return util::json::True();
|
||||
else
|
||||
@ -151,11 +152,11 @@ util::json::Object makeIntersection(const guidance::IntermediateIntersection &in
|
||||
{
|
||||
util::json::Array classes;
|
||||
classes.values.reserve(intersection.classes.size());
|
||||
std::transform(
|
||||
intersection.classes.begin(),
|
||||
intersection.classes.end(),
|
||||
std::back_inserter(classes.values),
|
||||
[](const std::string &class_name) { return util::json::String{class_name}; });
|
||||
std::transform(intersection.classes.begin(),
|
||||
intersection.classes.end(),
|
||||
std::back_inserter(classes.values),
|
||||
[](const std::string &class_name)
|
||||
{ return util::json::String{class_name}; });
|
||||
result.values["classes"] = std::move(classes);
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,11 @@ std::vector<util::Coordinate> douglasPeucker(std::vector<util::Coordinate>::cons
|
||||
}
|
||||
|
||||
std::vector<util::FloatCoordinate> projected_coordinates(size);
|
||||
std::transform(begin, end, projected_coordinates.begin(), [](const util::Coordinate coord) {
|
||||
return util::web_mercator::fromWGS84(coord);
|
||||
});
|
||||
std::transform(begin,
|
||||
end,
|
||||
projected_coordinates.begin(),
|
||||
[](const util::Coordinate coord)
|
||||
{ return util::web_mercator::fromWGS84(coord); });
|
||||
|
||||
std::vector<bool> is_necessary(size, false);
|
||||
BOOST_ASSERT(is_necessary.size() >= 2);
|
||||
|
@ -9,9 +9,8 @@ bool EngineConfig::IsValid() const
|
||||
// leads to an empty path
|
||||
const bool all_path_are_empty = storage_config.GetPath("").empty();
|
||||
|
||||
const auto unlimited_or_more_than = [](const auto v, const auto limit) {
|
||||
return v == -1 || v > limit;
|
||||
};
|
||||
const auto unlimited_or_more_than = [](const auto v, const auto limit)
|
||||
{ return v == -1 || v > limit; };
|
||||
|
||||
const bool limits_valid =
|
||||
unlimited_or_more_than(max_locations_distance_table, 2) &&
|
||||
|
@ -40,22 +40,21 @@ unsigned calculateOverviewZoomLevel(const std::vector<LegGeometry> &leg_geometri
|
||||
std::vector<util::Coordinate> assembleOverview(const std::vector<LegGeometry> &leg_geometries,
|
||||
const bool use_simplification)
|
||||
{
|
||||
auto overview_size =
|
||||
std::accumulate(leg_geometries.begin(),
|
||||
leg_geometries.end(),
|
||||
0,
|
||||
[](const std::size_t sum, const LegGeometry &leg_geometry) {
|
||||
return sum + leg_geometry.locations.size();
|
||||
}) -
|
||||
leg_geometries.size() + 1;
|
||||
auto overview_size = std::accumulate(leg_geometries.begin(),
|
||||
leg_geometries.end(),
|
||||
0,
|
||||
[](const std::size_t sum, const LegGeometry &leg_geometry)
|
||||
{ return sum + leg_geometry.locations.size(); }) -
|
||||
leg_geometries.size() + 1;
|
||||
std::vector<util::Coordinate> overview_geometry;
|
||||
overview_geometry.reserve(overview_size);
|
||||
|
||||
using GeometryIter = decltype(overview_geometry)::const_iterator;
|
||||
|
||||
auto leg_reverse_index = leg_geometries.size();
|
||||
const auto insert_without_overlap = [&leg_reverse_index, &overview_geometry](GeometryIter begin,
|
||||
GeometryIter end) {
|
||||
const auto insert_without_overlap =
|
||||
[&leg_reverse_index, &overview_geometry](GeometryIter begin, GeometryIter end)
|
||||
{
|
||||
// not the last leg
|
||||
if (leg_reverse_index > 1)
|
||||
{
|
||||
|
@ -7,18 +7,21 @@ namespace osrm::engine::guidance
|
||||
|
||||
Route assembleRoute(const std::vector<RouteLeg> &route_legs)
|
||||
{
|
||||
auto distance = std::accumulate(
|
||||
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
|
||||
return sum + leg.distance;
|
||||
});
|
||||
auto duration = std::accumulate(
|
||||
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
|
||||
return sum + leg.duration;
|
||||
});
|
||||
auto weight = std::accumulate(
|
||||
route_legs.begin(), route_legs.end(), 0., [](const double sum, const RouteLeg &leg) {
|
||||
return sum + leg.weight;
|
||||
});
|
||||
auto distance =
|
||||
std::accumulate(route_legs.begin(),
|
||||
route_legs.end(),
|
||||
0.,
|
||||
[](const double sum, const RouteLeg &leg) { return sum + leg.distance; });
|
||||
auto duration =
|
||||
std::accumulate(route_legs.begin(),
|
||||
route_legs.end(),
|
||||
0.,
|
||||
[](const double sum, const RouteLeg &leg) { return sum + leg.duration; });
|
||||
auto weight =
|
||||
std::accumulate(route_legs.begin(),
|
||||
route_legs.end(),
|
||||
0.,
|
||||
[](const double sum, const RouteLeg &leg) { return sum + leg.weight; });
|
||||
|
||||
return Route{distance, duration, weight};
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ bool isStaggeredIntersection(const RouteStepIterator step_prior_to_intersection,
|
||||
// If adjusted, make sure to check validity of the is_right/is_left classification below
|
||||
const constexpr auto MAX_STAGGERED_DISTANCE = 3; // debatable, but keep short to be on safe side
|
||||
|
||||
const auto angle = [](const RouteStep &step) {
|
||||
const auto angle = [](const RouteStep &step)
|
||||
{
|
||||
const auto &intersection = step.intersections.front();
|
||||
const auto entry_bearing = util::bearing::reverse(intersection.bearings[intersection.in]);
|
||||
const auto exit_bearing = intersection.bearings[intersection.out];
|
||||
|
@ -59,7 +59,8 @@ double findTotalTurnAngle(const RouteStep &entry_step, const RouteStep &exit_ste
|
||||
// c
|
||||
// |
|
||||
// d
|
||||
const auto use_total_angle = [&]() {
|
||||
const auto use_total_angle = [&]()
|
||||
{
|
||||
// only consider actual turns in combination:
|
||||
if (angularDeviation(total_angle, 180) < 0.5 * NARROW_TURN_ANGLE)
|
||||
return false;
|
||||
@ -99,7 +100,8 @@ inline void handleSliproad(RouteStepIterator sliproad_step)
|
||||
{
|
||||
// find the next step after the sliproad step itself (this is not necessarily the next step,
|
||||
// since we might have to skip over traffic lights/node penalties)
|
||||
auto next_step = [&sliproad_step]() {
|
||||
auto next_step = [&sliproad_step]()
|
||||
{
|
||||
auto next_step = findNextTurn(sliproad_step);
|
||||
while (isTrafficLightStep(*next_step))
|
||||
{
|
||||
@ -196,7 +198,8 @@ void AdjustToCombinedTurnStrategy::operator()(RouteStep &step_at_turn_location,
|
||||
: getTurnDirection(angle);
|
||||
|
||||
// a turn that is a new name or straight (turn/continue)
|
||||
const auto is_non_turn = [](const RouteStep &step) {
|
||||
const auto is_non_turn = [](const RouteStep &step)
|
||||
{
|
||||
return hasTurnType(step, TurnType::NewName) ||
|
||||
(hasTurnType(step, TurnType::Turn) &&
|
||||
hasModifier(step, DirectionModifier::Straight)) ||
|
||||
@ -307,7 +310,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
|
||||
// Used to control updating of the modifier based on turn direction
|
||||
bool update_modifier_for_turn_direction = true;
|
||||
|
||||
const auto calculate_turn_angle = [](const RouteStep &entry_step, const RouteStep &exit_step) {
|
||||
const auto calculate_turn_angle = [](const RouteStep &entry_step, const RouteStep &exit_step)
|
||||
{
|
||||
return util::bearing::angleBetween(entry_step.maneuver.bearing_before,
|
||||
exit_step.maneuver.bearing_after);
|
||||
};
|
||||
@ -316,7 +320,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
|
||||
const auto turn_angle = calculate_turn_angle(step_at_turn_location, transfer_from_step);
|
||||
const auto turn_direction = getTurnDirection(turn_angle);
|
||||
|
||||
const auto is_straight_step = [](const RouteStep &step) {
|
||||
const auto is_straight_step = [](const RouteStep &step)
|
||||
{
|
||||
return ((hasTurnType(step, TurnType::NewName) || hasTurnType(step, TurnType::Continue) ||
|
||||
hasTurnType(step, TurnType::Suppressed) || hasTurnType(step, TurnType::Turn)) &&
|
||||
(hasModifier(step, DirectionModifier::Straight) ||
|
||||
@ -324,7 +329,8 @@ void SegregatedTurnStrategy::operator()(RouteStep &step_at_turn_location,
|
||||
hasModifier(step, DirectionModifier::SlightRight)));
|
||||
};
|
||||
|
||||
const auto is_turn_step = [](const RouteStep &step) {
|
||||
const auto is_turn_step = [](const RouteStep &step)
|
||||
{
|
||||
return (hasTurnType(step, TurnType::Turn) || hasTurnType(step, TurnType::Continue) ||
|
||||
hasTurnType(step, TurnType::NewName) || hasTurnType(step, TurnType::Suppressed));
|
||||
};
|
||||
|
@ -17,7 +17,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||
const double min_distance_needed_for_lane_change)
|
||||
{
|
||||
// Lane anticipation works on contiguous ranges of short steps that have lane information
|
||||
const auto is_short_has_lanes = [&](const RouteStep &step) {
|
||||
const auto is_short_has_lanes = [&](const RouteStep &step)
|
||||
{
|
||||
const auto has_lanes = step.intersections.front().lanes.lanes_in_turn > 0;
|
||||
|
||||
if (!has_lanes)
|
||||
@ -45,7 +46,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||
|
||||
std::vector<StepIterRange> quick_lanes_ranges;
|
||||
|
||||
const auto range_back_inserter = [&](StepIterRange range) {
|
||||
const auto range_back_inserter = [&](StepIterRange range)
|
||||
{
|
||||
if (std::distance(range.first, range.second) > 1)
|
||||
quick_lanes_ranges.push_back(std::move(range));
|
||||
};
|
||||
@ -58,7 +60,8 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||
|
||||
// Walk backwards over all turns, constraining possible turn lanes.
|
||||
// Later turn lanes constrain earlier ones: we have to anticipate lane changes.
|
||||
const auto constrain_lanes = [&](const StepIterRange &turns) {
|
||||
const auto constrain_lanes = [&](const StepIterRange &turns)
|
||||
{
|
||||
const std::reverse_iterator<StepIter> rev_first{turns.second};
|
||||
const std::reverse_iterator<StepIter> rev_last{turns.first};
|
||||
|
||||
@ -74,127 +77,135 @@ std::vector<RouteStep> anticipateLaneChange(std::vector<RouteStep> steps,
|
||||
// segment for a lane switch, but the total distance shouldn't be unlimited.
|
||||
double distance_to_constrained = 0.0;
|
||||
|
||||
util::for_each_pair(rev_first, rev_last, [&](RouteStep ¤t, RouteStep &previous) {
|
||||
const auto current_inst = current.maneuver.instruction;
|
||||
const auto current_lanes = current.intersections.front().lanes;
|
||||
|
||||
// Constrain the previous turn's lanes
|
||||
auto &previous_lanes = previous.intersections.front().lanes;
|
||||
const auto previous_inst = previous.maneuver.instruction;
|
||||
|
||||
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
|
||||
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
|
||||
// otherwise nothing to constrain
|
||||
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
|
||||
const bool lanes_fan_in = previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
|
||||
|
||||
// only prevent use lanes due to making all turns. don't make turns during curvy
|
||||
// segments
|
||||
if (previous_inst.type == TurnType::Suppressed)
|
||||
distance_to_constrained += previous.distance;
|
||||
else
|
||||
distance_to_constrained = 0.;
|
||||
|
||||
const auto lane_delta = previous_lanes.lanes_in_turn - current_lanes.lanes_in_turn;
|
||||
const auto can_make_all_turns =
|
||||
distance_to_constrained > lane_delta * min_distance_needed_for_lane_change;
|
||||
|
||||
if (!lanes_to_constrain || !lanes_fan_in || can_make_all_turns)
|
||||
return;
|
||||
|
||||
// We do not have a mapping from lanes to lanes. All we have is the lanes in the turn
|
||||
// and all the lanes at that situation. To perfectly handle lane anticipation in cases
|
||||
// where lanes in the turn fan in but for example the overall lanes at that location
|
||||
// fan out, we would have to know the asymmetric mapping of lanes. This is currently
|
||||
// not possible at the moment. In the following we implement a heuristic instead.
|
||||
const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight();
|
||||
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
|
||||
|
||||
// 0/ Tag keep straight with the next turn's direction if available
|
||||
const auto previous_is_straight =
|
||||
!isLeftTurn(previous_inst) && !isRightTurn(previous_inst);
|
||||
|
||||
if (previous_is_straight)
|
||||
util::for_each_pair(
|
||||
rev_first,
|
||||
rev_last,
|
||||
[&](RouteStep ¤t, RouteStep &previous)
|
||||
{
|
||||
if (isLeftTurn(current_inst) || is_straight_left.count(¤t) > 0)
|
||||
is_straight_left.insert(&previous);
|
||||
else if (isRightTurn(current_inst) || is_straight_right.count(¤t) > 0)
|
||||
is_straight_right.insert(&previous);
|
||||
}
|
||||
const auto current_inst = current.maneuver.instruction;
|
||||
const auto current_lanes = current.intersections.front().lanes;
|
||||
|
||||
// 1/ How to anticipate left, right:
|
||||
const auto anticipate_for_left_turn = [&] {
|
||||
// Current turn is left turn, already keep left during previous turn.
|
||||
// This implies constraining the rightmost lanes in previous step.
|
||||
LaneID new_first_lane_from_the_right =
|
||||
previous_lanes.first_lane_from_the_right // start from rightmost lane
|
||||
+ previous_lanes.lanes_in_turn // one past leftmost lane
|
||||
- current_lanes.lanes_in_turn; // back number of new lanes
|
||||
// Constrain the previous turn's lanes
|
||||
auto &previous_lanes = previous.intersections.front().lanes;
|
||||
const auto previous_inst = previous.maneuver.instruction;
|
||||
|
||||
// The leftmost target lanes might not be involved in the turn. Figure out
|
||||
// how many lanes are to the left and not in the turn.
|
||||
new_first_lane_from_the_right -=
|
||||
std::min(current_num_lanes_left_of_turn, current_lanes.lanes_in_turn);
|
||||
// Lane mapping (N:M) from previous lanes (N) to current lanes (M), with:
|
||||
// N > M, N > 1 fan-in situation, constrain N lanes to min(N,M) shared lanes
|
||||
// otherwise nothing to constrain
|
||||
const bool lanes_to_constrain = previous_lanes.lanes_in_turn > 1;
|
||||
const bool lanes_fan_in =
|
||||
previous_lanes.lanes_in_turn > current_lanes.lanes_in_turn;
|
||||
|
||||
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
|
||||
};
|
||||
// only prevent use lanes due to making all turns. don't make turns during curvy
|
||||
// segments
|
||||
if (previous_inst.type == TurnType::Suppressed)
|
||||
distance_to_constrained += previous.distance;
|
||||
else
|
||||
distance_to_constrained = 0.;
|
||||
|
||||
const auto anticipate_for_right_turn = [&] {
|
||||
// Current turn is right turn, already keep right during the previous turn.
|
||||
// This implies constraining the leftmost lanes in the previous turn step.
|
||||
LaneID new_first_lane_from_the_right = previous_lanes.first_lane_from_the_right;
|
||||
const auto lane_delta = previous_lanes.lanes_in_turn - current_lanes.lanes_in_turn;
|
||||
const auto can_make_all_turns =
|
||||
distance_to_constrained > lane_delta * min_distance_needed_for_lane_change;
|
||||
|
||||
// The rightmost target lanes might not be involved in the turn. Figure out
|
||||
// how many lanes are to the right and not in the turn.
|
||||
new_first_lane_from_the_right +=
|
||||
std::min(current_num_lanes_right_of_turn, current_lanes.lanes_in_turn);
|
||||
if (!lanes_to_constrain || !lanes_fan_in || can_make_all_turns)
|
||||
return;
|
||||
|
||||
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
|
||||
};
|
||||
// We do not have a mapping from lanes to lanes. All we have is the lanes in the
|
||||
// turn and all the lanes at that situation. To perfectly handle lane anticipation
|
||||
// in cases where lanes in the turn fan in but for example the overall lanes at that
|
||||
// location fan out, we would have to know the asymmetric mapping of lanes. This is
|
||||
// currently not possible at the moment. In the following we implement a heuristic
|
||||
// instead.
|
||||
const LaneID current_num_lanes_right_of_turn = current.NumLanesToTheRight();
|
||||
const LaneID current_num_lanes_left_of_turn = current.NumLanesToTheLeft();
|
||||
|
||||
// 2/ When to anticipate a left, right turn
|
||||
if (isLeftTurn(current_inst))
|
||||
anticipate_for_left_turn();
|
||||
else if (isRightTurn(current_inst))
|
||||
anticipate_for_right_turn();
|
||||
else // keepStraight
|
||||
{
|
||||
// Heuristic: we do not have a from-lanes -> to-lanes mapping. What we use
|
||||
// here instead in addition is the number of all lanes (not only the lanes
|
||||
// in a turn):
|
||||
//
|
||||
// -v-v v-v- straight follows
|
||||
// | | | |
|
||||
// <- v v -> keep straight here
|
||||
// | |
|
||||
// <-| |->
|
||||
//
|
||||
// A route from the top left to the bottom right here goes over a keep
|
||||
// straight. If we handle all keep straights as right turns (in right-sided
|
||||
// driving), we wrongly guide the user to the rightmost lanes in the first turn.
|
||||
// Not only is this wrong but the opposite of what we expect.
|
||||
//
|
||||
// The following implements a heuristic to determine a keep straight's
|
||||
// direction in relation to the next step. In the above example we would get:
|
||||
//
|
||||
// coming from right, going to left (in direction of way) -> handle as left turn
|
||||
// 0/ Tag keep straight with the next turn's direction if available
|
||||
const auto previous_is_straight =
|
||||
!isLeftTurn(previous_inst) && !isRightTurn(previous_inst);
|
||||
|
||||
if (is_straight_left.count(¤t) > 0)
|
||||
if (previous_is_straight)
|
||||
{
|
||||
if (isLeftTurn(current_inst) || is_straight_left.count(¤t) > 0)
|
||||
is_straight_left.insert(&previous);
|
||||
else if (isRightTurn(current_inst) || is_straight_right.count(¤t) > 0)
|
||||
is_straight_right.insert(&previous);
|
||||
}
|
||||
|
||||
// 1/ How to anticipate left, right:
|
||||
const auto anticipate_for_left_turn = [&]
|
||||
{
|
||||
// Current turn is left turn, already keep left during previous turn.
|
||||
// This implies constraining the rightmost lanes in previous step.
|
||||
LaneID new_first_lane_from_the_right =
|
||||
previous_lanes.first_lane_from_the_right // start from rightmost lane
|
||||
+ previous_lanes.lanes_in_turn // one past leftmost lane
|
||||
- current_lanes.lanes_in_turn; // back number of new lanes
|
||||
|
||||
// The leftmost target lanes might not be involved in the turn. Figure out
|
||||
// how many lanes are to the left and not in the turn.
|
||||
new_first_lane_from_the_right -=
|
||||
std::min(current_num_lanes_left_of_turn, current_lanes.lanes_in_turn);
|
||||
|
||||
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
|
||||
};
|
||||
|
||||
const auto anticipate_for_right_turn = [&]
|
||||
{
|
||||
// Current turn is right turn, already keep right during the previous turn.
|
||||
// This implies constraining the leftmost lanes in the previous turn step.
|
||||
LaneID new_first_lane_from_the_right = previous_lanes.first_lane_from_the_right;
|
||||
|
||||
// The rightmost target lanes might not be involved in the turn. Figure out
|
||||
// how many lanes are to the right and not in the turn.
|
||||
new_first_lane_from_the_right +=
|
||||
std::min(current_num_lanes_right_of_turn, current_lanes.lanes_in_turn);
|
||||
|
||||
previous_lanes = {current_lanes.lanes_in_turn, new_first_lane_from_the_right};
|
||||
};
|
||||
|
||||
// 2/ When to anticipate a left, right turn
|
||||
if (isLeftTurn(current_inst))
|
||||
anticipate_for_left_turn();
|
||||
else if (is_straight_right.count(¤t) > 0)
|
||||
else if (isRightTurn(current_inst))
|
||||
anticipate_for_right_turn();
|
||||
else // FIXME: right-sided driving
|
||||
anticipate_for_right_turn();
|
||||
}
|
||||
else // keepStraight
|
||||
{
|
||||
// Heuristic: we do not have a from-lanes -> to-lanes mapping. What we use
|
||||
// here instead in addition is the number of all lanes (not only the lanes
|
||||
// in a turn):
|
||||
//
|
||||
// -v-v v-v- straight follows
|
||||
// | | | |
|
||||
// <- v v -> keep straight here
|
||||
// | |
|
||||
// <-| |->
|
||||
//
|
||||
// A route from the top left to the bottom right here goes over a keep
|
||||
// straight. If we handle all keep straights as right turns (in right-sided
|
||||
// driving), we wrongly guide the user to the rightmost lanes in the first turn.
|
||||
// Not only is this wrong but the opposite of what we expect.
|
||||
//
|
||||
// The following implements a heuristic to determine a keep straight's
|
||||
// direction in relation to the next step. In the above example we would get:
|
||||
//
|
||||
// coming from right, going to left (in direction of way) -> handle as left turn
|
||||
|
||||
if (previous_inst.type == TurnType::Suppressed &&
|
||||
current_inst.type == TurnType::Suppressed && previous.mode == current.mode &&
|
||||
previous_lanes == current_lanes)
|
||||
{
|
||||
previous.ElongateBy(current);
|
||||
current.Invalidate();
|
||||
}
|
||||
});
|
||||
if (is_straight_left.count(¤t) > 0)
|
||||
anticipate_for_left_turn();
|
||||
else if (is_straight_right.count(¤t) > 0)
|
||||
anticipate_for_right_turn();
|
||||
else // FIXME: right-sided driving
|
||||
anticipate_for_right_turn();
|
||||
}
|
||||
|
||||
if (previous_inst.type == TurnType::Suppressed &&
|
||||
current_inst.type == TurnType::Suppressed && previous.mode == current.mode &&
|
||||
previous_lanes == current_lanes)
|
||||
{
|
||||
previous.ElongateBy(current);
|
||||
current.Invalidate();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
std::for_each(begin(quick_lanes_ranges), end(quick_lanes_ranges), constrain_lanes);
|
||||
|
@ -77,7 +77,8 @@ void processRoundaboutExits(const RouteStepIterator begin, const RouteStepIterat
|
||||
return;
|
||||
}
|
||||
|
||||
const auto passes_exit_or_leaves_roundabout = [](auto const &step) {
|
||||
const auto passes_exit_or_leaves_roundabout = [](auto const &step)
|
||||
{
|
||||
return staysOnRoundabout(step.maneuver.instruction) ||
|
||||
leavesRoundabout(step.maneuver.instruction);
|
||||
};
|
||||
@ -142,9 +143,8 @@ void processRoundaboutExits(const RouteStepIterator begin, const RouteStepIterat
|
||||
// instructions in between
|
||||
void processRoundaboutGroups(const std::pair<RouteStepIterator, RouteStepIterator> &range)
|
||||
{
|
||||
const auto leaves_roundabout = [](auto const &step) {
|
||||
return leavesRoundabout(step.maneuver.instruction);
|
||||
};
|
||||
const auto leaves_roundabout = [](auto const &step)
|
||||
{ return leavesRoundabout(step.maneuver.instruction); };
|
||||
|
||||
auto itr = range.first;
|
||||
while (itr != range.second)
|
||||
@ -174,9 +174,8 @@ void processRoundaboutGroups(const std::pair<RouteStepIterator, RouteStepIterato
|
||||
std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps)
|
||||
{
|
||||
// check if a step has roundabout type
|
||||
const auto has_roundabout_type = [](auto const &step) {
|
||||
return hasRoundaboutType(step.maneuver.instruction);
|
||||
};
|
||||
const auto has_roundabout_type = [](auto const &step)
|
||||
{ return hasRoundaboutType(step.maneuver.instruction); };
|
||||
const auto first_roundabout_type =
|
||||
std::find_if(steps.begin(), steps.end(), has_roundabout_type);
|
||||
|
||||
@ -193,7 +192,8 @@ std::vector<RouteStep> handleRoundabouts(std::vector<RouteStep> steps)
|
||||
// this group by paradigm does might contain intermediate roundabout instructions, when they are
|
||||
// directly connected. Otherwise it will be a sequence containing everything from enter to exit.
|
||||
// If we already start on the roundabout, the first valid place will be steps.begin().
|
||||
const auto is_on_roundabout = [¤tly_on_roundabout](const auto &step) {
|
||||
const auto is_on_roundabout = [¤tly_on_roundabout](const auto &step)
|
||||
{
|
||||
if (currently_on_roundabout)
|
||||
{
|
||||
if (leavesRoundabout(step.maneuver.instruction))
|
||||
@ -327,10 +327,13 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry)
|
||||
}
|
||||
|
||||
// and update the leg geometry indices for the removed entry
|
||||
std::for_each(steps.begin(), steps.end(), [offset](RouteStep &step) {
|
||||
step.geometry_begin -= offset;
|
||||
step.geometry_end -= offset;
|
||||
});
|
||||
std::for_each(steps.begin(),
|
||||
steps.end(),
|
||||
[offset](RouteStep &step)
|
||||
{
|
||||
step.geometry_begin -= offset;
|
||||
step.geometry_end -= offset;
|
||||
});
|
||||
|
||||
auto &first_step = steps.front();
|
||||
auto bearing = first_bearing;
|
||||
@ -645,16 +648,18 @@ void applyOverrides(const datafacade::BaseDataFacade &facade,
|
||||
auto step_to_update = std::find_if(
|
||||
current_step_it,
|
||||
route_iter,
|
||||
[&leg_geometry, &via_node_coords](const auto &step) {
|
||||
[&leg_geometry, &via_node_coords](const auto &step)
|
||||
{
|
||||
util::Log(logDEBUG) << "Leg geom from " << step.geometry_begin << " to "
|
||||
<< step.geometry_end << std::endl;
|
||||
|
||||
// iterators over geometry of current step
|
||||
auto begin = leg_geometry.locations.begin() + step.geometry_begin;
|
||||
auto end = leg_geometry.locations.begin() + step.geometry_end;
|
||||
auto via_match = std::find_if(begin, end, [&](const auto &location) {
|
||||
return location == via_node_coords;
|
||||
});
|
||||
auto via_match = std::find_if(begin,
|
||||
end,
|
||||
[&](const auto &location)
|
||||
{ return location == via_node_coords; });
|
||||
if (via_match != end)
|
||||
{
|
||||
util::Log(logDEBUG)
|
||||
|
@ -15,19 +15,20 @@ std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps)
|
||||
return steps;
|
||||
|
||||
// we remove only name changes that don't offer additional information
|
||||
const auto name_change_without_lanes = [](const RouteStep &step) {
|
||||
return hasTurnType(step, TurnType::NewName) && !hasLanes(step);
|
||||
};
|
||||
const auto name_change_without_lanes = [](const RouteStep &step)
|
||||
{ return hasTurnType(step, TurnType::NewName) && !hasLanes(step); };
|
||||
|
||||
// check if the next step is not important enough to announce
|
||||
const auto can_be_extended_to = [](const RouteStep &step) {
|
||||
const auto can_be_extended_to = [](const RouteStep &step)
|
||||
{
|
||||
const auto is_not_arrive = !hasWaypointType(step);
|
||||
const auto is_silent = !hasTurnType(step) || hasTurnType(step, TurnType::Suppressed);
|
||||
|
||||
return is_not_arrive && is_silent;
|
||||
};
|
||||
|
||||
const auto suppress = [](RouteStep &from_step, RouteStep &onto_step) {
|
||||
const auto suppress = [](RouteStep &from_step, RouteStep &onto_step)
|
||||
{
|
||||
from_step.ElongateBy(onto_step);
|
||||
onto_step.Invalidate();
|
||||
};
|
||||
@ -36,28 +37,29 @@ std::vector<RouteStep> suppressShortNameSegments(std::vector<RouteStep> steps)
|
||||
// only available for a very short time
|
||||
const auto reduce_verbosity_if_possible =
|
||||
[suppress, can_be_extended_to](RouteStepIterator ¤t_turn_itr,
|
||||
RouteStepIterator &previous_turn_itr) {
|
||||
if (haveSameName(*previous_turn_itr, *current_turn_itr))
|
||||
RouteStepIterator &previous_turn_itr)
|
||||
{
|
||||
if (haveSameName(*previous_turn_itr, *current_turn_itr))
|
||||
suppress(*previous_turn_itr, *current_turn_itr);
|
||||
else
|
||||
{
|
||||
// remember the location of the name change so we can advance the previous turn
|
||||
const auto location_of_name_change = current_turn_itr;
|
||||
auto distance = current_turn_itr->distance;
|
||||
// sum up all distances that can be relevant to the name change
|
||||
while (can_be_extended_to(*(current_turn_itr + 1)) &&
|
||||
distance < NAME_SEGMENT_CUTOFF_LENGTH)
|
||||
{
|
||||
++current_turn_itr;
|
||||
distance += current_turn_itr->distance;
|
||||
}
|
||||
|
||||
if (distance < NAME_SEGMENT_CUTOFF_LENGTH)
|
||||
suppress(*previous_turn_itr, *current_turn_itr);
|
||||
else
|
||||
{
|
||||
// remember the location of the name change so we can advance the previous turn
|
||||
const auto location_of_name_change = current_turn_itr;
|
||||
auto distance = current_turn_itr->distance;
|
||||
// sum up all distances that can be relevant to the name change
|
||||
while (can_be_extended_to(*(current_turn_itr + 1)) &&
|
||||
distance < NAME_SEGMENT_CUTOFF_LENGTH)
|
||||
{
|
||||
++current_turn_itr;
|
||||
distance += current_turn_itr->distance;
|
||||
}
|
||||
|
||||
if (distance < NAME_SEGMENT_CUTOFF_LENGTH)
|
||||
suppress(*previous_turn_itr, *current_turn_itr);
|
||||
else
|
||||
previous_turn_itr = location_of_name_change;
|
||||
}
|
||||
};
|
||||
previous_turn_itr = location_of_name_change;
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_ASSERT(!hasTurnType(steps.back()) && hasWaypointType(steps.back()));
|
||||
for (auto previous_turn_itr = steps.begin(), current_turn_itr = std::next(previous_turn_itr);
|
||||
|
@ -93,10 +93,10 @@ Hint Hint::FromBase64(const std::string &base64Hint)
|
||||
bool Hint::IsValid(const util::Coordinate new_input_coordinates,
|
||||
const datafacade::BaseDataFacade &facade) const
|
||||
{
|
||||
const auto all_valid =
|
||||
std::all_of(segment_hints.begin(), segment_hints.end(), [&](const auto &seg_hint) {
|
||||
return seg_hint.IsValid(new_input_coordinates, facade);
|
||||
});
|
||||
const auto all_valid = std::all_of(segment_hints.begin(),
|
||||
segment_hints.end(),
|
||||
[&](const auto &seg_hint)
|
||||
{ return seg_hint.IsValid(new_input_coordinates, facade); });
|
||||
if (!all_valid)
|
||||
{
|
||||
return false;
|
||||
|
@ -50,7 +50,8 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
|
||||
// sort by forward id, then by reverse id and then by distance
|
||||
std::sort(candidates.begin(),
|
||||
candidates.end(),
|
||||
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs) {
|
||||
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
|
||||
{
|
||||
return lhs.phantom_node.forward_segment_id.id <
|
||||
rhs.phantom_node.forward_segment_id.id ||
|
||||
(lhs.phantom_node.forward_segment_id.id ==
|
||||
@ -65,7 +66,8 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
|
||||
auto new_end =
|
||||
std::unique(candidates.begin(),
|
||||
candidates.end(),
|
||||
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs) {
|
||||
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
|
||||
{
|
||||
return lhs.phantom_node.forward_segment_id.id ==
|
||||
rhs.phantom_node.forward_segment_id.id &&
|
||||
lhs.phantom_node.reverse_segment_id.id ==
|
||||
@ -95,9 +97,8 @@ void filterCandidates(const std::vector<util::Coordinate> &coordinates,
|
||||
// sort by distance to make pruning effective
|
||||
std::sort(candidates.begin(),
|
||||
candidates.end(),
|
||||
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs) {
|
||||
return lhs.distance < rhs.distance;
|
||||
});
|
||||
[](const PhantomNodeWithDistance &lhs, const PhantomNodeWithDistance &rhs)
|
||||
{ return lhs.distance < rhs.distance; });
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +134,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
|
||||
if (max_radius_map_matching > 0 && std::any_of(parameters.radiuses.begin(),
|
||||
parameters.radiuses.end(),
|
||||
[&](const auto &radius) {
|
||||
[&](const auto &radius)
|
||||
{
|
||||
if (!radius)
|
||||
return false;
|
||||
return *radius > max_radius_map_matching;
|
||||
@ -192,7 +194,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
tidied.parameters.radiuses.begin(),
|
||||
tidied.parameters.radiuses.end(),
|
||||
search_radiuses.begin(),
|
||||
[default_radius = this->default_radius](const boost::optional<double> &maybe_radius) {
|
||||
[default_radius = this->default_radius](const boost::optional<double> &maybe_radius)
|
||||
{
|
||||
if (maybe_radius)
|
||||
{
|
||||
return *maybe_radius * RADIUS_MULTIPLIER;
|
||||
@ -212,9 +215,8 @@ Status MatchPlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
|
||||
filterCandidates(tidied.parameters.coordinates, candidates_lists);
|
||||
if (std::all_of(candidates_lists.begin(),
|
||||
candidates_lists.end(),
|
||||
[](const std::vector<PhantomNodeWithDistance> &candidates) {
|
||||
return candidates.empty();
|
||||
}))
|
||||
[](const std::vector<PhantomNodeWithDistance> &candidates)
|
||||
{ return candidates.empty(); }))
|
||||
{
|
||||
return Error("NoSegment",
|
||||
std::string("Could not find a matching segment for any coordinate."),
|
||||
|
@ -251,7 +251,8 @@ std::vector<std::size_t> getEdgeIndex(const std::vector<RTreeLeaf> &edges)
|
||||
// as the sort condition
|
||||
std::sort(sorted_edge_indexes.begin(),
|
||||
sorted_edge_indexes.end(),
|
||||
[&edges](const std::size_t &left, const std::size_t &right) -> bool {
|
||||
[&edges](const std::size_t &left, const std::size_t &right) -> bool
|
||||
{
|
||||
return (edges[left].u != edges[right].u) ? edges[left].u < edges[right].u
|
||||
: edges[left].v < edges[right].v;
|
||||
});
|
||||
@ -430,9 +431,8 @@ void encodeVectorTile(const DataFacadeBase &facade,
|
||||
{
|
||||
vtzero::tile_builder tile;
|
||||
|
||||
const auto get_geometry_id = [&facade](auto edge) {
|
||||
return facade.GetGeometryIndex(edge.forward_segment_id.id).id;
|
||||
};
|
||||
const auto get_geometry_id = [&facade](auto edge)
|
||||
{ return facade.GetGeometryIndex(edge.forward_segment_id.id).id; };
|
||||
|
||||
// Convert tile coordinates into mercator coordinates
|
||||
double min_mercator_lon, min_mercator_lat, max_mercator_lon, max_mercator_lat;
|
||||
|
@ -137,7 +137,8 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
|
||||
std::vector<bool> waypoint_legs(route_parameters.coordinates.size(), false);
|
||||
std::for_each(route_parameters.waypoints.begin(),
|
||||
route_parameters.waypoints.end(),
|
||||
[&](const std::size_t waypoint_index) {
|
||||
[&](const std::size_t waypoint_index)
|
||||
{
|
||||
BOOST_ASSERT(waypoint_index < waypoint_legs.size());
|
||||
waypoint_legs[waypoint_index] = true;
|
||||
});
|
||||
@ -156,22 +157,23 @@ Status ViaRoutePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithm
|
||||
else
|
||||
{
|
||||
const auto all_in_same_component =
|
||||
[](const std::vector<PhantomNodeCandidates> &waypoint_candidates) {
|
||||
return std::any_of(waypoint_candidates.front().begin(),
|
||||
waypoint_candidates.front().end(),
|
||||
// For each of the first possible phantoms, check if all other
|
||||
// positions in the list have a phantom from the same component.
|
||||
[&](const PhantomNode &phantom) {
|
||||
const auto component_id = phantom.component.id;
|
||||
return std::all_of(
|
||||
std::next(waypoint_candidates.begin()),
|
||||
std::end(waypoint_candidates),
|
||||
[component_id](const PhantomNodeCandidates &candidates) {
|
||||
return candidatesHaveComponent(candidates,
|
||||
component_id);
|
||||
});
|
||||
});
|
||||
};
|
||||
[](const std::vector<PhantomNodeCandidates> &waypoint_candidates)
|
||||
{
|
||||
return std::any_of(waypoint_candidates.front().begin(),
|
||||
waypoint_candidates.front().end(),
|
||||
// For each of the first possible phantoms, check if all other
|
||||
// positions in the list have a phantom from the same component.
|
||||
[&](const PhantomNode &phantom)
|
||||
{
|
||||
const auto component_id = phantom.component.id;
|
||||
return std::all_of(
|
||||
std::next(waypoint_candidates.begin()),
|
||||
std::end(waypoint_candidates),
|
||||
[component_id](const PhantomNodeCandidates &candidates) {
|
||||
return candidatesHaveComponent(candidates, component_id);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (!all_in_same_component(snapped_phantoms))
|
||||
{
|
||||
|
@ -223,9 +223,8 @@ RandIt filterViaCandidatesByStretch(RandIt first,
|
||||
const auto stretch_weight_limit =
|
||||
(1. + parameters.kAtMostLongerBy) * from_alias<double>(weight);
|
||||
|
||||
const auto over_weight_limit = [=](const auto via) {
|
||||
return from_alias<double>(via.weight) > stretch_weight_limit;
|
||||
};
|
||||
const auto over_weight_limit = [=](const auto via)
|
||||
{ return from_alias<double>(via.weight) > stretch_weight_limit; };
|
||||
|
||||
return std::remove_if(first, last, over_weight_limit);
|
||||
}
|
||||
@ -298,13 +297,15 @@ RandIt filterPackedPathsByCellSharing(RandIt first,
|
||||
for (const auto &edge : shortest_path.path)
|
||||
cells.insert(get_cell(std::get<1>(edge)));
|
||||
|
||||
const auto over_sharing_limit = [&](const auto &packed) {
|
||||
const auto over_sharing_limit = [&](const auto &packed)
|
||||
{
|
||||
if (packed.path.empty())
|
||||
{ // don't remove routes with single-node (empty) path
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto not_seen = [&](const PackedEdge edge) {
|
||||
const auto not_seen = [&](const PackedEdge edge)
|
||||
{
|
||||
const auto source_cell = get_cell(std::get<0>(edge));
|
||||
const auto target_cell = get_cell(std::get<1>(edge));
|
||||
return cells.count(source_cell) < 1 && cells.count(target_cell) < 1;
|
||||
@ -364,7 +365,8 @@ RandIt filterPackedPathsByLocalOptimality(const WeightedViaNodePackedPath &path,
|
||||
BOOST_ASSERT(path.via.weight != INVALID_EDGE_WEIGHT);
|
||||
|
||||
// node == parent_in_main_heap(parent_in_side_heap(v)) -> plateaux at `node`
|
||||
const auto has_plateaux_at_node = [&](const NodeID node, const Heap &fst, const Heap &snd) {
|
||||
const auto has_plateaux_at_node = [&](const NodeID node, const Heap &fst, const Heap &snd)
|
||||
{
|
||||
BOOST_ASSERT(fst.WasInserted(node));
|
||||
auto const parent = fst.GetData(node).parent;
|
||||
return snd.WasInserted(parent) && snd.GetData(parent).parent == node;
|
||||
@ -374,7 +376,8 @@ RandIt filterPackedPathsByLocalOptimality(const WeightedViaNodePackedPath &path,
|
||||
// tree from t overlap. An edge is part of such a plateaux around `v` if:
|
||||
// v == parent_in_reverse_search(parent_in_forward_search(v)).
|
||||
// Here we calculate the last node on the plateaux in either direction.
|
||||
const auto plateaux_end = [&](NodeID node, const Heap &fst, const Heap &snd) {
|
||||
const auto plateaux_end = [&](NodeID node, const Heap &fst, const Heap &snd)
|
||||
{
|
||||
BOOST_ASSERT(node != SPECIAL_NODEID);
|
||||
BOOST_ASSERT(fst.WasInserted(node));
|
||||
BOOST_ASSERT(snd.WasInserted(node));
|
||||
@ -388,7 +391,8 @@ RandIt filterPackedPathsByLocalOptimality(const WeightedViaNodePackedPath &path,
|
||||
return node;
|
||||
};
|
||||
|
||||
const auto is_not_locally_optimal = [&](const auto &packed) {
|
||||
const auto is_not_locally_optimal = [&](const auto &packed)
|
||||
{
|
||||
BOOST_ASSERT(packed.via.node != path.via.node);
|
||||
BOOST_ASSERT(packed.via.weight != INVALID_EDGE_WEIGHT);
|
||||
BOOST_ASSERT(packed.via.node != SPECIAL_NODEID);
|
||||
@ -475,14 +479,16 @@ RandIt filterUnpackedPathsBySharing(RandIt first,
|
||||
|
||||
nodes.insert(begin(shortest_path.nodes), end(shortest_path.nodes));
|
||||
|
||||
const auto over_sharing_limit = [&](auto &unpacked) {
|
||||
const auto over_sharing_limit = [&](auto &unpacked)
|
||||
{
|
||||
if (unpacked.edges.empty())
|
||||
{ // don't remove routes with single-node (empty) path
|
||||
return false;
|
||||
}
|
||||
|
||||
EdgeDuration total_duration = {0};
|
||||
const auto add_if_seen = [&](const EdgeDuration duration, const NodeID node) {
|
||||
const auto add_if_seen = [&](const EdgeDuration duration, const NodeID node)
|
||||
{
|
||||
auto node_duration = facade.GetNodeDuration(node);
|
||||
total_duration += node_duration;
|
||||
if (nodes.count(node) > 0)
|
||||
@ -533,9 +539,8 @@ RandIt filterAnnotatedRoutesByStretch(RandIt first,
|
||||
const auto stretch_duration_limit =
|
||||
(1. + parameters.kAtMostLongerBy) * from_alias<double>(shortest_route_duration);
|
||||
|
||||
const auto over_duration_limit = [=](const auto &route) {
|
||||
return from_alias<double>(route.duration()) > stretch_duration_limit;
|
||||
};
|
||||
const auto over_duration_limit = [=](const auto &route)
|
||||
{ return from_alias<double>(route.duration()) > stretch_duration_limit; };
|
||||
|
||||
return std::remove_if(first, last, over_duration_limit);
|
||||
}
|
||||
@ -837,9 +842,9 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
|
||||
it = filterViaCandidatesByStretch(begin(candidate_vias), it, shortest_path_weight, parameters);
|
||||
|
||||
// Pre-rank by weight; sharing filtering below then discards by similarity.
|
||||
std::sort(begin(candidate_vias), it, [](const auto lhs, const auto rhs) {
|
||||
return lhs.weight < rhs.weight;
|
||||
});
|
||||
std::sort(begin(candidate_vias),
|
||||
it,
|
||||
[](const auto lhs, const auto rhs) { return lhs.weight < rhs.weight; });
|
||||
|
||||
// Filtered and ranked candidate range
|
||||
const auto candidate_vias_first = begin(candidate_vias);
|
||||
@ -850,7 +855,8 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
|
||||
// The recursive path unpacking below destructs heaps.
|
||||
// We need to save all packed paths from the heaps upfront.
|
||||
|
||||
const auto extract_packed_path_from_heaps = [&](WeightedViaNode via) {
|
||||
const auto extract_packed_path_from_heaps = [&](WeightedViaNode via)
|
||||
{
|
||||
auto packed_path = retrievePackedPathFromHeap(forward_heap, reverse_heap, via.node);
|
||||
|
||||
return WeightedViaNodePackedPath{via, std::move(packed_path)};
|
||||
@ -928,9 +934,8 @@ InternalManyRoutesResult alternativePathSearch(SearchEngineData<Algorithm> &sear
|
||||
std::vector<InternalRouteResult> routes;
|
||||
routes.reserve(number_of_unpacked_paths);
|
||||
|
||||
const auto unpacked_path_to_route = [&](const WeightedViaNodeUnpackedPath &path) {
|
||||
return extractRoute(facade, path.via.weight, endpoint_candidates, path.nodes, path.edges);
|
||||
};
|
||||
const auto unpacked_path_to_route = [&](const WeightedViaNodeUnpackedPath &path)
|
||||
{ return extractRoute(facade, path.via.weight, endpoint_candidates, path.nodes, path.edges); };
|
||||
|
||||
std::transform(unpacked_paths_first,
|
||||
unpacked_paths_last,
|
||||
|
@ -45,15 +45,16 @@ InternalRouteResult directShortestPathSearch(SearchEngineData<ch::Algorithm> &en
|
||||
unpacked_nodes.reserve(packed_leg.size());
|
||||
unpacked_edges.reserve(packed_leg.size());
|
||||
unpacked_nodes.push_back(packed_leg.front());
|
||||
ch::unpackPath(facade,
|
||||
packed_leg.begin(),
|
||||
packed_leg.end(),
|
||||
[&unpacked_nodes, &unpacked_edges](std::pair<NodeID, NodeID> &edge,
|
||||
const auto &edge_id) {
|
||||
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
||||
unpacked_nodes.push_back(edge.second);
|
||||
unpacked_edges.push_back(edge_id);
|
||||
});
|
||||
ch::unpackPath(
|
||||
facade,
|
||||
packed_leg.begin(),
|
||||
packed_leg.end(),
|
||||
[&unpacked_nodes, &unpacked_edges](std::pair<NodeID, NodeID> &edge, const auto &edge_id)
|
||||
{
|
||||
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
||||
unpacked_nodes.push_back(edge.second);
|
||||
unpacked_edges.push_back(edge_id);
|
||||
});
|
||||
}
|
||||
|
||||
return extractRoute(facade, weight, endpoint_candidates, unpacked_nodes, unpacked_edges);
|
||||
|
@ -95,7 +95,7 @@ void relaxOutgoingEdges(
|
||||
const DataFacade<mld::Algorithm> &facade,
|
||||
const typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap::HeapNode &heapNode,
|
||||
typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &query_heap,
|
||||
const Args &... args)
|
||||
const Args &...args)
|
||||
{
|
||||
BOOST_ASSERT(!facade.ExcludeNode(heapNode.node));
|
||||
|
||||
@ -280,49 +280,51 @@ oneToManySearch(SearchEngineData<Algorithm> &engine_working_data,
|
||||
|
||||
// Check if node is in the destinations list and update weights/durations
|
||||
auto update_values =
|
||||
[&](NodeID node, EdgeWeight weight, EdgeDuration duration, EdgeDistance distance) {
|
||||
auto candidates = target_nodes_index.equal_range(node);
|
||||
for (auto it = candidates.first; it != candidates.second;)
|
||||
[&](NodeID node, EdgeWeight weight, EdgeDuration duration, EdgeDistance distance)
|
||||
{
|
||||
auto candidates = target_nodes_index.equal_range(node);
|
||||
for (auto it = candidates.first; it != candidates.second;)
|
||||
{
|
||||
std::size_t index;
|
||||
EdgeWeight target_weight;
|
||||
EdgeDuration target_duration;
|
||||
EdgeDistance target_distance;
|
||||
std::tie(index, target_weight, target_duration, target_distance) = it->second;
|
||||
|
||||
const auto path_weight = weight + target_weight;
|
||||
if (path_weight >= EdgeWeight{0})
|
||||
{
|
||||
std::size_t index;
|
||||
EdgeWeight target_weight;
|
||||
EdgeDuration target_duration;
|
||||
EdgeDistance target_distance;
|
||||
std::tie(index, target_weight, target_duration, target_distance) = it->second;
|
||||
const auto path_duration = duration + target_duration;
|
||||
const auto path_distance = distance + target_distance;
|
||||
|
||||
const auto path_weight = weight + target_weight;
|
||||
if (path_weight >= EdgeWeight{0})
|
||||
EdgeDistance nulldistance = {0};
|
||||
auto ¤t_distance =
|
||||
distances_table.empty() ? nulldistance : distances_table[index];
|
||||
|
||||
if (std::tie(path_weight, path_duration, path_distance) <
|
||||
std::tie(weights_table[index], durations_table[index], current_distance))
|
||||
{
|
||||
const auto path_duration = duration + target_duration;
|
||||
const auto path_distance = distance + target_distance;
|
||||
|
||||
EdgeDistance nulldistance = {0};
|
||||
auto ¤t_distance =
|
||||
distances_table.empty() ? nulldistance : distances_table[index];
|
||||
|
||||
if (std::tie(path_weight, path_duration, path_distance) <
|
||||
std::tie(weights_table[index], durations_table[index], current_distance))
|
||||
{
|
||||
weights_table[index] = path_weight;
|
||||
durations_table[index] = path_duration;
|
||||
current_distance = path_distance;
|
||||
middle_nodes_table[index] = node;
|
||||
}
|
||||
|
||||
// Remove node from destinations list
|
||||
it = target_nodes_index.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
weights_table[index] = path_weight;
|
||||
durations_table[index] = path_duration;
|
||||
current_distance = path_distance;
|
||||
middle_nodes_table[index] = node;
|
||||
}
|
||||
|
||||
// Remove node from destinations list
|
||||
it = target_nodes_index.erase(it);
|
||||
}
|
||||
};
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto insert_node = [&](NodeID node,
|
||||
EdgeWeight initial_weight,
|
||||
EdgeDuration initial_duration,
|
||||
EdgeDistance initial_distance) {
|
||||
EdgeDistance initial_distance)
|
||||
{
|
||||
if (target_nodes_index.count(node))
|
||||
{
|
||||
// Source and target on the same edge node. If target is not reachable directly via
|
||||
|
@ -83,7 +83,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
|
||||
const bool use_timestamps = trace_timestamps.size() > 1;
|
||||
|
||||
const auto median_sample_time = [&] {
|
||||
const auto median_sample_time = [&]
|
||||
{
|
||||
if (use_timestamps)
|
||||
{
|
||||
return std::max(1u, getMedianSampleTime(trace_timestamps));
|
||||
@ -104,9 +105,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
std::transform(candidates_list[t].begin(),
|
||||
candidates_list[t].end(),
|
||||
emission_log_probabilities[t].begin(),
|
||||
[&](const PhantomNodeWithDistance &candidate) {
|
||||
return default_emission_log_probability(candidate.distance);
|
||||
});
|
||||
[&](const PhantomNodeWithDistance &candidate)
|
||||
{ return default_emission_log_probability(candidate.distance); });
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -118,22 +118,19 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
{
|
||||
map_matching::EmissionLogProbability emission_log_probability(
|
||||
*trace_gps_precision[t]);
|
||||
std::transform(
|
||||
candidates_list[t].begin(),
|
||||
candidates_list[t].end(),
|
||||
emission_log_probabilities[t].begin(),
|
||||
[&emission_log_probability](const PhantomNodeWithDistance &candidate) {
|
||||
return emission_log_probability(candidate.distance);
|
||||
});
|
||||
std::transform(candidates_list[t].begin(),
|
||||
candidates_list[t].end(),
|
||||
emission_log_probabilities[t].begin(),
|
||||
[&emission_log_probability](const PhantomNodeWithDistance &candidate)
|
||||
{ return emission_log_probability(candidate.distance); });
|
||||
}
|
||||
else
|
||||
{
|
||||
std::transform(candidates_list[t].begin(),
|
||||
candidates_list[t].end(),
|
||||
emission_log_probabilities[t].begin(),
|
||||
[&](const PhantomNodeWithDistance &candidate) {
|
||||
return default_emission_log_probability(candidate.distance);
|
||||
});
|
||||
[&](const PhantomNodeWithDistance &candidate)
|
||||
{ return default_emission_log_probability(candidate.distance); });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,7 +155,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
for (auto t = initial_timestamp + 1; t < candidates_list.size(); ++t)
|
||||
{
|
||||
|
||||
const auto step_time = [&] {
|
||||
const auto step_time = [&]
|
||||
{
|
||||
if (use_timestamps)
|
||||
{
|
||||
return trace_timestamps[t] - trace_timestamps[prev_unbroken_timestamps.back()];
|
||||
@ -169,7 +167,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
}
|
||||
}();
|
||||
|
||||
const auto max_distance_delta = [&] {
|
||||
const auto max_distance_delta = [&]
|
||||
{
|
||||
if (use_timestamps)
|
||||
{
|
||||
return step_time * facade.GetMapMatchingMaxSpeed();
|
||||
@ -180,7 +179,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
}
|
||||
}();
|
||||
|
||||
const bool gap_in_trace = [&]() {
|
||||
const bool gap_in_trace = [&]()
|
||||
{
|
||||
// use temporal information if available to determine a split
|
||||
// but do not determine split by timestamps if wasn't asked about it
|
||||
if (use_timestamps && allow_splitting)
|
||||
@ -419,7 +419,8 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
||||
util::for_each_pair(
|
||||
reconstructed_indices,
|
||||
[&trace_distance, &trace_coordinates](const std::pair<std::size_t, std::size_t> &prev,
|
||||
const std::pair<std::size_t, std::size_t> &curr) {
|
||||
const std::pair<std::size_t, std::size_t> &curr)
|
||||
{
|
||||
trace_distance += util::coordinate_calculation::greatCircleDistance(
|
||||
trace_coordinates[prev.first], trace_coordinates[curr.first]);
|
||||
});
|
||||
|
@ -25,9 +25,8 @@ std::vector<NodeID> getForwardLoopNodes(const PhantomEndpointCandidates &endpoin
|
||||
auto requires_loop =
|
||||
std::any_of(endpoint_candidates.target_phantoms.begin(),
|
||||
endpoint_candidates.target_phantoms.end(),
|
||||
[&](const auto &target_phantom) {
|
||||
return requiresForwardLoop(source_phantom, target_phantom);
|
||||
});
|
||||
[&](const auto &target_phantom)
|
||||
{ return requiresForwardLoop(source_phantom, target_phantom); });
|
||||
if (requires_loop)
|
||||
{
|
||||
res.push_back(source_phantom.forward_segment_id.id);
|
||||
@ -57,9 +56,8 @@ std::vector<NodeID> getBackwardLoopNodes(const PhantomEndpointCandidates &endpoi
|
||||
auto requires_loop =
|
||||
std::any_of(endpoint_candidates.target_phantoms.begin(),
|
||||
endpoint_candidates.target_phantoms.end(),
|
||||
[&](const auto &target_phantom) {
|
||||
return requiresBackwardLoop(source_phantom, target_phantom);
|
||||
});
|
||||
[&](const auto &target_phantom)
|
||||
{ return requiresBackwardLoop(source_phantom, target_phantom); });
|
||||
if (requires_loop)
|
||||
{
|
||||
res.push_back(source_phantom.reverse_segment_id.id);
|
||||
@ -86,7 +84,8 @@ PhantomEndpoints endpointsFromCandidates(const PhantomEndpointCandidates &candid
|
||||
{
|
||||
auto source_it = std::find_if(candidates.source_phantoms.begin(),
|
||||
candidates.source_phantoms.end(),
|
||||
[&path](const auto &source_phantom) {
|
||||
[&path](const auto &source_phantom)
|
||||
{
|
||||
return path.front() == source_phantom.forward_segment_id.id ||
|
||||
path.front() == source_phantom.reverse_segment_id.id;
|
||||
});
|
||||
@ -94,7 +93,8 @@ PhantomEndpoints endpointsFromCandidates(const PhantomEndpointCandidates &candid
|
||||
|
||||
auto target_it = std::find_if(candidates.target_phantoms.begin(),
|
||||
candidates.target_phantoms.end(),
|
||||
[&path](const auto &target_phantom) {
|
||||
[&path](const auto &target_phantom)
|
||||
{
|
||||
return path.back() == target_phantom.forward_segment_id.id ||
|
||||
path.back() == target_phantom.reverse_segment_id.id;
|
||||
});
|
||||
|
@ -19,9 +19,8 @@ void unpackEdge(const DataFacade<Algorithm> &facade,
|
||||
unpackPath(facade,
|
||||
path.begin(),
|
||||
path.end(),
|
||||
[&unpacked_path](const std::pair<NodeID, NodeID> &edge, const auto & /* data */) {
|
||||
unpacked_path.emplace_back(edge.first);
|
||||
});
|
||||
[&unpacked_path](const std::pair<NodeID, NodeID> &edge, const auto & /* data */)
|
||||
{ unpacked_path.emplace_back(edge.first); });
|
||||
unpacked_path.emplace_back(to);
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,8 @@ std::vector<TurnData> generateTurns(const datafacade &facade,
|
||||
// it saves us a bunch of re-allocations during iteration.
|
||||
directed_graph.reserve(edges.size() * 2);
|
||||
|
||||
const auto get_geometry_id = [&facade](auto edge) {
|
||||
return facade.GetGeometryIndex(edge.forward_segment_id.id).id;
|
||||
};
|
||||
const auto get_geometry_id = [&facade](auto edge)
|
||||
{ return facade.GetGeometryIndex(edge.forward_segment_id.id).id; };
|
||||
|
||||
// To build a tile, we can only rely on the r-tree to quickly find all data visible within the
|
||||
// tile itself. The Rtree returns a series of segments that may or may not offer turns
|
||||
@ -215,10 +214,10 @@ std::vector<TurnData> getTileTurns(const DataFacade<ch::Algorithm> &facade,
|
||||
//
|
||||
// would offer a backward edge at `b` to `a` (due to the oneway from a to b)
|
||||
// but could also offer a shortcut (b-c-a) from `b` to `a` which is longer.
|
||||
EdgeID edge_id = facade.FindSmallestEdge(
|
||||
approach_node, exit_node, [](const contractor::QueryEdge::EdgeData &data) {
|
||||
return data.forward && !data.shortcut;
|
||||
});
|
||||
EdgeID edge_id = facade.FindSmallestEdge(approach_node,
|
||||
exit_node,
|
||||
[](const contractor::QueryEdge::EdgeData &data)
|
||||
{ return data.forward && !data.shortcut; });
|
||||
|
||||
// Depending on how the graph is constructed, we might have to look for
|
||||
// a backwards edge instead. They're equivalent, just one is available for
|
||||
@ -227,10 +226,10 @@ std::vector<TurnData> getTileTurns(const DataFacade<ch::Algorithm> &facade,
|
||||
// If we didn't find a forward edge, try for a backward one
|
||||
if (SPECIAL_EDGEID == edge_id)
|
||||
{
|
||||
edge_id = facade.FindSmallestEdge(
|
||||
exit_node, approach_node, [](const contractor::QueryEdge::EdgeData &data) {
|
||||
return data.backward && !data.shortcut;
|
||||
});
|
||||
edge_id = facade.FindSmallestEdge(exit_node,
|
||||
approach_node,
|
||||
[](const contractor::QueryEdge::EdgeData &data)
|
||||
{ return data.backward && !data.shortcut; });
|
||||
}
|
||||
|
||||
BOOST_ASSERT_MSG(edge_id == SPECIAL_EDGEID || !facade.GetEdgeData(edge_id).shortcut,
|
||||
|
@ -151,7 +151,8 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N
|
||||
|
||||
NodeID current_edge_source_coordinate_id = node_u;
|
||||
|
||||
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id) {
|
||||
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id)
|
||||
{
|
||||
if (edge_based_node_id == SPECIAL_NODEID)
|
||||
{
|
||||
return SegmentID{SPECIAL_SEGMENTID, false};
|
||||
@ -409,7 +410,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedNodes(const WayRestrictionMap &way_re
|
||||
NodeID current_edge_source_coordinate_id = node_u;
|
||||
const EdgeData &forward_data = m_node_based_graph.GetEdgeData(eid);
|
||||
|
||||
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id) {
|
||||
const auto edge_id_to_segment_id = [](const NodeID edge_based_node_id)
|
||||
{
|
||||
if (edge_based_node_id == SPECIAL_NODEID)
|
||||
{
|
||||
return SegmentID{SPECIAL_SEGMENTID, false};
|
||||
@ -532,7 +534,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
TurnPenalty turn_duration_penalty;
|
||||
};
|
||||
|
||||
auto const transfer_data = [&](const EdgeWithData &edge_with_data) {
|
||||
auto const transfer_data = [&](const EdgeWithData &edge_with_data)
|
||||
{
|
||||
m_edge_based_edge_list.push_back(edge_with_data.edge);
|
||||
turn_weight_penalties.push_back(edge_with_data.turn_weight_penalty);
|
||||
turn_duration_penalties.push_back(edge_with_data.turn_duration_penalty);
|
||||
@ -568,7 +571,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
// First part of the pipeline generates iterator ranges of IDs in sets of GRAINSIZE
|
||||
tbb::filter<void, tbb::blocked_range<NodeID>> generator_stage(
|
||||
tbb::filter_mode::serial_in_order, [&](tbb::flow_control &fc) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&](tbb::flow_control &fc)
|
||||
{
|
||||
if (current_node < node_count)
|
||||
{
|
||||
auto next_node = std::min(current_node + GRAINSIZE, node_count);
|
||||
@ -599,7 +604,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const auto &turn_angle,
|
||||
const auto &road_legs_on_the_right,
|
||||
const auto &road_legs_on_the_left,
|
||||
const auto &edge_geometries) {
|
||||
const auto &edge_geometries)
|
||||
{
|
||||
const auto &edge_data1 = m_node_based_graph.GetEdgeData(node_based_edge_from);
|
||||
const auto &edge_data2 = m_node_based_graph.GetEdgeData(node_based_edge_to);
|
||||
|
||||
@ -710,7 +716,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
//
|
||||
tbb::filter<tbb::blocked_range<NodeID>, EdgesPipelineBufferPtr> processor_stage(
|
||||
tbb::filter_mode::parallel,
|
||||
[&](const tbb::blocked_range<NodeID> &intersection_node_range) {
|
||||
[&](const tbb::blocked_range<NodeID> &intersection_node_range)
|
||||
{
|
||||
auto buffer = std::make_shared<EdgesPipelineBuffer>();
|
||||
buffer->nodes_processed = intersection_node_range.size();
|
||||
|
||||
@ -795,16 +802,16 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
const auto turn =
|
||||
std::find_if(connected_roads.begin(),
|
||||
connected_roads.end(),
|
||||
[edge = outgoing_edge.edge](const auto &road) {
|
||||
return road.eid == edge;
|
||||
});
|
||||
[edge = outgoing_edge.edge](const auto &road)
|
||||
{ return road.eid == edge; });
|
||||
OSRM_ASSERT(turn != connected_roads.end(),
|
||||
m_coordinates[intersection_node]);
|
||||
|
||||
std::vector<ExtractionTurnLeg> road_legs_on_the_right;
|
||||
std::vector<ExtractionTurnLeg> road_legs_on_the_left;
|
||||
|
||||
auto get_connected_road_info = [&](const auto &connected_edge) {
|
||||
auto get_connected_road_info = [&](const auto &connected_edge)
|
||||
{
|
||||
const auto &edge_data =
|
||||
m_node_based_graph.GetEdgeData(connected_edge.eid);
|
||||
|
||||
@ -1012,9 +1019,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
auto const has_unconditional =
|
||||
std::any_of(restrictions.begin(),
|
||||
restrictions.end(),
|
||||
[](const auto &restriction) {
|
||||
return restriction->IsUnconditional();
|
||||
});
|
||||
[](const auto &restriction)
|
||||
{ return restriction->IsUnconditional(); });
|
||||
if (has_unconditional)
|
||||
continue;
|
||||
|
||||
@ -1120,7 +1126,9 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
util::Percent routing_progress(log, node_count);
|
||||
std::vector<EdgeWithData> delayed_data;
|
||||
tbb::filter<EdgesPipelineBufferPtr, void> output_stage(
|
||||
tbb::filter_mode::serial_in_order, [&](auto buffer) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&](auto buffer)
|
||||
{
|
||||
routing_progress.PrintAddition(buffer->nodes_processed);
|
||||
|
||||
m_connectivity_checksum = buffer->checksum.update_checksum(m_connectivity_checksum);
|
||||
@ -1140,7 +1148,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
|
||||
std::for_each(buffer->turn_to_ebn_map.begin(),
|
||||
buffer->turn_to_ebn_map.end(),
|
||||
[&global_turn_to_ebn_map](const auto &p) {
|
||||
[&global_turn_to_ebn_map](const auto &p)
|
||||
{
|
||||
// TODO: log conflicts here
|
||||
global_turn_to_ebn_map.insert(p);
|
||||
});
|
||||
@ -1178,26 +1187,32 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
return std::vector<NodeID>{turn_edges.second.first, turn_edges.second.second};
|
||||
});
|
||||
|
||||
std::for_each(std::next(turns.begin()), turns.end(), [&](const auto &turn) {
|
||||
std::vector<std::vector<NodeID>> next_node_sequences;
|
||||
const auto next_turn_edges = global_turn_to_ebn_map.equal_range(turn);
|
||||
for (auto &node_sequence : node_sequences)
|
||||
{
|
||||
const auto found_it = std::find_if(
|
||||
next_turn_edges.first, next_turn_edges.second, [&](const auto &turn_edges) {
|
||||
const auto pre_turn_edge = turn_edges.second.first;
|
||||
return (node_sequence.back() == pre_turn_edge);
|
||||
});
|
||||
std::for_each(std::next(turns.begin()),
|
||||
turns.end(),
|
||||
[&](const auto &turn)
|
||||
{
|
||||
std::vector<std::vector<NodeID>> next_node_sequences;
|
||||
const auto next_turn_edges = global_turn_to_ebn_map.equal_range(turn);
|
||||
for (auto &node_sequence : node_sequences)
|
||||
{
|
||||
const auto found_it = std::find_if(
|
||||
next_turn_edges.first,
|
||||
next_turn_edges.second,
|
||||
[&](const auto &turn_edges)
|
||||
{
|
||||
const auto pre_turn_edge = turn_edges.second.first;
|
||||
return (node_sequence.back() == pre_turn_edge);
|
||||
});
|
||||
|
||||
if (found_it != next_turn_edges.second)
|
||||
{
|
||||
const auto post_turn_edge = found_it->second.second;
|
||||
node_sequence.push_back(post_turn_edge);
|
||||
next_node_sequences.push_back(std::move(node_sequence));
|
||||
}
|
||||
}
|
||||
node_sequences = std::move(next_node_sequences);
|
||||
});
|
||||
if (found_it != next_turn_edges.second)
|
||||
{
|
||||
const auto post_turn_edge = found_it->second.second;
|
||||
node_sequence.push_back(post_turn_edge);
|
||||
next_node_sequences.push_back(std::move(node_sequence));
|
||||
}
|
||||
}
|
||||
node_sequences = std::move(next_node_sequences);
|
||||
});
|
||||
|
||||
for (const auto &node_sequence : node_sequences)
|
||||
{
|
||||
@ -1237,7 +1252,8 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
||||
// Now, update the turn_id property on every EdgeBasedEdge - it will equal the position in the
|
||||
// m_edge_based_edge_list array for each object.
|
||||
tbb::parallel_for(tbb::blocked_range<NodeID>(0, m_edge_based_edge_list.size()),
|
||||
[this](const tbb::blocked_range<NodeID> &range) {
|
||||
[this](const tbb::blocked_range<NodeID> &range)
|
||||
{
|
||||
for (auto x = range.begin(), end = range.end(); x != end; ++x)
|
||||
{
|
||||
m_edge_based_edge_list[x].data.turn_id = x;
|
||||
|
@ -460,10 +460,10 @@ void ExtractionContainers::PrepareNodes()
|
||||
util::UnbufferedLog log;
|
||||
log << "Sorting all nodes ... " << std::flush;
|
||||
TIMER_START(sorting_nodes);
|
||||
tbb::parallel_sort(
|
||||
all_nodes_list.begin(), all_nodes_list.end(), [](const auto &left, const auto &right) {
|
||||
return left.node_id < right.node_id;
|
||||
});
|
||||
tbb::parallel_sort(all_nodes_list.begin(),
|
||||
all_nodes_list.end(),
|
||||
[](const auto &left, const auto &right)
|
||||
{ return left.node_id < right.node_id; });
|
||||
TIMER_STOP(sorting_nodes);
|
||||
log << "ok, after " << TIMER_SEC(sorting_nodes) << "s";
|
||||
}
|
||||
@ -629,7 +629,8 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
|
||||
|
||||
// Remove all remaining edges. They are invalid because there are no corresponding nodes for
|
||||
// them. This happens when using osmosis with bbox or polygon to extract smaller areas.
|
||||
auto markSourcesInvalid = [](InternalExtractorEdge &edge) {
|
||||
auto markSourcesInvalid = [](InternalExtractorEdge &edge)
|
||||
{
|
||||
util::Log(logDEBUG) << "Found invalid node reference " << edge.result.source;
|
||||
edge.result.source = SPECIAL_NODEID;
|
||||
edge.result.osm_source_id = SPECIAL_OSM_NODEID;
|
||||
@ -743,7 +744,8 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
|
||||
|
||||
// Remove all remaining edges. They are invalid because there are no corresponding nodes for
|
||||
// them. This happens when using osmosis with bbox or polygon to extract smaller areas.
|
||||
auto markTargetsInvalid = [](InternalExtractorEdge &edge) {
|
||||
auto markTargetsInvalid = [](InternalExtractorEdge &edge)
|
||||
{
|
||||
util::Log(logDEBUG) << "Found invalid node reference " << edge.result.target;
|
||||
edge.result.target = SPECIAL_NODEID;
|
||||
};
|
||||
@ -898,7 +900,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
|
||||
<< " maneuver overrides...";
|
||||
TIMER_START(identify_maneuver_override_ways);
|
||||
|
||||
const auto mark_ids = [&](auto const &external_maneuver_override) {
|
||||
const auto mark_ids = [&](auto const &external_maneuver_override)
|
||||
{
|
||||
NodesOfWay dummy_segment{MAX_OSM_WAYID, {MAX_OSM_NODEID, MAX_OSM_NODEID}};
|
||||
const auto &turn_path = external_maneuver_override.turn_path;
|
||||
maneuver_override_ways[turn_path.From()] = dummy_segment;
|
||||
@ -918,7 +921,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyManeuverOverr
|
||||
std::for_each(
|
||||
external_maneuver_overrides_list.begin(), external_maneuver_overrides_list.end(), mark_ids);
|
||||
|
||||
const auto set_ids = [&](size_t way_list_idx, auto const &way_id) {
|
||||
const auto set_ids = [&](size_t way_list_idx, auto const &way_id)
|
||||
{
|
||||
auto itr = maneuver_override_ways.find(way_id);
|
||||
if (itr != maneuver_override_ways.end())
|
||||
{
|
||||
@ -984,7 +988,8 @@ void ExtractionContainers::PrepareTrafficSignals(
|
||||
|
||||
void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuver_override_ways)
|
||||
{
|
||||
auto const osm_node_to_internal_nbn = [&](auto const osm_node) {
|
||||
auto const osm_node_to_internal_nbn = [&](auto const osm_node)
|
||||
{
|
||||
auto internal = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
||||
if (internal == SPECIAL_NODEID)
|
||||
@ -994,8 +999,9 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
|
||||
return internal;
|
||||
};
|
||||
|
||||
const auto strings_to_turn_type_and_direction = [](const std::string &turn_string,
|
||||
const std::string &direction_string) {
|
||||
const auto strings_to_turn_type_and_direction =
|
||||
[](const std::string &turn_string, const std::string &direction_string)
|
||||
{
|
||||
auto result = std::make_pair(guidance::TurnType::MaxTurnType,
|
||||
guidance::DirectionModifier::MaxDirectionModifier);
|
||||
|
||||
@ -1059,7 +1065,8 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
|
||||
// Returns true on successful transformation, false in case of invalid references.
|
||||
// Later, the UnresolvedManeuverOverride will be converted into a final ManeuverOverride
|
||||
// once the edge-based-node IDs are generated by the edge-based-graph-factory
|
||||
const auto transform = [&](const auto &external_type, auto &internal_type) {
|
||||
const auto transform = [&](const auto &external_type, auto &internal_type)
|
||||
{
|
||||
if (external_type.turn_path.Type() == TurnPathType::VIA_WAY_TURN_PATH)
|
||||
{
|
||||
auto const &external = external_type.turn_path.AsViaWayPath();
|
||||
@ -1092,11 +1099,12 @@ void ExtractionContainers::PrepareManeuverOverrides(const ReferencedWays &maneuv
|
||||
};
|
||||
|
||||
const auto transform_into_internal_types =
|
||||
[&](const InputManeuverOverride &external_maneuver_override) {
|
||||
UnresolvedManeuverOverride internal_maneuver_override;
|
||||
if (transform(external_maneuver_override, internal_maneuver_override))
|
||||
internal_maneuver_overrides.push_back(std::move(internal_maneuver_override));
|
||||
};
|
||||
[&](const InputManeuverOverride &external_maneuver_override)
|
||||
{
|
||||
UnresolvedManeuverOverride internal_maneuver_override;
|
||||
if (transform(external_maneuver_override, internal_maneuver_override))
|
||||
internal_maneuver_overrides.push_back(std::move(internal_maneuver_override));
|
||||
};
|
||||
|
||||
// Transforming the overrides into the dedicated internal types
|
||||
{
|
||||
@ -1124,7 +1132,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
|
||||
|
||||
// Enter invalid IDs into the map to indicate that we want to find out about
|
||||
// nodes of these ways.
|
||||
const auto mark_ids = [&](auto const &turn_restriction) {
|
||||
const auto mark_ids = [&](auto const &turn_restriction)
|
||||
{
|
||||
NodesOfWay dummy_segment{MAX_OSM_WAYID, {MAX_OSM_NODEID, MAX_OSM_NODEID}};
|
||||
const auto &turn_path = turn_restriction.turn_path;
|
||||
restriction_ways[turn_path.From()] = dummy_segment;
|
||||
@ -1142,7 +1151,8 @@ ExtractionContainers::ReferencedWays ExtractionContainers::IdentifyRestrictionWa
|
||||
std::for_each(restrictions_list.begin(), restrictions_list.end(), mark_ids);
|
||||
|
||||
// Update the values for all ways already sporting SPECIAL_NODEID
|
||||
const auto set_ids = [&](const size_t way_list_idx, auto const &way_id) {
|
||||
const auto set_ids = [&](const size_t way_list_idx, auto const &way_id)
|
||||
{
|
||||
auto itr = restriction_ways.find(way_id);
|
||||
if (itr != restriction_ways.end())
|
||||
{
|
||||
@ -1178,7 +1188,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
|
||||
std::unordered_set<OSMNodeID> bidirectional_signals;
|
||||
|
||||
const auto mark_signals = [&](auto const &traffic_signal) {
|
||||
const auto mark_signals = [&](auto const &traffic_signal)
|
||||
{
|
||||
if (traffic_signal.second == TrafficLightClass::DIRECTION_FORWARD ||
|
||||
traffic_signal.second == TrafficLightClass::DIRECTION_REVERSE)
|
||||
{
|
||||
@ -1193,7 +1204,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
std::for_each(external_traffic_signals.begin(), external_traffic_signals.end(), mark_signals);
|
||||
|
||||
// Extract all the segments that lead up to unidirectional traffic signals.
|
||||
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/) {
|
||||
const auto set_segments = [&](const size_t way_list_idx, auto const & /*unused*/)
|
||||
{
|
||||
const auto node_start_offset =
|
||||
used_node_id_list.begin() + way_node_id_offsets[way_list_idx];
|
||||
const auto node_end_offset =
|
||||
@ -1227,7 +1239,9 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
util::for_each_indexed(ways_list.cbegin(), ways_list.cend(), set_segments);
|
||||
|
||||
util::for_each_pair(
|
||||
signal_segments, [](const auto pair_a, const auto pair_b) {
|
||||
signal_segments,
|
||||
[](const auto pair_a, const auto pair_b)
|
||||
{
|
||||
if (pair_a.first == pair_b.first)
|
||||
{
|
||||
// If a node is appearing multiple times in this map, then it's ambiguous.
|
||||
@ -1252,7 +1266,8 @@ ExtractionContainers::ReferencedTrafficSignals ExtractionContainers::IdentifyTra
|
||||
void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction_ways)
|
||||
{
|
||||
|
||||
auto const to_internal = [&](auto const osm_node) {
|
||||
auto const to_internal = [&](auto const osm_node)
|
||||
{
|
||||
auto internal = mapExternalToInternalNodeID(
|
||||
used_node_id_list.begin(), used_node_id_list.end(), osm_node);
|
||||
if (internal == SPECIAL_NODEID)
|
||||
@ -1264,7 +1279,8 @@ void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction
|
||||
|
||||
// Transform an OSMRestriction (based on WayIDs) into an OSRM restriction (base on NodeIDs).
|
||||
// Returns true on successful transformation, false in case of invalid references.
|
||||
const auto transform = [&](const auto &external_type, auto &internal_type) {
|
||||
const auto transform = [&](const auto &external_type, auto &internal_type)
|
||||
{
|
||||
if (external_type.turn_path.Type() == TurnPathType::VIA_WAY_TURN_PATH)
|
||||
{
|
||||
auto const &external = external_type.turn_path.AsViaWayPath();
|
||||
@ -1293,7 +1309,8 @@ void ExtractionContainers::PrepareRestrictions(const ReferencedWays &restriction
|
||||
return internal_type.Valid();
|
||||
};
|
||||
|
||||
const auto transform_into_internal_types = [&](InputTurnRestriction &external_restriction) {
|
||||
const auto transform_into_internal_types = [&](InputTurnRestriction &external_restriction)
|
||||
{
|
||||
TurnRestriction restriction;
|
||||
if (transform(external_restriction, restriction))
|
||||
{
|
||||
|
@ -442,9 +442,12 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
|
||||
ExtractionRelationContainer relations;
|
||||
|
||||
const auto buffer_reader = [](osmium::io::Reader &reader) {
|
||||
const auto buffer_reader = [](osmium::io::Reader &reader)
|
||||
{
|
||||
return tbb::filter<void, SharedBuffer>(
|
||||
tbb::filter_mode::serial_in_order, [&reader](tbb::flow_control &fc) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&reader](tbb::flow_control &fc)
|
||||
{
|
||||
if (auto buffer = reader.read())
|
||||
{
|
||||
return std::make_shared<osmium::memory::Buffer>(std::move(buffer));
|
||||
@ -466,7 +469,9 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
osmium_location_handler_type location_handler(location_cache);
|
||||
|
||||
tbb::filter<SharedBuffer, SharedBuffer> location_cacher(
|
||||
tbb::filter_mode::serial_in_order, [&location_handler](SharedBuffer buffer) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&location_handler](SharedBuffer buffer)
|
||||
{
|
||||
osmium::apply(buffer->begin(), buffer->end(), location_handler);
|
||||
return buffer;
|
||||
});
|
||||
@ -475,7 +480,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
tbb::filter<SharedBuffer, ParsedBuffer> buffer_transformer(
|
||||
tbb::filter_mode::parallel,
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
[&](const SharedBuffer buffer) {
|
||||
[&](const SharedBuffer buffer)
|
||||
{
|
||||
ParsedBuffer parsed_buffer;
|
||||
parsed_buffer.buffer = buffer;
|
||||
scripting_environment.ProcessElements(*buffer,
|
||||
@ -495,7 +501,9 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
unsigned number_of_restrictions = 0;
|
||||
unsigned number_of_maneuver_overrides = 0;
|
||||
tbb::filter<ParsedBuffer, void> buffer_storage(
|
||||
tbb::filter_mode::serial_in_order, [&](const ParsedBuffer &parsed_buffer) {
|
||||
tbb::filter_mode::serial_in_order,
|
||||
[&](const ParsedBuffer &parsed_buffer)
|
||||
{
|
||||
number_of_nodes += parsed_buffer.resulting_nodes.size();
|
||||
// put parsed objects thru extractor callbacks
|
||||
for (const auto &result : parsed_buffer.resulting_nodes)
|
||||
@ -524,7 +532,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
tbb::filter<SharedBuffer, std::shared_ptr<ExtractionRelationContainer>> buffer_relation_cache(
|
||||
tbb::filter_mode::parallel,
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
[&](const SharedBuffer buffer) {
|
||||
[&](const SharedBuffer buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
return std::shared_ptr<ExtractionRelationContainer>{};
|
||||
|
||||
@ -562,7 +571,8 @@ Extractor::ParsedOSMData Extractor::ParseOSMData(ScriptingEnvironment &scripting
|
||||
tbb::filter<std::shared_ptr<ExtractionRelationContainer>, void> buffer_storage_relation(
|
||||
tbb::filter_mode::serial_in_order,
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
[&](const std::shared_ptr<ExtractionRelationContainer> parsed_relations) {
|
||||
[&](const std::shared_ptr<ExtractionRelationContainer> parsed_relations)
|
||||
{
|
||||
number_of_relations += parsed_relations->GetRelationsNum();
|
||||
relations.Merge(std::move(*parsed_relations));
|
||||
});
|
||||
@ -749,7 +759,8 @@ EdgeID Extractor::BuildEdgeExpandedGraph(
|
||||
segregated_edges,
|
||||
turn_lane_map);
|
||||
|
||||
const auto create_edge_based_edges = [&]() {
|
||||
const auto create_edge_based_edges = [&]()
|
||||
{
|
||||
// scoped to release intermediate data structures right after the call
|
||||
RestrictionMap unconditional_node_restriction_map(restriction_graph);
|
||||
ConditionalRestrictionMap conditional_node_restriction_map(restriction_graph);
|
||||
@ -795,9 +806,8 @@ void Extractor::BuildRTree(std::vector<EdgeBasedNodeSegment> edge_based_node_seg
|
||||
auto start_point_count = std::accumulate(edge_based_node_segments.begin(),
|
||||
edge_based_node_segments.end(),
|
||||
0,
|
||||
[](const size_t so_far, const auto &segment) {
|
||||
return so_far + (segment.is_startpoint ? 1 : 0);
|
||||
});
|
||||
[](const size_t so_far, const auto &segment)
|
||||
{ return so_far + (segment.is_startpoint ? 1 : 0); });
|
||||
if (start_point_count == 0)
|
||||
{
|
||||
throw util::exception("There are no snappable edges left after processing. Are you "
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user