Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorДобрый Ээх <bukharaev@gmail.com>2017-06-16 17:29:23 +0300
committerVladimir Byko-Ianko <bykoianko@gmail.com>2017-06-27 12:44:18 +0300
commite1ede4b1100a47b57e781d8bc9d77a9431f3bb18 (patch)
tree2d49a149e84071ecbeed28954cbe47e421a469b5
parent2bb50364bf783ad788e72b315c598f118c77d8f6 (diff)
[routing] Pull request #6176 review fixes
-rw-r--r--generator/routing_index_generator.cpp15
-rw-r--r--map/routing_manager.cpp5
-rw-r--r--routing/async_router.cpp10
-rw-r--r--routing/async_router.hpp14
-rw-r--r--routing/base/astar_algorithm.hpp275
-rw-r--r--routing/index_router.cpp177
-rw-r--r--routing/index_router.hpp10
-rw-r--r--routing/road_graph_router.hpp2
-rw-r--r--routing/routing_algorithm.cpp17
-rw-r--r--routing/routing_helpers.cpp16
-rw-r--r--routing/routing_integration_tests/routing_test_tools.cpp4
-rw-r--r--routing/routing_session.cpp6
-rw-r--r--routing/routing_session.hpp2
-rw-r--r--routing/routing_tests/astar_algorithm_test.cpp68
-rw-r--r--routing/routing_tests/async_router_test.cpp6
-rw-r--r--routing/segmented_route.cpp15
-rw-r--r--routing/segmented_route.hpp41
-rw-r--r--routing/traffic_stash.cpp17
-rw-r--r--routing/traffic_stash.hpp21
-rw-r--r--xcode/routing/routing.xcodeproj/project.pbxproj30
20 files changed, 455 insertions, 296 deletions
diff --git a/generator/routing_index_generator.cpp b/generator/routing_index_generator.cpp
index f4e01e0ca9..1e293e2f39 100644
--- a/generator/routing_index_generator.cpp
+++ b/generator/routing_index_generator.cpp
@@ -289,7 +289,6 @@ void FillWeights(string const & path, string const & mwmFile, string const & cou
DeserializeIndexGraph(mwmValue, graph);
map<Segment, map<Segment, double>> weights;
- map<Segment, double> distanceMap;
auto const numEnters = connector.GetEnters().size();
size_t foundCount = 0;
size_t notFoundCount = 0;
@@ -302,18 +301,16 @@ void FillWeights(string const & path, string const & mwmFile, string const & cou
AStarAlgorithm<DijkstraWrapper> astar;
DijkstraWrapper wrapper(graph);
- astar.PropagateWave(
- wrapper, enter, [](Segment const & /* vertex */) { return false; },
- [](Segment const & /* vertex */, SegmentEdge const & edge) { return edge.GetWeight(); },
- [](Segment const & /* from */, Segment const & /* to */) {} /* putToParents */,
- distanceMap);
+ AStarAlgorithm<DijkstraWrapper>::Context context;
+ astar.PropagateWave(wrapper, enter,
+ [](Segment const & /* vertex */) { return true; } /* visitVertex */,
+ context);
for (Segment const & exit : connector.GetExits())
{
- auto it = distanceMap.find(exit);
- if (it != distanceMap.end())
+ if (context.HasDistance(exit))
{
- weights[enter][exit] = it->second;
+ weights[enter][exit] = context.GetDistance(exit);
++foundCount;
}
else
diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp
index 8a8ab0db49..23b88f8b32 100644
--- a/map/routing_manager.cpp
+++ b/map/routing_manager.cpp
@@ -565,8 +565,9 @@ void RoutingManager::CheckLocationForRouting(location::GpsInfo const & info)
{
m_routingSession.RebuildRoute(
MercatorBounds::FromLatLon(info.m_latitude, info.m_longitude),
- [&](Route const & route, IRouter::ResultCode code) { OnRebuildRouteReady(route, code); },
- 0 /* timeoutSec */, routing::RoutingSession::State::RouteRebuilding);
+ [this](Route const & route, IRouter::ResultCode code) { OnRebuildRouteReady(route, code); },
+ 0 /* timeoutSec */, routing::RoutingSession::State::RouteRebuilding,
+ true /* adjustToPrevRoute */);
}
}
diff --git a/routing/async_router.cpp b/routing/async_router.cpp
index 140bb8c044..3a7bb737b3 100644
--- a/routing/async_router.cpp
+++ b/routing/async_router.cpp
@@ -147,7 +147,7 @@ void AsyncRouter::SetRouter(unique_ptr<IRouter> && router, unique_ptr<IOnlineFet
}
void AsyncRouter::CalculateRoute(m2::PointD const & startPoint, m2::PointD const & direction,
- m2::PointD const & finalPoint, bool adjust,
+ m2::PointD const & finalPoint, bool adjustToPrevRoute,
TReadyCallback const & readyCallback,
RouterDelegate::TProgressCallback const & progressCallback,
uint32_t timeoutSec)
@@ -157,7 +157,7 @@ void AsyncRouter::CalculateRoute(m2::PointD const & startPoint, m2::PointD const
m_startPoint = startPoint;
m_startDirection = direction;
m_finalPoint = finalPoint;
- m_adjust = adjust;
+ m_adjustToPrevRoute = adjustToPrevRoute;
ResetDelegate();
@@ -259,7 +259,7 @@ void AsyncRouter::CalculateRoute()
{
shared_ptr<RouterDelegateProxy> delegate;
m2::PointD startPoint, finalPoint, startDirection;
- bool adjust = false;
+ bool adjustToPrevRoute = false;
shared_ptr<IOnlineFetcher> absentFetcher;
shared_ptr<IRouter> router;
@@ -278,7 +278,7 @@ void AsyncRouter::CalculateRoute()
startPoint = m_startPoint;
finalPoint = m_finalPoint;
startDirection = m_startDirection;
- adjust = m_adjust;
+ adjustToPrevRoute = m_adjustToPrevRoute;
delegate = m_delegate;
router = m_router;
absentFetcher = m_absentFetcher;
@@ -298,7 +298,7 @@ void AsyncRouter::CalculateRoute()
absentFetcher->GenerateRequest(startPoint, finalPoint);
// Run basic request.
- code = router->CalculateRoute(startPoint, startDirection, finalPoint, adjust,
+ code = router->CalculateRoute(startPoint, startDirection, finalPoint, adjustToPrevRoute,
delegate->GetDelegate(), route);
elapsedSec = timer.ElapsedSeconds(); // routing time
diff --git a/routing/async_router.hpp b/routing/async_router.hpp
index 21698ed376..769db545bf 100644
--- a/routing/async_router.hpp
+++ b/routing/async_router.hpp
@@ -43,12 +43,12 @@ public:
/// @param startPoint point to start routing
/// @param direction start direction for routers with high cost of the turnarounds
/// @param finalPoint target point for route
- /// @param adjust adjust route to the previous one if possible
+ /// @param adjustToPrevRoute adjust route to the previous one if possible
/// @param readyCallback function to return routing result
/// @param progressCallback function to update the router progress
/// @param timeoutSec timeout to cancel routing. 0 is infinity.
void CalculateRoute(m2::PointD const & startPoint, m2::PointD const & direction,
- m2::PointD const & finalPoint, bool adjust,
+ m2::PointD const & finalPoint, bool adjustToPrevRoute,
TReadyCallback const & readyCallback,
RouterDelegate::TProgressCallback const & progressCallback,
uint32_t timeoutSec);
@@ -112,11 +112,11 @@ private:
bool m_hasRequest;
/// Current request parameters
- bool m_clearState;
- m2::PointD m_startPoint;
- m2::PointD m_finalPoint;
- m2::PointD m_startDirection;
- bool m_adjust = false;
+ bool m_clearState = false;
+ m2::PointD m_startPoint = m2::PointD::Zero();
+ m2::PointD m_finalPoint = m2::PointD::Zero();
+ m2::PointD m_startDirection = m2::PointD::Zero();
+ bool m_adjustToPrevRoute = false;
shared_ptr<RouterDelegateProxy> m_delegate;
shared_ptr<IOnlineFetcher> m_absentFetcher;
shared_ptr<IRouter> m_router;
diff --git a/routing/base/astar_algorithm.hpp b/routing/base/astar_algorithm.hpp
index d7f8964011..ebd27b4085 100644
--- a/routing/base/astar_algorithm.hpp
+++ b/routing/base/astar_algorithm.hpp
@@ -5,6 +5,7 @@
#include "std/algorithm.hpp"
#include "std/functional.hpp"
#include "std/iostream.hpp"
+#include "std/limits.hpp"
#include "std/map.hpp"
#include "std/queue.hpp"
#include "std/vector.hpp"
@@ -61,17 +62,56 @@ public:
using TOnVisitedVertexCallback = std::function<void(TVertexType const &, TVertexType const &)>;
- template <typename CheckForStop, typename AdjustEdgeWeight, typename PutToParents>
+ class Context final
+ {
+ public:
+ void Clear()
+ {
+ m_distanceMap.clear();
+ m_parents.clear();
+ }
+
+ bool HasDistance(TVertexType const & vertex) const
+ {
+ return m_distanceMap.find(vertex) != m_distanceMap.cend();
+ }
+
+ double GetDistance(TVertexType const & vertex) const
+ {
+ auto const & it = m_distanceMap.find(vertex);
+ if (it == m_distanceMap.cend())
+ return kInfiniteDistance;
+
+ return it->second;
+ }
+
+ void SetDistance(TVertexType const & vertex, double distance)
+ {
+ m_distanceMap[vertex] = distance;
+ }
+
+ void SetParent(TVertexType const & parent, TVertexType const & child)
+ {
+ m_parents[parent] = child;
+ }
+
+ void ReconstructPath(TVertexType const & v, vector<TVertexType> & path) const;
+
+ private:
+ map<TVertexType, double> m_distanceMap;
+ map<TVertexType, TVertexType> m_parents;
+ };
+
+ // VisitVertex returns true: wave will continue
+ // VisitVertex returns false: wave will stop
+ template <typename VisitVertex, typename AdjustEdgeWeight>
void PropagateWave(TGraphType & graph, TVertexType const & startVertex,
- CheckForStop && checkForStop, AdjustEdgeWeight && adjustEdgeWeight,
- PutToParents && putToParents, map<TVertexType, double> & bestDistance) const;
+ VisitVertex && visitVertex, AdjustEdgeWeight && adjustEdgeWeight,
+ Context & context) const;
- template <typename IsFinalVertex>
- Result FindPath(TGraphType & graph, TVertexType const & startVertex,
- TVertexType const & finalVertex, RoutingResult<TVertexType> & result,
- my::Cancellable const & cancellable,
- TOnVisitedVertexCallback onVisitedVertexCallback,
- IsFinalVertex && isFinalVertex) const;
+ template <typename VisitVertex>
+ void PropagateWave(TGraphType & graph, TVertexType const & startVertex,
+ VisitVertex && visitVertex, Context & context) const;
Result FindPath(TGraphType & graph, TVertexType const & startVertex,
TVertexType const & finalVertex, RoutingResult<TVertexType> & result,
@@ -84,18 +124,37 @@ public:
my::Cancellable const & cancellable = my::Cancellable(),
TOnVisitedVertexCallback onVisitedVertexCallback = nullptr) const;
-private:
- // Periodicy of checking is cancellable cancelled.
- static uint32_t constexpr kCancelledPollPeriod = 128;
+ // Adjust route to the previous one.
+ // adjustLimit - distance limit for wave propagation, measured in same units as graph edges length.
+ typename AStarAlgorithm<TGraph>::Result AdjustRoute(
+ TGraphType & graph, TVertexType const & startVertex, vector<TEdgeType> const & prevRoute,
+ double adjustLimit, RoutingResult<TVertexType> & result, my::Cancellable const & cancellable,
+ TOnVisitedVertexCallback onVisitedVertexCallback) const;
- // Periodicy of switching a wave of bidirectional algorithm.
+private:
+ // Periodicity of switching a wave of bidirectional algorithm.
static uint32_t constexpr kQueueSwitchPeriod = 128;
- // Periodicy of calling callback about visited vertice.
- static uint32_t constexpr kVisitedVerticesPeriod = 4;
-
// Precision of comparison weights.
static double constexpr kEpsilon = 1e-6;
+ static double constexpr kInfiniteDistance = numeric_limits<double>::max();
+
+ class PeriodicPollCancellable final
+ {
+ public:
+ PeriodicPollCancellable(my::Cancellable const & cancellable) : m_cancellable(cancellable) {}
+
+ bool IsCancelled()
+ {
+ // Periodicity of checking is cancellable cancelled.
+ uint32_t constexpr kPeriod = 128;
+ return count++ % kPeriod == 0 && m_cancellable.IsCancelled();
+ }
+
+ private:
+ my::Cancellable const & m_cancellable;
+ uint32_t count = 0;
+ };
// State is what is going to be put in the priority queue. See the
// comment for FindPath for more information.
@@ -183,18 +242,17 @@ private:
};
template <typename TGraph>
-template <typename CheckForStop, typename AdjustEdgeWeight, typename PutToParents>
+template <typename VisitVertex, typename AdjustEdgeWeight>
void AStarAlgorithm<TGraph>::PropagateWave(TGraphType & graph, TVertexType const & startVertex,
- CheckForStop && checkForStop,
+ VisitVertex && visitVertex,
AdjustEdgeWeight && adjustEdgeWeight,
- PutToParents && putToParents,
- map<TVertexType, double> & bestDistance) const
+ AStarAlgorithm<TGraph>::Context & context) const
{
- bestDistance.clear();
+ context.Clear();
priority_queue<State, vector<State>, greater<State>> queue;
- bestDistance[startVertex] = 0.0;
+ context.SetDistance(startVertex, 0.0);
queue.push(State(startVertex, 0.0));
vector<TEdgeType> adj;
@@ -204,10 +262,10 @@ void AStarAlgorithm<TGraph>::PropagateWave(TGraphType & graph, TVertexType const
State const stateV = queue.top();
queue.pop();
- if (stateV.distance > bestDistance[stateV.vertex])
+ if (stateV.distance > context.GetDistance(stateV.vertex))
continue;
- if (checkForStop(stateV.vertex))
+ if (!visitVertex(stateV.vertex))
return;
graph.GetOutgoingEdgesList(stateV.vertex, adj);
@@ -220,18 +278,29 @@ void AStarAlgorithm<TGraph>::PropagateWave(TGraphType & graph, TVertexType const
double const edgeWeight = adjustEdgeWeight(stateV.vertex, edge);
double const newReducedDist = stateV.distance + edgeWeight;
- auto const t = bestDistance.find(stateW.vertex);
- if (t != bestDistance.end() && newReducedDist >= t->second - kEpsilon)
+ if (newReducedDist >= context.GetDistance(stateW.vertex) - kEpsilon)
continue;
stateW.distance = newReducedDist;
- bestDistance[stateW.vertex] = newReducedDist;
- putToParents(stateW.vertex, stateV.vertex);
+ context.SetDistance(stateW.vertex, newReducedDist);
+ context.SetParent(stateW.vertex, stateV.vertex);
queue.push(stateW);
}
}
}
+template <typename TGraph>
+template <typename VisitVertex>
+void AStarAlgorithm<TGraph>::PropagateWave(TGraphType & graph, TVertexType const & startVertex,
+ VisitVertex && visitVertex,
+ AStarAlgorithm<TGraph>::Context & context) const
+{
+ auto const adjustEdgeWeight = [](TVertexType const & /* vertex */, TEdgeType const & edge) {
+ return edge.GetWeight();
+ };
+ PropagateWave(graph, startVertex, visitVertex, adjustEdgeWeight, context);
+}
+
// This implementation is based on the view that the A* algorithm
// is equivalent to Dijkstra's algorithm that is run on a reweighted
// version of the graph. If an edge (v, w) has length l(v, w), its reduced
@@ -244,43 +313,35 @@ void AStarAlgorithm<TGraph>::PropagateWave(TGraphType & graph, TVertexType const
// http://www.cs.princeton.edu/courses/archive/spr06/cos423/Handouts/EPP%20shortest%20path%20algorithms.pdf
template <typename TGraph>
-template <typename IsFinalVertex>
typename AStarAlgorithm<TGraph>::Result AStarAlgorithm<TGraph>::FindPath(
TGraphType & graph, TVertexType const & startVertex, TVertexType const & finalVertex,
RoutingResult<TVertexType> & result, my::Cancellable const & cancellable,
- TOnVisitedVertexCallback onVisitedVertexCallback, IsFinalVertex && isFinalVertex) const
+ TOnVisitedVertexCallback onVisitedVertexCallback) const
{
result.Clear();
if (nullptr == onVisitedVertexCallback)
onVisitedVertexCallback = [](TVertexType const &, TVertexType const &) {};
- map<TVertexType, double> bestDistance;
- map<TVertexType, TVertexType> parents;
- uint32_t steps = 0;
+ Context context;
+ PeriodicPollCancellable periodicCancellable(cancellable);
Result resultCode = Result::NoPath;
- auto checkForStop = [&](TVertexType const & vertex) {
- ++steps;
-
- if (steps % kCancelledPollPeriod == 0 && cancellable.IsCancelled())
+ auto visitVertex = [&](TVertexType const & vertex) {
+ if (periodicCancellable.IsCancelled())
{
resultCode = Result::Cancelled;
- return true;
+ return false;
}
- if (steps % kVisitedVerticesPeriod == 0)
- onVisitedVertexCallback(vertex, finalVertex);
+ onVisitedVertexCallback(vertex, finalVertex);
- if (isFinalVertex(vertex))
+ if (vertex == finalVertex)
{
- ReconstructPath(vertex, parents, result.path);
- result.distance = bestDistance[vertex] - graph.HeuristicCostEstimate(vertex, finalVertex) +
- graph.HeuristicCostEstimate(startVertex, finalVertex);
resultCode = Result::OK;
- return true;
+ return false;
}
- return false;
+ return true;
};
auto adjustEdgeWeight = [&](TVertexType const & vertex, TEdgeType const & edge) {
@@ -293,21 +354,16 @@ typename AStarAlgorithm<TGraph>::Result AStarAlgorithm<TGraph>::FindPath(
return max(reducedLen, 0.0);
};
- auto putToParents = [&](TVertexType const & from, TVertexType const & to) { parents[from] = to; };
+ PropagateWave(graph, startVertex, visitVertex, adjustEdgeWeight, context);
- PropagateWave(graph, startVertex, checkForStop, adjustEdgeWeight, putToParents, bestDistance);
- return resultCode;
-}
+ if (resultCode == Result::OK)
+ {
+ context.ReconstructPath(finalVertex, result.path);
+ result.distance =
+ context.GetDistance(finalVertex) - graph.HeuristicCostEstimate(startVertex, finalVertex);
+ }
-template <typename TGraph>
-typename AStarAlgorithm<TGraph>::Result AStarAlgorithm<TGraph>::FindPath(
- TGraphType & graph, TVertexType const & startVertex, TVertexType const & finalVertex,
- RoutingResult<TVertexType> & result, my::Cancellable const & cancellable,
- TOnVisitedVertexCallback onVisitedVertexCallback) const
-{
- auto const isFinalVertex = [&](TVertexType const & vertex) { return vertex == finalVertex; };
- return FindPath(graph, startVertex, finalVertex, result, cancellable, onVisitedVertexCallback,
- isFinalVertex);
+ return resultCode;
}
template <typename TGraph>
@@ -347,11 +403,13 @@ typename AStarAlgorithm<TGraph>::Result AStarAlgorithm<TGraph>::FindPathBidirect
// because if we have not found a path by the time one of the
// queues is exhausted, we never will.
uint32_t steps = 0;
+ PeriodicPollCancellable periodicCancellable(cancellable);
+
while (!cur->queue.empty() && !nxt->queue.empty())
{
++steps;
- if (steps % kCancelledPollPeriod == 0 && cancellable.IsCancelled())
+ if (periodicCancellable.IsCancelled())
return Result::Cancelled;
if (steps % kQueueSwitchPeriod == 0)
@@ -391,8 +449,7 @@ typename AStarAlgorithm<TGraph>::Result AStarAlgorithm<TGraph>::FindPathBidirect
if (stateV.distance > cur->bestDistance[stateV.vertex])
continue;
- if (steps % kVisitedVerticesPeriod == 0)
- onVisitedVertexCallback(stateV.vertex, cur->forward ? cur->finalVertex : cur->startVertex);
+ onVisitedVertexCallback(stateV.vertex, cur->forward ? cur->finalVertex : cur->startVertex);
cur->GetAdjacencyList(stateV.vertex, adj);
for (auto const & edge : adj)
@@ -445,6 +502,94 @@ typename AStarAlgorithm<TGraph>::Result AStarAlgorithm<TGraph>::FindPathBidirect
return Result::NoPath;
}
+template <typename TGraph>
+typename AStarAlgorithm<TGraph>::Result AStarAlgorithm<TGraph>::AdjustRoute(
+ TGraphType & graph, TVertexType const & startVertex, vector<TEdgeType> const & prevRoute,
+ double adjustLimit, RoutingResult<TVertexType> & result, my::Cancellable const & cancellable,
+ TOnVisitedVertexCallback onVisitedVertexCallback) const
+{
+ CHECK(!prevRoute.empty(), ());
+
+ result.Clear();
+ if (onVisitedVertexCallback == nullptr)
+ onVisitedVertexCallback = [](TVertexType const &, TVertexType const &) {};
+
+ bool wasCancelled = false;
+ double minDistance = kInfiniteDistance;
+ TVertexType returnVertex;
+
+ map<TVertexType, double> remainingDistances;
+ double remainingDistance = 0.0;
+
+ for (auto it = prevRoute.crbegin(); it != prevRoute.crend(); ++it)
+ {
+ remainingDistances[it->GetTarget()] = remainingDistance;
+ remainingDistance += it->GetWeight();
+ }
+
+ Context context;
+ PeriodicPollCancellable periodicCancellable(cancellable);
+
+ auto visitVertex = [&](TVertexType const & vertex) {
+
+ if (periodicCancellable.IsCancelled())
+ {
+ wasCancelled = true;
+ return false;
+ }
+
+ auto const distance = context.GetDistance(vertex);
+ if (distance > adjustLimit)
+ return false;
+
+ onVisitedVertexCallback(startVertex, vertex);
+
+ auto it = remainingDistances.find(vertex);
+ if (it != remainingDistances.cend())
+ {
+ double const fullDistance = distance + it->second;
+ if (fullDistance < minDistance)
+ {
+ minDistance = fullDistance;
+ returnVertex = vertex;
+ }
+ }
+
+ return true;
+ };
+
+ PropagateWave(graph, startVertex, visitVertex, context);
+ if (wasCancelled)
+ return Result::Cancelled;
+
+ if (minDistance == kInfiniteDistance)
+ return Result::NoPath;
+
+ context.ReconstructPath(returnVertex, result.path);
+
+ // Append remaining route.
+ bool found = false;
+ for (size_t i = 0; i < prevRoute.size(); ++i)
+ {
+ if (prevRoute[i].GetTarget() == returnVertex)
+ {
+ for (size_t j = i + 1; j < prevRoute.size(); ++j)
+ result.path.push_back(prevRoute[j].GetTarget());
+
+ found = true;
+ break;
+ }
+ }
+
+ CHECK(found,
+ ("Can't find", returnVertex, ", prev:", prevRoute.size(), ", adjust:", result.path.size()));
+
+ auto const & it = remainingDistances.find(returnVertex);
+ CHECK(it != remainingDistances.end(), ());
+ result.distance = context.GetDistance(returnVertex) + it->second;
+ return Result::OK;
+}
+
// static
template <typename TGraph>
void AStarAlgorithm<TGraph>::ReconstructPath(TVertexType const & v,
@@ -480,4 +625,10 @@ void AStarAlgorithm<TGraph>::ReconstructPathBidirectional(
path.insert(path.end(), pathW.rbegin(), pathW.rend());
}
+template <typename TGraph>
+void AStarAlgorithm<TGraph>::Context::ReconstructPath(TVertexType const & v,
+ vector<TVertexType> & path) const
+{
+ AStarAlgorithm<TGraph>::ReconstructPath(v, m_parents, path);
+}
} // namespace routing
diff --git a/routing/index_router.cpp b/routing/index_router.cpp
index 9212eedd13..88d55ca211 100644
--- a/routing/index_router.cpp
+++ b/routing/index_router.cpp
@@ -29,21 +29,23 @@
#include "base/exception.hpp"
#include <algorithm>
+#include <map>
using namespace routing;
+using namespace std;
namespace
{
size_t constexpr kMaxRoadCandidates = 6;
float constexpr kProgressInterval = 2;
-uint32_t constexpr kDrawPointsPeriod = 10;
+uint32_t constexpr kVisitPeriod = 40;
-// If user left the route within this range, adjust the route. Else full rebuild.
-double constexpr kAdjustRange = 5000.0;
-// Propagate astar wave for some distance to try to find a better return point.
-double constexpr kAdjustDistance = 2000.0;
-// Full rebuild if distance to finish is lesser.
-double const kMinDistanceToFinish = kAdjustDistance * 2.0;
+// If user left the route within this range(meters), adjust the route. Else full rebuild.
+double constexpr kAdjustRangeM = 5000.0;
+// Full rebuild if distance(meters) is less.
+double constexpr kMinDistanceToFinishM = 10000;
+// Limit of adjust in seconds.
+double constexpr kAdjustLimitSec = 5 * 60;
template <typename Graph>
IRouter::ResultCode ConvertResult(typename AStarAlgorithm<Graph>::Result result)
@@ -65,7 +67,7 @@ IRouter::ResultCode FindPath(
{
AStarAlgorithm<Graph> algorithm;
return ConvertResult<Graph>(algorithm.FindPathBidirectional(graph, start, finish, routingResult,
- delegate, onVisitedVertexCallback));
+ delegate, onVisitedVertexCallback));
}
bool IsDeadEnd(Segment const & segment, bool isOutgoing, WorldGraph & worldGraph)
@@ -142,7 +144,8 @@ IndexRouter::IndexRouter(string const & name, TCountryFileFn const & countryFile
IRouter::ResultCode IndexRouter::CalculateRoute(m2::PointD const & startPoint,
m2::PointD const & startDirection,
- m2::PointD const & finalPoint, bool adjust,
+ m2::PointD const & finalPoint,
+ bool adjustToPrevRoute,
RouterDelegate const & delegate, Route & route)
{
if (!AllMwmsHaveRoutingIndex(m_index, route))
@@ -151,37 +154,35 @@ IRouter::ResultCode IndexRouter::CalculateRoute(m2::PointD const & startPoint,
string const startCountry = m_countryFileFn(startPoint);
string const finishCountry = m_countryFileFn(finalPoint);
- return CalculateRoute(startCountry, finishCountry, false /* blockMwmBorders */, startPoint,
- startDirection, finalPoint, adjust, delegate, route);
-}
-
-IRouter::ResultCode IndexRouter::CalculateRoute(string const & startCountry,
- string const & finishCountry, bool forSingleMwm,
- m2::PointD const & startPoint,
- m2::PointD const & startDirection,
- m2::PointD const & finalPoint, bool adjust,
- RouterDelegate const & delegate, Route & route)
-{
try
{
auto const startFile = platform::CountryFile(startCountry);
auto const finishFile = platform::CountryFile(finishCountry);
- if (adjust && !m_lastRoute.IsEmpty() && finalPoint == m_lastRoute.GetFinish())
+ if (adjustToPrevRoute && m_lastRoute && finalPoint == m_lastRoute->GetFinish())
{
- double const distanceToRoute = m_lastRoute.CalcDistance(startPoint);
+ double const distanceToRoute = m_lastRoute->CalcDistance(startPoint);
double const distanceToFinish = MercatorBounds::DistanceOnEarth(startPoint, finalPoint);
- if (distanceToRoute <= kAdjustRange && distanceToFinish >= kMinDistanceToFinish)
- return AdjustRoute(startFile, startPoint, startDirection, finalPoint, delegate, route);
+ if (distanceToRoute <= kAdjustRangeM && distanceToFinish >= kMinDistanceToFinishM)
+ {
+ auto code = AdjustRoute(startFile, startPoint, startDirection, finalPoint, delegate, route);
+ if (code != IRouter::RouteNotFound)
+ return code;
+
+ LOG(LWARNING, ("Can't adjust route, do full rebuild, prev start:",
+ MercatorBounds::ToLatLon(m_lastRoute->GetStart()), ", start:",
+ MercatorBounds::ToLatLon(startPoint), ", finish:",
+ MercatorBounds::ToLatLon(finalPoint)));
+ }
}
- return DoCalculateRoute(startFile, finishFile, forSingleMwm, startPoint, startDirection,
- finalPoint, delegate, route);
+ return DoCalculateRoute(startFile, finishFile, false /* forSingleMwm */, startPoint,
+ startDirection, finalPoint, delegate, route);
}
catch (RootException const & e)
{
LOG(LERROR, ("Can't find path from", MercatorBounds::ToLatLon(startPoint), "to",
- MercatorBounds::ToLatLon(finalPoint), ":\n ", e.what()));
+ MercatorBounds::ToLatLon(finalPoint), ":\n ", e.what()));
return IRouter::InternalError;
}
}
@@ -193,7 +194,7 @@ IRouter::ResultCode IndexRouter::DoCalculateRoute(platform::CountryFile const &
m2::PointD const & finalPoint,
RouterDelegate const & delegate, Route & route)
{
- m_lastRoute.Clear();
+ m_lastRoute.reset();
TrafficStash::Guard guard(*m_trafficStash);
WorldGraph graph = MakeWorldGraph();
@@ -232,17 +233,20 @@ IRouter::ResultCode IndexRouter::DoCalculateRoute(platform::CountryFile const &
AStarProgress progress(0, 100);
progress.Initialize(starter.GetStartVertex().GetPoint(), starter.GetFinishVertex().GetPoint());
- uint32_t drawPointsStep = 0;
+ uint32_t visitCount = 0;
+
auto onVisitJunction = [&](Segment const & from, Segment const & to) {
+ if (++visitCount % kVisitPeriod != 0)
+ return;
+
m2::PointD const & pointFrom = starter.GetPoint(from, true /* front */);
m2::PointD const & pointTo = starter.GetPoint(to, true /* front */);
auto const lastValue = progress.GetLastValue();
auto const newValue = progress.GetProgressForBidirectedAlgo(pointFrom, pointTo);
if (newValue - lastValue > kProgressInterval)
delegate.OnProgress(newValue);
- if (drawPointsStep % kDrawPointsPeriod == 0)
- delegate.OnPointCheck(pointFrom);
- ++drawPointsStep;
+
+ delegate.OnPointCheck(pointFrom);
};
RoutingResult<Segment> routingResult;
@@ -263,9 +267,12 @@ IRouter::ResultCode IndexRouter::DoCalculateRoute(platform::CountryFile const &
if (redressResult != IRouter::NoError)
return redressResult;
- m_lastRoute.Init(startPoint, finalPoint);
+ m_lastRoute = make_unique<SegmentedRoute>(startPoint, finalPoint);
for (Segment const & segment : routingResult.path)
- m_lastRoute.AddStep(segment, starter.GetPoint(segment, true /* front */));
+ {
+ if (!IndexGraphStarter::IsFakeSegment(segment))
+ m_lastRoute->AddStep(segment, starter.GetPoint(segment, true /* front */));
+ }
return IRouter::NoError;
}
@@ -285,95 +292,55 @@ IRouter::ResultCode IndexRouter::AdjustRoute(platform::CountryFile const & start
if (!FindClosestSegment(startCountry, startPoint, true /* isOutgoing */, graph, startSegment))
return IRouter::StartPointNotFound;
- IndexGraphStarter starter(
- IndexGraphStarter::FakeVertex(startSegment, startPoint),
- IndexGraphStarter::FakeVertex(m_lastRoute.GetFinishSegment(), finalPoint), graph);
+ auto const & steps = m_lastRoute->GetSteps();
+
+ IndexGraphStarter starter(IndexGraphStarter::FakeVertex(startSegment, startPoint),
+ IndexGraphStarter::FakeVertex(steps.back().GetSegment(), finalPoint),
+ graph);
AStarProgress progress(0, 100);
progress.Initialize(starter.GetStartVertex().GetPoint(), starter.GetFinishVertex().GetPoint());
- uint32_t drawPointsStep = 0;
- auto onVisitJunction = [&](Segment const & from, Segment const & /* to */) {
- m2::PointD const & point = starter.GetPoint(from, true /* front */);
+ vector<SegmentEdge> prevEdges;
+ for (auto const & step : steps)
+ prevEdges.emplace_back(step.GetSegment(), starter.CalcSegmentWeight(step.GetSegment()));
+
+ uint32_t visitCount = 0;
+
+ auto onVisitJunction = [&](Segment const & /* start */, Segment const & vertex) {
+ if (visitCount++ % kVisitPeriod != 0)
+ return;
+
+ m2::PointD const & point = starter.GetPoint(vertex, true /* front */);
auto const lastValue = progress.GetLastValue();
auto const newValue = progress.GetProgressForDirectedAlgo(point);
if (newValue - lastValue > kProgressInterval)
delegate.OnProgress(newValue);
- if (drawPointsStep % kDrawPointsPeriod == 0)
- delegate.OnPointCheck(point);
- ++drawPointsStep;
- };
- AStarAlgorithm<IndexGraphStarter> algorithm;
- RoutingResult<Segment> routingResult;
-
- auto const & steps = m_lastRoute.GetSteps();
- set<Segment> routeSegmentsSet;
- for (auto const & step : steps)
- {
- auto const & segment = step.GetSegment();
- if (!IndexGraphStarter::IsFakeSegment(segment))
- routeSegmentsSet.insert(segment);
- }
-
- double const requiredDistanceToFinish =
- MercatorBounds::DistanceOnEarth(startPoint, finalPoint) - kAdjustDistance;
- CHECK_GREATER(requiredDistanceToFinish, 0.0, ());
-
- auto const isFinalVertex = [&](Segment const & vertex) {
- if (vertex == starter.GetFinish())
- return true;
-
- return routeSegmentsSet.count(vertex) > 0 &&
- MercatorBounds::DistanceOnEarth(
- starter.GetPoint(vertex, true /* front */), finalPoint) <= requiredDistanceToFinish;
+ delegate.OnPointCheck(point);
};
- auto const code = ConvertResult<IndexGraphStarter>(
- algorithm.FindPath(starter, starter.GetStart(), starter.GetFinish(), routingResult, delegate,
- onVisitJunction, isFinalVertex));
- if (code != IRouter::NoError)
- return code;
-
- size_t const adjustingRouteSize = routingResult.path.size();
- AppendRemainingRoute(routingResult.path);
-
- auto const redressResult = RedressRoute(routingResult.path, delegate, false, starter, route);
+ AStarAlgorithm<IndexGraphStarter> algorithm;
+ RoutingResult<Segment> result;
+ auto resultCode = ConvertResult<IndexGraphStarter>(algorithm.AdjustRoute(
+ starter, starter.GetStart(), prevEdges, kAdjustLimitSec, result, delegate, onVisitJunction));
+ if (resultCode != IRouter::NoError)
+ return resultCode;
+
+ result.path.push_back(starter.GetFinish());
+ auto const redressResult = RedressRoute(result.path, delegate, false, starter, route);
if (redressResult != IRouter::NoError)
return redressResult;
- LOG(LINFO, ("Adjust route, elapsed:", timer.ElapsedSeconds(), ", start:",
- MercatorBounds::ToLatLon(startPoint), ", finish:",
- MercatorBounds::ToLatLon(finalPoint), ", old route:", steps.size(), ", new route:",
- routingResult.path.size(), ", adjust:", adjustingRouteSize));
+ LOG(LINFO,
+ ("Adjust route, elapsed:", timer.ElapsedSeconds(), ", prev start:",
+ MercatorBounds::ToLatLon(m_lastRoute->GetStart()), ", start:",
+ MercatorBounds::ToLatLon(startPoint), ", finish:", MercatorBounds::ToLatLon(finalPoint),
+ ", prev route:", steps.size(), ", new route:", result.path.size()));
return IRouter::NoError;
}
-void IndexRouter::AppendRemainingRoute(vector<Segment> & route) const
-{
- auto const steps = m_lastRoute.GetSteps();
- Segment const joinSegment = route.back();
-
- // Route to finish found, append is not needed.
- if (IndexGraphStarter::IsFakeSegment(joinSegment))
- return;
-
- for (size_t i = 0; i < steps.size(); ++i)
- {
- if (steps[i].GetSegment() == joinSegment)
- {
- for (size_t j = i + 1; j < steps.size(); ++j)
- route.push_back(steps[j].GetSegment());
-
- return;
- }
- }
-
- CHECK(false,
- ("Can't find", joinSegment, ", m_routeSegments:", steps.size(), "path:", route.size()));
-}
-
WorldGraph IndexRouter::MakeWorldGraph()
{
WorldGraph graph(
diff --git a/routing/index_router.hpp b/routing/index_router.hpp
index a2c003d064..8d4c1a2d8f 100644
--- a/routing/index_router.hpp
+++ b/routing/index_router.hpp
@@ -41,7 +41,7 @@ public:
virtual string GetName() const override { return m_name; }
virtual IRouter::ResultCode CalculateRoute(m2::PointD const & startPoint,
m2::PointD const & startDirection,
- m2::PointD const & finalPoint, bool adjust,
+ m2::PointD const & finalPoint, bool adjustToPrevRoute,
RouterDelegate const & delegate,
Route & route) override;
@@ -54,11 +54,6 @@ public:
Index & index);
private:
- IRouter::ResultCode CalculateRoute(string const & startCountry, string const & finishCountry,
- bool forSingleMwm, m2::PointD const & startPoint,
- m2::PointD const & startDirection,
- m2::PointD const & finalPoint, bool adjust,
- RouterDelegate const & delegate, Route & route);
IRouter::ResultCode DoCalculateRoute(platform::CountryFile const & startCountry,
platform::CountryFile const & finishCountry,
bool forSingleMwm, m2::PointD const & startPoint,
@@ -69,7 +64,6 @@ private:
m2::PointD const & startPoint, m2::PointD const & startDirection,
m2::PointD const & finalPoint, RouterDelegate const & delegate,
Route & route);
- void AppendRemainingRoute(std::vector<Segment> & route) const;
WorldGraph MakeWorldGraph();
@@ -103,6 +97,6 @@ private:
shared_ptr<VehicleModelFactory> m_vehicleModelFactory;
shared_ptr<EdgeEstimator> m_estimator;
unique_ptr<IDirectionsEngine> m_directionsEngine;
- SegmentedRoute m_lastRoute;
+ unique_ptr<SegmentedRoute> m_lastRoute;
};
} // namespace routing
diff --git a/routing/road_graph_router.hpp b/routing/road_graph_router.hpp
index 280f96b23d..f790246305 100644
--- a/routing/road_graph_router.hpp
+++ b/routing/road_graph_router.hpp
@@ -35,7 +35,7 @@ public:
string GetName() const override { return m_name; }
void ClearState() override;
ResultCode CalculateRoute(m2::PointD const & startPoint, m2::PointD const & startDirection,
- m2::PointD const & finalPoint, bool adjust,
+ m2::PointD const & finalPoint, bool adjustToPrevRoute,
RouterDelegate const & delegate, Route & route) override;
private:
diff --git a/routing/routing_algorithm.cpp b/routing/routing_algorithm.cpp
index b93344f78a..2d3b1220ed 100644
--- a/routing/routing_algorithm.cpp
+++ b/routing/routing_algorithm.cpp
@@ -12,6 +12,7 @@ namespace routing
namespace
{
+uint32_t constexpr kVisitPeriod = 4;
float constexpr kProgressInterval = 2;
double constexpr KMPH2MPS = 1000.0 / (60 * 60);
@@ -137,10 +138,12 @@ IRoutingAlgorithm::Result AStarRoutingAlgorithm::CalculateRoute(IRoadGraph const
RoutingResult<Junction> & path)
{
AStarProgress progress(0, 100);
+ uint32_t visitCount = 0;
+
+ auto onVisitJunctionFn = [&](Junction const & junction, Junction const & /* target */) {
+ if (++visitCount % kVisitPeriod != 0)
+ return;
- function<void(Junction const &, Junction const &)> onVisitJunctionFn =
- [&delegate, &progress](Junction const & junction, Junction const & /* target */)
- {
delegate.OnPointCheck(junction.GetPoint());
auto const lastValue = progress.GetLastValue();
auto const newValue = progress.GetProgressForDirectedAlgo(junction.GetPoint());
@@ -164,10 +167,12 @@ IRoutingAlgorithm::Result AStarBidirectionalRoutingAlgorithm::CalculateRoute(
RouterDelegate const & delegate, RoutingResult<Junction> & path)
{
AStarProgress progress(0, 100);
+ uint32_t visitCount = 0;
+
+ auto onVisitJunctionFn = [&](Junction const & junction, Junction const & target) {
+ if (++visitCount % kVisitPeriod != 0)
+ return;
- function<void(Junction const &, Junction const &)> onVisitJunctionFn =
- [&delegate, &progress](Junction const & junction, Junction const & target)
- {
delegate.OnPointCheck(junction.GetPoint());
auto const lastValue = progress.GetLastValue();
auto const newValue =
diff --git a/routing/routing_helpers.cpp b/routing/routing_helpers.cpp
index 555ce45b8a..a6986faa57 100644
--- a/routing/routing_helpers.cpp
+++ b/routing/routing_helpers.cpp
@@ -73,21 +73,7 @@ void ReconstructRoute(IDirectionsEngine & engine, RoadGraphBase const & graph,
{
traffic.reserve(segments.size());
for (Segment const & seg : segments)
- {
- traffic::TrafficInfo::RoadSegmentId roadSegment(
- seg.GetFeatureId(), seg.GetSegmentIdx(),
- seg.IsForward() ? traffic::TrafficInfo::RoadSegmentId::kForwardDirection
- : traffic::TrafficInfo::RoadSegmentId::kReverseDirection);
-
- auto segTraffic = SpeedGroup::Unknown;
- if (auto trafficColoring = trafficStash->Get(seg.GetMwmId()))
- {
- auto const it = trafficColoring->find(roadSegment);
- if (it != trafficColoring->cend())
- segTraffic = it->second;
- }
- traffic.push_back(segTraffic);
- }
+ traffic.push_back(trafficStash->GetSpeedGroup(seg));
CHECK_EQUAL(segments.size(), traffic.size(), ());
}
diff --git a/routing/routing_integration_tests/routing_test_tools.cpp b/routing/routing_integration_tests/routing_test_tools.cpp
index 6f504e715a..da74756a90 100644
--- a/routing/routing_integration_tests/routing_test_tools.cpp
+++ b/routing/routing_integration_tests/routing_test_tools.cpp
@@ -243,8 +243,8 @@ namespace integration
IRouter * router = routerComponents.GetRouter();
ASSERT(router, ());
shared_ptr<Route> route(new Route("mapsme"));
- IRouter::ResultCode result =
- router->CalculateRoute(startPoint, startDirection, finalPoint, delegate, *route.get());
+ IRouter::ResultCode result = router->CalculateRoute(startPoint, startDirection, finalPoint,
+ false /* adjust */, delegate, *route.get());
ASSERT(route, ());
return TRouteResult(route, result);
}
diff --git a/routing/routing_session.cpp b/routing/routing_session.cpp
index b2d8b68db7..718ce0e212 100644
--- a/routing/routing_session.cpp
+++ b/routing/routing_session.cpp
@@ -84,7 +84,7 @@ void RoutingSession::BuildRoute(m2::PointD const & startPoint, m2::PointD const
void RoutingSession::RebuildRoute(m2::PointD const & startPoint,
TReadyCallback const & readyCallback, uint32_t timeoutSec,
- State routeRebuildingState, bool adjust)
+ State routeRebuildingState, bool adjustToPrevRoute)
{
ASSERT(m_router != nullptr, ());
ASSERT_NOT_EQUAL(m_endPoint, m2::PointD::Zero(), ("End point was not set"));
@@ -95,7 +95,7 @@ void RoutingSession::RebuildRoute(m2::PointD const & startPoint,
// Use old-style callback construction, because lambda constructs buggy function on Android
// (callback param isn't captured by value).
- m_router->CalculateRoute(startPoint, startPoint - m_lastGoodPosition, m_endPoint, adjust,
+ m_router->CalculateRoute(startPoint, startPoint - m_lastGoodPosition, m_endPoint, adjustToPrevRoute,
DoReadyCallback(*this, readyCallback, m_routingSessionMutex),
m_progressCallback, timeoutSec);
}
@@ -157,7 +157,7 @@ void RoutingSession::RebuildRouteOnTrafficUpdate()
// Cancel current route building if going.
m_router->ClearState();
RebuildRoute(m_lastGoodPosition, m_rebuildReadyCallback, 0 /* timeoutSec */,
- routing::RoutingSession::State::RouteRebuilding, false /* adjust */);
+ routing::RoutingSession::State::RouteRebuilding, false /* adjustToPrevRoute */);
}
void RoutingSession::Reset()
diff --git a/routing/routing_session.hpp b/routing/routing_session.hpp
index 6acfe3e244..04abd78480 100644
--- a/routing/routing_session.hpp
+++ b/routing/routing_session.hpp
@@ -90,7 +90,7 @@ public:
void BuildRoute(m2::PointD const & startPoint, m2::PointD const & endPoint,
uint32_t timeoutSec);
void RebuildRoute(m2::PointD const & startPoint, TReadyCallback const & readyCallback,
- uint32_t timeoutSec, State routeRebuildingState, bool adjust);
+ uint32_t timeoutSec, State routeRebuildingState, bool adjustToPrevRoute);
m2::PointD GetEndPoint() const { return m_endPoint; }
bool IsActive() const { return (m_state != RoutingNotActive); }
diff --git a/routing/routing_tests/astar_algorithm_test.cpp b/routing/routing_tests/astar_algorithm_test.cpp
index f3887b3cc7..40c40b6015 100644
--- a/routing/routing_tests/astar_algorithm_test.cpp
+++ b/routing/routing_tests/astar_algorithm_test.cpp
@@ -57,10 +57,10 @@ private:
map<unsigned, vector<Edge>> m_adjs;
};
+using TAlgorithm = AStarAlgorithm<UndirectedGraph>;
+
void TestAStar(UndirectedGraph & graph, vector<unsigned> const & expectedRoute, double const & expectedDistance)
{
- using TAlgorithm = AStarAlgorithm<UndirectedGraph>;
-
TAlgorithm algo;
RoutingResult<unsigned> actualRoute;
@@ -90,4 +90,68 @@ UNIT_TEST(AStarAlgorithm_Sample)
TestAStar(graph, expectedRoute, 23);
}
+UNIT_TEST(AdjustRoute)
+{
+ UndirectedGraph graph;
+
+ for (unsigned int i = 0; i < 5; ++i)
+ graph.AddEdge(i /* from */, i + 1 /* to */, 1 /* weight */);
+
+ graph.AddEdge(6, 0, 1);
+ graph.AddEdge(6, 1, 1);
+ graph.AddEdge(6, 2, 1);
+
+ // Each edge contains {vertexId, weight}.
+ vector<Edge> const prevRoute = {{0, 0}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}};
+
+ TAlgorithm algo;
+ RoutingResult<unsigned> result;
+ auto code = algo.AdjustRoute(graph, 6 /* start */, prevRoute, 1.0 /* limit */, result,
+ my::Cancellable(), nullptr /* onVisitedVertexCallback */);
+
+ vector<unsigned> const expectedRoute = {6, 2, 3, 4, 5};
+ TEST_EQUAL(code, TAlgorithm::Result::OK, ());
+ TEST_EQUAL(result.path, expectedRoute, ());
+ TEST_EQUAL(result.distance, 4.0, ());
+}
+
+UNIT_TEST(AdjustRouteNoPath)
+{
+ UndirectedGraph graph;
+
+ for (unsigned int i = 0; i < 5; ++i)
+ graph.AddEdge(i /* from */, i + 1 /* to */, 1 /* weight */);
+
+ // Each edge contains {vertexId, weight}.
+ vector<Edge> const prevRoute = {{0, 0}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}};
+
+ TAlgorithm algo;
+ RoutingResult<unsigned> result;
+ auto code = algo.AdjustRoute(graph, 6 /* start */, prevRoute, 1.0 /* limit */, result,
+ my::Cancellable(), nullptr /* onVisitedVertexCallback */);
+
+ TEST_EQUAL(code, TAlgorithm::Result::NoPath, ());
+ TEST(result.path.empty(), ());
+}
+
+UNIT_TEST(AdjustRouteOutOfLimit)
+{
+ UndirectedGraph graph;
+
+ for (unsigned int i = 0; i < 5; ++i)
+ graph.AddEdge(i /* from */, i + 1 /* to */, 1 /* weight */);
+
+ graph.AddEdge(6, 2, 2);
+
+ // Each edge contains {vertexId, weight}.
+ vector<Edge> const prevRoute = {{0, 0}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}};
+
+ TAlgorithm algo;
+ RoutingResult<unsigned> result;
+ auto code = algo.AdjustRoute(graph, 6 /* start */, prevRoute, 1.0 /* limit */, result,
+ my::Cancellable(), nullptr /* onVisitedVertexCallback */);
+
+ TEST_EQUAL(code, TAlgorithm::Result::NoPath, ());
+ TEST(result.path.empty(), ());
+}
} // namespace routing_test
diff --git a/routing/routing_tests/async_router_test.cpp b/routing/routing_tests/async_router_test.cpp
index 6aeb0ba1dc..5063463751 100644
--- a/routing/routing_tests/async_router_test.cpp
+++ b/routing/routing_tests/async_router_test.cpp
@@ -30,7 +30,7 @@ public:
// IRouter overrides:
string GetName() const override { return "Dummy"; }
ResultCode CalculateRoute(m2::PointD const & startPoint, m2::PointD const & startDirection,
- m2::PointD const & finalPoint, bool adjust,
+ m2::PointD const & finalPoint, bool adjustToPrevRoute,
RouterDelegate const & delegate, Route & route) override
{
vector<m2::PointD> points({startPoint, finalPoint});
@@ -97,7 +97,7 @@ UNIT_TEST(NeedMoreMapsSignalTest)
DummyResultCallback resultCallback(2 /* expectedCalls */);
AsyncRouter async(DummyStatisticsCallback, nullptr /* pointCheckCallback */);
async.SetRouter(move(router), move(fetcher));
- async.CalculateRoute({1, 2}, {3, 4}, {5, 6}, false /* rebuild */,
+ async.CalculateRoute({1, 2}, {3, 4}, {5, 6}, false /* adjustToPrevRoute */,
bind(ref(resultCallback), _1, _2), nullptr /* progressCallback */,
0 /* timeoutSec */);
@@ -119,7 +119,7 @@ UNIT_TEST(StandartAsyncFogTest)
DummyResultCallback resultCallback(1 /* expectedCalls */);
AsyncRouter async(DummyStatisticsCallback, nullptr /* pointCheckCallback */);
async.SetRouter(move(router), move(fetcher));
- async.CalculateRoute({1, 2}, {3, 4}, {5, 6}, false /* rebuild */,
+ async.CalculateRoute({1, 2}, {3, 4}, {5, 6}, false /* adjustToPrevRoute */,
bind(ref(resultCallback), _1, _2), nullptr /* progressCallback */,
0 /* timeoutSec */);
diff --git a/routing/segmented_route.cpp b/routing/segmented_route.cpp
index dbd475d379..9fdf6aa3ae 100644
--- a/routing/segmented_route.cpp
+++ b/routing/segmented_route.cpp
@@ -1,5 +1,7 @@
#include "routing/segmented_route.hpp"
+#include "routing/index_graph_starter.hpp"
+
#include "geometry/mercator.hpp"
#include "base/assert.hpp"
@@ -9,11 +11,9 @@
namespace routing
{
-void SegmentedRoute::Init(m2::PointD const & start, m2::PointD const & finish)
+SegmentedRoute::SegmentedRoute(m2::PointD const & start, m2::PointD const & finish)
+ : m_start(start), m_finish(finish)
{
- m_start = start;
- m_finish = finish;
- m_steps.clear();
}
double SegmentedRoute::CalcDistance(m2::PointD const & point) const
@@ -26,11 +26,4 @@ double SegmentedRoute::CalcDistance(m2::PointD const & point) const
return result;
}
-
-Segment const & SegmentedRoute::GetFinishSegment() const
-{
- // Last segment is fake, before last is finish
- CHECK_GREATER(m_steps.size(), 2, ());
- return m_steps[m_steps.size() - 2].GetSegment();
-}
} // namespace routing
diff --git a/routing/segmented_route.hpp b/routing/segmented_route.hpp
index c393d88cec..296e8eb1c0 100644
--- a/routing/segmented_route.hpp
+++ b/routing/segmented_route.hpp
@@ -8,48 +8,41 @@
namespace routing
{
-class SegmentedRouteStep final
+class SegmentedRoute final
{
public:
- SegmentedRouteStep() = default;
-
- SegmentedRouteStep(Segment const & segment, m2::PointD const & point)
- : m_segment(segment), m_point(point)
+ class Step final
{
- }
+ public:
+ Step() = default;
+ Step(Segment const & segment, m2::PointD const & point) : m_segment(segment), m_point(point) {}
- Segment const & GetSegment() const { return m_segment; }
- m2::PointD const & GetPoint() const { return m_point; }
+ Segment const & GetSegment() const { return m_segment; }
+ m2::PointD const & GetPoint() const { return m_point; }
-private:
- Segment m_segment;
- // The front point of segment
- m2::PointD m_point = m2::PointD::Zero();
-};
+ private:
+ Segment const m_segment;
+ // The front point of segment
+ m2::PointD const m_point = m2::PointD::Zero();
+ };
-class SegmentedRoute final
-{
-public:
- void Init(m2::PointD const & start, m2::PointD const & finish);
+ SegmentedRoute(m2::PointD const & start, m2::PointD const & finish);
void AddStep(Segment const & segment, m2::PointD const & point)
{
m_steps.emplace_back(segment, point);
}
- void Clear() { Init(m2::PointD::Zero(), m2::PointD::Zero()); }
-
double CalcDistance(m2::PointD const & point) const;
- Segment const & GetFinishSegment() const;
m2::PointD const & GetStart() const { return m_start; }
m2::PointD const & GetFinish() const { return m_finish; }
- std::vector<SegmentedRouteStep> const & GetSteps() const { return m_steps; }
+ std::vector<Step> const & GetSteps() const { return m_steps; }
bool IsEmpty() const { return m_steps.empty(); }
private:
- m2::PointD m_start = m2::PointD::Zero();
- m2::PointD m_finish = m2::PointD::Zero();
- std::vector<SegmentedRouteStep> m_steps;
+ m2::PointD const m_start;
+ m2::PointD const m_finish;
+ std::vector<Step> m_steps;
};
} // namespace routing
diff --git a/routing/traffic_stash.cpp b/routing/traffic_stash.cpp
index 04c2856b5b..3aaa9158cd 100644
--- a/routing/traffic_stash.cpp
+++ b/routing/traffic_stash.cpp
@@ -6,6 +6,12 @@
namespace routing
{
+TrafficStash::TrafficStash(traffic::TrafficCache const & source, shared_ptr<NumMwmIds> numMwmIds)
+ : m_source(source), m_numMwmIds(std::move(numMwmIds))
+{
+ CHECK(m_numMwmIds, ());
+}
+
traffic::SpeedGroup TrafficStash::GetSpeedGroup(Segment const & segment) const
{
auto itMwm = m_mwmToTraffic.find(segment.GetMwmId());
@@ -24,6 +30,17 @@ traffic::SpeedGroup TrafficStash::GetSpeedGroup(Segment const & segment) const
return itSeg->second;
}
+void TrafficStash::SetColoring(NumMwmId numMwmId,
+ std::shared_ptr<traffic::TrafficInfo::Coloring> coloring)
+{
+ m_mwmToTraffic[numMwmId] = coloring;
+}
+
+bool TrafficStash::Has(NumMwmId numMwmId) const
+{
+ return m_mwmToTraffic.find(numMwmId) != m_mwmToTraffic.cend();
+}
+
void TrafficStash::CopyTraffic()
{
std::map<MwmSet::MwmId, std::shared_ptr<traffic::TrafficInfo::Coloring>> copy;
diff --git a/routing/traffic_stash.hpp b/routing/traffic_stash.hpp
index 679ebb686e..451e85e0cd 100644
--- a/routing/traffic_stash.hpp
+++ b/routing/traffic_stash.hpp
@@ -10,6 +10,7 @@
#include "base/assert.hpp"
+#include <memory>
#include <unordered_map>
namespace routing
@@ -27,23 +28,11 @@ public:
TrafficStash & m_stash;
};
- TrafficStash(traffic::TrafficCache const & source, shared_ptr<NumMwmIds> numMwmIds)
- : m_source(source), m_numMwmIds(numMwmIds)
- {
- CHECK(m_numMwmIds, ());
- }
+ TrafficStash(traffic::TrafficCache const & source, std::shared_ptr<NumMwmIds> numMwmIds);
traffic::SpeedGroup GetSpeedGroup(Segment const & segment) const;
-
- void SetColoring(NumMwmId numMwmId, std::shared_ptr<traffic::TrafficInfo::Coloring> coloring)
- {
- m_mwmToTraffic[numMwmId] = coloring;
- }
-
- bool Has(NumMwmId numMwmId) const
- {
- return m_mwmToTraffic.find(numMwmId) != m_mwmToTraffic.cend();
- }
+ void SetColoring(NumMwmId numMwmId, std::shared_ptr<traffic::TrafficInfo::Coloring> coloring);
+ bool Has(NumMwmId numMwmId) const;
private:
void CopyTraffic();
@@ -52,6 +41,6 @@ private:
traffic::TrafficCache const & m_source;
shared_ptr<NumMwmIds> m_numMwmIds;
- std::unordered_map<NumMwmId, shared_ptr<traffic::TrafficInfo::Coloring>> m_mwmToTraffic;
+ std::unordered_map<NumMwmId, std::shared_ptr<traffic::TrafficInfo::Coloring>> m_mwmToTraffic;
};
} // namespace routing
diff --git a/xcode/routing/routing.xcodeproj/project.pbxproj b/xcode/routing/routing.xcodeproj/project.pbxproj
index aaedc75fb7..fd2dd59385 100644
--- a/xcode/routing/routing.xcodeproj/project.pbxproj
+++ b/xcode/routing/routing.xcodeproj/project.pbxproj
@@ -13,7 +13,6 @@
0C08AA391DF8329B004195DD /* routing_exceptions.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C08AA381DF8329B004195DD /* routing_exceptions.hpp */; };
0C090C811E4E274000D52AFD /* index_graph_loader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C090C7F1E4E274000D52AFD /* index_graph_loader.cpp */; };
0C090C821E4E274000D52AFD /* index_graph_loader.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C090C801E4E274000D52AFD /* index_graph_loader.hpp */; };
- 0C090C841E4E275E00D52AFD /* traffic_stash.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C090C831E4E275E00D52AFD /* traffic_stash.hpp */; };
0C090C871E4E276700D52AFD /* world_graph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C090C851E4E276700D52AFD /* world_graph.cpp */; };
0C090C881E4E276700D52AFD /* world_graph.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C090C861E4E276700D52AFD /* world_graph.hpp */; };
0C0DF9211DE898B70055A22F /* index_graph_starter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C0DF91F1DE898B70055A22F /* index_graph_starter.cpp */; };
@@ -45,10 +44,11 @@
0C5FEC6B1DDE193F0017688C /* road_point.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C5FEC681DDE193F0017688C /* road_point.hpp */; };
0C5FEC6D1DDE19A40017688C /* index_graph_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C5FEC6C1DDE19A40017688C /* index_graph_test.cpp */; };
0C62BFE61E8ADC3100055A79 /* coding.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C62BFE51E8ADC3100055A79 /* coding.hpp */; };
+ 0C81E1531F02589800DC66DF /* traffic_stash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C81E1511F02589800DC66DF /* traffic_stash.cpp */; };
+ 0C81E1541F02589800DC66DF /* traffic_stash.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C81E1521F02589800DC66DF /* traffic_stash.hpp */; };
+ 0C81E1571F0258AA00DC66DF /* segmented_route.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C81E1551F0258AA00DC66DF /* segmented_route.cpp */; };
+ 0C81E1581F0258AA00DC66DF /* segmented_route.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C81E1561F0258AA00DC66DF /* segmented_route.hpp */; };
0C8705051E0182F200BCAF71 /* route_point.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C8705041E0182F200BCAF71 /* route_point.hpp */; };
- 0CA683581EE04ADB004B7269 /* segmented_route.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CA683561EE04ADB004B7269 /* segmented_route.cpp */; };
- 0CA683591EE04ADB004B7269 /* segmented_route.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0CA683571EE04ADB004B7269 /* segmented_route.hpp */; };
- 0CA6835B1EE04AF3004B7269 /* traffic_stash.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CA6835A1EE04AF3004B7269 /* traffic_stash.cpp */; };
0CF5E8AA1E8EA7A1001ED497 /* coding_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0CF5E8A91E8EA7A1001ED497 /* coding_test.cpp */; };
3462FDAD1DC1E5BF00906FD7 /* libopening_hours.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3462FDAC1DC1E5BF00906FD7 /* libopening_hours.a */; };
349D1CE01E3F589900A878FD /* restrictions_serialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 349D1CDE1E3F589900A878FD /* restrictions_serialization.cpp */; };
@@ -272,7 +272,6 @@
0C08AA381DF8329B004195DD /* routing_exceptions.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = routing_exceptions.hpp; sourceTree = "<group>"; };
0C090C7F1E4E274000D52AFD /* index_graph_loader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = index_graph_loader.cpp; sourceTree = "<group>"; };
0C090C801E4E274000D52AFD /* index_graph_loader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = index_graph_loader.hpp; sourceTree = "<group>"; };
- 0C090C831E4E275E00D52AFD /* traffic_stash.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = traffic_stash.hpp; sourceTree = "<group>"; };
0C090C851E4E276700D52AFD /* world_graph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = world_graph.cpp; sourceTree = "<group>"; };
0C090C861E4E276700D52AFD /* world_graph.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = world_graph.hpp; sourceTree = "<group>"; };
0C0DF91F1DE898B70055A22F /* index_graph_starter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = index_graph_starter.cpp; sourceTree = "<group>"; };
@@ -304,10 +303,11 @@
0C5FEC681DDE193F0017688C /* road_point.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = road_point.hpp; sourceTree = "<group>"; };
0C5FEC6C1DDE19A40017688C /* index_graph_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = index_graph_test.cpp; sourceTree = "<group>"; };
0C62BFE51E8ADC3100055A79 /* coding.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = coding.hpp; sourceTree = "<group>"; };
+ 0C81E1511F02589800DC66DF /* traffic_stash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = traffic_stash.cpp; sourceTree = "<group>"; };
+ 0C81E1521F02589800DC66DF /* traffic_stash.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = traffic_stash.hpp; sourceTree = "<group>"; };
+ 0C81E1551F0258AA00DC66DF /* segmented_route.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = segmented_route.cpp; sourceTree = "<group>"; };
+ 0C81E1561F0258AA00DC66DF /* segmented_route.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = segmented_route.hpp; sourceTree = "<group>"; };
0C8705041E0182F200BCAF71 /* route_point.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = route_point.hpp; sourceTree = "<group>"; };
- 0CA683561EE04ADB004B7269 /* segmented_route.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = segmented_route.cpp; sourceTree = "<group>"; };
- 0CA683571EE04ADB004B7269 /* segmented_route.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = segmented_route.hpp; sourceTree = "<group>"; };
- 0CA6835A1EE04AF3004B7269 /* traffic_stash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = traffic_stash.cpp; sourceTree = "<group>"; };
0CF5E8A91E8EA7A1001ED497 /* coding_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coding_test.cpp; sourceTree = "<group>"; };
3462FDAC1DC1E5BF00906FD7 /* libopening_hours.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopening_hours.a; path = "../../../omim-build/xcode/Debug/libopening_hours.a"; sourceTree = "<group>"; };
349D1CDE1E3F589900A878FD /* restrictions_serialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = restrictions_serialization.cpp; sourceTree = "<group>"; };
@@ -819,12 +819,12 @@
670EE55B1B6001E7001E8064 /* routing_session.hpp */,
670EE55C1B6001E7001E8064 /* routing_settings.hpp */,
0C470E6F1E0D4EB1005B824D /* segment.hpp */,
- 0CA683561EE04ADB004B7269 /* segmented_route.cpp */,
- 0CA683571EE04ADB004B7269 /* segmented_route.hpp */,
+ 0C81E1551F0258AA00DC66DF /* segmented_route.cpp */,
+ 0C81E1561F0258AA00DC66DF /* segmented_route.hpp */,
A1876BC41BB19C4300C9C743 /* speed_camera.cpp */,
A1876BC51BB19C4300C9C743 /* speed_camera.hpp */,
- 0CA6835A1EE04AF3004B7269 /* traffic_stash.cpp */,
- 0C090C831E4E275E00D52AFD /* traffic_stash.hpp */,
+ 0C81E1511F02589800DC66DF /* traffic_stash.cpp */,
+ 0C81E1521F02589800DC66DF /* traffic_stash.hpp */,
56099E271CC7C97D00A7772A /* turn_candidate.hpp */,
674F9BC61B0A580E00704FFA /* turns_generator.cpp */,
674F9BC71B0A580E00704FFA /* turns_generator.hpp */,
@@ -874,7 +874,6 @@
0C5BC9D21E28FD4E0071BFDD /* index_road_graph.hpp in Headers */,
674F9BD11B0A580E00704FFA /* online_cross_fetcher.hpp in Headers */,
0C470E701E0D4EB1005B824D /* segment.hpp in Headers */,
- 0C090C841E4E275E00D52AFD /* traffic_stash.hpp in Headers */,
A120B3531B4A7C1C002F3808 /* astar_algorithm.hpp in Headers */,
0C5FEC5F1DDE192A0017688C /* geometry.hpp in Headers */,
674A28B21B1605D2001A525C /* osrm_engine.hpp in Headers */,
@@ -902,6 +901,7 @@
56099E291CC7C97D00A7772A /* loaded_path_segment.hpp in Headers */,
670EE55F1B6001E7001E8064 /* routing_settings.hpp in Headers */,
56CA09E61E30E73B00D05C9A /* index_graph_tools.hpp in Headers */,
+ 0C81E1581F0258AA00DC66DF /* segmented_route.hpp in Headers */,
671F58BE1B874EC80032311E /* followed_polyline.hpp in Headers */,
0C5FEC6A1DDE193F0017688C /* road_index.hpp in Headers */,
674F9BCD1B0A580E00704FFA /* features_road_graph.hpp in Headers */,
@@ -913,6 +913,7 @@
0C090C821E4E274000D52AFD /* index_graph_loader.hpp in Headers */,
670EE5721B664796001E8064 /* directions_engine.hpp in Headers */,
56C439291E93BF8C00998E29 /* cross_mwm_graph.hpp in Headers */,
+ 0C81E1541F02589800DC66DF /* traffic_stash.hpp in Headers */,
0C8705051E0182F200BCAF71 /* route_point.hpp in Headers */,
A1876BC71BB19C4300C9C743 /* speed_camera.hpp in Headers */,
56EA2FD51D8FD8590083F01A /* routing_helpers.hpp in Headers */,
@@ -929,7 +930,6 @@
0C5FEC6B1DDE193F0017688C /* road_point.hpp in Headers */,
56099E2B1CC7C97D00A7772A /* turn_candidate.hpp in Headers */,
56C4392D1E93E5DF00998E29 /* transition_points.hpp in Headers */,
- 0CA683591EE04ADB004B7269 /* segmented_route.hpp in Headers */,
0C5FEC551DDE191E0017688C /* edge_estimator.hpp in Headers */,
670B84C11A9381D900CE4492 /* cross_routing_context.hpp in Headers */,
0C12ED241E5C822A0080D0F4 /* index_router.hpp in Headers */,
@@ -1168,6 +1168,7 @@
6753441B1A3F644F00A0A8C3 /* route.cpp in Sources */,
674F9BCA1B0A580E00704FFA /* async_router.cpp in Sources */,
0C5F5D221E798B0400307B98 /* cross_mwm_connector.cpp in Sources */,
+ 0C81E1531F02589800DC66DF /* traffic_stash.cpp in Sources */,
0CF5E8AA1E8EA7A1001ED497 /* coding_test.cpp in Sources */,
675344191A3F644F00A0A8C3 /* osrm2feature_map.cpp in Sources */,
670D049E1B0B4A970013A7AC /* nearest_edge_finder.cpp in Sources */,
@@ -1185,6 +1186,7 @@
0C08AA341DF83223004195DD /* index_graph_serialization.cpp in Sources */,
5694CECA1EBA25F7004576D3 /* road_access_serialization.cpp in Sources */,
674F9BD41B0A580E00704FFA /* road_graph.cpp in Sources */,
+ 0C81E1571F0258AA00DC66DF /* segmented_route.cpp in Sources */,
56CA09E51E30E73B00D05C9A /* index_graph_tools.cpp in Sources */,
0C0DF92A1DE898FF0055A22F /* routing_helpers.cpp in Sources */,
67AB92E61B7B3E6E00AB5194 /* turns_tts_text.cpp in Sources */,