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