mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-22 06:03:45 +00:00
Format all C++ and Java code via clang-format
Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
This commit is contained in:
@@ -5,8 +5,7 @@ namespace routing
|
||||
{
|
||||
AbsentRegionsFinder::AbsentRegionsFinder(CountryFileGetterFn const & countryFileGetter,
|
||||
LocalFileCheckerFn const & localFileChecker,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
DataSource & dataSource)
|
||||
std::shared_ptr<NumMwmIds> numMwmIds, DataSource & dataSource)
|
||||
: m_countryFileGetterFn(countryFileGetter)
|
||||
, m_localFileCheckerFn(localFileChecker)
|
||||
, m_numMwmIds(std::move(numMwmIds))
|
||||
@@ -16,8 +15,7 @@ AbsentRegionsFinder::AbsentRegionsFinder(CountryFileGetterFn const & countryFile
|
||||
CHECK(m_localFileCheckerFn, ());
|
||||
}
|
||||
|
||||
void AbsentRegionsFinder::GenerateAbsentRegions(Checkpoints const & checkpoints,
|
||||
RouterDelegate const & delegate)
|
||||
void AbsentRegionsFinder::GenerateAbsentRegions(Checkpoints const & checkpoints, RouterDelegate const & delegate)
|
||||
{
|
||||
if (m_routerThread)
|
||||
{
|
||||
@@ -28,8 +26,8 @@ void AbsentRegionsFinder::GenerateAbsentRegions(Checkpoints const & checkpoints,
|
||||
if (AreCheckpointsInSameMwm(checkpoints))
|
||||
return;
|
||||
|
||||
std::unique_ptr<RegionsRouter> router = std::make_unique<RegionsRouter>(
|
||||
m_countryFileGetterFn, m_numMwmIds, m_dataSource, delegate, checkpoints);
|
||||
std::unique_ptr<RegionsRouter> router =
|
||||
std::make_unique<RegionsRouter>(m_countryFileGetterFn, m_numMwmIds, m_dataSource, delegate, checkpoints);
|
||||
|
||||
// iOS can't reuse threads. So we need to recreate the thread.
|
||||
m_routerThread = std::make_unique<threads::Thread>();
|
||||
@@ -42,12 +40,10 @@ void AbsentRegionsFinder::GetAbsentRegions(std::set<std::string> & regions)
|
||||
GetAllRegions(regions);
|
||||
|
||||
for (auto i = regions.begin(); i != regions.end();)
|
||||
{
|
||||
if (m_localFileCheckerFn(*i))
|
||||
i = regions.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void AbsentRegionsFinder::GetAllRegions(std::set<std::string> & countries)
|
||||
@@ -60,10 +56,8 @@ void AbsentRegionsFinder::GetAllRegions(std::set<std::string> & countries)
|
||||
m_routerThread->Join();
|
||||
|
||||
for (auto const & mwmName : m_routerThread->GetRoutineAs<RegionsRouter>()->GetMwmNames())
|
||||
{
|
||||
if (!mwmName.empty())
|
||||
countries.emplace(mwmName);
|
||||
}
|
||||
|
||||
m_routerThread.reset();
|
||||
}
|
||||
@@ -71,13 +65,8 @@ void AbsentRegionsFinder::GetAllRegions(std::set<std::string> & countries)
|
||||
bool AbsentRegionsFinder::AreCheckpointsInSameMwm(Checkpoints const & checkpoints) const
|
||||
{
|
||||
for (size_t i = 0; i < checkpoints.GetNumSubroutes(); ++i)
|
||||
{
|
||||
if (m_countryFileGetterFn(checkpoints.GetPoint(i)) !=
|
||||
m_countryFileGetterFn(checkpoints.GetPoint(i + 1)))
|
||||
{
|
||||
if (m_countryFileGetterFn(checkpoints.GetPoint(i)) != m_countryFileGetterFn(checkpoints.GetPoint(i + 1)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ using LocalFileCheckerFn = std::function<bool(std::string const &)>;
|
||||
class AbsentRegionsFinder
|
||||
{
|
||||
public:
|
||||
AbsentRegionsFinder(CountryFileGetterFn const & countryFileGetter,
|
||||
LocalFileCheckerFn const & localFileChecker,
|
||||
AbsentRegionsFinder(CountryFileGetterFn const & countryFileGetter, LocalFileCheckerFn const & localFileChecker,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds, DataSource & dataSource);
|
||||
|
||||
// Creates new thread |m_routerThread| and starts routing in it.
|
||||
|
||||
@@ -19,8 +19,7 @@ AsyncRouter::RouterDelegateProxy::RouterDelegateProxy(ReadyCallbackOwnership con
|
||||
NeedMoreMapsCallback const & onNeedMoreMaps,
|
||||
RemoveRouteCallback const & onRemoveRoute,
|
||||
PointCheckCallback const & onPointCheck,
|
||||
ProgressCallback const & onProgress,
|
||||
uint32_t timeoutSec)
|
||||
ProgressCallback const & onProgress, uint32_t timeoutSec)
|
||||
: m_onReadyOwnership(onReady)
|
||||
, m_onNeedMoreMaps(onNeedMoreMaps)
|
||||
, m_onRemoveRoute(onRemoveRoute)
|
||||
@@ -45,8 +44,7 @@ void AsyncRouter::RouterDelegateProxy::OnReady(std::shared_ptr<Route> route, Rou
|
||||
m_onReadyOwnership(std::move(route), resultCode);
|
||||
}
|
||||
|
||||
void AsyncRouter::RouterDelegateProxy::OnNeedMoreMaps(uint64_t routeId,
|
||||
std::set<std::string> const & absentCounties)
|
||||
void AsyncRouter::RouterDelegateProxy::OnNeedMoreMaps(uint64_t routeId, std::set<std::string> const & absentCounties)
|
||||
{
|
||||
if (!m_onNeedMoreMaps)
|
||||
return;
|
||||
@@ -76,8 +74,7 @@ void AsyncRouter::RouterDelegateProxy::Cancel()
|
||||
m_delegate.Cancel();
|
||||
}
|
||||
|
||||
bool AsyncRouter::FindClosestProjectionToRoad(m2::PointD const & point,
|
||||
m2::PointD const & direction, double radius,
|
||||
bool AsyncRouter::FindClosestProjectionToRoad(m2::PointD const & point, m2::PointD const & direction, double radius,
|
||||
EdgeProj & proj)
|
||||
{
|
||||
return m_router->FindClosestProjectionToRoad(point, direction, radius, proj);
|
||||
@@ -96,9 +93,7 @@ void AsyncRouter::RouterDelegateProxy::OnProgress(float progress)
|
||||
return;
|
||||
|
||||
onProgress = m_onProgress;
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [onProgress, progress]() {
|
||||
onProgress(progress);
|
||||
});
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [onProgress, progress]() { onProgress(progress); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,8 +144,7 @@ AsyncRouter::~AsyncRouter()
|
||||
m_thread.join();
|
||||
}
|
||||
|
||||
void AsyncRouter::SetRouter(std::unique_ptr<IRouter> && router,
|
||||
std::unique_ptr<AbsentRegionsFinder> && finder)
|
||||
void AsyncRouter::SetRouter(std::unique_ptr<IRouter> && router, std::unique_ptr<AbsentRegionsFinder> && finder)
|
||||
{
|
||||
unique_lock ul(m_guard);
|
||||
|
||||
@@ -160,8 +154,7 @@ void AsyncRouter::SetRouter(std::unique_ptr<IRouter> && router,
|
||||
m_absentRegionsFinder = std::move(finder);
|
||||
}
|
||||
|
||||
void AsyncRouter::CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & direction,
|
||||
bool adjustToPrevRoute,
|
||||
void AsyncRouter::CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & direction, bool adjustToPrevRoute,
|
||||
ReadyCallbackOwnership const & readyCallback,
|
||||
NeedMoreMapsCallback const & needMoreMapsCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback,
|
||||
@@ -175,9 +168,8 @@ void AsyncRouter::CalculateRoute(Checkpoints const & checkpoints, m2::PointD con
|
||||
|
||||
ResetDelegate();
|
||||
|
||||
m_delegateProxy =
|
||||
std::make_shared<RouterDelegateProxy>(readyCallback, needMoreMapsCallback, removeRouteCallback,
|
||||
m_pointCheckCallback, progressCallback, timeoutSec);
|
||||
m_delegateProxy = std::make_shared<RouterDelegateProxy>(readyCallback, needMoreMapsCallback, removeRouteCallback,
|
||||
m_pointCheckCallback, progressCallback, timeoutSec);
|
||||
|
||||
m_hasRequest = true;
|
||||
m_threadCondVar.notify_one();
|
||||
@@ -204,59 +196,32 @@ void AsyncRouter::LogCode(RouterResultCode code, double const elapsedSec)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case RouterResultCode::StartPointNotFound:
|
||||
LOG(LWARNING, ("Can't find start or end node"));
|
||||
break;
|
||||
case RouterResultCode::EndPointNotFound:
|
||||
LOG(LWARNING, ("Can't find end point node"));
|
||||
break;
|
||||
case RouterResultCode::PointsInDifferentMWM:
|
||||
LOG(LWARNING, ("Points are in different MWMs"));
|
||||
break;
|
||||
case RouterResultCode::RouteNotFound:
|
||||
LOG(LWARNING, ("Route not found"));
|
||||
break;
|
||||
case RouterResultCode::RouteFileNotExist:
|
||||
LOG(LWARNING, ("There is no routing file"));
|
||||
break;
|
||||
case RouterResultCode::NeedMoreMaps:
|
||||
LOG(LINFO,
|
||||
("Routing can find a better way with additional maps, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::Cancelled:
|
||||
LOG(LINFO, ("Route calculation cancelled, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::NoError:
|
||||
LOG(LINFO, ("Route found, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::NoCurrentPosition:
|
||||
LOG(LINFO, ("No current position"));
|
||||
break;
|
||||
case RouterResultCode::InconsistentMWMandRoute:
|
||||
LOG(LINFO, ("Inconsistent mwm and route"));
|
||||
break;
|
||||
case RouterResultCode::InternalError:
|
||||
LOG(LINFO, ("Internal error"));
|
||||
break;
|
||||
case RouterResultCode::FileTooOld:
|
||||
LOG(LINFO, ("File too old"));
|
||||
break;
|
||||
case RouterResultCode::IntermediatePointNotFound:
|
||||
LOG(LWARNING, ("Can't find intermediate point node"));
|
||||
break;
|
||||
case RouterResultCode::TransitRouteNotFoundNoNetwork:
|
||||
LOG(LWARNING, ("No transit route is found because there's no transit network in the mwm of "
|
||||
"the route point"));
|
||||
break;
|
||||
case RouterResultCode::TransitRouteNotFoundTooLongPedestrian:
|
||||
LOG(LWARNING, ("No transit route is found because pedestrian way is too long"));
|
||||
break;
|
||||
case RouterResultCode::RouteNotFoundRedressRouteError:
|
||||
LOG(LWARNING, ("Route not found because of a redress route error"));
|
||||
break;
|
||||
case RouterResultCode::HasWarnings:
|
||||
LOG(LINFO, ("Route has warnings, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::StartPointNotFound: LOG(LWARNING, ("Can't find start or end node")); break;
|
||||
case RouterResultCode::EndPointNotFound: LOG(LWARNING, ("Can't find end point node")); break;
|
||||
case RouterResultCode::PointsInDifferentMWM: LOG(LWARNING, ("Points are in different MWMs")); break;
|
||||
case RouterResultCode::RouteNotFound: LOG(LWARNING, ("Route not found")); break;
|
||||
case RouterResultCode::RouteFileNotExist: LOG(LWARNING, ("There is no routing file")); break;
|
||||
case RouterResultCode::NeedMoreMaps:
|
||||
LOG(LINFO, ("Routing can find a better way with additional maps, elapsed seconds:", elapsedSec));
|
||||
break;
|
||||
case RouterResultCode::Cancelled: LOG(LINFO, ("Route calculation cancelled, elapsed seconds:", elapsedSec)); break;
|
||||
case RouterResultCode::NoError: LOG(LINFO, ("Route found, elapsed seconds:", elapsedSec)); break;
|
||||
case RouterResultCode::NoCurrentPosition: LOG(LINFO, ("No current position")); break;
|
||||
case RouterResultCode::InconsistentMWMandRoute: LOG(LINFO, ("Inconsistent mwm and route")); break;
|
||||
case RouterResultCode::InternalError: LOG(LINFO, ("Internal error")); break;
|
||||
case RouterResultCode::FileTooOld: LOG(LINFO, ("File too old")); break;
|
||||
case RouterResultCode::IntermediatePointNotFound: LOG(LWARNING, ("Can't find intermediate point node")); break;
|
||||
case RouterResultCode::TransitRouteNotFoundNoNetwork:
|
||||
LOG(LWARNING, ("No transit route is found because there's no transit network in the mwm of "
|
||||
"the route point"));
|
||||
break;
|
||||
case RouterResultCode::TransitRouteNotFoundTooLongPedestrian:
|
||||
LOG(LWARNING, ("No transit route is found because pedestrian way is too long"));
|
||||
break;
|
||||
case RouterResultCode::RouteNotFoundRedressRouteError:
|
||||
LOG(LWARNING, ("Route not found because of a redress route error"));
|
||||
break;
|
||||
case RouterResultCode::HasWarnings: LOG(LINFO, ("Route has warnings, elapsed seconds:", elapsedSec)); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +240,7 @@ void AsyncRouter::ThreadFunc()
|
||||
{
|
||||
{
|
||||
unique_lock ul(m_guard);
|
||||
m_threadCondVar.wait(ul, [this](){ return m_threadExit || m_hasRequest || m_clearState; });
|
||||
m_threadCondVar.wait(ul, [this]() { return m_threadExit || m_hasRequest || m_clearState; });
|
||||
|
||||
if (m_clearState && m_router)
|
||||
{
|
||||
@@ -344,10 +309,9 @@ void AsyncRouter::CalculateRoute()
|
||||
absentRegionsFinder->GenerateAbsentRegions(checkpoints, delegateProxy->GetDelegate());
|
||||
|
||||
// Run basic request.
|
||||
code = router->CalculateRoute(checkpoints, startDirection, adjustToPrevRoute,
|
||||
delegateProxy->GetDelegate(), *route);
|
||||
code = router->CalculateRoute(checkpoints, startDirection, adjustToPrevRoute, delegateProxy->GetDelegate(), *route);
|
||||
router->SetGuides({});
|
||||
elapsedSec = timer.ElapsedSeconds(); // routing time
|
||||
elapsedSec = timer.ElapsedSeconds(); // routing time
|
||||
LogCode(code, elapsedSec);
|
||||
LOG(LINFO, ("ETA:", route->GetTotalTimeSec(), "sec."));
|
||||
}
|
||||
@@ -371,8 +335,7 @@ void AsyncRouter::CalculateRoute()
|
||||
[delegateProxy, route, code]() { delegateProxy->OnReady(route, code); });
|
||||
}
|
||||
|
||||
bool const needAbsentRegions = (code != RouterResultCode::Cancelled &&
|
||||
route->GetRouterId() != "ruler-router");
|
||||
bool const needAbsentRegions = (code != RouterResultCode::Cancelled && route->GetRouterId() != "ruler-router");
|
||||
|
||||
std::set<std::string> absent;
|
||||
if (needAbsentRegions)
|
||||
@@ -388,7 +351,7 @@ void AsyncRouter::CalculateRoute()
|
||||
}
|
||||
}
|
||||
|
||||
elapsedSec = timer.ElapsedSeconds(); // routing time + absents fetch time
|
||||
elapsedSec = timer.ElapsedSeconds(); // routing time + absents fetch time
|
||||
LogCode(code, elapsedSec);
|
||||
|
||||
// Call callback only if we have some new data.
|
||||
@@ -396,14 +359,12 @@ void AsyncRouter::CalculateRoute()
|
||||
{
|
||||
if (code == RouterResultCode::NeedMoreMaps)
|
||||
{
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [delegateProxy, routeId, absent]() {
|
||||
delegateProxy->OnNeedMoreMaps(routeId, absent);
|
||||
});
|
||||
GetPlatform().RunTask(Platform::Thread::Gui,
|
||||
[delegateProxy, routeId, absent]() { delegateProxy->OnNeedMoreMaps(routeId, absent); });
|
||||
}
|
||||
else
|
||||
{
|
||||
GetPlatform().RunTask(Platform::Thread::Gui,
|
||||
[delegateProxy, code]() { delegateProxy->OnRemoveRoute(code); });
|
||||
GetPlatform().RunTask(Platform::Thread::Gui, [delegateProxy, code]() { delegateProxy->OnRemoveRoute(code); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,7 @@ public:
|
||||
/// Sets a synchronous router, current route calculation will be cancelled
|
||||
/// @param router pointer to a router implementation
|
||||
/// @param finder pointer to a router for generated absent wmwms.
|
||||
void SetRouter(std::unique_ptr<IRouter> && router,
|
||||
std::unique_ptr<AbsentRegionsFinder> && finder);
|
||||
void SetRouter(std::unique_ptr<IRouter> && router, std::unique_ptr<AbsentRegionsFinder> && finder);
|
||||
|
||||
/// Main method to calculate new route from startPt to finalPt with start direction
|
||||
/// Processed result will be passed to callback. Callback will be called at the GUI thread.
|
||||
@@ -48,19 +47,17 @@ public:
|
||||
/// @param timeoutSec timeout to cancel routing. 0 is infinity.
|
||||
// @TODO(bykoianko) Gather |readyCallback|, |needMoreMapsCallback| and |removeRouteCallback|
|
||||
// to one delegate. No need to add |progressCallback| to the delegate.
|
||||
void CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & direction,
|
||||
bool adjustToPrevRoute, ReadyCallbackOwnership const & readyCallback,
|
||||
NeedMoreMapsCallback const & needMoreMapsCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback,
|
||||
ProgressCallback const & progressCallback,
|
||||
void CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & direction, bool adjustToPrevRoute,
|
||||
ReadyCallbackOwnership const & readyCallback, NeedMoreMapsCallback const & needMoreMapsCallback,
|
||||
RemoveRouteCallback const & removeRouteCallback, ProgressCallback const & progressCallback,
|
||||
uint32_t timeoutSec = RouterDelegate::kNoTimeout);
|
||||
|
||||
void SetGuidesTracks(GuidesTracks && guides);
|
||||
/// Interrupt routing and clear buffers
|
||||
void ClearState();
|
||||
|
||||
bool FindClosestProjectionToRoad(m2::PointD const & point, m2::PointD const & direction,
|
||||
double radius, EdgeProj & proj);
|
||||
bool FindClosestProjectionToRoad(m2::PointD const & point, m2::PointD const & direction, double radius,
|
||||
EdgeProj & proj);
|
||||
|
||||
private:
|
||||
/// Worker thread function
|
||||
@@ -75,12 +72,9 @@ private:
|
||||
class RouterDelegateProxy
|
||||
{
|
||||
public:
|
||||
RouterDelegateProxy(ReadyCallbackOwnership const & onReady,
|
||||
NeedMoreMapsCallback const & onNeedMoreMaps,
|
||||
RemoveRouteCallback const & onRemoveRoute,
|
||||
PointCheckCallback const & onPointCheck,
|
||||
ProgressCallback const & onProgress,
|
||||
uint32_t timeoutSec);
|
||||
RouterDelegateProxy(ReadyCallbackOwnership const & onReady, NeedMoreMapsCallback const & onNeedMoreMaps,
|
||||
RemoveRouteCallback const & onRemoveRoute, PointCheckCallback const & onPointCheck,
|
||||
ProgressCallback const & onProgress, uint32_t timeoutSec);
|
||||
|
||||
void OnReady(std::shared_ptr<Route> route, RouterResultCode resultCode);
|
||||
void OnNeedMoreMaps(uint64_t routeId, std::set<std::string> const & absentCounties);
|
||||
|
||||
@@ -28,12 +28,18 @@ namespace astar
|
||||
|
||||
struct DefaultVisitor
|
||||
{
|
||||
template <class State, class Vertex> void operator() (State const &, Vertex const &) const {}
|
||||
template <class State, class Vertex>
|
||||
void operator()(State const &, Vertex const &) const
|
||||
{}
|
||||
};
|
||||
|
||||
struct DefaultLengthChecker
|
||||
{
|
||||
template <class Weight> bool operator()(Weight const &) const { return true; }
|
||||
template <class Weight>
|
||||
bool operator()(Weight const &) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // namespace astar
|
||||
|
||||
@@ -41,7 +47,6 @@ template <typename Vertex, typename Edge, typename Weight>
|
||||
class AStarAlgorithm
|
||||
{
|
||||
public:
|
||||
|
||||
using Graph = AStarGraph<Vertex, Edge, Weight>;
|
||||
|
||||
enum class Result
|
||||
@@ -55,15 +60,9 @@ public:
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case Result::OK:
|
||||
os << "OK";
|
||||
break;
|
||||
case Result::NoPath:
|
||||
os << "NoPath";
|
||||
break;
|
||||
case Result::Cancelled:
|
||||
os << "Cancelled";
|
||||
break;
|
||||
case Result::OK: os << "OK"; break;
|
||||
case Result::NoPath: os << "NoPath"; break;
|
||||
case Result::Cancelled: os << "Cancelled"; break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
@@ -72,12 +71,11 @@ public:
|
||||
{
|
||||
ParamsBase(Graph & graph, Vertex const & startVertex, Vertex const & finalVertex,
|
||||
base::Cancellable const & cancellable)
|
||||
: m_graph(graph)
|
||||
, m_startVertex(startVertex)
|
||||
, m_finalVertex(finalVertex)
|
||||
, m_cancellable(cancellable)
|
||||
{
|
||||
}
|
||||
: m_graph(graph)
|
||||
, m_startVertex(startVertex)
|
||||
, m_finalVertex(finalVertex)
|
||||
, m_cancellable(cancellable)
|
||||
{}
|
||||
|
||||
Graph & m_graph;
|
||||
Weight const m_weightEpsilon = m_graph.GetAStarWeightEpsilon();
|
||||
@@ -92,19 +90,16 @@ public:
|
||||
// |LengthChecker| callback used to check path length from start/finish to the edge (including the
|
||||
// edge itself) before adding the edge to AStar queue. Can be used to clip some path which does
|
||||
// not meet restrictions.
|
||||
template <typename Visitor = astar::DefaultVisitor,
|
||||
typename LengthChecker = astar::DefaultLengthChecker>
|
||||
template <typename Visitor = astar::DefaultVisitor, typename LengthChecker = astar::DefaultLengthChecker>
|
||||
struct Params : public ParamsBase
|
||||
{
|
||||
Params(Graph & graph, Vertex const & startVertex, Vertex const & finalVertex,
|
||||
base::Cancellable const & cancellable,
|
||||
Params(Graph & graph, Vertex const & startVertex, Vertex const & finalVertex, base::Cancellable const & cancellable,
|
||||
Visitor && onVisitedVertexCallback = astar::DefaultVisitor(),
|
||||
LengthChecker && checkLengthCallback = astar::DefaultLengthChecker())
|
||||
: ParamsBase(graph, startVertex, finalVertex, cancellable)
|
||||
, m_onVisitedVertexCallback(std::forward<Visitor>(onVisitedVertexCallback))
|
||||
, m_checkLengthCallback(std::forward<LengthChecker>(checkLengthCallback))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
Visitor m_onVisitedVertexCallback;
|
||||
LengthChecker const m_checkLengthCallback;
|
||||
@@ -117,8 +112,7 @@ public:
|
||||
LengthChecker && checkLengthCallback = astar::DefaultLengthChecker())
|
||||
: ParamsBase(graph, startVertex, finalVertex, m_dummy)
|
||||
, m_checkLengthCallback(std::forward<LengthChecker>(checkLengthCallback))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
astar::DefaultVisitor const m_onVisitedVertexCallback{};
|
||||
LengthChecker const m_checkLengthCallback;
|
||||
@@ -130,15 +124,9 @@ public:
|
||||
class Context final
|
||||
{
|
||||
public:
|
||||
Context(Graph & graph) : m_graph(graph)
|
||||
{
|
||||
m_graph.SetAStarParents(true /* forward */, m_parents);
|
||||
}
|
||||
Context(Graph & graph) : m_graph(graph) { m_graph.SetAStarParents(true /* forward */, m_parents); }
|
||||
|
||||
~Context()
|
||||
{
|
||||
m_graph.DropAStarParents();
|
||||
}
|
||||
~Context() { m_graph.DropAStarParents(); }
|
||||
|
||||
void Clear()
|
||||
{
|
||||
@@ -146,10 +134,7 @@ public:
|
||||
m_parents.clear();
|
||||
}
|
||||
|
||||
bool HasDistance(Vertex const & vertex) const
|
||||
{
|
||||
return m_distanceMap.find(vertex) != m_distanceMap.cend();
|
||||
}
|
||||
bool HasDistance(Vertex const & vertex) const { return m_distanceMap.find(vertex) != m_distanceMap.cend(); }
|
||||
|
||||
Weight GetDistance(Vertex const & vertex) const
|
||||
{
|
||||
@@ -160,20 +145,11 @@ public:
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void SetDistance(Vertex const & vertex, Weight const & distance)
|
||||
{
|
||||
m_distanceMap[vertex] = distance;
|
||||
}
|
||||
void SetDistance(Vertex const & vertex, Weight const & distance) { m_distanceMap[vertex] = distance; }
|
||||
|
||||
void SetParent(Vertex const & parent, Vertex const & child)
|
||||
{
|
||||
m_parents[parent] = child;
|
||||
}
|
||||
void SetParent(Vertex const & parent, Vertex const & child) { m_parents[parent] = child; }
|
||||
|
||||
bool HasParent(Vertex const & child) const
|
||||
{
|
||||
return m_parents.count(child) != 0;
|
||||
}
|
||||
bool HasParent(Vertex const & child) const { return m_parents.count(child) != 0; }
|
||||
|
||||
Vertex const & GetParent(Vertex const & child) const
|
||||
{
|
||||
@@ -194,15 +170,13 @@ public:
|
||||
|
||||
// VisitVertex returns true: wave will continue
|
||||
// VisitVertex returns false: wave will stop
|
||||
template <typename VisitVertex, typename AdjustEdgeWeight, typename FilterStates,
|
||||
typename ReducedToRealLength>
|
||||
template <typename VisitVertex, typename AdjustEdgeWeight, typename FilterStates, typename ReducedToRealLength>
|
||||
void PropagateWave(Graph & graph, Vertex const & startVertex, VisitVertex && visitVertex,
|
||||
AdjustEdgeWeight && adjustEdgeWeight, FilterStates && filterStates,
|
||||
ReducedToRealLength && reducedToRealLength, Context & context) const;
|
||||
|
||||
template <typename VisitVertex>
|
||||
void PropagateWave(Graph & graph, Vertex const & startVertex, VisitVertex && visitVertex,
|
||||
Context & context) const;
|
||||
void PropagateWave(Graph & graph, Vertex const & startVertex, VisitVertex && visitVertex, Context & context) const;
|
||||
|
||||
template <typename P>
|
||||
Result FindPath(P & params, RoutingResult<Vertex, Weight> & result) const;
|
||||
@@ -225,8 +199,7 @@ public:
|
||||
// Adjust route to the previous one.
|
||||
// Expects |params.m_checkLengthCallback| to check wave propagation limit.
|
||||
template <typename P>
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result AdjustRoute(P & params,
|
||||
std::vector<Edge> const & prevRoute,
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result AdjustRoute(P & params, std::vector<Edge> const & prevRoute,
|
||||
RoutingResult<Vertex, Weight> & result) const;
|
||||
|
||||
private:
|
||||
@@ -259,9 +232,10 @@ private:
|
||||
struct State
|
||||
{
|
||||
State(Vertex const & vertex, Weight const & distance, Weight const & heuristic)
|
||||
: vertex(vertex), distance(distance), heuristic(heuristic)
|
||||
{
|
||||
}
|
||||
: vertex(vertex)
|
||||
, distance(distance)
|
||||
, heuristic(heuristic)
|
||||
{}
|
||||
State(Vertex const & vertex, Weight const & distance) : State(vertex, distance, Weight()) {}
|
||||
|
||||
inline bool operator>(State const & rhs) const { return distance > rhs.distance; }
|
||||
@@ -278,22 +252,18 @@ private:
|
||||
{
|
||||
using Parents = typename Graph::Parents;
|
||||
|
||||
BidirectionalStepContext(bool forward, Vertex const & startVertex, Vertex const & finalVertex,
|
||||
Graph & graph)
|
||||
: forward(forward)
|
||||
, startVertex(startVertex)
|
||||
, finalVertex(finalVertex)
|
||||
, graph(graph)
|
||||
BidirectionalStepContext(bool forward, Vertex const & startVertex, Vertex const & finalVertex, Graph & graph)
|
||||
: forward(forward)
|
||||
, startVertex(startVertex)
|
||||
, finalVertex(finalVertex)
|
||||
, graph(graph)
|
||||
{
|
||||
bestVertex = forward ? startVertex : finalVertex;
|
||||
pS = ConsistentHeuristic(bestVertex);
|
||||
graph.SetAStarParents(forward, parent);
|
||||
}
|
||||
|
||||
~BidirectionalStepContext()
|
||||
{
|
||||
graph.DropAStarParents();
|
||||
}
|
||||
~BidirectionalStepContext() { graph.DropAStarParents(); }
|
||||
|
||||
Weight TopDistance() const
|
||||
{
|
||||
@@ -336,10 +306,7 @@ private:
|
||||
return it != bestDistance.end() && state.distance > it->second - eps;
|
||||
}
|
||||
|
||||
void UpdateDistance(State const & state)
|
||||
{
|
||||
bestDistance.insert_or_assign(state.vertex, state.distance);
|
||||
}
|
||||
void UpdateDistance(State const & state) { bestDistance.insert_or_assign(state.vertex, state.distance); }
|
||||
|
||||
std::optional<Weight> GetDistance(Vertex const & vertex) const
|
||||
{
|
||||
@@ -347,10 +314,7 @@ private:
|
||||
return it != bestDistance.cend() ? std::optional<Weight>(it->second) : std::nullopt;
|
||||
}
|
||||
|
||||
void UpdateParent(Vertex const & to, Vertex const & from)
|
||||
{
|
||||
parent.insert_or_assign(to, from);
|
||||
}
|
||||
void UpdateParent(Vertex const & to, Vertex const & from) { parent.insert_or_assign(to, from); }
|
||||
|
||||
void GetAdjacencyList(State const & state, typename Graph::EdgeListT & adj)
|
||||
{
|
||||
@@ -383,13 +347,12 @@ private:
|
||||
Weight pS;
|
||||
};
|
||||
|
||||
static void ReconstructPath(Vertex const & v,
|
||||
typename BidirectionalStepContext::Parents const & parent,
|
||||
static void ReconstructPath(Vertex const & v, typename BidirectionalStepContext::Parents const & parent,
|
||||
std::vector<Vertex> & path);
|
||||
static void ReconstructPathBidirectional(
|
||||
Vertex const & v, Vertex const & w,
|
||||
typename BidirectionalStepContext::Parents const & parentV,
|
||||
typename BidirectionalStepContext::Parents const & parentW, std::vector<Vertex> & path);
|
||||
static void ReconstructPathBidirectional(Vertex const & v, Vertex const & w,
|
||||
typename BidirectionalStepContext::Parents const & parentV,
|
||||
typename BidirectionalStepContext::Parents const & parentW,
|
||||
std::vector<Vertex> & path);
|
||||
};
|
||||
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
@@ -399,13 +362,12 @@ constexpr Weight AStarAlgorithm<Vertex, Edge, Weight>::kZeroDistance;
|
||||
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
template <typename VisitVertex, typename AdjustEdgeWeight, typename FilterStates, typename ReducedToFullLength>
|
||||
void AStarAlgorithm<Vertex, Edge, Weight>::PropagateWave(
|
||||
Graph & graph, Vertex const & startVertex,
|
||||
VisitVertex && visitVertex,
|
||||
AdjustEdgeWeight && adjustEdgeWeight,
|
||||
FilterStates && filterStates,
|
||||
ReducedToFullLength && reducedToFullLength,
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::Context & context) const
|
||||
void AStarAlgorithm<Vertex, Edge, Weight>::PropagateWave(Graph & graph, Vertex const & startVertex,
|
||||
VisitVertex && visitVertex,
|
||||
AdjustEdgeWeight && adjustEdgeWeight,
|
||||
FilterStates && filterStates,
|
||||
ReducedToFullLength && reducedToFullLength,
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::Context & context) const
|
||||
{
|
||||
auto const epsilon = graph.GetAStarWeightEpsilon();
|
||||
|
||||
@@ -457,17 +419,14 @@ void AStarAlgorithm<Vertex, Edge, Weight>::PropagateWave(
|
||||
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
template <typename VisitVertex>
|
||||
void AStarAlgorithm<Vertex, Edge, Weight>::PropagateWave(
|
||||
Graph & graph, Vertex const & startVertex, VisitVertex && visitVertex,
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::Context & context) const
|
||||
void AStarAlgorithm<Vertex, Edge, Weight>::PropagateWave(Graph & graph, Vertex const & startVertex,
|
||||
VisitVertex && visitVertex,
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::Context & context) const
|
||||
{
|
||||
auto const adjustEdgeWeight = [](Vertex const & /* vertex */, Edge const & edge) {
|
||||
return edge.GetWeight();
|
||||
};
|
||||
auto const adjustEdgeWeight = [](Vertex const & /* vertex */, Edge const & edge) { return edge.GetWeight(); };
|
||||
auto const filterStates = [](State const & /* state */) { return true; };
|
||||
auto const reducedToRealLength = [](State const & state) { return state.distance; };
|
||||
PropagateWave(graph, startVertex, visitVertex, adjustEdgeWeight, filterStates,
|
||||
reducedToRealLength, context);
|
||||
PropagateWave(graph, startVertex, visitVertex, adjustEdgeWeight, filterStates, reducedToRealLength, context);
|
||||
}
|
||||
|
||||
// This implementation is based on the view that the A* algorithm
|
||||
@@ -488,8 +447,8 @@ void AStarAlgorithm<Vertex, Edge, Weight>::PropagateWave(
|
||||
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
template <typename P>
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::FindPath(P & params, RoutingResult<Vertex, Weight> & result) const
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result AStarAlgorithm<Vertex, Edge, Weight>::FindPath(
|
||||
P & params, RoutingResult<Vertex, Weight> & result) const
|
||||
{
|
||||
auto const epsilon = params.m_weightEpsilon;
|
||||
|
||||
@@ -503,22 +462,17 @@ AStarAlgorithm<Vertex, Edge, Weight>::FindPath(P & params, RoutingResult<Vertex,
|
||||
PeriodicPollCancellable periodicCancellable(params.m_cancellable);
|
||||
Result resultCode = Result::NoPath;
|
||||
|
||||
auto const heuristicDiff = [&](Vertex const & vertexFrom, Vertex const & vertexTo) {
|
||||
return graph.HeuristicCostEstimate(vertexFrom, finalVertex) -
|
||||
graph.HeuristicCostEstimate(vertexTo, finalVertex);
|
||||
};
|
||||
auto const heuristicDiff = [&](Vertex const & vertexFrom, Vertex const & vertexTo)
|
||||
{ return graph.HeuristicCostEstimate(vertexFrom, finalVertex) - graph.HeuristicCostEstimate(vertexTo, finalVertex); };
|
||||
|
||||
auto const fullToReducedLength = [&](Vertex const & vertexFrom, Vertex const & vertexTo,
|
||||
Weight const length) {
|
||||
return length - heuristicDiff(vertexFrom, vertexTo);
|
||||
};
|
||||
auto const fullToReducedLength = [&](Vertex const & vertexFrom, Vertex const & vertexTo, Weight const length)
|
||||
{ return length - heuristicDiff(vertexFrom, vertexTo); };
|
||||
|
||||
auto const reducedToFullLength = [&](Vertex const & vertexFrom, Vertex const & vertexTo,
|
||||
Weight const reducedLength) {
|
||||
return reducedLength + heuristicDiff(vertexFrom, vertexTo);
|
||||
};
|
||||
auto const reducedToFullLength = [&](Vertex const & vertexFrom, Vertex const & vertexTo, Weight const reducedLength)
|
||||
{ return reducedLength + heuristicDiff(vertexFrom, vertexTo); };
|
||||
|
||||
auto visitVertex = [&](Vertex const & vertex) {
|
||||
auto visitVertex = [&](Vertex const & vertex)
|
||||
{
|
||||
if (periodicCancellable.IsCancelled())
|
||||
{
|
||||
resultCode = Result::Cancelled;
|
||||
@@ -536,7 +490,8 @@ AStarAlgorithm<Vertex, Edge, Weight>::FindPath(P & params, RoutingResult<Vertex,
|
||||
return true;
|
||||
};
|
||||
|
||||
auto const adjustEdgeWeight = [&](Vertex const & vertexV, Edge const & edge) {
|
||||
auto const adjustEdgeWeight = [&](Vertex const & vertexV, Edge const & edge)
|
||||
{
|
||||
auto const reducedWeight = fullToReducedLength(vertexV, edge.GetTarget(), edge.GetWeight());
|
||||
|
||||
CHECK_GREATER_OR_EQUAL(reducedWeight, -epsilon, ("Invariant violated."));
|
||||
@@ -544,22 +499,18 @@ AStarAlgorithm<Vertex, Edge, Weight>::FindPath(P & params, RoutingResult<Vertex,
|
||||
return std::max(reducedWeight, kZeroDistance);
|
||||
};
|
||||
|
||||
auto const reducedToRealLength = [&](State const & state) {
|
||||
return reducedToFullLength(startVertex, state.vertex, state.distance);
|
||||
};
|
||||
auto const reducedToRealLength = [&](State const & state)
|
||||
{ return reducedToFullLength(startVertex, state.vertex, state.distance); };
|
||||
|
||||
auto const filterStates = [&](State const & state) {
|
||||
return params.m_checkLengthCallback(reducedToRealLength(state));
|
||||
};
|
||||
auto const filterStates = [&](State const & state)
|
||||
{ return params.m_checkLengthCallback(reducedToRealLength(state)); };
|
||||
|
||||
PropagateWave(graph, startVertex, visitVertex, adjustEdgeWeight, filterStates,
|
||||
reducedToRealLength, context);
|
||||
PropagateWave(graph, startVertex, visitVertex, adjustEdgeWeight, filterStates, reducedToRealLength, context);
|
||||
|
||||
if (resultCode == Result::OK)
|
||||
{
|
||||
context.ReconstructPath(finalVertex, result.m_path);
|
||||
result.m_distance =
|
||||
reducedToFullLength(startVertex, finalVertex, context.GetDistance(finalVertex));
|
||||
result.m_distance = reducedToFullLength(startVertex, finalVertex, context.GetDistance(finalVertex));
|
||||
|
||||
if (!params.m_checkLengthCallback(result.m_distance))
|
||||
resultCode = Result::NoPath;
|
||||
@@ -570,8 +521,8 @@ AStarAlgorithm<Vertex, Edge, Weight>::FindPath(P & params, RoutingResult<Vertex,
|
||||
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
template <class P, class Emitter>
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::FindPathBidirectionalEx(P & params, Emitter && emitter) const
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result AStarAlgorithm<Vertex, Edge, Weight>::FindPathBidirectionalEx(
|
||||
P & params, Emitter && emitter) const
|
||||
{
|
||||
auto const epsilon = params.m_weightEpsilon;
|
||||
auto & graph = params.m_graph;
|
||||
@@ -605,7 +556,7 @@ AStarAlgorithm<Vertex, Edge, Weight>::FindPathBidirectionalEx(P & params, Emitte
|
||||
{
|
||||
// No problem if length check fails, but we still emit the result.
|
||||
// Happens with "transit" route because of length, haven't seen with regular car route.
|
||||
//ASSERT(params.m_checkLengthCallback(bestPathRealLength), ());
|
||||
// ASSERT(params.m_checkLengthCallback(bestPathRealLength), ());
|
||||
|
||||
RoutingResult<Vertex, Weight> result;
|
||||
ReconstructPathBidirectional(cur->bestVertex, nxt->bestVertex, cur->parent, nxt->parent, result.m_path);
|
||||
@@ -684,8 +635,8 @@ AStarAlgorithm<Vertex, Edge, Weight>::FindPathBidirectionalEx(P & params, Emitte
|
||||
if (reducedWeight < -epsilon && params.m_badReducedWeight(reducedWeight, std::max(pW, pV)))
|
||||
{
|
||||
// Break in Debug, log in Release and safe continue: std::max(reducedWeight, kZeroDistance).
|
||||
LOG(LERROR, ("Invariant violated for:", "v =", stateV.vertex, "w =", stateW.vertex,
|
||||
"reduced weight =", reducedWeight));
|
||||
LOG(LERROR,
|
||||
("Invariant violated for:", "v =", stateV.vertex, "w =", stateW.vertex, "reduced weight =", reducedWeight));
|
||||
}
|
||||
|
||||
stateW.distance = stateV.distance + std::max(reducedWeight, kZeroDistance);
|
||||
@@ -739,10 +690,8 @@ AStarAlgorithm<Vertex, Edge, Weight>::FindPathBidirectionalEx(P & params, Emitte
|
||||
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
template <typename P>
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::AdjustRoute(P & params,
|
||||
std::vector<Edge> const & prevRoute,
|
||||
RoutingResult<Vertex, Weight> & result) const
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result AStarAlgorithm<Vertex, Edge, Weight>::AdjustRoute(
|
||||
P & params, std::vector<Edge> const & prevRoute, RoutingResult<Vertex, Weight> & result) const
|
||||
{
|
||||
auto & graph = params.m_graph;
|
||||
auto const & startVertex = params.m_startVertex;
|
||||
@@ -766,8 +715,8 @@ AStarAlgorithm<Vertex, Edge, Weight>::AdjustRoute(P & params,
|
||||
Context context(graph);
|
||||
PeriodicPollCancellable periodicCancellable(params.m_cancellable);
|
||||
|
||||
auto visitVertex = [&](Vertex const & vertex) {
|
||||
|
||||
auto visitVertex = [&](Vertex const & vertex)
|
||||
{
|
||||
if (periodicCancellable.IsCancelled())
|
||||
{
|
||||
wasCancelled = true;
|
||||
@@ -790,18 +739,13 @@ AStarAlgorithm<Vertex, Edge, Weight>::AdjustRoute(P & params,
|
||||
return true;
|
||||
};
|
||||
|
||||
auto const adjustEdgeWeight = [](Vertex const & /* vertex */, Edge const & edge) {
|
||||
return edge.GetWeight();
|
||||
};
|
||||
auto const adjustEdgeWeight = [](Vertex const & /* vertex */, Edge const & edge) { return edge.GetWeight(); };
|
||||
|
||||
auto const filterStates = [&](State const & state) {
|
||||
return params.m_checkLengthCallback(state.distance);
|
||||
};
|
||||
auto const filterStates = [&](State const & state) { return params.m_checkLengthCallback(state.distance); };
|
||||
|
||||
auto const reducedToRealLength = [&](State const & state) { return state.distance; };
|
||||
|
||||
PropagateWave(graph, startVertex, visitVertex, adjustEdgeWeight, filterStates,
|
||||
reducedToRealLength, context);
|
||||
PropagateWave(graph, startVertex, visitVertex, adjustEdgeWeight, filterStates, reducedToRealLength, context);
|
||||
if (wasCancelled)
|
||||
return Result::Cancelled;
|
||||
|
||||
@@ -824,8 +768,7 @@ AStarAlgorithm<Vertex, Edge, Weight>::AdjustRoute(P & params,
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(found, ("Can't find", returnVertex, ", prev:", prevRoute.size(),
|
||||
", adjust:", result.m_path.size()));
|
||||
CHECK(found, ("Can't find", returnVertex, ", prev:", prevRoute.size(), ", adjust:", result.m_path.size()));
|
||||
|
||||
auto const & it = remainingDistances.find(returnVertex);
|
||||
CHECK(it != remainingDistances.end(), ());
|
||||
@@ -835,9 +778,9 @@ AStarAlgorithm<Vertex, Edge, Weight>::AdjustRoute(P & params,
|
||||
|
||||
// static
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
void AStarAlgorithm<Vertex, Edge, Weight>::ReconstructPath(
|
||||
Vertex const & v, typename BidirectionalStepContext::Parents const & parent,
|
||||
std::vector<Vertex> & path)
|
||||
void AStarAlgorithm<Vertex, Edge, Weight>::ReconstructPath(Vertex const & v,
|
||||
typename BidirectionalStepContext::Parents const & parent,
|
||||
std::vector<Vertex> & path)
|
||||
{
|
||||
path.clear();
|
||||
Vertex cur = v;
|
||||
@@ -870,9 +813,7 @@ void AStarAlgorithm<Vertex, Edge, Weight>::ReconstructPathBidirectional(
|
||||
}
|
||||
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
void
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::Context::ReconstructPath(Vertex const & v,
|
||||
std::vector<Vertex> & path) const
|
||||
void AStarAlgorithm<Vertex, Edge, Weight>::Context::ReconstructPath(Vertex const & v, std::vector<Vertex> & path) const
|
||||
{
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::ReconstructPath(v, m_parents, path);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "routing/base/astar_weight.hpp"
|
||||
#include "routing/base/astar_vertex_data.hpp"
|
||||
#include "routing/base/astar_weight.hpp"
|
||||
#include "routing/base/small_list.hpp"
|
||||
|
||||
#include "base/buffer_vector.hpp"
|
||||
@@ -27,15 +27,12 @@ public:
|
||||
|
||||
virtual Weight HeuristicCostEstimate(Vertex const & from, Vertex const & to) = 0;
|
||||
|
||||
virtual void GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges) = 0;
|
||||
virtual void GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges) = 0;
|
||||
virtual void GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges) = 0;
|
||||
virtual void GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges) = 0;
|
||||
|
||||
virtual void SetAStarParents(bool forward, Parents & parents);
|
||||
virtual void DropAStarParents();
|
||||
virtual bool AreWavesConnectible(Parents & forwardParents, Vertex const & commonVertex,
|
||||
Parents & backwardParents);
|
||||
virtual bool AreWavesConnectible(Parents & forwardParents, Vertex const & commonVertex, Parents & backwardParents);
|
||||
|
||||
virtual Weight GetAStarWeightEpsilon();
|
||||
|
||||
@@ -43,11 +40,12 @@ public:
|
||||
};
|
||||
|
||||
template <typename VertexType, typename EdgeType, typename WeightType>
|
||||
void AStarGraph<VertexType, EdgeType, WeightType>::SetAStarParents(bool /* forward */,
|
||||
Parents & /* parents */) {}
|
||||
void AStarGraph<VertexType, EdgeType, WeightType>::SetAStarParents(bool /* forward */, Parents & /* parents */)
|
||||
{}
|
||||
|
||||
template <typename VertexType, typename EdgeType, typename WeightType>
|
||||
void AStarGraph<VertexType, EdgeType, WeightType>::DropAStarParents() {}
|
||||
void AStarGraph<VertexType, EdgeType, WeightType>::DropAStarParents()
|
||||
{}
|
||||
|
||||
template <typename VertexType, typename EdgeType, typename WeightType>
|
||||
bool AStarGraph<VertexType, EdgeType, WeightType>::AreWavesConnectible(AStarGraph::Parents & /* forwardParents */,
|
||||
|
||||
@@ -19,9 +19,10 @@ double AStarSubProgress::CalcDistance(ms::LatLon const & from, ms::LatLon const
|
||||
return fabs(from.m_lon - to.m_lon) + fabs(from.m_lat - to.m_lat);
|
||||
}
|
||||
|
||||
AStarSubProgress::AStarSubProgress(ms::LatLon const & start, ms::LatLon const & finish,
|
||||
double contributionCoef)
|
||||
: m_contributionCoef(contributionCoef), m_startPoint(start), m_finishPoint(finish)
|
||||
AStarSubProgress::AStarSubProgress(ms::LatLon const & start, ms::LatLon const & finish, double contributionCoef)
|
||||
: m_contributionCoef(contributionCoef)
|
||||
, m_startPoint(start)
|
||||
, m_finishPoint(finish)
|
||||
{
|
||||
ASSERT_GREATER(m_contributionCoef, 0.0, ());
|
||||
|
||||
@@ -30,8 +31,7 @@ AStarSubProgress::AStarSubProgress(ms::LatLon const & start, ms::LatLon const &
|
||||
m_backwardDistance = m_fullDistance;
|
||||
}
|
||||
|
||||
AStarSubProgress::AStarSubProgress(double contributionCoef)
|
||||
: m_contributionCoef(contributionCoef)
|
||||
AStarSubProgress::AStarSubProgress(double contributionCoef) : m_contributionCoef(contributionCoef)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(m_contributionCoef, 0.0, ());
|
||||
}
|
||||
@@ -49,7 +49,7 @@ double AStarSubProgress::UpdateProgress(ms::LatLon const & current, ms::LatLon c
|
||||
|
||||
double part = 2.0 - (m_forwardDistance + m_backwardDistance) / m_fullDistance;
|
||||
part = math::Clamp(part, 0.0, 1.0);
|
||||
double const newProgress = m_contributionCoef * part;
|
||||
double const newProgress = m_contributionCoef * part;
|
||||
|
||||
m_currentProgress = std::max(newProgress, m_currentProgress);
|
||||
return m_currentProgress;
|
||||
@@ -65,7 +65,10 @@ void AStarSubProgress::Flush(double progress)
|
||||
m_currentProgress += m_contributionCoef * progress;
|
||||
}
|
||||
|
||||
double AStarSubProgress::GetMaxContribution() const { return m_contributionCoef; }
|
||||
double AStarSubProgress::GetMaxContribution() const
|
||||
{
|
||||
return m_contributionCoef;
|
||||
}
|
||||
|
||||
// AStarProgress -------------------------------------------------------------------------
|
||||
|
||||
@@ -107,18 +110,19 @@ double AStarProgress::UpdateProgress(ms::LatLon const & current, ms::LatLon cons
|
||||
double const newProgress = UpdateProgressImpl(m_subProgresses.begin(), current, end) * 100.0;
|
||||
m_lastPercentValue = std::max(m_lastPercentValue, newProgress);
|
||||
|
||||
ASSERT(m_lastPercentValue < kMaxPercent ||
|
||||
AlmostEqualAbs(m_lastPercentValue, kMaxPercent, 1e-5 /* eps */),
|
||||
ASSERT(m_lastPercentValue < kMaxPercent || AlmostEqualAbs(m_lastPercentValue, kMaxPercent, 1e-5 /* eps */),
|
||||
(m_lastPercentValue, kMaxPercent));
|
||||
|
||||
m_lastPercentValue = std::min(m_lastPercentValue, kMaxPercent);
|
||||
return m_lastPercentValue;
|
||||
}
|
||||
|
||||
double AStarProgress::GetLastPercent() const { return m_lastPercentValue; }
|
||||
double AStarProgress::GetLastPercent() const
|
||||
{
|
||||
return m_lastPercentValue;
|
||||
}
|
||||
|
||||
double AStarProgress::UpdateProgressImpl(ListItem subProgress, ms::LatLon const & current,
|
||||
ms::LatLon const & end)
|
||||
double AStarProgress::UpdateProgressImpl(ListItem subProgress, ms::LatLon const & current, ms::LatLon const & end)
|
||||
{
|
||||
if (std::next(subProgress) != m_subProgresses.end())
|
||||
return subProgress->UpdateProgress(UpdateProgressImpl(std::next(subProgress), current, end));
|
||||
|
||||
@@ -53,8 +53,7 @@ public:
|
||||
private:
|
||||
using ListItem = std::list<AStarSubProgress>::iterator;
|
||||
|
||||
double UpdateProgressImpl(ListItem subProgress, ms::LatLon const & current,
|
||||
ms::LatLon const & end);
|
||||
double UpdateProgressImpl(ListItem subProgress, ms::LatLon const & current, ms::LatLon const & end);
|
||||
|
||||
// This value is in range: [0, 1].
|
||||
double m_lastPercentValue = 0.0;
|
||||
|
||||
@@ -7,12 +7,9 @@ struct VertexData
|
||||
{
|
||||
static VertexData Zero() { return VertexData(Vertex(), Weight()); }
|
||||
|
||||
VertexData(Vertex const & vertex, Weight const & realDistance)
|
||||
: m_vertex(vertex), m_realDistance(realDistance)
|
||||
{
|
||||
}
|
||||
VertexData(Vertex const & vertex, Weight const & realDistance) : m_vertex(vertex), m_realDistance(realDistance) {}
|
||||
|
||||
Vertex m_vertex;
|
||||
Weight m_realDistance;
|
||||
};
|
||||
} // namespace routing
|
||||
} // namespace routing::astar
|
||||
|
||||
@@ -27,10 +27,9 @@ public:
|
||||
Vertex m_parent;
|
||||
};
|
||||
|
||||
explicit BFS(Graph & graph): m_graph(graph) {}
|
||||
explicit BFS(Graph & graph) : m_graph(graph) {}
|
||||
|
||||
void Run(Vertex const & start, bool isOutgoing,
|
||||
std::function<bool(State const &)> && onVisitCallback);
|
||||
void Run(Vertex const & start, bool isOutgoing, std::function<bool(State const &)> && onVisitCallback);
|
||||
|
||||
std::vector<Vertex> ReconstructPath(Vertex from, bool reverse);
|
||||
|
||||
@@ -40,15 +39,12 @@ private:
|
||||
};
|
||||
|
||||
template <typename Graph>
|
||||
void BFS<Graph>::Run(Vertex const & start, bool isOutgoing,
|
||||
std::function<bool(State const &)> && onVisitCallback)
|
||||
void BFS<Graph>::Run(Vertex const & start, bool isOutgoing, std::function<bool(State const &)> && onVisitCallback)
|
||||
{
|
||||
m_parents.clear();
|
||||
|
||||
m_parents.emplace(start, start);
|
||||
SCOPE_GUARD(removeStart, [&]() {
|
||||
m_parents.erase(start);
|
||||
});
|
||||
SCOPE_GUARD(removeStart, [&]() { m_parents.erase(start); });
|
||||
|
||||
std::queue<Vertex> queue;
|
||||
queue.emplace(start);
|
||||
|
||||
@@ -41,9 +41,8 @@ double FollowedPolyline::GetDistanceM(Iter const & it1, Iter const & it2) const
|
||||
if (it1.m_ind == it2.m_ind)
|
||||
return mercator::DistanceOnEarth(it1.m_pt, it2.m_pt);
|
||||
|
||||
return (mercator::DistanceOnEarth(it1.m_pt, m_poly.GetPoint(it1.m_ind + 1)) +
|
||||
m_segDistance[it2.m_ind - 1] - m_segDistance[it1.m_ind] +
|
||||
mercator::DistanceOnEarth(m_poly.GetPoint(it2.m_ind), it2.m_pt));
|
||||
return (mercator::DistanceOnEarth(it1.m_pt, m_poly.GetPoint(it1.m_ind + 1)) + m_segDistance[it2.m_ind - 1] -
|
||||
m_segDistance[it1.m_ind] + mercator::DistanceOnEarth(m_poly.GetPoint(it2.m_ind), it2.m_pt));
|
||||
}
|
||||
|
||||
double FollowedPolyline::GetTotalDistanceMeters() const
|
||||
@@ -115,16 +114,14 @@ bool FollowedPolyline::IsFakeSegment(size_t index) const
|
||||
}
|
||||
|
||||
template <class DistanceFn>
|
||||
Iter FollowedPolyline::GetBestProjection(m2::RectD const & posRect,
|
||||
DistanceFn const & distFn) const
|
||||
Iter FollowedPolyline::GetBestProjection(m2::RectD const & posRect, DistanceFn const & distFn) const
|
||||
{
|
||||
CHECK_EQUAL(m_segProj.size() + 1, m_poly.GetSize(), ());
|
||||
// At first trying to find a projection to two closest route segments of route which is close
|
||||
// enough to |posRect| center. If |m_current| is right before intermediate point we can get |closestIter|
|
||||
// right after intermediate point (in next subroute).
|
||||
size_t const hoppingBorderIdx = min(m_segProj.size(), m_current.m_ind + 2);
|
||||
Iter const closestIter =
|
||||
GetClosestProjectionInInterval(posRect, distFn, m_current.m_ind, hoppingBorderIdx);
|
||||
Iter const closestIter = GetClosestProjectionInInterval(posRect, distFn, m_current.m_ind, hoppingBorderIdx);
|
||||
if (closestIter.IsValid())
|
||||
return closestIter;
|
||||
|
||||
@@ -139,8 +136,7 @@ Iter FollowedPolyline::GetBestMatchingProjection(m2::RectD const & posRect) cons
|
||||
// At first trying to find a projection to two closest route segments of route which is close
|
||||
// enough to |posRect| center. If |m_current| is right before intermediate point we can get |iter|
|
||||
// right after intermediate point (in next subroute).
|
||||
size_t const hoppingBorderIdx =
|
||||
min(m_nextCheckpointIndex, min(m_segProj.size(), m_current.m_ind + 3));
|
||||
size_t const hoppingBorderIdx = min(m_nextCheckpointIndex, min(m_segProj.size(), m_current.m_ind + 3));
|
||||
auto const iter = GetClosestMatchingProjectionInInterval(posRect, m_current.m_ind, hoppingBorderIdx);
|
||||
if (iter.IsValid())
|
||||
return iter;
|
||||
@@ -172,10 +168,7 @@ Iter FollowedPolyline::UpdateProjection(m2::RectD const & posRect)
|
||||
|
||||
Iter res;
|
||||
m2::PointD const currPos = posRect.Center();
|
||||
res = GetBestProjection(posRect, [&](Iter const & it)
|
||||
{
|
||||
return mercator::DistanceOnEarth(it.m_pt, currPos);
|
||||
});
|
||||
res = GetBestProjection(posRect, [&](Iter const & it) { return mercator::DistanceOnEarth(it.m_pt, currPos); });
|
||||
|
||||
if (res.IsValid())
|
||||
m_current = res;
|
||||
@@ -210,16 +203,14 @@ void FollowedPolyline::GetCurrentDirectionPoint(m2::PointD & pt, double toleranc
|
||||
size_t currentIndex = min(m_current.m_ind + 1, m_poly.GetSize() - 1);
|
||||
m2::PointD point = m_poly.GetPoint(currentIndex);
|
||||
for (; currentIndex < m_poly.GetSize() - 1; point = m_poly.GetPoint(++currentIndex))
|
||||
{
|
||||
if (mercator::DistanceOnEarth(point, m_current.m_pt) > toleranceM)
|
||||
break;
|
||||
}
|
||||
|
||||
pt = point;
|
||||
}
|
||||
|
||||
Iter FollowedPolyline::GetClosestMatchingProjectionInInterval(m2::RectD const & posRect,
|
||||
size_t startIdx, size_t endIdx) const
|
||||
Iter FollowedPolyline::GetClosestMatchingProjectionInInterval(m2::RectD const & posRect, size_t startIdx,
|
||||
size_t endIdx) const
|
||||
{
|
||||
CHECK_LESS_OR_EQUAL(endIdx, m_segProj.size(), ());
|
||||
CHECK_LESS_OR_EQUAL(startIdx, endIdx, ());
|
||||
|
||||
@@ -93,8 +93,8 @@ public:
|
||||
/// \param endIdx The index after the last one in |m_segProj|.
|
||||
/// \returns iterator which contains projection point and projection segment index.
|
||||
template <typename DistanceFn>
|
||||
Iter GetClosestProjectionInInterval(m2::RectD const & posRect, DistanceFn const & distFn,
|
||||
size_t startIdx, size_t endIdx) const
|
||||
Iter GetClosestProjectionInInterval(m2::RectD const & posRect, DistanceFn const & distFn, size_t startIdx,
|
||||
size_t endIdx) const
|
||||
{
|
||||
CHECK_LESS_OR_EQUAL(endIdx, m_segProj.size(), ());
|
||||
CHECK_LESS_OR_EQUAL(startIdx, endIdx, ());
|
||||
@@ -121,8 +121,7 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
Iter GetClosestMatchingProjectionInInterval(m2::RectD const & posRect, size_t startIdx,
|
||||
size_t endIdx) const;
|
||||
Iter GetClosestMatchingProjectionInInterval(m2::RectD const & posRect, size_t startIdx, size_t endIdx) const;
|
||||
|
||||
bool IsFakeSegment(size_t index) const;
|
||||
|
||||
|
||||
@@ -24,10 +24,7 @@ struct RoutingResult final
|
||||
|
||||
struct LessWeight
|
||||
{
|
||||
bool operator() (RoutingResult const & l, RoutingResult const & r) const
|
||||
{
|
||||
return l.m_distance < r.m_distance;
|
||||
}
|
||||
bool operator()(RoutingResult const & l, RoutingResult const & r) const { return l.m_distance < r.m_distance; }
|
||||
};
|
||||
};
|
||||
} // namespace routing
|
||||
|
||||
@@ -20,8 +20,9 @@ void Statistics::Add(char const * name, size_t val)
|
||||
void Statistics::Dump()
|
||||
{
|
||||
for (auto const & e : s_map)
|
||||
LOG(LINFO, (e.first, ": count = ", e.second.m_count, "; max = ", e.second.m_max, "; avg = ", e.second.m_sum / double(e.second.m_count)));
|
||||
LOG(LINFO, (e.first, ": count = ", e.second.m_count, "; max = ", e.second.m_max,
|
||||
"; avg = ", e.second.m_sum / double(e.second.m_count)));
|
||||
}
|
||||
|
||||
} // namespace impl
|
||||
} // namesapce routing
|
||||
} // namespace impl
|
||||
} // namespace routing
|
||||
|
||||
@@ -24,9 +24,10 @@ public:
|
||||
static void Dump();
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
} // namespace impl
|
||||
|
||||
template <class T> class SmallList : public buffer_vector<T, 8>
|
||||
template <class T>
|
||||
class SmallList : public buffer_vector<T, 8>
|
||||
{
|
||||
using BaseT = buffer_vector<T, 8>;
|
||||
|
||||
@@ -54,4 +55,4 @@ inline std::string DebugPrint(SmallList<T> const & v)
|
||||
return DebugPrint(static_cast<buffer_vector<T, 8> const &>(v));
|
||||
}
|
||||
|
||||
} // namesapce routing
|
||||
} // namespace routing
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "geometry/angles.hpp"
|
||||
|
||||
|
||||
namespace routing
|
||||
{
|
||||
using namespace std;
|
||||
@@ -15,8 +14,7 @@ using namespace ftypes;
|
||||
|
||||
CarDirectionsEngine::CarDirectionsEngine(MwmDataSource & dataSource, shared_ptr<NumMwmIds> numMwmIds)
|
||||
: DirectionsEngine(dataSource, std::move(numMwmIds))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void CarDirectionsEngine::FixupTurns(vector<RouteSegment> & routeSegments)
|
||||
{
|
||||
@@ -40,19 +38,21 @@ void FixupCarTurns(vector<RouteSegment> & routeSegments)
|
||||
if (t.IsTurnNone())
|
||||
continue;
|
||||
|
||||
if (enterRoundAbout != kInvalidEnter && t.m_turn != CarDirection::StayOnRoundAbout
|
||||
&& t.m_turn != CarDirection::LeaveRoundAbout && t.m_turn != CarDirection::ReachedYourDestination)
|
||||
if (enterRoundAbout != kInvalidEnter && t.m_turn != CarDirection::StayOnRoundAbout &&
|
||||
t.m_turn != CarDirection::LeaveRoundAbout && t.m_turn != CarDirection::ReachedYourDestination)
|
||||
{
|
||||
ASSERT(false, ("Only StayOnRoundAbout, LeaveRoundAbout or ReachedYourDestination are expected after EnterRoundAbout."));
|
||||
ASSERT(false,
|
||||
("Only StayOnRoundAbout, LeaveRoundAbout or ReachedYourDestination are expected after EnterRoundAbout."));
|
||||
exitNum = 0;
|
||||
enterRoundAbout = kInvalidEnter;
|
||||
}
|
||||
else if (t.m_turn == CarDirection::EnterRoundAbout)
|
||||
{
|
||||
ASSERT(enterRoundAbout == kInvalidEnter, ("It's not expected to find new EnterRoundAbout until previous EnterRoundAbout was leaved."));
|
||||
ASSERT(enterRoundAbout == kInvalidEnter,
|
||||
("It's not expected to find new EnterRoundAbout until previous EnterRoundAbout was leaved."));
|
||||
enterRoundAbout = idx;
|
||||
ASSERT(exitNum == 0, ("exitNum is reset at start and after LeaveRoundAbout."));
|
||||
exitNum = t.m_exitNum; // Normally it is 0, but sometimes it can be 1.
|
||||
exitNum = t.m_exitNum; // Normally it is 0, but sometimes it can be 1.
|
||||
}
|
||||
else if (t.m_turn == CarDirection::StayOnRoundAbout)
|
||||
{
|
||||
@@ -66,7 +66,7 @@ void FixupCarTurns(vector<RouteSegment> & routeSegments)
|
||||
// if route calculation started at roundabout (e.g. if user made full turn on roundabout).
|
||||
if (enterRoundAbout != kInvalidEnter)
|
||||
routeSegments[enterRoundAbout].SetTurnExits(exitNum + 1);
|
||||
routeSegments[idx].SetTurnExits(exitNum + 1); // For LeaveRoundAbout turn.
|
||||
routeSegments[idx].SetTurnExits(exitNum + 1); // For LeaveRoundAbout turn.
|
||||
enterRoundAbout = kInvalidEnter;
|
||||
exitNum = 0;
|
||||
}
|
||||
@@ -75,8 +75,7 @@ void FixupCarTurns(vector<RouteSegment> & routeSegments)
|
||||
// distance(turnsDir[idx - 1].m_index, turnsDir[idx].m_index) < kMergeDistMeters
|
||||
// means the distance in meters between the former turn (idx - 1)
|
||||
// and the current turn (idx).
|
||||
if (idx > 0 && IsStayOnRoad(routeSegments[idx - 1].GetTurn().m_turn) &&
|
||||
IsLeftOrRightTurn(t.m_turn))
|
||||
if (idx > 0 && IsStayOnRoad(routeSegments[idx - 1].GetTurn().m_turn) && IsLeftOrRightTurn(t.m_turn))
|
||||
{
|
||||
auto const & junction = routeSegments[idx].GetJunction();
|
||||
auto const & prevJunction = routeSegments[idx - 1].GetJunction();
|
||||
@@ -88,12 +87,11 @@ void FixupCarTurns(vector<RouteSegment> & routeSegments)
|
||||
}
|
||||
|
||||
void GetTurnDirectionBasic(IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings,
|
||||
TurnItem & turn);
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings, TurnItem & turn);
|
||||
|
||||
size_t CarDirectionsEngine::GetTurnDirection(IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds,
|
||||
RoutingSettings const & vehicleSettings, TurnItem & turnItem)
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings,
|
||||
TurnItem & turnItem)
|
||||
{
|
||||
if (outgoingSegmentIndex == result.GetSegments().size())
|
||||
{
|
||||
@@ -104,8 +102,9 @@ size_t CarDirectionsEngine::GetTurnDirection(IRoutingResult const & result, size
|
||||
// This is for jump from initial point to start of the route. No direction is given.
|
||||
/// @todo Sometimes results of GetPossibleTurns are empty, sometimes are invalid.
|
||||
/// The best will be to fix GetPossibleTurns(). It will allow us to use following approach.
|
||||
/// E.g. Google Maps until you reach the destination will guide you to go to the left or to the right of the first road.
|
||||
if (outgoingSegmentIndex == 2) // The same as turnItem.m_index == 2.
|
||||
/// E.g. Google Maps until you reach the destination will guide you to go to the left or to the right of the first
|
||||
/// road.
|
||||
if (outgoingSegmentIndex == 2) // The same as turnItem.m_index == 2.
|
||||
return 0;
|
||||
|
||||
size_t skipTurnSegments = CheckUTurnOnRoute(result, outgoingSegmentIndex, numMwmIds, vehicleSettings, turnItem);
|
||||
@@ -163,8 +162,8 @@ CarDirection GetRoundaboutDirectionBasic(bool isIngoingEdgeRoundabout, bool isOu
|
||||
/*!
|
||||
* \brief Returns false when other possible turns leads to service roads;
|
||||
*/
|
||||
bool KeepRoundaboutTurnByHighwayClass(TurnCandidates const & possibleTurns,
|
||||
TurnInfo const & turnInfo, NumMwmIds const & numMwmIds)
|
||||
bool KeepRoundaboutTurnByHighwayClass(TurnCandidates const & possibleTurns, TurnInfo const & turnInfo,
|
||||
NumMwmIds const & numMwmIds)
|
||||
{
|
||||
Segment firstOutgoingSegment;
|
||||
turnInfo.m_outgoing->m_segmentRange.GetFirstSegment(numMwmIds, firstOutgoingSegment);
|
||||
@@ -181,11 +180,12 @@ bool KeepRoundaboutTurnByHighwayClass(TurnCandidates const & possibleTurns,
|
||||
return false;
|
||||
}
|
||||
|
||||
CarDirection GetRoundaboutDirection(TurnInfo const & turnInfo, TurnCandidates const & nodes, NumMwmIds const & numMwmIds)
|
||||
CarDirection GetRoundaboutDirection(TurnInfo const & turnInfo, TurnCandidates const & nodes,
|
||||
NumMwmIds const & numMwmIds)
|
||||
{
|
||||
bool const keepTurnByHighwayClass = KeepRoundaboutTurnByHighwayClass(nodes, turnInfo, numMwmIds);
|
||||
return GetRoundaboutDirectionBasic(turnInfo.m_ingoing->m_onRoundabout, turnInfo.m_outgoing->m_onRoundabout,
|
||||
nodes.candidates.size() > 1, keepTurnByHighwayClass);
|
||||
nodes.candidates.size() > 1, keepTurnByHighwayClass);
|
||||
}
|
||||
|
||||
/// \brief Return |CarDirection::ExitHighwayToRight| or |CarDirection::ExitHighwayToLeft|
|
||||
@@ -201,7 +201,8 @@ CarDirection TryToGetExitDirection(TurnCandidates const & possibleTurns, TurnInf
|
||||
if (!IsHighway(turnInfo.m_ingoing->m_highwayClass, turnInfo.m_ingoing->m_isLink))
|
||||
return CarDirection::None;
|
||||
|
||||
if (!turnInfo.m_outgoing->m_isLink && !(IsSmallRoad(turnInfo.m_outgoing->m_highwayClass) && IsGoStraightOrSlightTurn(intermediateDirection)))
|
||||
if (!turnInfo.m_outgoing->m_isLink &&
|
||||
!(IsSmallRoad(turnInfo.m_outgoing->m_highwayClass) && IsGoStraightOrSlightTurn(intermediateDirection)))
|
||||
return CarDirection::None;
|
||||
|
||||
// At this point it is known that the route goes form a highway to a link road or to a small road
|
||||
@@ -231,15 +232,12 @@ CarDirection TryToGetExitDirection(TurnCandidates const & possibleTurns, TurnInf
|
||||
{
|
||||
++highwayCandidateNumber;
|
||||
if (highwayCandidateNumber >= 2)
|
||||
return CarDirection::None; // There are two or more highway candidates from the junction.
|
||||
return CarDirection::None; // There are two or more highway candidates from the junction.
|
||||
isHighwayCandidateBeforeOutgoing = isCandidateBeforeOutgoing;
|
||||
}
|
||||
}
|
||||
if (highwayCandidateNumber == 1)
|
||||
{
|
||||
return isHighwayCandidateBeforeOutgoing ? CarDirection::ExitHighwayToRight
|
||||
: CarDirection::ExitHighwayToLeft;
|
||||
}
|
||||
return isHighwayCandidateBeforeOutgoing ? CarDirection::ExitHighwayToRight : CarDirection::ExitHighwayToLeft;
|
||||
return CarDirection::None;
|
||||
}
|
||||
|
||||
@@ -263,10 +261,8 @@ double constexpr kMinAbsAngleDiffForSameOrSmallerRoad = 35.0;
|
||||
/// \param routeAngle is route angle.
|
||||
/// \param turnCandidates is all possible ways out from a junction except uturn.
|
||||
/// \param turnInfo is information about ingoing and outgoing segments of the route.
|
||||
bool CanDiscardTurnByHighwayClassOrAngles(CarDirection const routeDirection,
|
||||
double const routeAngle,
|
||||
vector<TurnCandidate> const & turnCandidates,
|
||||
TurnInfo const & turnInfo,
|
||||
bool CanDiscardTurnByHighwayClassOrAngles(CarDirection const routeDirection, double const routeAngle,
|
||||
vector<TurnCandidate> const & turnCandidates, TurnInfo const & turnInfo,
|
||||
NumMwmIds const & numMwmIds)
|
||||
{
|
||||
if (!IsGoStraightOrSlightTurn(routeDirection))
|
||||
@@ -292,7 +288,8 @@ bool CanDiscardTurnByHighwayClassOrAngles(CarDirection const routeDirection,
|
||||
double constexpr kMinAbsAngleDiffForGoLink = 70.0;
|
||||
|
||||
// If route goes from non-link to link and there is not too sharp candidate then turn can't be discarded.
|
||||
if (!turnInfo.m_ingoing->m_isLink && turnInfo.m_outgoing->m_isLink && abs(t.m_angle) < abs(routeAngle) + kMinAbsAngleDiffForGoLink)
|
||||
if (!turnInfo.m_ingoing->m_isLink && turnInfo.m_outgoing->m_isLink &&
|
||||
abs(t.m_angle) < abs(routeAngle) + kMinAbsAngleDiffForGoLink)
|
||||
return false;
|
||||
|
||||
HighwayClass candidateRoadClass = t.m_highwayClass;
|
||||
@@ -310,8 +307,7 @@ bool CanDiscardTurnByHighwayClassOrAngles(CarDirection const routeDirection,
|
||||
// and outgoing route road is the same or large than ingoing
|
||||
// then candidate-link can be ignored.
|
||||
if (!turnInfo.m_ingoing->m_isLink && !turnInfo.m_outgoing->m_isLink &&
|
||||
CalcDiffRoadClasses(outgoingRouteRoadClass, ingoingRouteRoadClass) <= 0 &&
|
||||
t.m_isLink)
|
||||
CalcDiffRoadClasses(outgoingRouteRoadClass, ingoingRouteRoadClass) <= 0 && t.m_isLink)
|
||||
continue;
|
||||
|
||||
// If alternative cadidate's road size is the same or smaller
|
||||
@@ -364,13 +360,13 @@ void CorrectGoStraight(TurnCandidate const & notRouteCandidate, double const rou
|
||||
// and there's another not sharp enough turn
|
||||
// GoStraight is corrected to TurnSlightRight/TurnSlightLeft
|
||||
// to avoid ambiguity for GoStraight direction: 2 or more almost straight turns.
|
||||
void CorrectRightmostAndLeftmost(vector<TurnCandidate> const & turnCandidates,
|
||||
Segment const & firstOutgoingSeg, double const turnAngle,
|
||||
TurnItem & turn)
|
||||
void CorrectRightmostAndLeftmost(vector<TurnCandidate> const & turnCandidates, Segment const & firstOutgoingSeg,
|
||||
double const turnAngle, TurnItem & turn)
|
||||
{
|
||||
// turnCandidates are sorted by angle from leftmost to rightmost.
|
||||
// Normally no duplicates should be found. But if they are present we can't identify the leftmost/rightmost by order.
|
||||
if (adjacent_find(turnCandidates.begin(), turnCandidates.end(), base::EqualsBy(&TurnCandidate::m_angle)) != turnCandidates.end())
|
||||
if (adjacent_find(turnCandidates.begin(), turnCandidates.end(), base::EqualsBy(&TurnCandidate::m_angle)) !=
|
||||
turnCandidates.end())
|
||||
{
|
||||
LOG(LWARNING, ("nodes.candidates are not expected to have same m_angle."));
|
||||
return;
|
||||
@@ -419,8 +415,7 @@ void CorrectRightmostAndLeftmost(vector<TurnCandidate> const & turnCandidates,
|
||||
}
|
||||
|
||||
void GetTurnDirectionBasic(IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings,
|
||||
TurnItem & turn)
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings, TurnItem & turn)
|
||||
{
|
||||
TurnInfo turnInfo;
|
||||
if (!GetTurnInfo(result, outgoingSegmentIndex, vehicleSettings, turnInfo))
|
||||
@@ -479,15 +474,16 @@ void GetTurnDirectionBasic(IRoutingResult const & result, size_t const outgoingS
|
||||
|
||||
if (turnCandidates.size() == 1)
|
||||
{
|
||||
//ASSERT_EQUAL(turnCandidates.front().m_segment, firstOutgoingSeg, ());
|
||||
// ASSERT_EQUAL(turnCandidates.front().m_segment, firstOutgoingSeg, ());
|
||||
|
||||
if (IsGoStraightOrSlightTurn(intermediateDirection))
|
||||
return;
|
||||
// IngoingCount includes ingoing segment and reversed outgoing (if it is not one-way).
|
||||
// If any other one is present, turn (not straight or slight) is kept to prevent user from going to oneway alternative.
|
||||
// If any other one is present, turn (not straight or slight) is kept to prevent user from going to oneway
|
||||
// alternative.
|
||||
|
||||
/// @todo Min abs angle of ingoing ones should be considered. If it's much bigger than route angle - ignore ingoing ones.
|
||||
/// Now this data is not available from IRoutingResult::GetPossibleTurns().
|
||||
/// @todo Min abs angle of ingoing ones should be considered. If it's much bigger than route angle - ignore ingoing
|
||||
/// ones. Now this data is not available from IRoutingResult::GetPossibleTurns().
|
||||
if (ingoingCount <= 1 + (turnInfo.m_outgoing->m_isOneWay ? 0 : 1))
|
||||
return;
|
||||
}
|
||||
@@ -506,7 +502,8 @@ void GetTurnDirectionBasic(IRoutingResult const & result, size_t const outgoingS
|
||||
else if (abs(turnOneSegmentAngle) > 10)
|
||||
LOG(LWARNING, ("Significant angles are expected to have the same sign."));
|
||||
|
||||
if (CanDiscardTurnByHighwayClassOrAngles(intermediateDirection, turnAngleToCompare, turnCandidates, turnInfo, numMwmIds))
|
||||
if (CanDiscardTurnByHighwayClassOrAngles(intermediateDirection, turnAngleToCompare, turnCandidates, turnInfo,
|
||||
numMwmIds))
|
||||
return;
|
||||
|
||||
turn.m_turn = intermediateDirection;
|
||||
@@ -515,9 +512,8 @@ void GetTurnDirectionBasic(IRoutingResult const & result, size_t const outgoingS
|
||||
CorrectRightmostAndLeftmost(turnCandidates, firstOutgoingSeg, turnAngle, turn);
|
||||
}
|
||||
|
||||
size_t CheckUTurnOnRoute(IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings,
|
||||
TurnItem & turn)
|
||||
size_t CheckUTurnOnRoute(IRoutingResult const & result, size_t const outgoingSegmentIndex, NumMwmIds const & numMwmIds,
|
||||
RoutingSettings const & vehicleSettings, TurnItem & turn)
|
||||
{
|
||||
size_t constexpr kUTurnLookAhead = 3;
|
||||
double constexpr kUTurnHeadingSensitivity = math::pi / 10.0;
|
||||
@@ -583,12 +579,12 @@ size_t CheckUTurnOnRoute(IRoutingResult const & result, size_t const outgoingSeg
|
||||
// Determine turn direction.
|
||||
m2::PointD const junctionPoint = masterSegment.m_path.back().GetPoint();
|
||||
|
||||
m2::PointD const ingoingPoint = GetPointForTurn(
|
||||
result, outgoingSegmentIndex, numMwmIds, vehicleSettings.m_maxIngoingPointsCount,
|
||||
vehicleSettings.m_minIngoingDistMeters, false /* forward */);
|
||||
m2::PointD const outgoingPoint = GetPointForTurn(
|
||||
result, outgoingSegmentIndex, numMwmIds, vehicleSettings.m_maxOutgoingPointsCount,
|
||||
vehicleSettings.m_minOutgoingDistMeters, true /* forward */);
|
||||
m2::PointD const ingoingPoint =
|
||||
GetPointForTurn(result, outgoingSegmentIndex, numMwmIds, vehicleSettings.m_maxIngoingPointsCount,
|
||||
vehicleSettings.m_minIngoingDistMeters, false /* forward */);
|
||||
m2::PointD const outgoingPoint =
|
||||
GetPointForTurn(result, outgoingSegmentIndex, numMwmIds, vehicleSettings.m_maxOutgoingPointsCount,
|
||||
vehicleSettings.m_minOutgoingDistMeters, true /* forward */);
|
||||
|
||||
if (PiMinusTwoVectorsAngle(junctionPoint, ingoingPoint, outgoingPoint) < 0)
|
||||
turn.m_turn = CarDirection::UTurnLeft;
|
||||
@@ -625,7 +621,7 @@ bool FixupLaneSet(CarDirection turn, vector<SingleLaneInfo> & lanes, bool (*chec
|
||||
template <typename It>
|
||||
bool SelectFirstUnrestrictedLane(LaneWay direction, It lanesBegin, It lanesEnd)
|
||||
{
|
||||
const It firstUnrestricted = find_if(lanesBegin, lanesEnd, IsLaneUnrestricted);
|
||||
It const firstUnrestricted = find_if(lanesBegin, lanesEnd, IsLaneUnrestricted);
|
||||
if (firstUnrestricted == lanesEnd)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include "routing/directions_engine.hpp"
|
||||
|
||||
#include "routing_common/num_mwm_id.hpp"
|
||||
#include "routing/route.hpp"
|
||||
#include "routing_common/num_mwm_id.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -19,8 +19,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual size_t GetTurnDirection(turns::IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds,
|
||||
RoutingSettings const & vehicleSettings, turns::TurnItem & turn);
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings,
|
||||
turns::TurnItem & turn);
|
||||
virtual void FixupTurns(std::vector<RouteSegment> & routeSegments);
|
||||
};
|
||||
|
||||
@@ -38,8 +38,7 @@ void FixupCarTurns(std::vector<RouteSegment> & routeSegments);
|
||||
* \warning |currentSegment| must be greater than 0.
|
||||
*/
|
||||
size_t CheckUTurnOnRoute(turns::IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings,
|
||||
turns::TurnItem & turn);
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings, turns::TurnItem & turn);
|
||||
|
||||
/*!
|
||||
* \brief Calculates a turn instruction if the ingoing edge or (and) the outgoing edge belongs to a
|
||||
|
||||
@@ -15,13 +15,11 @@ double CheckpointPredictor::CalculateDeltaMeters(m2::PointD const & from, m2::Po
|
||||
m2::PointD const & between)
|
||||
{
|
||||
double const directDist = mercator::DistanceOnEarth(from, to);
|
||||
double const distThroughPoint =
|
||||
mercator::DistanceOnEarth(from, between) + mercator::DistanceOnEarth(between, to);
|
||||
double const distThroughPoint = mercator::DistanceOnEarth(from, between) + mercator::DistanceOnEarth(between, to);
|
||||
return distThroughPoint - directDist;
|
||||
}
|
||||
|
||||
size_t CheckpointPredictor::PredictPosition(vector<m2::PointD> const & points,
|
||||
m2::PointD const & point) const
|
||||
size_t CheckpointPredictor::PredictPosition(vector<m2::PointD> const & points, m2::PointD const & point) const
|
||||
{
|
||||
double constexpr kInvalidDistance = numeric_limits<double>::max();
|
||||
double minDeltaMeters = kInvalidDistance;
|
||||
@@ -30,8 +28,7 @@ size_t CheckpointPredictor::PredictPosition(vector<m2::PointD> const & points,
|
||||
size_t const checkpointNum = points.size() + 2 /* for start and finish points */;
|
||||
for (size_t i = 0; i + 1 != checkpointNum; ++i)
|
||||
{
|
||||
double const delta = CalculateDeltaMeters(GetCheckpoint(points, i),
|
||||
GetCheckpoint(points, i + 1), point);
|
||||
double const delta = CalculateDeltaMeters(GetCheckpoint(points, i), GetCheckpoint(points, i + 1), point);
|
||||
if (minDeltaMeters > delta)
|
||||
{
|
||||
minDeltaMeters = delta;
|
||||
@@ -43,8 +40,7 @@ size_t CheckpointPredictor::PredictPosition(vector<m2::PointD> const & points,
|
||||
return minDeltaIdx;
|
||||
}
|
||||
|
||||
m2::PointD const & CheckpointPredictor::GetCheckpoint(vector<m2::PointD> const & points,
|
||||
size_t index) const
|
||||
m2::PointD const & CheckpointPredictor::GetCheckpoint(vector<m2::PointD> const & points, size_t index) const
|
||||
{
|
||||
if (index == 0)
|
||||
return m_start;
|
||||
|
||||
@@ -18,10 +18,7 @@ class CheckpointPredictor final
|
||||
friend class CheckpointPredictorTest;
|
||||
|
||||
public:
|
||||
CheckpointPredictor(m2::PointD const & start, m2::PointD const & finish)
|
||||
: m_start(start), m_finish(finish)
|
||||
{
|
||||
}
|
||||
CheckpointPredictor(m2::PointD const & start, m2::PointD const & finish) : m_start(start), m_finish(finish) {}
|
||||
|
||||
/// \returns difference between distance |from|->|between| + |between|->|to| and distance |from|->|to|.
|
||||
static double CalculateDeltaMeters(m2::PointD const & from, m2::PointD const & to, m2::PointD const & between);
|
||||
|
||||
@@ -11,8 +11,7 @@ namespace routing
|
||||
{
|
||||
Checkpoints::Checkpoints(std::vector<m2::PointD> && points) : m_points(std::move(points))
|
||||
{
|
||||
CHECK_GREATER_OR_EQUAL(m_points.size(), 2,
|
||||
("Checkpoints should at least contain start and finish"));
|
||||
CHECK_GREATER_OR_EQUAL(m_points.size(), 2, ("Checkpoints should at least contain start and finish"));
|
||||
}
|
||||
|
||||
void Checkpoints::SetPointFrom(m2::PointD const & point)
|
||||
|
||||
@@ -37,8 +37,7 @@ std::unique_ptr<CityRoads> LoadCityRoads(MwmSet::MwmHandle const & handle)
|
||||
}
|
||||
catch (Reader::Exception const & e)
|
||||
{
|
||||
LOG(LERROR, ("File", value->GetCountryFileName(), "Error while reading", CITY_ROADS_FILE_TAG,
|
||||
"section.", e.Msg()));
|
||||
LOG(LERROR, ("File", value->GetCountryFileName(), "Error while reading", CITY_ROADS_FILE_TAG, "section.", e.Msg()));
|
||||
return std::make_unique<CityRoads>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,11 +56,9 @@ public:
|
||||
header.Serialize(sink);
|
||||
|
||||
std::sort(cityRoadFeatureIds.begin(), cityRoadFeatureIds.end());
|
||||
CHECK(adjacent_find(cityRoadFeatureIds.cbegin(), cityRoadFeatureIds.cend()) ==
|
||||
cityRoadFeatureIds.cend(),
|
||||
CHECK(adjacent_find(cityRoadFeatureIds.cbegin(), cityRoadFeatureIds.cend()) == cityRoadFeatureIds.cend(),
|
||||
("City road feature ids should be unique."));
|
||||
succinct::elias_fano::elias_fano_builder builder(cityRoadFeatureIds.back() + 1,
|
||||
cityRoadFeatureIds.size());
|
||||
succinct::elias_fano::elias_fano_builder builder(cityRoadFeatureIds.back() + 1, cityRoadFeatureIds.size());
|
||||
for (auto fid : cityRoadFeatureIds)
|
||||
builder.push_back(fid);
|
||||
|
||||
@@ -74,8 +72,8 @@ public:
|
||||
header.Serialize(sink);
|
||||
sink.Seek(endOffset);
|
||||
|
||||
LOG(LINFO, ("Serialized", cityRoadFeatureIds.size(),
|
||||
"road feature ids in cities. Size:", endOffset - startOffset, "bytes."));
|
||||
LOG(LINFO, ("Serialized", cityRoadFeatureIds.size(), "road feature ids in cities. Size:", endOffset - startOffset,
|
||||
"bytes."));
|
||||
}
|
||||
|
||||
template <typename Source>
|
||||
|
||||
@@ -21,10 +21,7 @@ T ReadDelta(BitReader<Source> & reader)
|
||||
static_assert(std::is_unsigned<T>::value, "T should be an unsigned type");
|
||||
uint64_t const decoded = coding::DeltaCoder::Decode(reader);
|
||||
if (decoded > std::numeric_limits<T>::max())
|
||||
{
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Decoded value", decoded, "out of limit", std::numeric_limits<T>::max()));
|
||||
}
|
||||
MYTHROW(CorruptedDataException, ("Decoded value", decoded, "out of limit", std::numeric_limits<T>::max()));
|
||||
|
||||
return static_cast<T>(decoded);
|
||||
}
|
||||
@@ -46,10 +43,7 @@ T ReadGamma(BitReader<Source> & reader)
|
||||
static_assert(std::is_unsigned<T>::value, "T should be an unsigned type");
|
||||
uint64_t const decoded = coding::GammaCoder::Decode(reader);
|
||||
if (decoded > std::numeric_limits<T>::max())
|
||||
{
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Decoded value", decoded, "out of limit", std::numeric_limits<T>::max()));
|
||||
}
|
||||
MYTHROW(CorruptedDataException, ("Decoded value", decoded, "out of limit", std::numeric_limits<T>::max()));
|
||||
|
||||
return static_cast<T>(decoded);
|
||||
}
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
namespace routing
|
||||
{
|
||||
void CrossBorderGraph::AddCrossBorderSegment(RegionSegmentId segId,
|
||||
CrossBorderSegment const & segment)
|
||||
void CrossBorderGraph::AddCrossBorderSegment(RegionSegmentId segId, CrossBorderSegment const & segment)
|
||||
{
|
||||
m_segments.emplace(segId, segment);
|
||||
|
||||
@@ -21,21 +20,20 @@ void CrossBorderGraph::AddCrossBorderSegment(RegionSegmentId segId,
|
||||
}
|
||||
|
||||
CrossBorderSegmentEnding::CrossBorderSegmentEnding(m2::PointD const & point, NumMwmId const & mwmId)
|
||||
: m_point(mercator::ToLatLon(point), geometry::kDefaultAltitudeMeters), m_numMwmId(mwmId)
|
||||
{
|
||||
}
|
||||
: m_point(mercator::ToLatLon(point), geometry::kDefaultAltitudeMeters)
|
||||
, m_numMwmId(mwmId)
|
||||
{}
|
||||
|
||||
CrossBorderSegmentEnding::CrossBorderSegmentEnding(ms::LatLon const & point, NumMwmId const & mwmId)
|
||||
: m_point(point, 0), m_numMwmId(mwmId)
|
||||
{
|
||||
}
|
||||
: m_point(point, 0)
|
||||
, m_numMwmId(mwmId)
|
||||
{}
|
||||
|
||||
CrossBorderGraphSerializer::Header::Header(CrossBorderGraph const & graph, uint32_t version)
|
||||
: m_numRegions(static_cast<uint32_t>(graph.m_mwms.size()))
|
||||
, m_numRoads(static_cast<uint32_t>(graph.m_segments.size()))
|
||||
, m_version(version)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// static
|
||||
uint32_t CrossBorderGraphSerializer::Hash(std::string const & s)
|
||||
|
||||
@@ -63,12 +63,10 @@ public:
|
||||
CrossBorderGraphSerializer() = delete;
|
||||
|
||||
template <class Sink>
|
||||
static void Serialize(CrossBorderGraph const & graph, Sink & sink,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
static void Serialize(CrossBorderGraph const & graph, Sink & sink, std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
|
||||
template <class Source>
|
||||
static void Deserialize(CrossBorderGraph & graph, Source & src,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
static void Deserialize(CrossBorderGraph & graph, Source & src, std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
|
||||
private:
|
||||
static uint32_t constexpr kVersion = 1;
|
||||
@@ -77,8 +75,7 @@ private:
|
||||
struct Header
|
||||
{
|
||||
Header() = default;
|
||||
explicit Header(CrossBorderGraph const & graph,
|
||||
uint32_t version = kVersion);
|
||||
explicit Header(CrossBorderGraph const & graph, uint32_t version = kVersion);
|
||||
|
||||
template <class Sink>
|
||||
void Serialize(Sink & sink) const;
|
||||
@@ -181,10 +178,10 @@ void CrossBorderGraphSerializer::Deserialize(CrossBorderGraph & graph, Source &
|
||||
|
||||
auto readSegEnding = [&](CrossBorderSegmentEnding & ending)
|
||||
{
|
||||
double const lat = Uint32ToDouble(ReadPrimitiveFromSource<uint32_t>(src),
|
||||
ms::LatLon::kMinLat, ms::LatLon::kMaxLat, kBitsForDouble);
|
||||
double const lon = Uint32ToDouble(ReadPrimitiveFromSource<uint32_t>(src),
|
||||
ms::LatLon::kMinLon, ms::LatLon::kMaxLon, kBitsForDouble);
|
||||
double const lat = Uint32ToDouble(ReadPrimitiveFromSource<uint32_t>(src), ms::LatLon::kMinLat, ms::LatLon::kMaxLat,
|
||||
kBitsForDouble);
|
||||
double const lon = Uint32ToDouble(ReadPrimitiveFromSource<uint32_t>(src), ms::LatLon::kMinLon, ms::LatLon::kMaxLon,
|
||||
kBitsForDouble);
|
||||
ending.m_point = LatLonWithAltitude(ms::LatLon(lat, lon), geometry::kDefaultAltitudeMeters);
|
||||
|
||||
NumMwmId index = ReadPrimitiveFromSource<uint16_t>(src);
|
||||
|
||||
@@ -38,13 +38,15 @@ std::string DebugPrint(WeightsLoadState state);
|
||||
} // namespace connector
|
||||
|
||||
/// @param CrossMwmId Encoded OSM feature (way) ID that should be equal and unique in all MWMs.
|
||||
template <typename CrossMwmId> class CrossMwmConnector final
|
||||
template <typename CrossMwmId>
|
||||
class CrossMwmConnector final
|
||||
{
|
||||
public:
|
||||
/// Should initialize with some valid mwm id here not to conflict with @see JointSegment::IsFake().
|
||||
explicit CrossMwmConnector(NumMwmId mwmId = kGeneratorMwmId) : m_mwmId(mwmId) {}
|
||||
|
||||
template <class FnT> void ForEachTransitSegmentId(uint32_t featureId, FnT && fn) const
|
||||
template <class FnT>
|
||||
void ForEachTransitSegmentId(uint32_t featureId, FnT && fn) const
|
||||
{
|
||||
auto it = std::lower_bound(m_transitions.begin(), m_transitions.end(), Key{featureId, 0}, LessKT());
|
||||
while (it != m_transitions.end() && it->first.m_featureId == featureId)
|
||||
@@ -75,10 +77,7 @@ public:
|
||||
return isEnter != isOutgoing;
|
||||
}
|
||||
|
||||
CrossMwmId const & GetCrossMwmId(Segment const & segment) const
|
||||
{
|
||||
return GetTransition(segment).m_crossMwmId;
|
||||
}
|
||||
CrossMwmId const & GetCrossMwmId(Segment const & segment) const { return GetTransition(segment).m_crossMwmId; }
|
||||
|
||||
/// @return {} if there is no transition for such cross mwm id.
|
||||
std::optional<Segment> GetTransition(CrossMwmId const & crossMwmId, uint32_t segmentIdx, bool isEnter) const
|
||||
@@ -115,7 +114,8 @@ public:
|
||||
|
||||
using EdgeListT = SmallList<SegmentEdge>;
|
||||
|
||||
template <class FnT> void ForEachEnter(FnT && fn) const
|
||||
template <class FnT>
|
||||
void ForEachEnter(FnT && fn) const
|
||||
{
|
||||
for (auto const & [key, transit] : m_transitions)
|
||||
{
|
||||
@@ -127,7 +127,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <class FnT> void ForEachExit(FnT && fn) const
|
||||
template <class FnT>
|
||||
void ForEachExit(FnT && fn) const
|
||||
{
|
||||
for (auto const & [key, transit] : m_transitions)
|
||||
{
|
||||
@@ -143,18 +144,14 @@ public:
|
||||
{
|
||||
auto const enterIdx = GetTransition(segment).m_enterIdx;
|
||||
ForEachExit([enterIdx, this, &edges](uint32_t exitIdx, Segment const & s)
|
||||
{
|
||||
AddEdge(s, enterIdx, exitIdx, edges);
|
||||
});
|
||||
{ AddEdge(s, enterIdx, exitIdx, edges); });
|
||||
}
|
||||
|
||||
void GetIngoingEdgeList(Segment const & segment, EdgeListT & edges) const
|
||||
{
|
||||
auto const exitIdx = GetTransition(segment).m_exitIdx;
|
||||
ForEachEnter([exitIdx, this, &edges](uint32_t enterIdx, Segment const & s)
|
||||
{
|
||||
AddEdge(s, enterIdx, exitIdx, edges);
|
||||
});
|
||||
{ AddEdge(s, enterIdx, exitIdx, edges); });
|
||||
}
|
||||
|
||||
RouteWeight GetWeightSure(Segment const & from, Segment const & to) const
|
||||
@@ -204,13 +201,12 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
template <class T> friend class CrossMwmConnectorBuilder;
|
||||
template <class T>
|
||||
friend class CrossMwmConnectorBuilder;
|
||||
|
||||
struct Key
|
||||
{
|
||||
Key(uint32_t featureId, uint32_t segmentIdx) : m_featureId(featureId), m_segmentIdx(segmentIdx)
|
||||
{
|
||||
}
|
||||
Key(uint32_t featureId, uint32_t segmentIdx) : m_featureId(featureId), m_segmentIdx(segmentIdx) {}
|
||||
|
||||
bool operator==(Key const & key) const
|
||||
{
|
||||
@@ -236,8 +232,7 @@ private:
|
||||
, m_crossMwmId(crossMwmId)
|
||||
, m_oneWay(oneWay)
|
||||
, m_forwardIsEnter(forwardIsEnter)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
uint32_t m_enterIdx;
|
||||
uint32_t m_exitIdx;
|
||||
@@ -279,18 +274,9 @@ private:
|
||||
using KeyTransitionT = std::pair<Key, Transition>;
|
||||
struct LessKT
|
||||
{
|
||||
bool operator()(KeyTransitionT const & l, KeyTransitionT const & r) const
|
||||
{
|
||||
return l.first < r.first;
|
||||
}
|
||||
bool operator()(KeyTransitionT const & l, Key const & r) const
|
||||
{
|
||||
return l.first < r;
|
||||
}
|
||||
bool operator()(Key const & l, KeyTransitionT const & r) const
|
||||
{
|
||||
return l < r.first;
|
||||
}
|
||||
bool operator()(KeyTransitionT const & l, KeyTransitionT const & r) const { return l.first < r.first; }
|
||||
bool operator()(KeyTransitionT const & l, Key const & r) const { return l.first < r; }
|
||||
bool operator()(Key const & l, KeyTransitionT const & r) const { return l < r.first; }
|
||||
};
|
||||
std::vector<KeyTransitionT> m_transitions;
|
||||
|
||||
@@ -321,7 +307,6 @@ private:
|
||||
bool Get(uint32_t idx, WeightT & weight) const
|
||||
{
|
||||
if (m_version < 2)
|
||||
{
|
||||
if (m_v1.Has(idx))
|
||||
{
|
||||
weight = m_v1.Get(idx);
|
||||
@@ -329,11 +314,8 @@ private:
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_v2->Get(idx, weight);
|
||||
}
|
||||
}
|
||||
|
||||
} m_weights;
|
||||
|
||||
@@ -32,21 +32,28 @@ static uint8_t constexpr kOsmIdBits = 64;
|
||||
static uint8_t constexpr kStopIdBits = 64;
|
||||
static uint8_t constexpr kLineIdBits = 32;
|
||||
|
||||
inline uint32_t constexpr CalcBitsPerTransitId() { return 2 * kStopIdBits + kLineIdBits; }
|
||||
inline uint32_t constexpr CalcBitsPerTransitId()
|
||||
{
|
||||
return 2 * kStopIdBits + kLineIdBits;
|
||||
}
|
||||
|
||||
template <typename CrossMwmId> uint32_t constexpr GetFeaturesOffset() noexcept;
|
||||
template <> uint32_t constexpr GetFeaturesOffset<base::GeoObjectId>() noexcept
|
||||
template <typename CrossMwmId>
|
||||
uint32_t constexpr GetFeaturesOffset() noexcept;
|
||||
template <>
|
||||
uint32_t constexpr GetFeaturesOffset<base::GeoObjectId>() noexcept
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
template <> uint32_t constexpr GetFeaturesOffset<TransitId>() noexcept
|
||||
template <>
|
||||
uint32_t constexpr GetFeaturesOffset<TransitId>() noexcept
|
||||
{
|
||||
return FakeFeatureIds::kTransitGraphFeaturesStart;
|
||||
}
|
||||
} // namespace connector
|
||||
|
||||
/// Builder class for deserialization.
|
||||
template <typename CrossMwmId> class CrossMwmConnectorBuilder
|
||||
template <typename CrossMwmId>
|
||||
class CrossMwmConnectorBuilder
|
||||
{
|
||||
protected:
|
||||
using ConnectorT = CrossMwmConnector<CrossMwmId>;
|
||||
@@ -61,18 +68,14 @@ public:
|
||||
explicit CrossMwmConnectorBuilder(ConnectorT & c) : m_c(c) {}
|
||||
|
||||
/// Called only in cross-mwm-graph when deserialization connectors.
|
||||
void ApplyNumerationOffset()
|
||||
{
|
||||
m_featureNumerationOffset = connector::GetFeaturesOffset<CrossMwmId>();
|
||||
}
|
||||
void ApplyNumerationOffset() { m_featureNumerationOffset = connector::GetFeaturesOffset<CrossMwmId>(); }
|
||||
|
||||
void AddTransition(CrossMwmId const & crossMwmId, uint32_t featureId, uint32_t segmentIdx,
|
||||
bool oneWay, bool forwardIsEnter)
|
||||
void AddTransition(CrossMwmId const & crossMwmId, uint32_t featureId, uint32_t segmentIdx, bool oneWay,
|
||||
bool forwardIsEnter)
|
||||
{
|
||||
featureId += m_featureNumerationOffset;
|
||||
|
||||
typename ConnectorT::Transition transition(m_c.m_entersCount, m_c.m_exitsCount,
|
||||
crossMwmId, oneWay, forwardIsEnter);
|
||||
typename ConnectorT::Transition transition(m_c.m_entersCount, m_c.m_exitsCount, crossMwmId, oneWay, forwardIsEnter);
|
||||
|
||||
if (forwardIsEnter)
|
||||
++m_c.m_entersCount;
|
||||
@@ -110,16 +113,15 @@ protected:
|
||||
public:
|
||||
Transition() = default;
|
||||
|
||||
Transition(CrossMwmId const & crossMwmId, uint32_t featureId, uint32_t segmentIdx,
|
||||
VehicleMask roadMask, VehicleMask oneWayMask, bool forwardIsEnter)
|
||||
Transition(CrossMwmId const & crossMwmId, uint32_t featureId, uint32_t segmentIdx, VehicleMask roadMask,
|
||||
VehicleMask oneWayMask, bool forwardIsEnter)
|
||||
: m_crossMwmId(crossMwmId)
|
||||
, m_featureId(featureId)
|
||||
, m_segmentIdx(segmentIdx)
|
||||
, m_roadMask(roadMask)
|
||||
, m_oneWayMask(oneWayMask)
|
||||
, m_forwardIsEnter(forwardIsEnter)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <class Sink>
|
||||
static void WriteCrossMwmId(base::GeoObjectId const & id, uint8_t bits, BitWriter<Sink> & w)
|
||||
@@ -237,9 +239,8 @@ public:
|
||||
|
||||
if (src.Pos() != weightsOffset)
|
||||
{
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Wrong position", src.Pos(), "after decoding transitions, expected:",
|
||||
weightsOffset, "size:", header.GetSizeTransitions()));
|
||||
MYTHROW(CorruptedDataException, ("Wrong position", src.Pos(), "after decoding transitions, expected:",
|
||||
weightsOffset, "size:", header.GetSizeTransitions()));
|
||||
}
|
||||
|
||||
for (Section const & section : header.GetSections())
|
||||
@@ -255,14 +256,14 @@ public:
|
||||
|
||||
if (base::checked_cast<size_t>(section.GetNumEnters()) != numEnters)
|
||||
{
|
||||
MYTHROW(CorruptedDataException, ("Mismatch enters number, section:", section.GetNumEnters(),
|
||||
", connector:", numEnters));
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Mismatch enters number, section:", section.GetNumEnters(), ", connector:", numEnters));
|
||||
}
|
||||
|
||||
if (base::checked_cast<size_t>(section.GetNumExits()) != numExits)
|
||||
{
|
||||
MYTHROW(CorruptedDataException, ("Mismatch exits number, section:", section.GetNumExits(),
|
||||
", connector:", numExits));
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Mismatch exits number, section:", section.GetNumExits(), ", connector:", numExits));
|
||||
}
|
||||
|
||||
m_c.m_weights.m_offset = weightsOffset;
|
||||
@@ -275,10 +276,7 @@ public:
|
||||
m_c.m_weights.m_loadState = connector::WeightsLoadState::NotExists;
|
||||
}
|
||||
|
||||
void DeserializeWeights(FilesContainerR::TReader & reader)
|
||||
{
|
||||
DeserializeWeights(*(reader.GetPtr()));
|
||||
}
|
||||
void DeserializeWeights(FilesContainerR::TReader & reader) { DeserializeWeights(*(reader.GetPtr())); }
|
||||
|
||||
/// @param[in] reader Initialized reader for the whole section (makes Skip inside).
|
||||
template <class Reader>
|
||||
@@ -301,7 +299,6 @@ public:
|
||||
|
||||
Weight prev = 1;
|
||||
for (size_t i = 0; i < amount; ++i)
|
||||
{
|
||||
if (bitReader.Read(1) != kNoRouteBit)
|
||||
{
|
||||
Weight const delta = ReadDelta<Weight>(bitReader) - 1;
|
||||
@@ -311,28 +308,28 @@ public:
|
||||
}
|
||||
else
|
||||
builder.PushEmpty();
|
||||
}
|
||||
|
||||
m_c.m_weights.m_v1 = builder.Build();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_c.m_weights.m_reader = reader.CreateSubReader(m_c.m_weights.m_offset, reader.Size() - m_c.m_weights.m_offset);
|
||||
m_c.m_weights.m_v2 = MapUint32ToValue<Weight>::Load(*(m_c.m_weights.m_reader),
|
||||
[granularity = m_c.m_weights.m_granularity](NonOwningReaderSource & source, uint32_t blockSize,
|
||||
std::vector<Weight> & values)
|
||||
m_c.m_weights.m_v2 = MapUint32ToValue<Weight>::Load(
|
||||
*(m_c.m_weights.m_reader),
|
||||
[granularity = m_c.m_weights.m_granularity](NonOwningReaderSource & source, uint32_t blockSize,
|
||||
std::vector<Weight> & values)
|
||||
{
|
||||
values.resize(blockSize);
|
||||
|
||||
uint32_t prev = ReadVarUint<uint32_t>(source);
|
||||
values[0] = granularity * prev;
|
||||
|
||||
for (size_t i = 1; i < blockSize && source.Size() > 0; ++i)
|
||||
{
|
||||
values.resize(blockSize);
|
||||
|
||||
uint32_t prev = ReadVarUint<uint32_t>(source);
|
||||
values[0] = granularity * prev;
|
||||
|
||||
for (size_t i = 1; i < blockSize && source.Size() > 0; ++i)
|
||||
{
|
||||
prev += ReadVarInt<int32_t>(source);
|
||||
values[i] = granularity * prev;
|
||||
}
|
||||
});
|
||||
prev += ReadVarInt<int32_t>(source);
|
||||
values[i] = granularity * prev;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
m_c.m_weights.m_loadState = connector::WeightsLoadState::Loaded;
|
||||
@@ -345,8 +342,8 @@ protected:
|
||||
return false;
|
||||
|
||||
bool const isOneWay = (transition.GetOneWayMask() & requiredMask) != 0;
|
||||
AddTransition(transition.GetCrossMwmId(), transition.GetFeatureId(),
|
||||
transition.GetSegmentIdx(), isOneWay, transition.ForwardIsEnter());
|
||||
AddTransition(transition.GetCrossMwmId(), transition.GetFeatureId(), transition.GetSegmentIdx(), isOneWay,
|
||||
transition.ForwardIsEnter());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -372,9 +369,11 @@ protected:
|
||||
Section() = default;
|
||||
|
||||
Section(uint64_t size, uint32_t numEnters, uint32_t numExits, VehicleType vehicleType)
|
||||
: m_size(size), m_numEnters(numEnters), m_numExits(numExits), m_vehicleType(vehicleType)
|
||||
{
|
||||
}
|
||||
: m_size(size)
|
||||
, m_numEnters(numEnters)
|
||||
, m_numExits(numExits)
|
||||
, m_vehicleType(vehicleType)
|
||||
{}
|
||||
|
||||
template <class Sink>
|
||||
void Serialize(Sink & sink) const
|
||||
@@ -416,8 +415,7 @@ protected:
|
||||
, m_sizeTransitions(sizeTransitions)
|
||||
, m_bitsPerCrossMwmId(bitsPerCrossMwmId)
|
||||
, m_bitsPerMask(bitsPerMask)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <class Sink>
|
||||
void Serialize(Sink & sink) const
|
||||
@@ -440,8 +438,8 @@ protected:
|
||||
m_version = ReadPrimitiveFromSource<decltype(m_version)>(src);
|
||||
if (m_version > kLastVersion)
|
||||
{
|
||||
MYTHROW(CorruptedDataException, ("Unknown cross mwm section version ", m_version,
|
||||
", current version ", kLastVersion));
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Unknown cross mwm section version ", m_version, ", current version ", kLastVersion));
|
||||
}
|
||||
|
||||
m_numTransitions = ReadPrimitiveFromSource<decltype(m_numTransitions)>(src);
|
||||
@@ -522,10 +520,7 @@ private:
|
||||
MemWriter writer(buffer);
|
||||
builder.Freeze(writer, [](auto & writer, auto beg, auto end)
|
||||
{
|
||||
auto const NextStoredValue = [&beg]()
|
||||
{
|
||||
return (*beg++ + BaseT::kGranularity - 1) / BaseT::kGranularity;
|
||||
};
|
||||
auto const NextStoredValue = [&beg]() { return (*beg++ + BaseT::kGranularity - 1) / BaseT::kGranularity; };
|
||||
|
||||
Weight prev = NextStoredValue();
|
||||
WriteVarUint(writer, prev);
|
||||
@@ -541,8 +536,8 @@ private:
|
||||
public:
|
||||
CrossMwmConnectorBuilderEx() : BaseT(m_connector) {}
|
||||
|
||||
void AddTransition(CrossMwmId const & crossMwmId, uint32_t featureId, uint32_t segmentIdx,
|
||||
VehicleMask roadMask, VehicleMask oneWayMask, bool forwardIsEnter)
|
||||
void AddTransition(CrossMwmId const & crossMwmId, uint32_t featureId, uint32_t segmentIdx, VehicleMask roadMask,
|
||||
VehicleMask oneWayMask, bool forwardIsEnter)
|
||||
{
|
||||
m_transitions.emplace_back(crossMwmId, featureId, segmentIdx, roadMask, oneWayMask, forwardIsEnter);
|
||||
}
|
||||
@@ -558,8 +553,7 @@ public:
|
||||
WriteTransitions(bitsPerCrossMwmId, bitsPerMask, transitionsBuf);
|
||||
|
||||
typename BaseT::Header header(base::checked_cast<uint32_t>(m_transitions.size()),
|
||||
base::checked_cast<uint64_t>(transitionsBuf.size()),
|
||||
bitsPerCrossMwmId, bitsPerMask);
|
||||
base::checked_cast<uint64_t>(transitionsBuf.size()), bitsPerCrossMwmId, bitsPerMask);
|
||||
|
||||
std::vector<uint8_t> weightsBuf;
|
||||
if (!m_weights.empty())
|
||||
@@ -567,8 +561,8 @@ public:
|
||||
std::sort(m_weights.begin(), m_weights.end(), base::LessBy(&IdxWeightT::first));
|
||||
WriteWeights(weightsBuf);
|
||||
|
||||
header.AddSection(typename BaseT::Section(
|
||||
weightsBuf.size(), m_connector.GetNumEnters(), m_connector.GetNumExits(), m_vehicleType));
|
||||
header.AddSection(typename BaseT::Section(weightsBuf.size(), m_connector.GetNumEnters(),
|
||||
m_connector.GetNumExits(), m_vehicleType));
|
||||
}
|
||||
|
||||
// Use buffer serialization above, because BaseT::Header is not plain (vector<Section>)
|
||||
@@ -581,10 +575,7 @@ public:
|
||||
typename BaseT::ConnectorT const & PrepareConnector(VehicleType requiredVehicle)
|
||||
{
|
||||
m_vehicleType = requiredVehicle;
|
||||
BaseT::FillTransitions(m_transitions.size(), m_vehicleType, [this](size_t i)
|
||||
{
|
||||
return m_transitions[i];
|
||||
});
|
||||
BaseT::FillTransitions(m_transitions.size(), m_vehicleType, [this](size_t i) { return m_transitions[i]; });
|
||||
return m_connector;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,10 +13,8 @@ namespace routing
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
CrossMwmGraph::CrossMwmGraph(shared_ptr<NumMwmIds> numMwmIds,
|
||||
shared_ptr<m4::Tree<NumMwmId>> numMwmTree,
|
||||
VehicleType vehicleType, CountryRectFn const & countryRectFn,
|
||||
MwmDataSource & dataSource)
|
||||
CrossMwmGraph::CrossMwmGraph(shared_ptr<NumMwmIds> numMwmIds, shared_ptr<m4::Tree<NumMwmId>> numMwmTree,
|
||||
VehicleType vehicleType, CountryRectFn const & countryRectFn, MwmDataSource & dataSource)
|
||||
: m_dataSource(dataSource)
|
||||
, m_numMwmIds(numMwmIds)
|
||||
, m_numMwmTree(numMwmTree)
|
||||
@@ -31,14 +29,9 @@ CrossMwmGraph::CrossMwmGraph(shared_ptr<NumMwmIds> numMwmIds,
|
||||
bool CrossMwmGraph::IsTransition(Segment const & s, bool isOutgoing)
|
||||
{
|
||||
if (TransitGraph::IsTransitSegment(s))
|
||||
{
|
||||
return TransitCrossMwmSectionExists(s.GetMwmId())
|
||||
? m_crossMwmTransitGraph.IsTransition(s, isOutgoing)
|
||||
: false;
|
||||
}
|
||||
return TransitCrossMwmSectionExists(s.GetMwmId()) ? m_crossMwmTransitGraph.IsTransition(s, isOutgoing) : false;
|
||||
|
||||
return CrossMwmSectionExists(s.GetMwmId()) ? m_crossMwmIndexGraph.IsTransition(s, isOutgoing)
|
||||
: false;
|
||||
return CrossMwmSectionExists(s.GetMwmId()) ? m_crossMwmIndexGraph.IsTransition(s, isOutgoing) : false;
|
||||
}
|
||||
|
||||
bool CrossMwmGraph::GetAllLoadedNeighbors(NumMwmId numMwmId, vector<NumMwmId> & neighbors)
|
||||
@@ -130,9 +123,8 @@ void CrossMwmGraph::GetTwins(Segment const & s, bool isOutgoing, vector<Segment>
|
||||
|
||||
void CrossMwmGraph::GetOutgoingEdgeList(Segment const & enter, EdgeListT & edges)
|
||||
{
|
||||
ASSERT(
|
||||
IsTransition(enter, false /* isEnter */),
|
||||
("The segment is not a transition segment. IsTransition(", enter, ", false) returns false."));
|
||||
ASSERT(IsTransition(enter, false /* isEnter */),
|
||||
("The segment is not a transition segment. IsTransition(", enter, ", false) returns false."));
|
||||
|
||||
// Is not supported yet.
|
||||
/*
|
||||
@@ -150,9 +142,8 @@ void CrossMwmGraph::GetOutgoingEdgeList(Segment const & enter, EdgeListT & edges
|
||||
|
||||
void CrossMwmGraph::GetIngoingEdgeList(Segment const & exit, EdgeListT & edges)
|
||||
{
|
||||
ASSERT(
|
||||
IsTransition(exit, true /* isEnter */),
|
||||
("The segment is not a transition segment. IsTransition(", exit, ", true) returns false."));
|
||||
ASSERT(IsTransition(exit, true /* isEnter */),
|
||||
("The segment is not a transition segment. IsTransition(", exit, ", true) returns false."));
|
||||
|
||||
// Is not supported yet.
|
||||
/*
|
||||
@@ -175,11 +166,11 @@ RouteWeight CrossMwmGraph::GetWeightSure(Segment const & from, Segment const & t
|
||||
return m_crossMwmIndexGraph.GetWeightSure(from, to);
|
||||
}
|
||||
|
||||
//void CrossMwmGraph::Clear()
|
||||
// void CrossMwmGraph::Clear()
|
||||
//{
|
||||
// m_crossMwmIndexGraph.Clear();
|
||||
// m_crossMwmTransitGraph.Clear();
|
||||
//}
|
||||
// m_crossMwmIndexGraph.Clear();
|
||||
// m_crossMwmTransitGraph.Clear();
|
||||
// }
|
||||
|
||||
void CrossMwmGraph::Purge()
|
||||
{
|
||||
|
||||
@@ -32,10 +32,8 @@ public:
|
||||
NoSection,
|
||||
};
|
||||
|
||||
CrossMwmGraph(std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
std::shared_ptr<m4::Tree<NumMwmId>> numMwmTree,
|
||||
VehicleType vehicleType, CountryRectFn const & countryRectFn,
|
||||
MwmDataSource & dataSource);
|
||||
CrossMwmGraph(std::shared_ptr<NumMwmIds> numMwmIds, std::shared_ptr<m4::Tree<NumMwmId>> numMwmTree,
|
||||
VehicleType vehicleType, CountryRectFn const & countryRectFn, MwmDataSource & dataSource);
|
||||
|
||||
/// \brief Transition segment is a segment which is crossed by mwm border. That means
|
||||
/// start and finish of such segment have to lie in different mwms. If a segment is
|
||||
@@ -90,10 +88,11 @@ public:
|
||||
|
||||
RouteWeight GetWeightSure(Segment const & from, Segment const & to);
|
||||
|
||||
//void Clear();
|
||||
// void Clear();
|
||||
void Purge();
|
||||
|
||||
template <class FnT> void ForEachTransition(NumMwmId numMwmId, bool isEnter, FnT && fn)
|
||||
template <class FnT>
|
||||
void ForEachTransition(NumMwmId numMwmId, bool isEnter, FnT && fn)
|
||||
{
|
||||
CHECK(CrossMwmSectionExists(numMwmId), ("Should be used in LeapsOnly mode only"));
|
||||
return m_crossMwmIndexGraph.ForEachTransition(numMwmId, isEnter, fn);
|
||||
@@ -127,4 +126,4 @@ private:
|
||||
};
|
||||
|
||||
std::string DebugPrint(CrossMwmGraph::MwmStatus status);
|
||||
} // routing
|
||||
} // namespace routing
|
||||
|
||||
@@ -17,14 +17,15 @@ namespace connector
|
||||
// for transit routing.
|
||||
struct TransitId
|
||||
{
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(TransitId, visitor(m_stop1Id, "stop1_id"),
|
||||
visitor(m_stop2Id, "stop2_id"), visitor(m_lineId, "line_id"))
|
||||
DECLARE_VISITOR_AND_DEBUG_PRINT(TransitId, visitor(m_stop1Id, "stop1_id"), visitor(m_stop2Id, "stop2_id"),
|
||||
visitor(m_lineId, "line_id"))
|
||||
|
||||
TransitId() = default;
|
||||
TransitId(transit::StopId stop1Id, transit::StopId stop2Id, transit::LineId lineId)
|
||||
: m_stop1Id(stop1Id), m_stop2Id(stop2Id), m_lineId(lineId)
|
||||
{
|
||||
}
|
||||
: m_stop1Id(stop1Id)
|
||||
, m_stop2Id(stop2Id)
|
||||
, m_lineId(lineId)
|
||||
{}
|
||||
|
||||
bool operator==(TransitId const & rhs) const
|
||||
{
|
||||
@@ -57,8 +58,7 @@ struct HashKey
|
||||
|
||||
size_t operator()(TransitId const & key) const
|
||||
{
|
||||
return std::hash<uint64_t>()(key.m_stop1Id ^ key.m_stop2Id ^
|
||||
static_cast<uint64_t>(key.m_lineId));
|
||||
return std::hash<uint64_t>()(key.m_stop1Id ^ key.m_stop2Id ^ static_cast<uint64_t>(key.m_lineId));
|
||||
}
|
||||
};
|
||||
} // namespace connector
|
||||
|
||||
@@ -48,8 +48,7 @@ void AssertConnectorIsFound(NumMwmId neighbor, bool isConnectorFound)
|
||||
|
||||
template <>
|
||||
inline void AssertConnectorIsFound<TransitId>(NumMwmId /* neighbor */, bool /* isConnectorFound */)
|
||||
{
|
||||
}
|
||||
{}
|
||||
} // namespace connector
|
||||
|
||||
template <typename CrossMwmId>
|
||||
@@ -59,9 +58,9 @@ public:
|
||||
using ReaderSourceFile = ReaderSource<FilesContainerR::TReader>;
|
||||
|
||||
CrossMwmIndexGraph(MwmDataSource & dataSource, VehicleType vehicleType)
|
||||
: m_dataSource(dataSource), m_vehicleType(vehicleType)
|
||||
{
|
||||
}
|
||||
: m_dataSource(dataSource)
|
||||
, m_vehicleType(vehicleType)
|
||||
{}
|
||||
|
||||
bool IsTransition(Segment const & s, bool isOutgoing)
|
||||
{
|
||||
@@ -69,7 +68,8 @@ public:
|
||||
return c.IsTransition(s, isOutgoing);
|
||||
}
|
||||
|
||||
template <class FnT> void ForEachTransitSegmentId(NumMwmId numMwmId, uint32_t featureId, FnT && fn)
|
||||
template <class FnT>
|
||||
void ForEachTransitSegmentId(NumMwmId numMwmId, uint32_t featureId, FnT && fn)
|
||||
{
|
||||
GetCrossMwmConnectorWithTransitions(numMwmId).ForEachTransitSegmentId(featureId, fn);
|
||||
}
|
||||
@@ -144,10 +144,10 @@ public:
|
||||
return c.GetWeightSure(from, to);
|
||||
}
|
||||
|
||||
// void Clear()
|
||||
// {
|
||||
// m_connectors.clear();
|
||||
// }
|
||||
// void Clear()
|
||||
// {
|
||||
// m_connectors.clear();
|
||||
// }
|
||||
void Purge()
|
||||
{
|
||||
ConnectersMapT tmp;
|
||||
@@ -163,17 +163,13 @@ public:
|
||||
return it->second;
|
||||
|
||||
return Deserialize(numMwmId, [this](CrossMwmConnectorBuilder<CrossMwmId> & builder, auto & src)
|
||||
{
|
||||
builder.DeserializeTransitions(m_vehicleType, src);
|
||||
});
|
||||
{ builder.DeserializeTransitions(m_vehicleType, src); });
|
||||
}
|
||||
|
||||
void LoadCrossMwmConnectorWithTransitions(NumMwmId numMwmId)
|
||||
{
|
||||
GetCrossMwmConnectorWithTransitions(numMwmId);
|
||||
}
|
||||
void LoadCrossMwmConnectorWithTransitions(NumMwmId numMwmId) { GetCrossMwmConnectorWithTransitions(numMwmId); }
|
||||
|
||||
template <class FnT> void ForEachTransition(NumMwmId numMwmId, bool isEnter, FnT && fn)
|
||||
template <class FnT>
|
||||
void ForEachTransition(NumMwmId numMwmId, bool isEnter, FnT && fn)
|
||||
{
|
||||
auto const & connector = GetCrossMwmConnectorWithTransitions(numMwmId);
|
||||
|
||||
@@ -184,7 +180,7 @@ public:
|
||||
private:
|
||||
std::vector<m2::PointD> GetFeaturePointsBySegment(MwmSet::MwmId const & mwmId, Segment const & segment)
|
||||
{
|
||||
auto ft = m_dataSource.GetFeature({ mwmId, segment.GetFeatureId() });
|
||||
auto ft = m_dataSource.GetFeature({mwmId, segment.GetFeatureId()});
|
||||
ft->ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
|
||||
size_t const count = ft->GetPointsCount();
|
||||
@@ -204,10 +200,10 @@ private:
|
||||
if (!s1.IsRealSegment() || !s2.IsRealSegment())
|
||||
return true;
|
||||
|
||||
static_assert(std::is_same<CrossMwmId, base::GeoObjectId>::value ||
|
||||
std::is_same<CrossMwmId, connector::TransitId>::value,
|
||||
"Be careful of usage other ids here. "
|
||||
"Make sure, there is not crash with your new CrossMwmId");
|
||||
static_assert(
|
||||
std::is_same<CrossMwmId, base::GeoObjectId>::value || std::is_same<CrossMwmId, connector::TransitId>::value,
|
||||
"Be careful of usage other ids here. "
|
||||
"Make sure, there is not crash with your new CrossMwmId");
|
||||
|
||||
ASSERT_NOT_EQUAL(s1.GetMwmId(), s2.GetMwmId(), ());
|
||||
|
||||
@@ -226,10 +222,8 @@ private:
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < geo1.size(); ++i)
|
||||
{
|
||||
if (!AlmostEqualAbs(geo1[i], geo2[i], kMwmPointAccuracy))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -240,10 +234,8 @@ private:
|
||||
if (c.WeightsWereLoaded())
|
||||
return c;
|
||||
|
||||
return Deserialize(numMwmId, [](CrossMwmConnectorBuilder<CrossMwmId> & builder, auto & src)
|
||||
{
|
||||
builder.DeserializeWeights(src);
|
||||
});
|
||||
return Deserialize(
|
||||
numMwmId, [](CrossMwmConnectorBuilder<CrossMwmId> & builder, auto & src) { builder.DeserializeWeights(src); });
|
||||
}
|
||||
|
||||
/// \brief Deserializes connectors for an mwm with |numMwmId|.
|
||||
|
||||
@@ -45,7 +45,8 @@ class MwmDataSource
|
||||
public:
|
||||
/// @param[in] numMwmIDs Can be null, if won't call NumMwmId functions.
|
||||
MwmDataSource(DataSource & dataSource, std::shared_ptr<NumMwmIds> numMwmIDs)
|
||||
: m_dataSource(dataSource), m_numMwmIDs(std::move(numMwmIDs))
|
||||
: m_dataSource(dataSource)
|
||||
, m_numMwmIDs(std::move(numMwmIDs))
|
||||
{}
|
||||
|
||||
void FreeHandles()
|
||||
@@ -80,10 +81,7 @@ public:
|
||||
return it->second;
|
||||
}
|
||||
|
||||
MwmValue const & GetMwmValue(NumMwmId numMwmId)
|
||||
{
|
||||
return *GetHandle(numMwmId).GetValue();
|
||||
}
|
||||
MwmValue const & GetMwmValue(NumMwmId numMwmId) { return *GetHandle(numMwmId).GetValue(); }
|
||||
|
||||
SectionStatus GetSectionStatus(NumMwmId numMwmId, std::string const & section)
|
||||
{
|
||||
@@ -99,7 +97,8 @@ public:
|
||||
return m_dataSource.GetMwmIdByCountryFile(m_numMwmIDs->GetFile(numMwmId));
|
||||
}
|
||||
|
||||
template <class FnT> void ForEachStreet(FnT && fn, m2::RectD const & rect)
|
||||
template <class FnT>
|
||||
void ForEachStreet(FnT && fn, m2::RectD const & rect)
|
||||
{
|
||||
m_dataSource.ForEachInRect(fn, rect, scales::GetUpperScale());
|
||||
}
|
||||
@@ -136,4 +135,4 @@ public:
|
||||
return ptr->GetOriginalFeature(id.m_index);
|
||||
}
|
||||
};
|
||||
} // namespace routing
|
||||
} // namespace routing
|
||||
|
||||
@@ -21,14 +21,13 @@ namespace
|
||||
{
|
||||
bool IsFakeFeature(uint32_t featureId)
|
||||
{
|
||||
return routing::FakeFeatureIds::IsGuidesFeature(featureId) ||
|
||||
routing::FakeFeatureIds::IsTransitFeature(featureId);
|
||||
return routing::FakeFeatureIds::IsGuidesFeature(featureId) || routing::FakeFeatureIds::IsTransitFeature(featureId);
|
||||
}
|
||||
|
||||
feature::Metadata::EType GetLanesMetadataTag(FeatureType & ft, bool isForward)
|
||||
{
|
||||
auto directionTag = isForward ? feature::Metadata::FMD_TURN_LANES_FORWARD
|
||||
: feature::Metadata::FMD_TURN_LANES_BACKWARD;
|
||||
auto directionTag =
|
||||
isForward ? feature::Metadata::FMD_TURN_LANES_FORWARD : feature::Metadata::FMD_TURN_LANES_BACKWARD;
|
||||
if (ft.HasMetadata(directionTag))
|
||||
return directionTag;
|
||||
return feature::Metadata::FMD_TURN_LANES;
|
||||
@@ -42,7 +41,8 @@ void LoadLanes(LoadedPathSegment & pathSegment, FeatureType & ft, bool isForward
|
||||
} // namespace
|
||||
|
||||
DirectionsEngine::DirectionsEngine(MwmDataSource & dataSource, std::shared_ptr<NumMwmIds> numMwmIds)
|
||||
: m_dataSource(dataSource), m_numMwmIds(numMwmIds)
|
||||
: m_dataSource(dataSource)
|
||||
, m_numMwmIds(numMwmIds)
|
||||
, m_linkChecker(IsLinkChecker::Instance())
|
||||
, m_roundAboutChecker(IsRoundAboutChecker::Instance())
|
||||
, m_onewayChecker(IsOneWayChecker::Instance())
|
||||
@@ -63,8 +63,7 @@ unique_ptr<FeatureType> DirectionsEngine::GetFeature(FeatureID const & featureId
|
||||
return m_dataSource.GetFeature(featureId);
|
||||
}
|
||||
|
||||
void DirectionsEngine::LoadPathAttributes(FeatureID const & featureId,
|
||||
LoadedPathSegment & pathSegment, bool isForward)
|
||||
void DirectionsEngine::LoadPathAttributes(FeatureID const & featureId, LoadedPathSegment & pathSegment, bool isForward)
|
||||
{
|
||||
if (!featureId.IsValid())
|
||||
return;
|
||||
@@ -93,16 +92,14 @@ void DirectionsEngine::LoadPathAttributes(FeatureID const & featureId,
|
||||
pathSegment.m_roadNameInfo.m_name = ft->GetName(StringUtf8Multilang::kDefaultCode);
|
||||
}
|
||||
|
||||
void DirectionsEngine::GetSegmentRangeAndAdjacentEdges(IRoadGraph::EdgeListT const & outgoingEdges,
|
||||
Edge const & inEdge, uint32_t startSegId,
|
||||
uint32_t endSegId,
|
||||
SegmentRange & segmentRange,
|
||||
TurnCandidates & outgoingTurns)
|
||||
void DirectionsEngine::GetSegmentRangeAndAdjacentEdges(IRoadGraph::EdgeListT const & outgoingEdges, Edge const & inEdge,
|
||||
uint32_t startSegId, uint32_t endSegId,
|
||||
SegmentRange & segmentRange, TurnCandidates & outgoingTurns)
|
||||
{
|
||||
outgoingTurns.isCandidatesAngleValid = true;
|
||||
outgoingTurns.candidates.reserve(outgoingEdges.size());
|
||||
segmentRange = SegmentRange(inEdge.GetFeatureId(), startSegId, endSegId, inEdge.IsForward(),
|
||||
inEdge.GetStartPoint(), inEdge.GetEndPoint());
|
||||
segmentRange = SegmentRange(inEdge.GetFeatureId(), startSegId, endSegId, inEdge.IsForward(), inEdge.GetStartPoint(),
|
||||
inEdge.GetEndPoint());
|
||||
CHECK(segmentRange.IsCorrect(), ());
|
||||
m2::PointD const & ingoingPoint = inEdge.GetStartJunction().GetPoint();
|
||||
m2::PointD const & junctionPoint = inEdge.GetEndJunction().GetPoint();
|
||||
@@ -127,8 +124,8 @@ void DirectionsEngine::GetSegmentRangeAndAdjacentEdges(IRoadGraph::EdgeListT con
|
||||
{
|
||||
ASSERT_LESS(mercator::DistanceOnEarth(junctionPoint, edge.GetStartJunction().GetPoint()),
|
||||
turns::kFeaturesNearTurnMeters, ());
|
||||
angle = math::RadToDeg(turns::PiMinusTwoVectorsAngle(junctionPoint, ingoingPoint,
|
||||
edge.GetEndJunction().GetPoint()));
|
||||
angle =
|
||||
math::RadToDeg(turns::PiMinusTwoVectorsAngle(junctionPoint, ingoingPoint, edge.GetEndJunction().GetPoint()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -140,20 +137,18 @@ void DirectionsEngine::GetSegmentRangeAndAdjacentEdges(IRoadGraph::EdgeListT con
|
||||
outgoingTurns.isCandidatesAngleValid = false;
|
||||
}
|
||||
|
||||
outgoingTurns.candidates.emplace_back(angle, ConvertEdgeToSegment(*m_numMwmIds, edge),
|
||||
highwayClass, m_linkChecker(types));
|
||||
outgoingTurns.candidates.emplace_back(angle, ConvertEdgeToSegment(*m_numMwmIds, edge), highwayClass,
|
||||
m_linkChecker(types));
|
||||
}
|
||||
|
||||
if (outgoingTurns.isCandidatesAngleValid)
|
||||
{
|
||||
sort(outgoingTurns.candidates.begin(), outgoingTurns.candidates.end(),
|
||||
base::LessBy(&TurnCandidate::m_angle));
|
||||
}
|
||||
sort(outgoingTurns.candidates.begin(), outgoingTurns.candidates.end(), base::LessBy(&TurnCandidate::m_angle));
|
||||
}
|
||||
|
||||
void DirectionsEngine::FillPathSegmentsAndAdjacentEdgesMap(
|
||||
IndexRoadGraph const & graph, vector<geometry::PointWithAltitude> const & path,
|
||||
IRoadGraph::EdgeVector const & routeEdges, base::Cancellable const & cancellable)
|
||||
void DirectionsEngine::FillPathSegmentsAndAdjacentEdgesMap(IndexRoadGraph const & graph,
|
||||
vector<geometry::PointWithAltitude> const & path,
|
||||
IRoadGraph::EdgeVector const & routeEdges,
|
||||
base::Cancellable const & cancellable)
|
||||
{
|
||||
size_t const pathSize = path.size();
|
||||
CHECK_GREATER(pathSize, 1, ());
|
||||
@@ -219,8 +214,8 @@ void DirectionsEngine::FillPathSegmentsAndAdjacentEdgesMap(
|
||||
/// @todo By VNG: Here was mostly investigational CHECK.
|
||||
/// Entry already exists, when start-end points are on the same fake segments.
|
||||
|
||||
//bool const isEmpty = adjacentEdges.m_outgoingTurns.candidates.empty();
|
||||
//CHECK(m_adjacentEdges.emplace(segmentRange, std::move(adjacentEdges)).second || isEmpty, ());
|
||||
// bool const isEmpty = adjacentEdges.m_outgoingTurns.candidates.empty();
|
||||
// CHECK(m_adjacentEdges.emplace(segmentRange, std::move(adjacentEdges)).second || isEmpty, ());
|
||||
m_adjacentEdges.emplace(segmentRange, std::move(adjacentEdges));
|
||||
}
|
||||
|
||||
@@ -232,10 +227,8 @@ void DirectionsEngine::FillPathSegmentsAndAdjacentEdgesMap(
|
||||
}
|
||||
}
|
||||
|
||||
bool DirectionsEngine::Generate(IndexRoadGraph const & graph,
|
||||
vector<geometry::PointWithAltitude> const & path,
|
||||
base::Cancellable const & cancellable,
|
||||
vector<RouteSegment> & routeSegments)
|
||||
bool DirectionsEngine::Generate(IndexRoadGraph const & graph, vector<geometry::PointWithAltitude> const & path,
|
||||
base::Cancellable const & cancellable, vector<RouteSegment> & routeSegments)
|
||||
{
|
||||
CHECK(m_numMwmIds, ());
|
||||
|
||||
@@ -324,10 +317,10 @@ void DirectionsEngine::MakeTurnAnnotation(IndexRoadGraph::EdgeVector const & rou
|
||||
|
||||
RoutingSettings const vehicleSettings = GetRoutingSettings(m_vehicleType);
|
||||
|
||||
auto const & loadedSegments = result.GetSegments(); // the same as m_pathSegments
|
||||
auto const & loadedSegments = result.GetSegments(); // the same as m_pathSegments
|
||||
|
||||
// First point of first loadedSegment is ignored. This is the reason for:
|
||||
//ASSERT_EQUAL(loadedSegments.front().m_path.back(), loadedSegments.front().m_path.front(), ());
|
||||
// ASSERT_EQUAL(loadedSegments.front().m_path.back(), loadedSegments.front().m_path.front(), ());
|
||||
|
||||
size_t skipTurnSegments = 0;
|
||||
for (size_t idxLoadedSegment = 0; idxLoadedSegment < loadedSegments.size(); ++idxLoadedSegment)
|
||||
@@ -345,7 +338,7 @@ void DirectionsEngine::MakeTurnAnnotation(IndexRoadGraph::EdgeVector const & rou
|
||||
auto const & junction = loadedSegment.m_path[i + 1];
|
||||
routeSegments.emplace_back(loadedSegment.m_segments[i], TurnItem(), junction, rni);
|
||||
if (i == 0)
|
||||
rni = {"","","","", "", loadedSegment.m_isLink};
|
||||
rni = {"", "", "", "", "", loadedSegment.m_isLink};
|
||||
}
|
||||
|
||||
// For the last segment of current loadedSegment put info about turn
|
||||
@@ -362,8 +355,8 @@ void DirectionsEngine::MakeTurnAnnotation(IndexRoadGraph::EdgeVector const & rou
|
||||
routeSegments.emplace_back(loadedSegment.m_segments.back(), turnItem, loadedSegment.m_path.back(), rni);
|
||||
}
|
||||
|
||||
//ASSERT_EQUAL(routeSegments.front().GetJunction(), result.GetStartPoint(), ());
|
||||
//ASSERT_EQUAL(routeSegments.back().GetJunction(), result.GetEndPoint(), ());
|
||||
// ASSERT_EQUAL(routeSegments.front().GetJunction(), result.GetStartPoint(), ());
|
||||
// ASSERT_EQUAL(routeSegments.back().GetJunction(), result.GetEndPoint(), ());
|
||||
|
||||
FixupTurns(routeSegments);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace turns
|
||||
{
|
||||
class IRoutingResult;
|
||||
struct TurnItem;
|
||||
}
|
||||
} // namespace turns
|
||||
|
||||
enum class RouterResultCode;
|
||||
class MwmDataSource;
|
||||
@@ -36,29 +36,26 @@ public:
|
||||
/// \brief Generates all args which are passed by reference.
|
||||
/// \param path is points of the route. It should not be empty.
|
||||
/// \returns true if fields passed by reference are filled correctly and false otherwise.
|
||||
bool Generate(IndexRoadGraph const & graph,
|
||||
std::vector<geometry::PointWithAltitude> const & path,
|
||||
base::Cancellable const & cancellable,
|
||||
std::vector<RouteSegment> & routeSegments);
|
||||
bool Generate(IndexRoadGraph const & graph, std::vector<geometry::PointWithAltitude> const & path,
|
||||
base::Cancellable const & cancellable, std::vector<RouteSegment> & routeSegments);
|
||||
void Clear();
|
||||
|
||||
void SetVehicleType(VehicleType const & vehicleType) { m_vehicleType = vehicleType; }
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \brief GetTurnDirection makes a primary decision about turns on the route.
|
||||
* \param outgoingSegmentIndex index of an outgoing segments in vector result.GetSegments().
|
||||
* \param turn is used for keeping the result of turn calculation.
|
||||
*/
|
||||
* \brief GetTurnDirection makes a primary decision about turns on the route.
|
||||
* \param outgoingSegmentIndex index of an outgoing segments in vector result.GetSegments().
|
||||
* \param turn is used for keeping the result of turn calculation.
|
||||
*/
|
||||
virtual size_t GetTurnDirection(turns::IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds,
|
||||
RoutingSettings const & vehicleSettings, turns::TurnItem & turn) = 0;
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings,
|
||||
turns::TurnItem & turn) = 0;
|
||||
virtual void FixupTurns(std::vector<RouteSegment> & routeSegments) = 0;
|
||||
std::unique_ptr<FeatureType> GetFeature(FeatureID const & featureId);
|
||||
void LoadPathAttributes(FeatureID const & featureId, LoadedPathSegment & pathSegment, bool isForward);
|
||||
void GetSegmentRangeAndAdjacentEdges(IRoadGraph::EdgeListT const & outgoingEdges,
|
||||
Edge const & inEdge, uint32_t startSegId, uint32_t endSegId,
|
||||
SegmentRange & segmentRange,
|
||||
void GetSegmentRangeAndAdjacentEdges(IRoadGraph::EdgeListT const & outgoingEdges, Edge const & inEdge,
|
||||
uint32_t startSegId, uint32_t endSegId, SegmentRange & segmentRange,
|
||||
turns::TurnCandidates & outgoingTurns);
|
||||
/// \brief The method gathers sequence of segments according to IsJoint() method
|
||||
/// and fills |m_adjacentEdges| and |m_pathSegments|.
|
||||
@@ -75,8 +72,7 @@ protected:
|
||||
VehicleType m_vehicleType = VehicleType::Count;
|
||||
|
||||
private:
|
||||
void MakeTurnAnnotation(IndexRoadGraph::EdgeVector const & routeEdges,
|
||||
std::vector<RouteSegment> & routeSegments);
|
||||
void MakeTurnAnnotation(IndexRoadGraph::EdgeVector const & routeEdges, std::vector<RouteSegment> & routeSegments);
|
||||
|
||||
ftypes::IsLinkChecker const & m_linkChecker;
|
||||
ftypes::IsRoundAboutChecker const & m_roundAboutChecker;
|
||||
|
||||
@@ -6,8 +6,7 @@ namespace routing
|
||||
{
|
||||
bool AdjacentEdges::IsAlmostEqual(AdjacentEdges const & rhs) const
|
||||
{
|
||||
return m_outgoingTurns.IsAlmostEqual(rhs.m_outgoingTurns) &&
|
||||
m_ingoingTurnsCount == rhs.m_ingoingTurnsCount;
|
||||
return m_outgoingTurns.IsAlmostEqual(rhs.m_outgoingTurns) && m_ingoingTurnsCount == rhs.m_ingoingTurnsCount;
|
||||
}
|
||||
|
||||
RoutingEngineResult::RoutingEngineResult(IRoadGraph::EdgeVector const & routeEdges,
|
||||
@@ -19,18 +18,14 @@ RoutingEngineResult::RoutingEngineResult(IRoadGraph::EdgeVector const & routeEdg
|
||||
, m_routeLength(0)
|
||||
{
|
||||
for (auto const & edge : routeEdges)
|
||||
{
|
||||
m_routeLength += mercator::DistanceOnEarth(edge.GetStartJunction().GetPoint(),
|
||||
edge.GetEndJunction().GetPoint());
|
||||
}
|
||||
m_routeLength += mercator::DistanceOnEarth(edge.GetStartJunction().GetPoint(), edge.GetEndJunction().GetPoint());
|
||||
}
|
||||
|
||||
void RoutingEngineResult::GetPossibleTurns(SegmentRange const & segmentRange,
|
||||
m2::PointD const & junctionPoint, size_t & ingoingCount,
|
||||
turns::TurnCandidates & outgoingTurns) const
|
||||
void RoutingEngineResult::GetPossibleTurns(SegmentRange const & segmentRange, m2::PointD const & junctionPoint,
|
||||
size_t & ingoingCount, turns::TurnCandidates & outgoingTurns) const
|
||||
{
|
||||
CHECK(!segmentRange.IsEmpty(), ("SegmentRange presents a fake feature.",
|
||||
"junctionPoint:", mercator::ToLatLon(junctionPoint)));
|
||||
CHECK(!segmentRange.IsEmpty(),
|
||||
("SegmentRange presents a fake feature.", "junctionPoint:", mercator::ToLatLon(junctionPoint)));
|
||||
|
||||
ingoingCount = 0;
|
||||
outgoingTurns.candidates.clear();
|
||||
@@ -58,9 +53,8 @@ geometry::PointWithAltitude RoutingEngineResult::GetEndPoint() const
|
||||
return m_routeEdges.back().GetEndJunction();
|
||||
}
|
||||
|
||||
bool IsJoint(IRoadGraph::EdgeListT const & ingoingEdges,
|
||||
IRoadGraph::EdgeListT const & outgoingEdges, Edge const & ingoingRouteEdge,
|
||||
Edge const & outgoingRouteEdge)
|
||||
bool IsJoint(IRoadGraph::EdgeListT const & ingoingEdges, IRoadGraph::EdgeListT const & outgoingEdges,
|
||||
Edge const & ingoingRouteEdge, Edge const & outgoingRouteEdge)
|
||||
{
|
||||
// When feature id is changed at a junction this junction should be considered as a joint.
|
||||
//
|
||||
@@ -83,10 +77,8 @@ bool IsJoint(IRoadGraph::EdgeListT const & ingoingEdges,
|
||||
FeatureID const & featureId = ingoingRouteEdge.GetFeatureId();
|
||||
uint32_t const segOut = outgoingRouteEdge.GetSegId();
|
||||
for (Edge const & e : ingoingEdges)
|
||||
{
|
||||
if (e.GetFeatureId() != featureId || abs(static_cast<int32_t>(segOut - e.GetSegId())) != 1)
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t const segIn = ingoingRouteEdge.GetSegId();
|
||||
for (Edge const & e : outgoingEdges)
|
||||
|
||||
@@ -24,15 +24,13 @@ using AdjacentEdgesMap = std::map<SegmentRange, AdjacentEdges>;
|
||||
class RoutingEngineResult : public turns::IRoutingResult
|
||||
{
|
||||
public:
|
||||
RoutingEngineResult(IRoadGraph::EdgeVector const & routeEdges,
|
||||
AdjacentEdgesMap const & adjacentEdges,
|
||||
RoutingEngineResult(IRoadGraph::EdgeVector const & routeEdges, AdjacentEdgesMap const & adjacentEdges,
|
||||
TUnpackedPathSegments const & pathSegments);
|
||||
|
||||
// turns::IRoutingResult overrides:
|
||||
TUnpackedPathSegments const & GetSegments() const override { return m_pathSegments; }
|
||||
|
||||
void GetPossibleTurns(SegmentRange const & segmentRange, m2::PointD const & junctionPoint,
|
||||
size_t & ingoingCount,
|
||||
void GetPossibleTurns(SegmentRange const & segmentRange, m2::PointD const & junctionPoint, size_t & ingoingCount,
|
||||
turns::TurnCandidates & outgoingTurns) const override;
|
||||
|
||||
double GetPathLength() const override { return m_routeLength; }
|
||||
@@ -51,7 +49,6 @@ private:
|
||||
/// \returns false if the junction is an internal point of feature segment and can be considered as
|
||||
/// a part of LoadedPathSegment and returns true if the junction should be considered as a beginning
|
||||
/// of a new LoadedPathSegment.
|
||||
bool IsJoint(IRoadGraph::EdgeListT const & ingoingEdges,
|
||||
IRoadGraph::EdgeListT const & outgoingEdges, Edge const & ingoingRouteEdge,
|
||||
Edge const & outgoingRouteEdge);
|
||||
bool IsJoint(IRoadGraph::EdgeListT const & ingoingEdges, IRoadGraph::EdgeListT const & outgoingEdges,
|
||||
Edge const & ingoingRouteEdge, Edge const & outgoingRouteEdge);
|
||||
} // namespace routing
|
||||
|
||||
@@ -23,45 +23,28 @@ class DummyWorldGraph final : public WorldGraph
|
||||
public:
|
||||
using WorldGraph::GetEdgeList;
|
||||
|
||||
void GetEdgeList(astar::VertexData<Segment, RouteWeight> const & vertexData, bool isOutgoing,
|
||||
bool useRoutingOptions, bool useAccessConditional,
|
||||
SegmentEdgeListT & edges) override
|
||||
void GetEdgeList(astar::VertexData<Segment, RouteWeight> const & vertexData, bool isOutgoing, bool useRoutingOptions,
|
||||
bool useAccessConditional, SegmentEdgeListT & edges) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void GetEdgeList(astar::VertexData<JointSegment, RouteWeight> const & vertexData,
|
||||
Segment const & segment, bool isOutgoing, bool useAccessConditional,
|
||||
JointEdgeListT & edges,
|
||||
void GetEdgeList(astar::VertexData<JointSegment, RouteWeight> const & vertexData, Segment const & segment,
|
||||
bool isOutgoing, bool useAccessConditional, JointEdgeListT & edges,
|
||||
WeightListT & parentWeights) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
bool CheckLength(RouteWeight const & weight, double startToFinishDistanceM) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool CheckLength(RouteWeight const & weight, double startToFinishDistanceM) const override { return true; }
|
||||
|
||||
LatLonWithAltitude const & GetJunction(Segment const & segment, bool front) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
LatLonWithAltitude const & GetJunction(Segment const & segment, bool front) override { UNREACHABLE(); }
|
||||
|
||||
ms::LatLon const & GetPoint(Segment const & segment, bool front) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
ms::LatLon const & GetPoint(Segment const & segment, bool front) override { UNREACHABLE(); }
|
||||
|
||||
bool IsOneWay(NumMwmId mwmId, uint32_t featureId) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
bool IsOneWay(NumMwmId mwmId, uint32_t featureId) override { UNREACHABLE(); }
|
||||
|
||||
bool IsPassThroughAllowed(NumMwmId mwmId, uint32_t featureId) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
bool IsPassThroughAllowed(NumMwmId mwmId, uint32_t featureId) override { UNREACHABLE(); }
|
||||
|
||||
void ClearCachedGraphs() override { UNREACHABLE(); }
|
||||
|
||||
@@ -74,13 +57,9 @@ public:
|
||||
return RouteWeight(ms::DistanceOnEarth(from, to));
|
||||
}
|
||||
|
||||
RouteWeight CalcSegmentWeight(Segment const & segment, EdgeEstimator::Purpose purpose) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
RouteWeight CalcSegmentWeight(Segment const & segment, EdgeEstimator::Purpose purpose) override { UNREACHABLE(); }
|
||||
|
||||
RouteWeight CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to,
|
||||
NumMwmId mwmId) const override
|
||||
RouteWeight CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to, NumMwmId mwmId) const override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
@@ -91,23 +70,13 @@ public:
|
||||
return RouteWeight(ms::DistanceOnEarth(from, to));
|
||||
}
|
||||
|
||||
double CalculateETA(Segment const & from, Segment const & to) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
double CalculateETA(Segment const & from, Segment const & to) override { UNREACHABLE(); }
|
||||
|
||||
double CalculateETAWithoutPenalty(Segment const & segment) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
double CalculateETAWithoutPenalty(Segment const & segment) override { UNREACHABLE(); }
|
||||
|
||||
IndexGraph & GetIndexGraph(NumMwmId numMwmId) override
|
||||
{
|
||||
UNREACHABLE();
|
||||
}
|
||||
IndexGraph & GetIndexGraph(NumMwmId numMwmId) override { UNREACHABLE(); }
|
||||
|
||||
void GetTwinsInner(Segment const & segment, bool isOutgoing,
|
||||
std::vector<Segment> & twins) override
|
||||
void GetTwinsInner(Segment const & segment, bool isOutgoing, std::vector<Segment> & twins) override
|
||||
{
|
||||
CHECK(false, ());
|
||||
}
|
||||
|
||||
@@ -60,13 +60,13 @@ bool IsTransit(std::optional<HighwayType> type)
|
||||
}
|
||||
|
||||
template <class CalcSpeed>
|
||||
double CalcClimbSegment(EdgeEstimator::Purpose purpose, Segment const & segment,
|
||||
RoadGeometry const & road, CalcSpeed && calcSpeed)
|
||||
double CalcClimbSegment(EdgeEstimator::Purpose purpose, Segment const & segment, RoadGeometry const & road,
|
||||
CalcSpeed && calcSpeed)
|
||||
{
|
||||
double const distance = road.GetDistance(segment.GetSegmentIdx());
|
||||
double speedMpS = GetSpeedMpS(purpose, segment, road);
|
||||
|
||||
static double constexpr kSmallDistanceM = 1; // we have altitude threshold is 0.5m
|
||||
static double constexpr kSmallDistanceM = 1; // we have altitude threshold is 0.5m
|
||||
if (distance > kSmallDistanceM && !IsTransit(road.GetHighwayType()))
|
||||
{
|
||||
LatLonWithAltitude const & from = road.GetJunction(segment.GetPointId(false /* front */));
|
||||
@@ -103,14 +103,13 @@ double GetPedestrianClimbPenalty(EdgeEstimator::Purpose purpose, double tangent,
|
||||
tangent = fabs(tangent);
|
||||
// Some thoughts about gradient and foot walking: https://gre-kow.livejournal.com/26916.html
|
||||
// 3cm diff with avg foot length 60cm is imperceptible (see Hungary_UseFootways).
|
||||
double constexpr kTangentThreshold = 3.0/60.0;
|
||||
double constexpr kTangentThreshold = 3.0 / 60.0;
|
||||
if (tangent < kTangentThreshold)
|
||||
return kMinPenalty;
|
||||
|
||||
// ETA coefficients are calculated in https://github.com/mapsme/omim-scripts/pull/21
|
||||
auto const penalty = purpose == EdgeEstimator::Purpose::Weight
|
||||
? 5.0 * tangent + 7.0 * tangent * tangent
|
||||
: 3.01 * tangent + 3.54 * tangent * tangent;
|
||||
auto const penalty = purpose == EdgeEstimator::Purpose::Weight ? 5.0 * tangent + 7.0 * tangent * tangent
|
||||
: 3.01 * tangent + 3.54 * tangent * tangent;
|
||||
|
||||
return kMinPenalty + penalty * impact;
|
||||
}
|
||||
@@ -171,8 +170,8 @@ EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroa
|
||||
DataSource * /*dataSourcePtr*/, std::shared_ptr<NumMwmIds> /*numMwmIds*/)
|
||||
: m_maxWeightSpeedMpS(KmphToMps(maxWeightSpeedKMpH))
|
||||
, m_offroadSpeedKMpH(offroadSpeedKMpH)
|
||||
//, m_dataSourcePtr(dataSourcePtr)
|
||||
//, m_numMwmIds(numMwmIds)
|
||||
//, m_dataSourcePtr(dataSourcePtr)
|
||||
//, m_numMwmIds(numMwmIds)
|
||||
{
|
||||
CHECK_GREATER(m_offroadSpeedKMpH.m_weight, 0.0, ());
|
||||
CHECK_GREATER(m_offroadSpeedKMpH.m_eta, 0.0, ());
|
||||
@@ -192,7 +191,7 @@ double EdgeEstimator::CalcHeuristic(ms::LatLon const & from, ms::LatLon const &
|
||||
double EdgeEstimator::ComputeDefaultLeapWeightSpeed() const
|
||||
{
|
||||
// 1.76 factor was computed as an average ratio of escape/enter speed to max MWM speed across all MWMs.
|
||||
//return m_maxWeightSpeedMpS / 1.76;
|
||||
// return m_maxWeightSpeedMpS / 1.76;
|
||||
|
||||
// By VNG: Current m_maxWeightSpeedMpS is > 120 km/h, so estimating speed was > 60km/h
|
||||
// for start/end fake edges by straight line! I strongly believe that this is very! optimistic.
|
||||
@@ -231,13 +230,13 @@ double EdgeEstimator::GetLeapWeightSpeed(NumMwmId /*mwmId*/)
|
||||
|
||||
/// @todo By VNG: We don't have LEAP_SPEEDS_FILE to assign RegionData::SetLeapWeightSpeed
|
||||
/// unique for each MWM, so this is useless now. And what about possible races here?
|
||||
// if (mwmId != kFakeNumMwmId)
|
||||
// {
|
||||
// auto [speedIt, inserted] = m_leapWeightSpeedMpS.emplace(mwmId, defaultSpeed);
|
||||
// if (inserted)
|
||||
// speedIt->second = LoadLeapWeightSpeed(mwmId);
|
||||
// return speedIt->second;
|
||||
// }
|
||||
// if (mwmId != kFakeNumMwmId)
|
||||
// {
|
||||
// auto [speedIt, inserted] = m_leapWeightSpeedMpS.emplace(mwmId, defaultSpeed);
|
||||
// if (inserted)
|
||||
// speedIt->second = LoadLeapWeightSpeed(mwmId);
|
||||
// return speedIt->second;
|
||||
// }
|
||||
|
||||
return defaultSpeed;
|
||||
}
|
||||
@@ -247,13 +246,14 @@ double EdgeEstimator::CalcLeapWeight(ms::LatLon const & from, ms::LatLon const &
|
||||
return TimeBetweenSec(from, to, GetLeapWeightSpeed(mwmId));
|
||||
}
|
||||
|
||||
double EdgeEstimator::GetMaxWeightSpeedMpS() const { return m_maxWeightSpeedMpS; }
|
||||
|
||||
double EdgeEstimator::CalcOffroad(ms::LatLon const & from, ms::LatLon const & to,
|
||||
Purpose purpose) const
|
||||
double EdgeEstimator::GetMaxWeightSpeedMpS() const
|
||||
{
|
||||
auto const offroadSpeedKMpH =
|
||||
purpose == Purpose::Weight ? m_offroadSpeedKMpH.m_weight : m_offroadSpeedKMpH.m_eta;
|
||||
return m_maxWeightSpeedMpS;
|
||||
}
|
||||
|
||||
double EdgeEstimator::CalcOffroad(ms::LatLon const & from, ms::LatLon const & to, Purpose purpose) const
|
||||
{
|
||||
auto const offroadSpeedKMpH = purpose == Purpose::Weight ? m_offroadSpeedKMpH.m_weight : m_offroadSpeedKMpH.m_eta;
|
||||
if (offroadSpeedKMpH == kNotUsed)
|
||||
return 0.0;
|
||||
|
||||
@@ -266,8 +266,7 @@ class PedestrianEstimator final : public EdgeEstimator
|
||||
public:
|
||||
PedestrianEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH)
|
||||
: EdgeEstimator(maxWeightSpeedKMpH, offroadSpeedKMpH)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// EdgeEstimator overrides:
|
||||
double GetUTurnPenalty(Purpose /* purpose */) const override { return 0.0 /* seconds */; }
|
||||
@@ -275,8 +274,8 @@ public:
|
||||
{
|
||||
switch (purpose)
|
||||
{
|
||||
case Purpose::Weight: return 10 * 60; // seconds
|
||||
case Purpose::ETA: return 8 * 60; // seconds
|
||||
case Purpose::Weight: return 10 * 60; // seconds
|
||||
case Purpose::ETA: return 8 * 60; // seconds
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
@@ -284,10 +283,8 @@ public:
|
||||
double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override
|
||||
{
|
||||
return CalcClimbSegment(purpose, segment, road,
|
||||
[purpose](double speedMpS, double tangent, geometry::Altitude altitude)
|
||||
{
|
||||
return speedMpS / GetPedestrianClimbPenalty(purpose, tangent, altitude);
|
||||
});
|
||||
[purpose](double speedMpS, double tangent, geometry::Altitude altitude)
|
||||
{ return speedMpS / GetPedestrianClimbPenalty(purpose, tangent, altitude); });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -297,8 +294,7 @@ class BicycleEstimator final : public EdgeEstimator
|
||||
public:
|
||||
BicycleEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH)
|
||||
: EdgeEstimator(maxWeightSpeedKMpH, offroadSpeedKMpH)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// EdgeEstimator overrides:
|
||||
double GetUTurnPenalty(Purpose /* purpose */) const override { return 20.0 /* seconds */; }
|
||||
@@ -306,8 +302,8 @@ public:
|
||||
{
|
||||
switch (purpose)
|
||||
{
|
||||
case Purpose::Weight: return 10 * 60; // seconds
|
||||
case Purpose::ETA: return 8 * 60; // seconds
|
||||
case Purpose::Weight: return 10 * 60; // seconds
|
||||
case Purpose::ETA: return 8 * 60; // seconds
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
@@ -315,38 +311,35 @@ public:
|
||||
double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override
|
||||
{
|
||||
return CalcClimbSegment(purpose, segment, road,
|
||||
[purpose, this](double speedMpS, double tangent, geometry::Altitude altitude)
|
||||
[purpose, this](double speedMpS, double tangent, geometry::Altitude altitude)
|
||||
{
|
||||
auto const factor = GetBicycleClimbPenalty(purpose, tangent, altitude);
|
||||
ASSERT_GREATER(factor, 0.0, ());
|
||||
|
||||
/// @todo Take out "bad" bicycle road (path, track, footway, ...) check into BicycleModel?
|
||||
static double constexpr badBicycleRoadSpeed = KmphToMps(9);
|
||||
if (speedMpS <= badBicycleRoadSpeed)
|
||||
{
|
||||
if (factor > 1)
|
||||
speedMpS /= factor;
|
||||
}
|
||||
else if (factor > 1)
|
||||
{
|
||||
// Calculate uphill speed according to the average bicycle speed, because "good-roads" like
|
||||
// residential, secondary, cycleway are "equal-low-speed" uphill and road type doesn't matter.
|
||||
static double constexpr avgBicycleSpeed = KmphToMps(20);
|
||||
double const upperBound = avgBicycleSpeed / factor;
|
||||
if (speedMpS > upperBound)
|
||||
{
|
||||
auto const factor = GetBicycleClimbPenalty(purpose, tangent, altitude);
|
||||
ASSERT_GREATER(factor, 0.0, ());
|
||||
// Add small weight to distinguish roads by class (10 is a max factor value).
|
||||
speedMpS = upperBound + (purpose == Purpose::Weight ? speedMpS / (10 * avgBicycleSpeed) : 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
speedMpS /= factor;
|
||||
|
||||
/// @todo Take out "bad" bicycle road (path, track, footway, ...) check into BicycleModel?
|
||||
static double constexpr badBicycleRoadSpeed = KmphToMps(9);
|
||||
if (speedMpS <= badBicycleRoadSpeed)
|
||||
{
|
||||
if (factor > 1)
|
||||
speedMpS /= factor;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (factor > 1)
|
||||
{
|
||||
// Calculate uphill speed according to the average bicycle speed, because "good-roads" like
|
||||
// residential, secondary, cycleway are "equal-low-speed" uphill and road type doesn't matter.
|
||||
static double constexpr avgBicycleSpeed = KmphToMps(20);
|
||||
double const upperBound = avgBicycleSpeed / factor;
|
||||
if (speedMpS > upperBound)
|
||||
{
|
||||
// Add small weight to distinguish roads by class (10 is a max factor value).
|
||||
speedMpS = upperBound + (purpose == Purpose::Weight ? speedMpS / (10 * avgBicycleSpeed) : 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
speedMpS /= factor;
|
||||
}
|
||||
|
||||
return std::min(speedMpS, GetMaxWeightSpeedMpS());
|
||||
});
|
||||
return std::min(speedMpS, GetMaxWeightSpeedMpS());
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -354,13 +347,11 @@ public:
|
||||
class CarEstimator final : public EdgeEstimator
|
||||
{
|
||||
public:
|
||||
CarEstimator(DataSource * dataSourcePtr, std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
shared_ptr<TrafficStash> trafficStash, double maxWeightSpeedKMpH,
|
||||
SpeedKMpH const & offroadSpeedKMpH)
|
||||
CarEstimator(DataSource * dataSourcePtr, std::shared_ptr<NumMwmIds> numMwmIds, shared_ptr<TrafficStash> trafficStash,
|
||||
double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH)
|
||||
: EdgeEstimator(maxWeightSpeedKMpH, offroadSpeedKMpH, dataSourcePtr, numMwmIds)
|
||||
, m_trafficStash(std::move(trafficStash))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// EdgeEstimator overrides:
|
||||
double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const override;
|
||||
@@ -376,8 +367,8 @@ public:
|
||||
{
|
||||
switch (purpose)
|
||||
{
|
||||
case Purpose::Weight: return 20 * 60; // seconds
|
||||
case Purpose::ETA: return 20 * 60; // seconds
|
||||
case Purpose::Weight: return 20 * 60; // seconds
|
||||
case Purpose::ETA: return 20 * 60; // seconds
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
@@ -413,35 +404,27 @@ double CarEstimator::CalcSegmentWeight(Segment const & segment, RoadGeometry con
|
||||
// static
|
||||
shared_ptr<EdgeEstimator> EdgeEstimator::Create(VehicleType vehicleType, double maxWeighSpeedKMpH,
|
||||
SpeedKMpH const & offroadSpeedKMpH,
|
||||
shared_ptr<TrafficStash> trafficStash,
|
||||
DataSource * dataSourcePtr,
|
||||
shared_ptr<TrafficStash> trafficStash, DataSource * dataSourcePtr,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds)
|
||||
{
|
||||
switch (vehicleType)
|
||||
{
|
||||
case VehicleType::Pedestrian:
|
||||
case VehicleType::Transit:
|
||||
return make_shared<PedestrianEstimator>(maxWeighSpeedKMpH, offroadSpeedKMpH);
|
||||
case VehicleType::Bicycle:
|
||||
return make_shared<BicycleEstimator>(maxWeighSpeedKMpH, offroadSpeedKMpH);
|
||||
case VehicleType::Transit: return make_shared<PedestrianEstimator>(maxWeighSpeedKMpH, offroadSpeedKMpH);
|
||||
case VehicleType::Bicycle: return make_shared<BicycleEstimator>(maxWeighSpeedKMpH, offroadSpeedKMpH);
|
||||
case VehicleType::Car:
|
||||
return make_shared<CarEstimator>(dataSourcePtr, numMwmIds, trafficStash, maxWeighSpeedKMpH,
|
||||
offroadSpeedKMpH);
|
||||
case VehicleType::Count:
|
||||
CHECK(false, ("Can't create EdgeEstimator for", vehicleType));
|
||||
return nullptr;
|
||||
return make_shared<CarEstimator>(dataSourcePtr, numMwmIds, trafficStash, maxWeighSpeedKMpH, offroadSpeedKMpH);
|
||||
case VehicleType::Count: CHECK(false, ("Can't create EdgeEstimator for", vehicleType)); return nullptr;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// static
|
||||
shared_ptr<EdgeEstimator> EdgeEstimator::Create(VehicleType vehicleType,
|
||||
VehicleModelInterface const & vehicleModel,
|
||||
shared_ptr<TrafficStash> trafficStash,
|
||||
DataSource * dataSourcePtr,
|
||||
shared_ptr<EdgeEstimator> EdgeEstimator::Create(VehicleType vehicleType, VehicleModelInterface const & vehicleModel,
|
||||
shared_ptr<TrafficStash> trafficStash, DataSource * dataSourcePtr,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds)
|
||||
{
|
||||
return Create(vehicleType, vehicleModel.GetMaxWeightSpeed(), vehicleModel.GetOffroadSpeed(),
|
||||
trafficStash, dataSourcePtr, numMwmIds);
|
||||
return Create(vehicleType, vehicleModel.GetMaxWeightSpeed(), vehicleModel.GetOffroadSpeed(), trafficStash,
|
||||
dataSourcePtr, numMwmIds);
|
||||
}
|
||||
} // namespace routing
|
||||
|
||||
@@ -27,8 +27,8 @@ public:
|
||||
ETA
|
||||
};
|
||||
|
||||
EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH,
|
||||
DataSource * dataSourcePtr = nullptr, std::shared_ptr<NumMwmIds> numMwmIds = nullptr);
|
||||
EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH, DataSource * dataSourcePtr = nullptr,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds = nullptr);
|
||||
virtual ~EdgeEstimator() = default;
|
||||
|
||||
double CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const;
|
||||
@@ -45,41 +45,34 @@ public:
|
||||
// Estimates time in seconds it takes to go from point |from| to point |to| along direct fake edge.
|
||||
double CalcOffroad(ms::LatLon const & from, ms::LatLon const & to, Purpose purpose) const;
|
||||
|
||||
virtual double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road,
|
||||
Purpose purpose) const = 0;
|
||||
virtual double CalcSegmentWeight(Segment const & segment, RoadGeometry const & road, Purpose purpose) const = 0;
|
||||
virtual double GetUTurnPenalty(Purpose purpose) const = 0;
|
||||
virtual double GetFerryLandingPenalty(Purpose purpose) const = 0;
|
||||
|
||||
static std::shared_ptr<EdgeEstimator> Create(VehicleType vehicleType, double maxWeighSpeedKMpH,
|
||||
SpeedKMpH const & offroadSpeedKMpH,
|
||||
std::shared_ptr<TrafficStash> trafficStash,
|
||||
DataSource * dataSourcePtr,
|
||||
std::shared_ptr<TrafficStash> trafficStash, DataSource * dataSourcePtr,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
|
||||
static std::shared_ptr<EdgeEstimator> Create(VehicleType vehicleType,
|
||||
VehicleModelInterface const & vehicleModel,
|
||||
std::shared_ptr<TrafficStash> trafficStash,
|
||||
DataSource * dataSourcePtr,
|
||||
static std::shared_ptr<EdgeEstimator> Create(VehicleType vehicleType, VehicleModelInterface const & vehicleModel,
|
||||
std::shared_ptr<TrafficStash> trafficStash, DataSource * dataSourcePtr,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds);
|
||||
|
||||
private:
|
||||
double const m_maxWeightSpeedMpS;
|
||||
SpeedKMpH const m_offroadSpeedKMpH;
|
||||
|
||||
//DataSource * m_dataSourcePtr;
|
||||
//std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
//std::unordered_map<NumMwmId, double> m_leapWeightSpeedMpS;
|
||||
// DataSource * m_dataSourcePtr;
|
||||
// std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
// std::unordered_map<NumMwmId, double> m_leapWeightSpeedMpS;
|
||||
|
||||
double ComputeDefaultLeapWeightSpeed() const;
|
||||
double GetLeapWeightSpeed(NumMwmId mwmId);
|
||||
//double LoadLeapWeightSpeed(NumMwmId mwmId);
|
||||
// double LoadLeapWeightSpeed(NumMwmId mwmId);
|
||||
};
|
||||
|
||||
double GetPedestrianClimbPenalty(EdgeEstimator::Purpose purpose, double tangent,
|
||||
geometry::Altitude altitudeM);
|
||||
double GetBicycleClimbPenalty(EdgeEstimator::Purpose purpose, double tangent,
|
||||
geometry::Altitude altitudeM);
|
||||
double GetCarClimbPenalty(EdgeEstimator::Purpose purpose, double tangent,
|
||||
geometry::Altitude altitudeM);
|
||||
double GetPedestrianClimbPenalty(EdgeEstimator::Purpose purpose, double tangent, geometry::Altitude altitudeM);
|
||||
double GetBicycleClimbPenalty(EdgeEstimator::Purpose purpose, double tangent, geometry::Altitude altitudeM);
|
||||
double GetCarClimbPenalty(EdgeEstimator::Purpose purpose, double tangent, geometry::Altitude altitudeM);
|
||||
|
||||
} // namespace routing
|
||||
|
||||
@@ -20,8 +20,7 @@ public:
|
||||
FakeEdgesContainer(IndexGraphStarter && starter)
|
||||
: m_finish(std::move(starter.m_finish))
|
||||
, m_fake(std::move(starter.m_fake))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
uint32_t GetNumFakeEdges() const
|
||||
{
|
||||
|
||||
@@ -17,8 +17,7 @@ namespace routing
|
||||
using namespace routing;
|
||||
using namespace std;
|
||||
|
||||
LatLonWithAltitude CalcProjectionToSegment(LatLonWithAltitude const & begin,
|
||||
LatLonWithAltitude const & end,
|
||||
LatLonWithAltitude CalcProjectionToSegment(LatLonWithAltitude const & begin, LatLonWithAltitude const & end,
|
||||
m2::PointD const & point)
|
||||
{
|
||||
m2::ParametrizedSegment<m2::PointD> segment(mercator::FromLatLon(begin.GetLatLon()),
|
||||
@@ -33,23 +32,20 @@ LatLonWithAltitude CalcProjectionToSegment(LatLonWithAltitude const & begin,
|
||||
if (AlmostEqualAbs(distBeginToEnd, 0.0, kEpsMeters))
|
||||
return LatLonWithAltitude(projectedLatLon, begin.GetAltitude());
|
||||
|
||||
auto const distBeginToProjection =
|
||||
ms::DistanceOnEarth(begin.GetLatLon(), projectedLatLon);
|
||||
auto const distBeginToProjection = ms::DistanceOnEarth(begin.GetLatLon(), projectedLatLon);
|
||||
|
||||
auto const altitude = begin.GetAltitude() + (end.GetAltitude() - begin.GetAltitude()) *
|
||||
distBeginToProjection / distBeginToEnd;
|
||||
auto const altitude =
|
||||
begin.GetAltitude() + (end.GetAltitude() - begin.GetAltitude()) * distBeginToProjection / distBeginToEnd;
|
||||
return LatLonWithAltitude(projectedLatLon, altitude);
|
||||
}
|
||||
|
||||
bool Projection::operator==(const Projection & other) const
|
||||
bool Projection::operator==(Projection const & other) const
|
||||
{
|
||||
return tie(m_segment, m_isOneWay, m_segmentFront, m_segmentBack, m_junction) ==
|
||||
tie(other.m_segment, other.m_isOneWay, other.m_segmentFront, other.m_segmentBack,
|
||||
other.m_junction);
|
||||
tie(other.m_segment, other.m_isOneWay, other.m_segmentFront, other.m_segmentBack, other.m_junction);
|
||||
}
|
||||
|
||||
FakeEnding MakeFakeEnding(vector<Segment> const & segments, m2::PointD const & point,
|
||||
WorldGraph & graph)
|
||||
FakeEnding MakeFakeEnding(vector<Segment> const & segments, m2::PointD const & point, WorldGraph & graph)
|
||||
{
|
||||
FakeEnding ending;
|
||||
double averageAltitude = 0.0;
|
||||
@@ -63,8 +59,7 @@ FakeEnding MakeFakeEnding(vector<Segment> const & segments, m2::PointD const & p
|
||||
auto const & backJunction = graph.GetJunction(segment, false /* front */);
|
||||
auto const & projectedJunction = CalcProjectionToSegment(backJunction, frontJunction, point);
|
||||
|
||||
ending.m_projections.emplace_back(segment, oneWay, frontJunction, backJunction,
|
||||
projectedJunction);
|
||||
ending.m_projections.emplace_back(segment, oneWay, frontJunction, backJunction, projectedJunction);
|
||||
|
||||
averageAltitude = (i * averageAltitude + projectedJunction.GetAltitude()) / (i + 1);
|
||||
}
|
||||
@@ -83,10 +78,8 @@ FakeEnding MakeFakeEnding(Segment const & segment, m2::PointD const & point, Ind
|
||||
auto const & projectedJunction = CalcProjectionToSegment(backJunction, frontJunction, point);
|
||||
|
||||
FakeEnding ending;
|
||||
ending.m_originJunction =
|
||||
LatLonWithAltitude(mercator::ToLatLon(point), projectedJunction.GetAltitude());
|
||||
ending.m_projections.emplace_back(segment, oneWay, frontJunction, backJunction,
|
||||
projectedJunction);
|
||||
ending.m_originJunction = LatLonWithAltitude(mercator::ToLatLon(point), projectedJunction.GetAltitude());
|
||||
ending.m_projections.emplace_back(segment, oneWay, frontJunction, backJunction, projectedJunction);
|
||||
return ending;
|
||||
}
|
||||
} // namespace routing
|
||||
|
||||
@@ -17,17 +17,14 @@ class WorldGraph;
|
||||
|
||||
struct Projection final
|
||||
{
|
||||
Projection(Segment const & segment, bool isOneWay,
|
||||
LatLonWithAltitude const & segmentFront,
|
||||
LatLonWithAltitude const & segmentBack,
|
||||
LatLonWithAltitude const & junction)
|
||||
Projection(Segment const & segment, bool isOneWay, LatLonWithAltitude const & segmentFront,
|
||||
LatLonWithAltitude const & segmentBack, LatLonWithAltitude const & junction)
|
||||
: m_segment(segment)
|
||||
, m_isOneWay(isOneWay)
|
||||
, m_segmentFront(segmentFront)
|
||||
, m_segmentBack(segmentBack)
|
||||
, m_junction(junction)
|
||||
{
|
||||
}
|
||||
{}
|
||||
bool operator==(Projection const & other) const;
|
||||
|
||||
Segment m_segment;
|
||||
@@ -43,11 +40,9 @@ struct FakeEnding final
|
||||
std::vector<Projection> m_projections;
|
||||
};
|
||||
|
||||
FakeEnding MakeFakeEnding(std::vector<Segment> const & segments, m2::PointD const & point,
|
||||
WorldGraph & graph);
|
||||
FakeEnding MakeFakeEnding(std::vector<Segment> const & segments, m2::PointD const & point, WorldGraph & graph);
|
||||
FakeEnding MakeFakeEnding(Segment const & segment, m2::PointD const & point, IndexGraph & graph);
|
||||
|
||||
LatLonWithAltitude CalcProjectionToSegment(LatLonWithAltitude const & begin,
|
||||
LatLonWithAltitude const & end,
|
||||
LatLonWithAltitude CalcProjectionToSegment(LatLonWithAltitude const & begin, LatLonWithAltitude const & end,
|
||||
m2::PointD const & point);
|
||||
} // namespace routing
|
||||
|
||||
@@ -26,25 +26,21 @@ struct FakeFeatureIds
|
||||
// and editor feature ids.
|
||||
static uint32_t constexpr k28BitsOffset = 0xfffffff;
|
||||
static uint32_t constexpr k24BitsOffset = 0xffffff;
|
||||
static uint32_t constexpr kTransitGraphFeaturesStart =
|
||||
std::numeric_limits<uint32_t>::max() - k28BitsOffset;
|
||||
static uint32_t constexpr kTransitGraphFeaturesStart = std::numeric_limits<uint32_t>::max() - k28BitsOffset;
|
||||
static uint32_t constexpr kGuidesGraphFeaturesStart = kTransitGraphFeaturesStart - k24BitsOffset;
|
||||
};
|
||||
|
||||
static_assert(feature::FakeFeatureIds::kEditorCreatedFeaturesStart >
|
||||
FakeFeatureIds::kTransitGraphFeaturesStart,
|
||||
static_assert(feature::FakeFeatureIds::kEditorCreatedFeaturesStart > FakeFeatureIds::kTransitGraphFeaturesStart,
|
||||
"routing::FakeFeatureIds::kTransitGraphFeaturesStart or "
|
||||
"feature::FakeFeatureIds::kEditorCreatedFeaturesStart was changed. "
|
||||
"Interval for transit fake features may be too small.");
|
||||
|
||||
static_assert(FakeFeatureIds::kTransitGraphFeaturesStart >
|
||||
FakeFeatureIds::kGuidesGraphFeaturesStart,
|
||||
static_assert(FakeFeatureIds::kTransitGraphFeaturesStart > FakeFeatureIds::kGuidesGraphFeaturesStart,
|
||||
"routing::FakeFeatureIds::kTransitGraphFeaturesStart or "
|
||||
"feature::FakeFeatureIds::kGuidesGraphFeaturesStart was changed. "
|
||||
"Interval for guides fake features may be too small.");
|
||||
|
||||
static_assert(feature::FakeFeatureIds::kEditorCreatedFeaturesStart -
|
||||
FakeFeatureIds::kTransitGraphFeaturesStart >=
|
||||
static_assert(feature::FakeFeatureIds::kEditorCreatedFeaturesStart - FakeFeatureIds::kTransitGraphFeaturesStart >=
|
||||
FakeFeatureIds::k24BitsOffset - feature::FakeFeatureIds::k20BitsOffset,
|
||||
"routing::FakeFeatureIds::kTransitGraphFeaturesStart or "
|
||||
"feature::FakeFeatureIds::kEditorCreatedFeaturesStart was changed. "
|
||||
|
||||
@@ -16,9 +16,8 @@ void FakeGraph::AddStandaloneVertex(Segment const & newSegment, FakeVertex const
|
||||
m_vertexToSegment[newVertex] = newSegment;
|
||||
}
|
||||
|
||||
void FakeGraph::AddVertex(Segment const & existentSegment, Segment const & newSegment,
|
||||
FakeVertex const & newVertex, bool isOutgoing, bool isPartOfReal,
|
||||
Segment const & real)
|
||||
void FakeGraph::AddVertex(Segment const & existentSegment, Segment const & newSegment, FakeVertex const & newVertex,
|
||||
bool isOutgoing, bool isPartOfReal, Segment const & real)
|
||||
{
|
||||
AddStandaloneVertex(newSegment, newVertex);
|
||||
auto const & segmentFrom = isOutgoing ? existentSegment : newSegment;
|
||||
@@ -34,10 +33,8 @@ void FakeGraph::AddVertex(Segment const & existentSegment, Segment const & newSe
|
||||
|
||||
void FakeGraph::AddConnection(Segment const & from, Segment const & to)
|
||||
{
|
||||
ASSERT(m_segmentToVertex.find(from) != m_segmentToVertex.end(),
|
||||
("Segment", from, "does not exist in fake graph."));
|
||||
ASSERT(m_segmentToVertex.find(to) != m_segmentToVertex.end(),
|
||||
("Segment", to, "does not exist in fake graph."));
|
||||
ASSERT(m_segmentToVertex.find(from) != m_segmentToVertex.end(), ("Segment", from, "does not exist in fake graph."));
|
||||
ASSERT(m_segmentToVertex.find(to) != m_segmentToVertex.end(), ("Segment", to, "does not exist in fake graph."));
|
||||
m_outgoing[from].insert(to);
|
||||
m_ingoing[to].insert(from);
|
||||
}
|
||||
@@ -47,9 +44,8 @@ void FakeGraph::Append(FakeGraph const & rhs)
|
||||
std::map<Segment, FakeVertex> intersection;
|
||||
typename std::map<Segment, FakeVertex>::iterator intersectionIt(intersection.begin());
|
||||
|
||||
std::set_intersection(m_segmentToVertex.begin(), m_segmentToVertex.end(),
|
||||
rhs.m_segmentToVertex.begin(), rhs.m_segmentToVertex.end(),
|
||||
std::inserter(intersection, intersectionIt),
|
||||
std::set_intersection(m_segmentToVertex.begin(), m_segmentToVertex.end(), rhs.m_segmentToVertex.begin(),
|
||||
rhs.m_segmentToVertex.end(), std::inserter(intersection, intersectionIt),
|
||||
base::LessBy(&std::pair<Segment, FakeVertex>::first));
|
||||
|
||||
size_t countEqual = 0;
|
||||
@@ -95,7 +91,10 @@ std::set<Segment> const & FakeGraph::GetEdges(Segment const & segment, bool isOu
|
||||
return kEmptySet;
|
||||
}
|
||||
|
||||
size_t FakeGraph::GetSize() const { return m_segmentToVertex.size(); }
|
||||
size_t FakeGraph::GetSize() const
|
||||
{
|
||||
return m_segmentToVertex.size();
|
||||
}
|
||||
|
||||
std::set<Segment> const & FakeGraph::GetFake(Segment const & real) const
|
||||
{
|
||||
@@ -126,10 +125,10 @@ bool FakeGraph::FindSegment(FakeVertex const & vertex, Segment & segment) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeGraph::ConnectLoopToGuideSegments(
|
||||
FakeVertex const & loop, Segment const & guidesSegment,
|
||||
LatLonWithAltitude const & guidesSegmentFrom, LatLonWithAltitude const & guidesSegmentTo,
|
||||
std::vector<std::pair<FakeVertex, Segment>> const & partsOfReal)
|
||||
void FakeGraph::ConnectLoopToGuideSegments(FakeVertex const & loop, Segment const & guidesSegment,
|
||||
LatLonWithAltitude const & guidesSegmentFrom,
|
||||
LatLonWithAltitude const & guidesSegmentTo,
|
||||
std::vector<std::pair<FakeVertex, Segment>> const & partsOfReal)
|
||||
{
|
||||
auto itLoop = m_vertexToSegment.find(loop);
|
||||
CHECK(itLoop != m_vertexToSegment.end(), (loop));
|
||||
@@ -149,8 +148,8 @@ void FakeGraph::ConnectLoopToGuideSegments(
|
||||
|
||||
Segment const & directedReal = (newVertex.GetPointFrom() == guidesSegmentTo.GetLatLon() ||
|
||||
newVertex.GetPointTo() == guidesSegmentFrom.GetLatLon())
|
||||
? backwardReal
|
||||
: guidesSegment;
|
||||
? backwardReal
|
||||
: guidesSegment;
|
||||
|
||||
m_realToFake[directedReal].insert(segment);
|
||||
|
||||
@@ -161,8 +160,7 @@ void FakeGraph::ConnectLoopToGuideSegments(
|
||||
m_vertexToSegment[newVertex] = segment;
|
||||
}
|
||||
|
||||
CHECK((newVertex.GetPointFrom() == loopPoint || newVertex.GetPointTo() == loopPoint),
|
||||
(newVertex, loopPoint));
|
||||
CHECK((newVertex.GetPointFrom() == loopPoint || newVertex.GetPointTo() == loopPoint), (newVertex, loopPoint));
|
||||
|
||||
auto const & to = (newVertex.GetPointTo() == loopPoint) ? loopSegment : segment;
|
||||
auto const & from = (newVertex.GetPointFrom() == loopPoint) ? loopSegment : segment;
|
||||
@@ -172,8 +170,7 @@ void FakeGraph::ConnectLoopToGuideSegments(
|
||||
}
|
||||
}
|
||||
|
||||
void FakeGraph::ConnectLoopToExistentPartsOfReal(FakeVertex const & loop,
|
||||
Segment const & guidesSegment,
|
||||
void FakeGraph::ConnectLoopToExistentPartsOfReal(FakeVertex const & loop, Segment const & guidesSegment,
|
||||
Segment const & directedGuidesSegment)
|
||||
{
|
||||
auto const & loopSegment = m_vertexToSegment[loop];
|
||||
|
||||
@@ -18,9 +18,8 @@ public:
|
||||
// Adds vertex. Connects newSegment to existentSegment. Adds ingoing and
|
||||
// outgoing edges, fills segment to vertex mapping. Fills real to fake and fake to real
|
||||
// mapping if isPartOfReal is true.
|
||||
void AddVertex(Segment const & existentSegment, Segment const & newSegment,
|
||||
FakeVertex const & newVertex, bool isOutgoing, bool isPartOfReal,
|
||||
Segment const & real);
|
||||
void AddVertex(Segment const & existentSegment, Segment const & newSegment, FakeVertex const & newVertex,
|
||||
bool isOutgoing, bool isPartOfReal, Segment const & real);
|
||||
// Adds connection from existent fake segment |from| to existent fake segment |to|
|
||||
void AddConnection(Segment const & from, Segment const & to);
|
||||
// Merges |rhs| into this.
|
||||
|
||||
@@ -25,24 +25,23 @@ public:
|
||||
PartOfReal,
|
||||
};
|
||||
|
||||
FakeVertex(NumMwmId numMwmId, LatLonWithAltitude const & from,
|
||||
LatLonWithAltitude const & to, Type type)
|
||||
: m_numMwmId(numMwmId), m_from(from), m_to(to), m_type(type)
|
||||
{
|
||||
}
|
||||
FakeVertex(NumMwmId numMwmId, LatLonWithAltitude const & from, LatLonWithAltitude const & to, Type type)
|
||||
: m_numMwmId(numMwmId)
|
||||
, m_from(from)
|
||||
, m_to(to)
|
||||
, m_type(type)
|
||||
{}
|
||||
|
||||
FakeVertex() = default;
|
||||
|
||||
bool operator==(FakeVertex const & rhs) const
|
||||
{
|
||||
return std::tie(m_numMwmId, m_from, m_to, m_type) ==
|
||||
std::tie(rhs.m_numMwmId, rhs.m_from, rhs.m_to, rhs.m_type);
|
||||
return std::tie(m_numMwmId, m_from, m_to, m_type) == std::tie(rhs.m_numMwmId, rhs.m_from, rhs.m_to, rhs.m_type);
|
||||
}
|
||||
|
||||
bool operator<(FakeVertex const & rhs) const
|
||||
{
|
||||
return std::tie(m_type, m_from, m_to, m_numMwmId) <
|
||||
std::tie(rhs.m_type, rhs.m_from, rhs.m_to,rhs.m_numMwmId);
|
||||
return std::tie(m_type, m_from, m_to, m_numMwmId) < std::tie(rhs.m_type, rhs.m_from, rhs.m_to, rhs.m_numMwmId);
|
||||
}
|
||||
|
||||
LatLonWithAltitude const & GetJunctionFrom() const { return m_from; }
|
||||
@@ -51,8 +50,8 @@ public:
|
||||
ms::LatLon const & GetPointTo() const { return m_to.GetLatLon(); }
|
||||
Type GetType() const { return m_type; }
|
||||
|
||||
DECLARE_VISITOR(visitor(m_numMwmId, "m_numMwmId"), visitor(m_from, "m_from"),
|
||||
visitor(m_to, "m_to"), visitor(m_type, "m_type"))
|
||||
DECLARE_VISITOR(visitor(m_numMwmId, "m_numMwmId"), visitor(m_from, "m_from"), visitor(m_to, "m_to"),
|
||||
visitor(m_type, "m_type"))
|
||||
DECLARE_DEBUG_PRINT(FakeVertex)
|
||||
|
||||
private:
|
||||
|
||||
@@ -16,23 +16,26 @@ using namespace std;
|
||||
|
||||
namespace
|
||||
{
|
||||
uint32_t constexpr kPowOfTwoForFeatureCacheSize = 10; // cache contains 2 ^ kPowOfTwoForFeatureCacheSize elements
|
||||
uint32_t constexpr kPowOfTwoForFeatureCacheSize = 10; // cache contains 2 ^ kPowOfTwoForFeatureCacheSize elements
|
||||
|
||||
double constexpr kMwmRoadCrossingRadiusMeters = 2.0;
|
||||
|
||||
auto constexpr kInvalidSpeedKMPH = numeric_limits<double>::max();
|
||||
} // namespace
|
||||
|
||||
double GetRoadCrossingRadiusMeters() { return kMwmRoadCrossingRadiusMeters; }
|
||||
double GetRoadCrossingRadiusMeters()
|
||||
{
|
||||
return kMwmRoadCrossingRadiusMeters;
|
||||
}
|
||||
|
||||
FeaturesRoadGraphBase::CrossCountryVehicleModel::CrossCountryVehicleModel(VehicleModelFactoryPtrT modelFactory)
|
||||
: m_modelFactory(modelFactory)
|
||||
, m_maxSpeed(m_modelFactory->GetVehicleModel()->GetMaxWeightSpeed())
|
||||
, m_offroadSpeedKMpH(m_modelFactory->GetVehicleModel()->GetOffroadSpeed())
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
SpeedKMpH FeaturesRoadGraphBase::CrossCountryVehicleModel::GetSpeed(FeatureType & f, SpeedParams const & speedParams) const
|
||||
SpeedKMpH FeaturesRoadGraphBase::CrossCountryVehicleModel::GetSpeed(FeatureType & f,
|
||||
SpeedParams const & speedParams) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->GetSpeed(FeatureTypes(f), speedParams);
|
||||
}
|
||||
@@ -62,7 +65,8 @@ bool FeaturesRoadGraphBase::CrossCountryVehicleModel::IsPassThroughAllowed(Featu
|
||||
return GetVehicleModel(f.GetID())->IsPassThroughAllowed(FeatureTypes(f));
|
||||
}
|
||||
|
||||
VehicleModelInterface * FeaturesRoadGraphBase::CrossCountryVehicleModel::GetVehicleModel(FeatureID const & featureId) const
|
||||
VehicleModelInterface * FeaturesRoadGraphBase::CrossCountryVehicleModel::GetVehicleModel(
|
||||
FeatureID const & featureId) const
|
||||
{
|
||||
auto itr = m_cache.find(featureId.m_mwmId);
|
||||
if (itr != m_cache.end())
|
||||
@@ -99,15 +103,17 @@ void FeaturesRoadGraph::RoadInfoCache::Clear()
|
||||
|
||||
FeaturesRoadGraphBase::FeaturesRoadGraphBase(MwmDataSource & dataSource, IRoadGraph::Mode mode,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory)
|
||||
: m_dataSource(dataSource), m_mode(mode), m_vehicleModel(vehicleModelFactory)
|
||||
{
|
||||
}
|
||||
: m_dataSource(dataSource)
|
||||
, m_mode(mode)
|
||||
, m_vehicleModel(vehicleModelFactory)
|
||||
{}
|
||||
|
||||
class CrossFeaturesLoader
|
||||
{
|
||||
public:
|
||||
CrossFeaturesLoader(FeaturesRoadGraphBase const & graph, IRoadGraph::ICrossEdgesLoader & edgesLoader)
|
||||
: m_graph(graph), m_edgesLoader(edgesLoader)
|
||||
: m_graph(graph)
|
||||
, m_edgesLoader(edgesLoader)
|
||||
{}
|
||||
|
||||
void operator()(FeatureType & ft)
|
||||
@@ -128,8 +134,8 @@ private:
|
||||
IRoadGraph::ICrossEdgesLoader & m_edgesLoader;
|
||||
};
|
||||
|
||||
void FeaturesRoadGraphBase::ForEachFeatureClosestToCross(
|
||||
m2::PointD const & cross, ICrossEdgesLoader & edgesLoader) const
|
||||
void FeaturesRoadGraphBase::ForEachFeatureClosestToCross(m2::PointD const & cross,
|
||||
ICrossEdgesLoader & edgesLoader) const
|
||||
{
|
||||
CrossFeaturesLoader featuresLoader(*this, edgesLoader);
|
||||
m2::RectD const rect = mercator::RectByCenterXYAndSizeInMeters(cross, kMwmRoadCrossingRadiusMeters);
|
||||
@@ -155,8 +161,8 @@ void FeaturesRoadGraphBase::FindClosestEdges(m2::RectD const & rect, uint32_t co
|
||||
finder.MakeResult(vicinities, count);
|
||||
}
|
||||
|
||||
vector<IRoadGraph::FullRoadInfo>
|
||||
FeaturesRoadGraphBase::FindRoads(m2::RectD const & rect, IsGoodFeatureFn const & isGoodFeature) const
|
||||
vector<IRoadGraph::FullRoadInfo> FeaturesRoadGraphBase::FindRoads(m2::RectD const & rect,
|
||||
IsGoodFeatureFn const & isGoodFeature) const
|
||||
{
|
||||
vector<IRoadGraph::FullRoadInfo> roads;
|
||||
|
||||
@@ -235,8 +241,8 @@ double FeaturesRoadGraphBase::GetSpeedKMpHFromFt(FeatureType & ft, SpeedParams c
|
||||
return m_vehicleModel.GetSpeed(ft, speedParams).m_weight;
|
||||
}
|
||||
|
||||
void FeaturesRoadGraphBase::ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft,
|
||||
double speedKMpH, RoadInfo & ri) const
|
||||
void FeaturesRoadGraphBase::ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft, double speedKMpH,
|
||||
RoadInfo & ri) const
|
||||
{
|
||||
ri.m_speedKMPH = speedKMpH;
|
||||
ri.m_bidirectional = !IsOneWay(ft);
|
||||
@@ -262,8 +268,8 @@ void FeaturesRoadGraphBase::ExtractRoadInfo(FeatureID const & featureId, Feature
|
||||
}
|
||||
}
|
||||
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraphBase::GetCachedRoadInfo(
|
||||
FeatureID const & featureId, SpeedParams const & speedParams) const
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraphBase::GetCachedRoadInfo(FeatureID const & featureId,
|
||||
SpeedParams const & speedParams) const
|
||||
{
|
||||
bool found = false;
|
||||
RoadInfo & ri = m_cache.Find(featureId, found);
|
||||
@@ -281,8 +287,8 @@ IRoadGraph::RoadInfo const & FeaturesRoadGraphBase::GetCachedRoadInfo(
|
||||
return ri;
|
||||
}
|
||||
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraphBase::GetCachedRoadInfo(
|
||||
FeatureID const & featureId, FeatureType & ft, double speedKMPH) const
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraphBase::GetCachedRoadInfo(FeatureID const & featureId, FeatureType & ft,
|
||||
double speedKMPH) const
|
||||
{
|
||||
bool found = false;
|
||||
RoadInfo & ri = m_cache.Find(featureId, found);
|
||||
|
||||
@@ -83,15 +83,13 @@ public:
|
||||
|
||||
/// @name IRoadGraph overrides
|
||||
/// @{
|
||||
void ForEachFeatureClosestToCross(m2::PointD const & cross,
|
||||
ICrossEdgesLoader & edgesLoader) const override;
|
||||
void ForEachFeatureClosestToCross(m2::PointD const & cross, ICrossEdgesLoader & edgesLoader) const override;
|
||||
void FindClosestEdges(m2::RectD const & rect, uint32_t count,
|
||||
std::vector<std::pair<Edge, geometry::PointWithAltitude>> & vicinities) const override;
|
||||
std::vector<IRoadGraph::FullRoadInfo> FindRoads(
|
||||
m2::RectD const & rect, IsGoodFeatureFn const & isGoodFeature) const override;
|
||||
std::vector<IRoadGraph::FullRoadInfo> FindRoads(m2::RectD const & rect,
|
||||
IsGoodFeatureFn const & isGoodFeature) const override;
|
||||
void GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & types) const override;
|
||||
void GetJunctionTypes(geometry::PointWithAltitude const & junction,
|
||||
feature::TypesHolder & types) const override;
|
||||
void GetJunctionTypes(geometry::PointWithAltitude const & junction, feature::TypesHolder & types) const override;
|
||||
IRoadGraph::Mode GetMode() const override;
|
||||
void ClearState() override;
|
||||
/// @}
|
||||
@@ -134,8 +132,7 @@ class FeaturesRoadGraph : public FeaturesRoadGraphBase
|
||||
public:
|
||||
FeaturesRoadGraph(MwmDataSource & dataSource, IRoadGraph::Mode mode, VehicleModelFactoryPtrT modelFactory)
|
||||
: FeaturesRoadGraphBase(dataSource, mode, modelFactory)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
protected:
|
||||
feature::AltitudeLoaderCached * GetAltitudesLoader(MwmSet::MwmId const & mwmId) const override;
|
||||
|
||||
@@ -24,25 +24,22 @@ public:
|
||||
, m_time(0)
|
||||
, m_completionPercent(0)
|
||||
, m_pedestrianTurn(turns::PedestrianDirection::None)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// SingleLaneInfoClient is used for passing information about a lane to client platforms such as
|
||||
// Android, iOS and so on.
|
||||
struct SingleLaneInfoClient
|
||||
{
|
||||
std::vector<int8_t> m_lane; // Possible directions for the lane.
|
||||
bool m_isRecommended; // m_isRecommended is true if the lane is recommended for a user.
|
||||
bool m_isRecommended; // m_isRecommended is true if the lane is recommended for a user.
|
||||
|
||||
explicit SingleLaneInfoClient(turns::SingleLaneInfo const & singleLaneInfo)
|
||||
: m_isRecommended(singleLaneInfo.m_isRecommended)
|
||||
: m_isRecommended(singleLaneInfo.m_isRecommended)
|
||||
{
|
||||
turns::TSingleLane const & lane = singleLaneInfo.m_lane;
|
||||
m_lane.resize(lane.size());
|
||||
std::transform(lane.cbegin(), lane.cend(), m_lane.begin(), [](turns::LaneWay l)
|
||||
{
|
||||
return static_cast<int8_t>(l);
|
||||
});
|
||||
std::transform(lane.cbegin(), lane.cend(), m_lane.begin(),
|
||||
[](turns::LaneWay l) { return static_cast<int8_t>(l); });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
SpeedInUnits GetSavedMaxspeed(uint32_t featureId, bool forward) override
|
||||
{
|
||||
auto const speed = m_attrsGetter.m_maxSpeeds.GetMaxspeed(featureId);
|
||||
return { speed.GetSpeedInUnits(forward), speed.GetUnits() };
|
||||
return {speed.GetSpeedInUnits(forward), speed.GetUnits()};
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -132,13 +132,16 @@ private:
|
||||
RoadAttrsGetter m_attrsGetter;
|
||||
VehicleModelPtrT m_vehicleModel;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
} // namespace
|
||||
|
||||
// RoadGeometry ------------------------------------------------------------------------------------
|
||||
RoadGeometry::RoadGeometry(bool oneWay, double weightSpeedKMpH, double etaSpeedKMpH, Points const & points)
|
||||
: m_forwardSpeed{weightSpeedKMpH, etaSpeedKMpH}, m_backwardSpeed(m_forwardSpeed)
|
||||
, m_isOneWay(oneWay), m_valid(true), m_isPassThroughAllowed(false), m_inCity(false)
|
||||
: m_forwardSpeed{weightSpeedKMpH, etaSpeedKMpH}
|
||||
, m_backwardSpeed(m_forwardSpeed)
|
||||
, m_isOneWay(oneWay)
|
||||
, m_valid(true)
|
||||
, m_isPassThroughAllowed(false)
|
||||
, m_inCity(false)
|
||||
{
|
||||
ASSERT_GREATER(weightSpeedKMpH, 0.0, ());
|
||||
ASSERT_GREATER(etaSpeedKMpH, 0.0, ());
|
||||
@@ -180,10 +183,8 @@ void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType
|
||||
|
||||
auto const & optionsClassfier = RoutingOptionsClassifier::Instance();
|
||||
for (uint32_t type : types)
|
||||
{
|
||||
if (auto const it = optionsClassfier.Get(type))
|
||||
m_routingOptions.Add(*it);
|
||||
}
|
||||
|
||||
m_junctions.clear();
|
||||
m_junctions.reserve(count);
|
||||
@@ -199,13 +200,13 @@ void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType
|
||||
// Since we store integer altitudes, 1 is a possible error for 2 points.
|
||||
geometry::Altitude constexpr kError = 1;
|
||||
|
||||
auto const altDiff = (*altitudes)[i] - (*altitudes)[i-1];
|
||||
auto const altDiff = (*altitudes)[i] - (*altitudes)[i - 1];
|
||||
auto const absDiff = abs(altDiff) - kError;
|
||||
if (absDiff > 0)
|
||||
{
|
||||
double const dist = ms::DistanceOnEarth(m_junctions[i-1].GetLatLon(), m_junctions[i].GetLatLon());
|
||||
double const dist = ms::DistanceOnEarth(m_junctions[i - 1].GetLatLon(), m_junctions[i].GetLatLon());
|
||||
if (absDiff / dist >= 1.0)
|
||||
LOG(LWARNING, ("Altitudes jump:", altDiff, "/", dist, m_junctions[i-1], m_junctions[i]));
|
||||
LOG(LWARNING, ("Altitudes jump:", altDiff, "/", dist, m_junctions[i - 1], m_junctions[i]));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -237,9 +238,7 @@ void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType
|
||||
}
|
||||
|
||||
if (m_valid)
|
||||
{
|
||||
ASSERT(m_forwardSpeed.IsValid() && m_backwardSpeed.IsValid(), (feature.DebugString()));
|
||||
}
|
||||
}
|
||||
|
||||
double RoadGeometry::GetDistance(uint32_t idx) const
|
||||
@@ -260,24 +259,19 @@ double RoadGeometry::GetRoadLengthM() const
|
||||
double lenM = 0.0;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
for (uint32_t i = 0; i < count - 1; ++i)
|
||||
lenM += GetDistance(i);
|
||||
}
|
||||
|
||||
return lenM;
|
||||
}
|
||||
|
||||
// Geometry ----------------------------------------------------------------------------------------
|
||||
Geometry::Geometry(unique_ptr<GeometryLoader> loader, size_t roadsCacheSize)
|
||||
: m_loader(std::move(loader))
|
||||
Geometry::Geometry(unique_ptr<GeometryLoader> loader, size_t roadsCacheSize) : m_loader(std::move(loader))
|
||||
{
|
||||
CHECK(m_loader, ());
|
||||
|
||||
m_featureIdToRoad = make_unique<RoutingCacheT>(roadsCacheSize, [this](uint32_t featureId, RoadGeometry & road)
|
||||
{
|
||||
m_loader->Load(featureId, road);
|
||||
});
|
||||
m_featureIdToRoad = make_unique<RoutingCacheT>(
|
||||
roadsCacheSize, [this](uint32_t featureId, RoadGeometry & road) { m_loader->Load(featureId, road); });
|
||||
}
|
||||
|
||||
RoadGeometry const & Geometry::GetRoad(uint32_t featureId)
|
||||
@@ -295,8 +289,7 @@ SpeedInUnits GeometryLoader::GetSavedMaxspeed(uint32_t featureId, bool forward)
|
||||
|
||||
// static
|
||||
unique_ptr<GeometryLoader> GeometryLoader::Create(MwmSet::MwmHandle const & handle,
|
||||
VehicleModelPtrT const & vehicleModel,
|
||||
bool loadAltitudes)
|
||||
VehicleModelPtrT const & vehicleModel, bool loadAltitudes)
|
||||
{
|
||||
CHECK(handle.IsAlive(), ());
|
||||
CHECK(vehicleModel, ());
|
||||
@@ -304,8 +297,8 @@ unique_ptr<GeometryLoader> GeometryLoader::Create(MwmSet::MwmHandle const & hand
|
||||
}
|
||||
|
||||
// static
|
||||
unique_ptr<GeometryLoader> GeometryLoader::CreateFromFile(
|
||||
string const & fileName, VehicleModelPtrT const & vehicleModel)
|
||||
unique_ptr<GeometryLoader> GeometryLoader::CreateFromFile(string const & fileName,
|
||||
VehicleModelPtrT const & vehicleModel)
|
||||
{
|
||||
CHECK(vehicleModel, ());
|
||||
return make_unique<FileGeometryLoader>(fileName, vehicleModel);
|
||||
|
||||
@@ -38,8 +38,8 @@ public:
|
||||
RoadGeometry(bool oneWay, double weightSpeedKMpH, double etaSpeedKMpH, Points const & points);
|
||||
|
||||
/// @param[in] altitudes May be nullptr.
|
||||
void Load(VehicleModelInterface const & vehicleModel, FeatureType & feature,
|
||||
geometry::Altitudes const * altitudes, RoadAttrsGetter & attrs);
|
||||
void Load(VehicleModelInterface const & vehicleModel, FeatureType & feature, geometry::Altitudes const * altitudes,
|
||||
RoadAttrsGetter & attrs);
|
||||
|
||||
SpeedKMpH const & GetSpeed(bool forward) const;
|
||||
std::optional<HighwayType> GetHighwayType() const { return m_highwayType; }
|
||||
@@ -72,10 +72,7 @@ public:
|
||||
return pointId == 0 || pointId + 1 == GetPointsCount();
|
||||
}
|
||||
|
||||
void SetPassThroughAllowedForTests(bool passThroughAllowed)
|
||||
{
|
||||
m_isPassThroughAllowed = passThroughAllowed;
|
||||
}
|
||||
void SetPassThroughAllowedForTests(bool passThroughAllowed) { m_isPassThroughAllowed = passThroughAllowed; }
|
||||
|
||||
bool SuitableForOptions(RoutingOptions avoidRoutingOptions) const
|
||||
{
|
||||
@@ -86,7 +83,7 @@ public:
|
||||
|
||||
private:
|
||||
std::vector<LatLonWithAltitude> m_junctions;
|
||||
mutable std::vector<double> m_distances; ///< as cache, @see GetDistance()
|
||||
mutable std::vector<double> m_distances; ///< as cache, @see GetDistance()
|
||||
|
||||
SpeedKMpH m_forwardSpeed;
|
||||
SpeedKMpH m_backwardSpeed;
|
||||
@@ -111,14 +108,13 @@ public:
|
||||
using VehicleModelPtrT = std::shared_ptr<VehicleModelInterface>;
|
||||
|
||||
/// @param[in] handle should be alive, its caller responsibility to check it.
|
||||
static std::unique_ptr<GeometryLoader> Create(MwmSet::MwmHandle const & handle,
|
||||
VehicleModelPtrT const & vehicleModel,
|
||||
static std::unique_ptr<GeometryLoader> Create(MwmSet::MwmHandle const & handle, VehicleModelPtrT const & vehicleModel,
|
||||
bool loadAltitudes);
|
||||
|
||||
/// This is for stand-alone work.
|
||||
/// Use in generator_tool and unit tests.
|
||||
static std::unique_ptr<GeometryLoader> CreateFromFile(
|
||||
std::string const & filePath, VehicleModelPtrT const & vehicleModel);
|
||||
static std::unique_ptr<GeometryLoader> CreateFromFile(std::string const & filePath,
|
||||
VehicleModelPtrT const & vehicleModel);
|
||||
};
|
||||
|
||||
/// \brief This class supports loading geometry of roads for routing.
|
||||
@@ -143,10 +139,7 @@ public:
|
||||
|
||||
/// \note The reference returned by the method is valid until the next call of GetRoad()
|
||||
/// of GetPoint() methods.
|
||||
ms::LatLon const & GetPoint(RoadPoint const & rp)
|
||||
{
|
||||
return GetRoad(rp.GetFeatureId()).GetPoint(rp.GetPointId());
|
||||
}
|
||||
ms::LatLon const & GetPoint(RoadPoint const & rp) { return GetRoad(rp.GetFeatureId()).GetPoint(rp.GetPointId()); }
|
||||
|
||||
SpeedInUnits GetSavedMaxspeed(uint32_t featureId, bool forward)
|
||||
{
|
||||
|
||||
@@ -19,8 +19,7 @@ double constexpr kEqDistToTrackPointM = 20.0;
|
||||
double constexpr kMaxDistToTrackForSkippingM = 100'000.0;
|
||||
} // namespace
|
||||
|
||||
CheckpointTrackProj::CheckpointTrackProj(kml::MarkGroupId guideId, size_t trackIdx,
|
||||
size_t trackPointIdx,
|
||||
CheckpointTrackProj::CheckpointTrackProj(kml::MarkGroupId guideId, size_t trackIdx, size_t trackPointIdx,
|
||||
geometry::PointWithAltitude const & projectedPoint,
|
||||
double distToProjectedPointM)
|
||||
: m_guideId(guideId)
|
||||
@@ -28,21 +27,22 @@ CheckpointTrackProj::CheckpointTrackProj(kml::MarkGroupId guideId, size_t trackI
|
||||
, m_trackPointIdx(trackPointIdx)
|
||||
, m_projectedPoint(projectedPoint)
|
||||
, m_distToProjectedPointM(distToProjectedPointM)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
std::pair<geometry::PointWithAltitude, double> GetProjectionAndDistOnSegment(
|
||||
m2::PointD const & point, geometry::PointWithAltitude const & startPath,
|
||||
geometry::PointWithAltitude const & endPath)
|
||||
{
|
||||
m2::PointD const projection =
|
||||
m2::ParametrizedSegment<m2::PointD>(startPath.GetPoint(), endPath.GetPoint())
|
||||
.ClosestPointTo(point);
|
||||
m2::ParametrizedSegment<m2::PointD>(startPath.GetPoint(), endPath.GetPoint()).ClosestPointTo(point);
|
||||
double const distM = mercator::DistanceOnEarth(projection, point);
|
||||
return std::make_pair(geometry::PointWithAltitude(projection, 0 /* altitude */), distM);
|
||||
}
|
||||
|
||||
bool GuidesConnections::IsActive() const { return !m_allTracks.empty(); }
|
||||
bool GuidesConnections::IsActive() const
|
||||
{
|
||||
return !m_allTracks.empty();
|
||||
}
|
||||
|
||||
std::vector<ConnectionToOsm> GuidesConnections::GetOsmConnections(size_t checkpointIdx) const
|
||||
{
|
||||
@@ -52,17 +52,14 @@ std::vector<ConnectionToOsm> GuidesConnections::GetOsmConnections(size_t checkpo
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void GuidesConnections::UpdateOsmConnections(size_t checkpointIdx,
|
||||
std::vector<ConnectionToOsm> const & links)
|
||||
void GuidesConnections::UpdateOsmConnections(size_t checkpointIdx, std::vector<ConnectionToOsm> const & links)
|
||||
{
|
||||
auto const it = m_connectionsToOsm.find(checkpointIdx);
|
||||
CHECK(it != m_connectionsToOsm.cend(), (checkpointIdx));
|
||||
it->second.clear();
|
||||
for (auto const & link : links)
|
||||
{
|
||||
if (!link.m_fakeEnding.m_projections.empty())
|
||||
it->second.push_back(link);
|
||||
}
|
||||
if (it->second.empty())
|
||||
m_connectionsToOsm.erase(it);
|
||||
}
|
||||
@@ -80,9 +77,8 @@ void GuidesConnections::PullCheckpointsToTracks(std::vector<m2::PointD> const &
|
||||
CHECK(!tracks[trackIdx].empty(), (trackIdx));
|
||||
for (size_t pointIdx = 0; pointIdx < tracks[trackIdx].size() - 1; ++pointIdx)
|
||||
{
|
||||
auto const [checkpointProj, distM] =
|
||||
GetProjectionAndDistOnSegment(checkpoints[checkpointIdx], tracks[trackIdx][pointIdx],
|
||||
tracks[trackIdx][pointIdx + 1]);
|
||||
auto const [checkpointProj, distM] = GetProjectionAndDistOnSegment(
|
||||
checkpoints[checkpointIdx], tracks[trackIdx][pointIdx], tracks[trackIdx][pointIdx + 1]);
|
||||
|
||||
// Skip too far track.
|
||||
if (distM > kMaxDistToTrackForSkippingM)
|
||||
@@ -103,8 +99,7 @@ void GuidesConnections::PullCheckpointsToTracks(std::vector<m2::PointD> const &
|
||||
}
|
||||
}
|
||||
|
||||
void GuidesConnections::AddTerminalGuidePoint(size_t checkpointIdx, size_t neighbourIdx,
|
||||
m2::PointD const & curPoint)
|
||||
void GuidesConnections::AddTerminalGuidePoint(size_t checkpointIdx, size_t neighbourIdx, m2::PointD const & curPoint)
|
||||
{
|
||||
auto const it = m_checkpointsOnTracks.find(neighbourIdx);
|
||||
CHECK(it != m_checkpointsOnTracks.cend(), (neighbourIdx));
|
||||
@@ -114,25 +109,23 @@ void GuidesConnections::AddTerminalGuidePoint(size_t checkpointIdx, size_t neigh
|
||||
auto const trackIdx = neighbour.m_trackIdx;
|
||||
auto const & track = m_allTracks[guideId][trackIdx];
|
||||
|
||||
CHECK_GREATER(
|
||||
track.size(), 1,
|
||||
("checkpointIdx:", checkpointIdx, "neighbourIdx:", neighbourIdx, "trackIdx:", trackIdx));
|
||||
CHECK_GREATER(track.size(), 1,
|
||||
("checkpointIdx:", checkpointIdx, "neighbourIdx:", neighbourIdx, "trackIdx:", trackIdx));
|
||||
|
||||
// Connect start checkpoint to the starting point of the track.
|
||||
if (checkpointIdx == 0)
|
||||
{
|
||||
double const distToStartM = mercator::DistanceOnEarth(curPoint, track.front().GetPoint());
|
||||
m_checkpointsOnTracks[checkpointIdx] = CheckpointTrackProj(
|
||||
guideId, trackIdx, 0 /* trackPointIdx */, track.front() /* proj */, distToStartM);
|
||||
m_checkpointsOnTracks[checkpointIdx] =
|
||||
CheckpointTrackProj(guideId, trackIdx, 0 /* trackPointIdx */, track.front() /* proj */, distToStartM);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Connect finish checkpoint to the finish point of the track.
|
||||
double const distToSFinishM = mercator::DistanceOnEarth(curPoint, track.back().GetPoint());
|
||||
m_checkpointsOnTracks[checkpointIdx] =
|
||||
CheckpointTrackProj(guideId, trackIdx, track.size() - 2 /* trackPointIdx */,
|
||||
track.back() /* proj */, distToSFinishM);
|
||||
m_checkpointsOnTracks[checkpointIdx] = CheckpointTrackProj(guideId, trackIdx, track.size() - 2 /* trackPointIdx */,
|
||||
track.back() /* proj */, distToSFinishM);
|
||||
}
|
||||
|
||||
bool GuidesConnections::IsCheckpointAttached(size_t checkpointIdx) const
|
||||
@@ -153,8 +146,7 @@ std::vector<size_t> GetNeighbourIntermediatePoints(size_t checkpointIdx, size_t
|
||||
return neighbours;
|
||||
}
|
||||
|
||||
bool GuidesConnections::FitsForDirectLinkToGuide(size_t checkpointIdx,
|
||||
size_t checkpointsCount) const
|
||||
bool GuidesConnections::FitsForDirectLinkToGuide(size_t checkpointIdx, size_t checkpointsCount) const
|
||||
{
|
||||
auto it = m_checkpointsOnTracks.find(checkpointIdx);
|
||||
CHECK(it != m_checkpointsOnTracks.end(), (checkpointIdx));
|
||||
@@ -168,16 +160,13 @@ bool GuidesConnections::FitsForDirectLinkToGuide(size_t checkpointIdx,
|
||||
return true;
|
||||
|
||||
for (auto const neighbourIdx : GetNeighbourIntermediatePoints(checkpointIdx, checkpointsCount))
|
||||
{
|
||||
if (m_checkpointsOnTracks.find(neighbourIdx) == m_checkpointsOnTracks.end())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuidesConnections::PullAdditionalCheckpointsToTracks(
|
||||
std::vector<m2::PointD> const & checkpoints)
|
||||
void GuidesConnections::PullAdditionalCheckpointsToTracks(std::vector<m2::PointD> const & checkpoints)
|
||||
{
|
||||
for (size_t i : {size_t(0), checkpoints.size() - 1})
|
||||
{
|
||||
@@ -195,7 +184,10 @@ void GuidesConnections::PullAdditionalCheckpointsToTracks(
|
||||
}
|
||||
}
|
||||
|
||||
bool GuidesConnections::IsAttached() const { return !m_checkpointsFakeEndings.empty(); }
|
||||
bool GuidesConnections::IsAttached() const
|
||||
{
|
||||
return !m_checkpointsFakeEndings.empty();
|
||||
}
|
||||
|
||||
FakeEnding GuidesConnections::GetFakeEnding(size_t checkpointIdx) const
|
||||
{
|
||||
@@ -208,7 +200,10 @@ FakeEnding GuidesConnections::GetFakeEnding(size_t checkpointIdx) const
|
||||
return FakeEnding();
|
||||
}
|
||||
|
||||
GuidesGraph const & GuidesConnections::GetGuidesGraph() const { return m_graph; }
|
||||
GuidesGraph const & GuidesConnections::GetGuidesGraph() const
|
||||
{
|
||||
return m_graph;
|
||||
}
|
||||
|
||||
void GuidesConnections::OverwriteFakeEnding(size_t checkpointIdx, FakeEnding const & newFakeEnding)
|
||||
{
|
||||
@@ -216,19 +211,19 @@ void GuidesConnections::OverwriteFakeEnding(size_t checkpointIdx, FakeEnding con
|
||||
}
|
||||
|
||||
// static
|
||||
void GuidesConnections::ExtendFakeEndingProjections(FakeEnding const & srcFakeEnding,
|
||||
FakeEnding & dstFakeEnding)
|
||||
void GuidesConnections::ExtendFakeEndingProjections(FakeEnding const & srcFakeEnding, FakeEnding & dstFakeEnding)
|
||||
{
|
||||
dstFakeEnding.m_originJunction = srcFakeEnding.m_originJunction;
|
||||
|
||||
for (auto const & proj : srcFakeEnding.m_projections)
|
||||
{
|
||||
if (!base::IsExist(dstFakeEnding.m_projections, proj))
|
||||
dstFakeEnding.m_projections.push_back(proj);
|
||||
}
|
||||
}
|
||||
|
||||
NumMwmId GuidesConnections::GetMwmId() const { return m_graph.GetMwmId(); }
|
||||
NumMwmId GuidesConnections::GetMwmId() const
|
||||
{
|
||||
return m_graph.GetMwmId();
|
||||
}
|
||||
|
||||
void GuidesConnections::SetGuidesGraphParams(NumMwmId mwmId, double maxSpeed)
|
||||
{
|
||||
@@ -254,11 +249,9 @@ void GuidesConnections::ConnectToGuidesGraph(std::vector<m2::PointD> const & che
|
||||
if (insertedSegment)
|
||||
{
|
||||
CHECK(!m_allTracks[proj.m_guideId][proj.m_trackIdx].empty(),
|
||||
("checkpointIdx:", checkpointIdx, "guideId:", proj.m_guideId,
|
||||
"trackIdx:", proj.m_trackIdx));
|
||||
("checkpointIdx:", checkpointIdx, "guideId:", proj.m_guideId, "trackIdx:", proj.m_trackIdx));
|
||||
|
||||
segmentOnTrack =
|
||||
m_graph.AddTrack(m_allTracks[proj.m_guideId][proj.m_trackIdx], proj.m_trackPointIdx);
|
||||
segmentOnTrack = m_graph.AddTrack(m_allTracks[proj.m_guideId][proj.m_trackIdx], proj.m_trackPointIdx);
|
||||
it->second = segmentOnTrack;
|
||||
}
|
||||
else
|
||||
@@ -279,8 +272,7 @@ void GuidesConnections::ConnectToGuidesGraph(std::vector<m2::PointD> const & che
|
||||
if (!(fitsForOsmLink && firstPointOnTrack == checkpointProj))
|
||||
{
|
||||
auto const & firstSegmentOnTrack = m_graph.FindSegment(segmentOnTrack, 0);
|
||||
AddConnectionToOsm(checkpointIdx, firstSegmentOnTrack, firstPointOnTrack,
|
||||
false /* fromCheckpoint */);
|
||||
AddConnectionToOsm(checkpointIdx, firstSegmentOnTrack, firstPointOnTrack, false /* fromCheckpoint */);
|
||||
}
|
||||
|
||||
auto const & lastPointIdx = m_allTracks[proj.m_guideId][proj.m_trackIdx].size() - 1;
|
||||
@@ -288,15 +280,13 @@ void GuidesConnections::ConnectToGuidesGraph(std::vector<m2::PointD> const & che
|
||||
if (!(fitsForOsmLink && lastPointOnTrack == checkpointProj))
|
||||
{
|
||||
auto const & lastSegmentOnTrack = m_graph.FindSegment(segmentOnTrack, lastPointIdx - 1);
|
||||
AddConnectionToOsm(checkpointIdx, lastSegmentOnTrack, lastPointOnTrack,
|
||||
false /* fromCheckpoint */);
|
||||
AddConnectionToOsm(checkpointIdx, lastSegmentOnTrack, lastPointOnTrack, false /* fromCheckpoint */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuidesConnections::AddConnectionToOsm(size_t checkpointIdx, Segment const & real,
|
||||
geometry::PointWithAltitude const & loop,
|
||||
bool fromCheckpoint)
|
||||
geometry::PointWithAltitude const & loop, bool fromCheckpoint)
|
||||
{
|
||||
LatLonWithAltitude const loopPoint(mercator::ToLatLon(loop.GetPoint()), loop.GetAltitude());
|
||||
|
||||
|
||||
@@ -43,8 +43,7 @@ struct CheckpointTrackProj
|
||||
{
|
||||
CheckpointTrackProj() = default;
|
||||
CheckpointTrackProj(kml::MarkGroupId guideId, size_t trackIdx, size_t trackPointIdx,
|
||||
geometry::PointWithAltitude const & projectedPoint,
|
||||
double distToProjectedPointM);
|
||||
geometry::PointWithAltitude const & projectedPoint, double distToProjectedPointM);
|
||||
// Guide id.
|
||||
kml::MarkGroupId m_guideId = 0;
|
||||
// Index of the track belonging to |m_guideId|.
|
||||
@@ -80,8 +79,7 @@ public:
|
||||
void OverwriteFakeEnding(size_t checkpointIdx, FakeEnding const & newFakeEnding);
|
||||
|
||||
// Merge existing |srcFakeEnding| with |dstFakeEnding|.
|
||||
static void ExtendFakeEndingProjections(FakeEnding const & srcFakeEnding,
|
||||
FakeEnding & dstFakeEnding);
|
||||
static void ExtendFakeEndingProjections(FakeEnding const & srcFakeEnding, FakeEnding & dstFakeEnding);
|
||||
|
||||
// Returns guides graph |m_graph| for index graph starter.
|
||||
GuidesGraph const & GetGuidesGraph() const;
|
||||
@@ -109,16 +107,15 @@ public:
|
||||
|
||||
private:
|
||||
// Fills |ConnectionToOsm| for checkpoints for its further attachment to the roads graph.
|
||||
void AddConnectionToOsm(size_t checkpointIdx, Segment const & real,
|
||||
geometry::PointWithAltitude const & loop, bool fromCheckpoint);
|
||||
void AddConnectionToOsm(size_t checkpointIdx, Segment const & real, geometry::PointWithAltitude const & loop,
|
||||
bool fromCheckpoint);
|
||||
|
||||
// Attaches checkpoints to the nearest guides tracks if possible.
|
||||
void PullCheckpointsToTracks(std::vector<m2::PointD> const & checkpoints);
|
||||
|
||||
// Attaches terminal point on the track to the terminal checkpoint: start to start;
|
||||
// finish - to finish.
|
||||
void AddTerminalGuidePoint(size_t checkpointIdx, size_t neighbourIdx,
|
||||
m2::PointD const & curPoint);
|
||||
void AddTerminalGuidePoint(size_t checkpointIdx, size_t neighbourIdx, m2::PointD const & curPoint);
|
||||
|
||||
// Attaches neighbour terminal checkpoints for those which are already attached.
|
||||
void PullAdditionalCheckpointsToTracks(std::vector<m2::PointD> const & checkpoints);
|
||||
|
||||
@@ -32,16 +32,14 @@ GuidesGraph::GuidesGraph(double maxSpeedMpS, NumMwmId mwmId)
|
||||
CHECK_NOT_EQUAL(m_maxSpeedMpS, 0.0, ());
|
||||
}
|
||||
|
||||
double GuidesGraph::CalcSegmentTimeS(LatLonWithAltitude const & point1,
|
||||
LatLonWithAltitude const & point2) const
|
||||
double GuidesGraph::CalcSegmentTimeS(LatLonWithAltitude const & point1, LatLonWithAltitude const & point2) const
|
||||
{
|
||||
double const distM = ms::DistanceOnEarth(point1.GetLatLon(), point2.GetLatLon());
|
||||
double const weight = distM / m_maxSpeedMpS;
|
||||
return weight;
|
||||
}
|
||||
|
||||
void GuidesGraph::GetEdgeList(Segment const & segment, bool isOutgoing,
|
||||
EdgeListT & edges,
|
||||
void GuidesGraph::GetEdgeList(Segment const & segment, bool isOutgoing, EdgeListT & edges,
|
||||
RouteWeight const & prevWeight) const
|
||||
{
|
||||
auto const it = m_segments.find(segment);
|
||||
@@ -52,8 +50,8 @@ void GuidesGraph::GetEdgeList(Segment const & segment, bool isOutgoing,
|
||||
|
||||
if (segment.IsForward() == isOutgoing)
|
||||
{
|
||||
Segment nextSegment(segmentOnTrack.GetMwmId(), segmentOnTrack.GetFeatureId(),
|
||||
segmentOnTrack.GetSegmentIdx() + 1, segmentOnTrack.IsForward());
|
||||
Segment nextSegment(segmentOnTrack.GetMwmId(), segmentOnTrack.GetFeatureId(), segmentOnTrack.GetSegmentIdx() + 1,
|
||||
segmentOnTrack.IsForward());
|
||||
itOnTrack = m_segments.find(nextSegment);
|
||||
if (itOnTrack == m_segments.end())
|
||||
return;
|
||||
@@ -63,14 +61,14 @@ void GuidesGraph::GetEdgeList(Segment const & segment, bool isOutgoing,
|
||||
if (it->first.GetSegmentIdx() == 0)
|
||||
return;
|
||||
|
||||
Segment prevSegment(segmentOnTrack.GetMwmId(), segmentOnTrack.GetFeatureId(),
|
||||
segmentOnTrack.GetSegmentIdx() - 1, segmentOnTrack.IsForward());
|
||||
Segment prevSegment(segmentOnTrack.GetMwmId(), segmentOnTrack.GetFeatureId(), segmentOnTrack.GetSegmentIdx() - 1,
|
||||
segmentOnTrack.IsForward());
|
||||
itOnTrack = m_segments.find(prevSegment);
|
||||
CHECK(itOnTrack != m_segments.end(), (segment));
|
||||
}
|
||||
auto const & neighbour = itOnTrack->first;
|
||||
Segment const resSegment(neighbour.GetMwmId(), neighbour.GetFeatureId(),
|
||||
neighbour.GetSegmentIdx(), segment.IsForward());
|
||||
Segment const resSegment(neighbour.GetMwmId(), neighbour.GetFeatureId(), neighbour.GetSegmentIdx(),
|
||||
segment.IsForward());
|
||||
|
||||
auto const weight = isOutgoing ? RouteWeight(itOnTrack->second.m_weight) : prevWeight;
|
||||
edges.emplace_back(resSegment, weight);
|
||||
@@ -83,10 +81,12 @@ LatLonWithAltitude const & GuidesGraph::GetJunction(Segment const & segment, boo
|
||||
return segment.IsForward() == front ? it->second.m_pointLast : it->second.m_pointFirst;
|
||||
}
|
||||
|
||||
NumMwmId GuidesGraph::GetMwmId() const { return m_mwmId; }
|
||||
NumMwmId GuidesGraph::GetMwmId() const
|
||||
{
|
||||
return m_mwmId;
|
||||
}
|
||||
|
||||
Segment GuidesGraph::AddTrack(std::vector<geometry::PointWithAltitude> const & guideTrack,
|
||||
size_t requiredSegmentIdx)
|
||||
Segment GuidesGraph::AddTrack(std::vector<geometry::PointWithAltitude> const & guideTrack, size_t requiredSegmentIdx)
|
||||
{
|
||||
uint32_t segmentIdx = 0;
|
||||
Segment segment;
|
||||
@@ -98,10 +98,9 @@ Segment GuidesGraph::AddTrack(std::vector<geometry::PointWithAltitude> const & g
|
||||
if (i == requiredSegmentIdx)
|
||||
segment = curSegment;
|
||||
|
||||
data.m_pointFirst = LatLonWithAltitude(mercator::ToLatLon(guideTrack[i].GetPoint()),
|
||||
guideTrack[i].GetAltitude());
|
||||
data.m_pointLast = LatLonWithAltitude(mercator::ToLatLon(guideTrack[i + 1].GetPoint()),
|
||||
guideTrack[i + 1].GetAltitude());
|
||||
data.m_pointFirst = LatLonWithAltitude(mercator::ToLatLon(guideTrack[i].GetPoint()), guideTrack[i].GetAltitude());
|
||||
data.m_pointLast =
|
||||
LatLonWithAltitude(mercator::ToLatLon(guideTrack[i + 1].GetPoint()), guideTrack[i + 1].GetAltitude());
|
||||
|
||||
data.m_weight = CalcSegmentTimeS(data.m_pointFirst, data.m_pointLast);
|
||||
|
||||
@@ -116,8 +115,8 @@ Segment GuidesGraph::FindSegment(Segment const & segment, size_t segmentIdx) con
|
||||
{
|
||||
auto const it = m_segments.find(segment);
|
||||
CHECK(it != m_segments.end(), (segment, segmentIdx));
|
||||
Segment segmentOnTrack(it->first.GetMwmId(), it->first.GetFeatureId(),
|
||||
static_cast<uint32_t>(segmentIdx), it->first.IsForward());
|
||||
Segment segmentOnTrack(it->first.GetMwmId(), it->first.GetFeatureId(), static_cast<uint32_t>(segmentIdx),
|
||||
it->first.IsForward());
|
||||
|
||||
auto const itByIndex = m_segments.find(segmentOnTrack);
|
||||
CHECK(itByIndex != m_segments.end(), (segment, segmentIdx));
|
||||
@@ -139,17 +138,16 @@ FakeEnding GuidesGraph::MakeFakeEnding(Segment const & segment, m2::PointD const
|
||||
auto const & backJunction = GetJunction(segment, false /* front */);
|
||||
|
||||
FakeEnding ending;
|
||||
ending.m_projections.emplace_back(segment, false /* isOneWay */, frontJunction, backJunction,
|
||||
LatLonWithAltitude(mercator::ToLatLon(projection.GetPoint()),
|
||||
projection.GetAltitude()) /* junction */);
|
||||
ending.m_projections.emplace_back(
|
||||
segment, false /* isOneWay */, frontJunction, backJunction,
|
||||
LatLonWithAltitude(mercator::ToLatLon(projection.GetPoint()), projection.GetAltitude()) /* junction */);
|
||||
|
||||
ending.m_originJunction =
|
||||
LatLonWithAltitude(mercator::ToLatLon(point), static_cast<geometry::Altitude>(kZeroAltitude));
|
||||
return ending;
|
||||
}
|
||||
|
||||
std::pair<LatLonWithAltitude, LatLonWithAltitude> GuidesGraph::GetFromTo(
|
||||
Segment const & segment) const
|
||||
std::pair<LatLonWithAltitude, LatLonWithAltitude> GuidesGraph::GetFromTo(Segment const & segment) const
|
||||
{
|
||||
auto const & from = GetJunction(segment, false /* front */);
|
||||
auto const & to = GetJunction(segment, true /* front */);
|
||||
|
||||
@@ -42,15 +42,13 @@ public:
|
||||
GuidesGraph() = default;
|
||||
explicit GuidesGraph(double maxSpeedMpS, NumMwmId mwmId);
|
||||
|
||||
Segment AddTrack(std::vector<geometry::PointWithAltitude> const & guideTrack,
|
||||
size_t requiredSegmentIdx);
|
||||
Segment AddTrack(std::vector<geometry::PointWithAltitude> const & guideTrack, size_t requiredSegmentIdx);
|
||||
|
||||
FakeEnding MakeFakeEnding(Segment const & segment, m2::PointD const & point,
|
||||
geometry::PointWithAltitude const & projection) const;
|
||||
|
||||
using EdgeListT = SmallList<SegmentEdge>;
|
||||
void GetEdgeList(Segment const & segment, bool isOutgoing, EdgeListT & edges,
|
||||
RouteWeight const & prevWeight) const;
|
||||
void GetEdgeList(Segment const & segment, bool isOutgoing, EdgeListT & edges, RouteWeight const & prevWeight) const;
|
||||
routing::LatLonWithAltitude const & GetJunction(Segment const & segment, bool front) const;
|
||||
RouteWeight CalcSegmentWeight(Segment const & segment) const;
|
||||
Segment FindSegment(Segment const & segment, size_t segmentIdx) const;
|
||||
@@ -61,8 +59,7 @@ public:
|
||||
NumMwmId GetMwmId() const;
|
||||
|
||||
private:
|
||||
double CalcSegmentTimeS(LatLonWithAltitude const & point1,
|
||||
LatLonWithAltitude const & point2) const;
|
||||
double CalcSegmentTimeS(LatLonWithAltitude const & point1, LatLonWithAltitude const & point2) const;
|
||||
|
||||
GuideSegments m_segments;
|
||||
double m_maxSpeedMpS = 0.0;
|
||||
|
||||
@@ -35,9 +35,9 @@ bool IsBoarding(bool prevIsFerry, bool nextIsFerry)
|
||||
|
||||
IndexGraph::IndexGraph(shared_ptr<Geometry> geometry, shared_ptr<EdgeEstimator> estimator,
|
||||
RoutingOptions routingOptions)
|
||||
: m_geometry(std::move(geometry)),
|
||||
m_estimator(std::move(estimator)),
|
||||
m_avoidRoutingOptions(routingOptions)
|
||||
: m_geometry(std::move(geometry))
|
||||
, m_estimator(std::move(estimator))
|
||||
, m_avoidRoutingOptions(routingOptions)
|
||||
{
|
||||
CHECK(m_geometry, ());
|
||||
CHECK(m_estimator, ());
|
||||
@@ -63,25 +63,22 @@ bool IndexGraph::IsJointOrEnd(Segment const & segment, bool fromStart) const
|
||||
return pointId + 1 == pointsNumber;
|
||||
}
|
||||
|
||||
void IndexGraph::GetEdgeList(astar::VertexData<Segment, RouteWeight> const & vertexData,
|
||||
bool isOutgoing, bool useRoutingOptions, SegmentEdgeListT & edges,
|
||||
Parents<Segment> const & parents) const
|
||||
void IndexGraph::GetEdgeList(astar::VertexData<Segment, RouteWeight> const & vertexData, bool isOutgoing,
|
||||
bool useRoutingOptions, SegmentEdgeListT & edges, Parents<Segment> const & parents) const
|
||||
{
|
||||
GetEdgeListImpl(vertexData, isOutgoing, useRoutingOptions, true /* useAccessConditional */, edges,
|
||||
parents);
|
||||
GetEdgeListImpl(vertexData, isOutgoing, useRoutingOptions, true /* useAccessConditional */, edges, parents);
|
||||
}
|
||||
|
||||
void IndexGraph::GetEdgeList(Segment const & segment,
|
||||
bool isOutgoing, bool useRoutingOptions, SegmentEdgeListT & edges,
|
||||
void IndexGraph::GetEdgeList(Segment const & segment, bool isOutgoing, bool useRoutingOptions, SegmentEdgeListT & edges,
|
||||
Parents<Segment> const & parents) const
|
||||
{
|
||||
GetEdgeListImpl({segment, Weight(0.0)} /* vertexData */, isOutgoing, useRoutingOptions,
|
||||
false /* useAccessConditional */, edges, parents);
|
||||
}
|
||||
|
||||
void IndexGraph::GetEdgeListImpl(astar::VertexData<Segment, RouteWeight> const & vertexData,
|
||||
bool isOutgoing, bool useRoutingOptions, bool useAccessConditional,
|
||||
SegmentEdgeListT & edges, Parents<Segment> const & parents) const
|
||||
void IndexGraph::GetEdgeListImpl(astar::VertexData<Segment, RouteWeight> const & vertexData, bool isOutgoing,
|
||||
bool useRoutingOptions, bool useAccessConditional, SegmentEdgeListT & edges,
|
||||
Parents<Segment> const & parents) const
|
||||
{
|
||||
auto const & segment = vertexData.m_vertex;
|
||||
|
||||
@@ -90,21 +87,16 @@ void IndexGraph::GetEdgeListImpl(astar::VertexData<Segment, RouteWeight> const &
|
||||
|
||||
if (jointId != Joint::kInvalidId)
|
||||
{
|
||||
m_jointIndex.ForEachPoint(jointId, [&](RoadPoint const & rp) {
|
||||
GetNeighboringEdges(vertexData, rp, isOutgoing, useRoutingOptions, edges, parents,
|
||||
useAccessConditional);
|
||||
});
|
||||
m_jointIndex.ForEachPoint(jointId, [&](RoadPoint const & rp)
|
||||
{ GetNeighboringEdges(vertexData, rp, isOutgoing, useRoutingOptions, edges, parents, useAccessConditional); });
|
||||
}
|
||||
else
|
||||
{
|
||||
GetNeighboringEdges(vertexData, roadPoint, isOutgoing, useRoutingOptions, edges, parents,
|
||||
useAccessConditional);
|
||||
GetNeighboringEdges(vertexData, roadPoint, isOutgoing, useRoutingOptions, edges, parents, useAccessConditional);
|
||||
}
|
||||
}
|
||||
|
||||
void IndexGraph::GetLastPointsForJoint(SegmentListT const & children,
|
||||
bool isOutgoing,
|
||||
PointIdListT & lastPoints) const
|
||||
void IndexGraph::GetLastPointsForJoint(SegmentListT const & children, bool isOutgoing, PointIdListT & lastPoints) const
|
||||
{
|
||||
ASSERT(lastPoints.empty(), ());
|
||||
|
||||
@@ -142,28 +134,24 @@ void IndexGraph::GetLastPointsForJoint(SegmentListT const & children,
|
||||
}
|
||||
|
||||
void IndexGraph::GetEdgeList(astar::VertexData<JointSegment, RouteWeight> const & parentVertexData,
|
||||
Segment const & parent, bool isOutgoing,
|
||||
JointEdgeListT & edges,
|
||||
WeightListT & parentWeights,
|
||||
Parents<JointSegment> const & parents) const
|
||||
Segment const & parent, bool isOutgoing, JointEdgeListT & edges,
|
||||
WeightListT & parentWeights, Parents<JointSegment> const & parents) const
|
||||
{
|
||||
GetEdgeListImpl(parentVertexData, parent, isOutgoing, true /* useAccessConditional */, edges,
|
||||
parentWeights, parents);
|
||||
GetEdgeListImpl(parentVertexData, parent, isOutgoing, true /* useAccessConditional */, edges, parentWeights, parents);
|
||||
}
|
||||
|
||||
void IndexGraph::GetEdgeList(JointSegment const & parentJoint, Segment const & parent,
|
||||
bool isOutgoing, JointEdgeListT & edges,
|
||||
WeightListT & parentWeights,
|
||||
void IndexGraph::GetEdgeList(JointSegment const & parentJoint, Segment const & parent, bool isOutgoing,
|
||||
JointEdgeListT & edges, WeightListT & parentWeights,
|
||||
Parents<JointSegment> const & parents) const
|
||||
{
|
||||
GetEdgeListImpl({parentJoint, Weight(0.0)}, parent, isOutgoing, false /* useAccessConditional */, edges,
|
||||
parentWeights, parents);
|
||||
}
|
||||
|
||||
void IndexGraph::GetEdgeListImpl(
|
||||
astar::VertexData<JointSegment, RouteWeight> const & parentVertexData, Segment const & parent,
|
||||
bool isOutgoing, bool useAccessConditional, JointEdgeListT & edges,
|
||||
WeightListT & parentWeights, Parents<JointSegment> const & parents) const
|
||||
void IndexGraph::GetEdgeListImpl(astar::VertexData<JointSegment, RouteWeight> const & parentVertexData,
|
||||
Segment const & parent, bool isOutgoing, bool useAccessConditional,
|
||||
JointEdgeListT & edges, WeightListT & parentWeights,
|
||||
Parents<JointSegment> const & parents) const
|
||||
{
|
||||
SegmentListT possibleChildren;
|
||||
GetSegmentCandidateForJoint(parent, isOutgoing, possibleChildren);
|
||||
@@ -171,13 +159,12 @@ void IndexGraph::GetEdgeListImpl(
|
||||
PointIdListT lastPoints;
|
||||
GetLastPointsForJoint(possibleChildren, isOutgoing, lastPoints);
|
||||
|
||||
ReconstructJointSegment(parentVertexData, parent, possibleChildren, lastPoints,
|
||||
isOutgoing, edges, parentWeights, parents);
|
||||
ReconstructJointSegment(parentVertexData, parent, possibleChildren, lastPoints, isOutgoing, edges, parentWeights,
|
||||
parents);
|
||||
}
|
||||
|
||||
optional<JointEdge> IndexGraph::GetJointEdgeByLastPoint(Segment const & parent,
|
||||
Segment const & firstChild, bool isOutgoing,
|
||||
uint32_t lastPoint) const
|
||||
optional<JointEdge> IndexGraph::GetJointEdgeByLastPoint(Segment const & parent, Segment const & firstChild,
|
||||
bool isOutgoing, uint32_t lastPoint) const
|
||||
{
|
||||
SegmentListT const possibleChildren = {firstChild};
|
||||
PointIdListT const lastPoints = {lastPoint};
|
||||
@@ -230,12 +217,10 @@ void IndexGraph::SetRestrictions(RestrictionVec && restrictions)
|
||||
void IndexGraph::SetUTurnRestrictions(vector<RestrictionUTurn> && noUTurnRestrictions)
|
||||
{
|
||||
for (auto const & noUTurn : noUTurnRestrictions)
|
||||
{
|
||||
if (noUTurn.m_viaIsFirstPoint)
|
||||
m_noUTurnRestrictions[noUTurn.m_featureId].m_atTheBegin = true;
|
||||
else
|
||||
m_noUTurnRestrictions[noUTurn.m_featureId].m_atTheEnd = true;
|
||||
}
|
||||
}
|
||||
|
||||
void IndexGraph::SetRoadAccess(RoadAccess && roadAccess)
|
||||
@@ -261,22 +246,19 @@ void IndexGraph::GetNeighboringEdges(astar::VertexData<Segment, RouteWeight> con
|
||||
auto const & from = fromVertexData.m_vertex;
|
||||
if ((isOutgoing || bidirectional) && rp.GetPointId() + 1 < road.GetPointsCount())
|
||||
{
|
||||
GetNeighboringEdge(fromVertexData,
|
||||
Segment(from.GetMwmId(), rp.GetFeatureId(), rp.GetPointId(), isOutgoing),
|
||||
GetNeighboringEdge(fromVertexData, Segment(from.GetMwmId(), rp.GetFeatureId(), rp.GetPointId(), isOutgoing),
|
||||
isOutgoing, edges, parents, useAccessConditional);
|
||||
}
|
||||
|
||||
if ((!isOutgoing || bidirectional) && rp.GetPointId() > 0)
|
||||
{
|
||||
GetNeighboringEdge(
|
||||
fromVertexData,
|
||||
Segment(from.GetMwmId(), rp.GetFeatureId(), rp.GetPointId() - 1, !isOutgoing), isOutgoing,
|
||||
edges, parents, useAccessConditional);
|
||||
GetNeighboringEdge(fromVertexData, Segment(from.GetMwmId(), rp.GetFeatureId(), rp.GetPointId() - 1, !isOutgoing),
|
||||
isOutgoing, edges, parents, useAccessConditional);
|
||||
}
|
||||
}
|
||||
|
||||
void IndexGraph::GetSegmentCandidateForRoadPoint(RoadPoint const & rp, NumMwmId numMwmId,
|
||||
bool isOutgoing, SegmentListT & children) const
|
||||
void IndexGraph::GetSegmentCandidateForRoadPoint(RoadPoint const & rp, NumMwmId numMwmId, bool isOutgoing,
|
||||
SegmentListT & children) const
|
||||
{
|
||||
RoadGeometry const & road = GetRoadGeometry(rp.GetFeatureId());
|
||||
if (!road.IsValid())
|
||||
@@ -295,8 +277,7 @@ void IndexGraph::GetSegmentCandidateForRoadPoint(RoadPoint const & rp, NumMwmId
|
||||
children.emplace_back(numMwmId, rp.GetFeatureId(), pointId - 1, !isOutgoing);
|
||||
}
|
||||
|
||||
void IndexGraph::GetSegmentCandidateForJoint(Segment const & parent, bool isOutgoing,
|
||||
SegmentListT & children) const
|
||||
void IndexGraph::GetSegmentCandidateForJoint(Segment const & parent, bool isOutgoing, SegmentListT & children) const
|
||||
{
|
||||
RoadPoint const roadPoint = parent.GetRoadPoint(isOutgoing);
|
||||
Joint::Id const jointId = m_roadIndex.GetJointId(roadPoint);
|
||||
@@ -304,9 +285,8 @@ void IndexGraph::GetSegmentCandidateForJoint(Segment const & parent, bool isOutg
|
||||
if (jointId == Joint::kInvalidId)
|
||||
return;
|
||||
|
||||
m_jointIndex.ForEachPoint(jointId, [&](RoadPoint const & rp) {
|
||||
GetSegmentCandidateForRoadPoint(rp, parent.GetMwmId(), isOutgoing, children);
|
||||
});
|
||||
m_jointIndex.ForEachPoint(jointId, [&](RoadPoint const & rp)
|
||||
{ GetSegmentCandidateForRoadPoint(rp, parent.GetMwmId(), isOutgoing, children); });
|
||||
}
|
||||
|
||||
/// \brief Prolongs segments from |parent| to |firstChildren| directions in order to
|
||||
@@ -318,12 +298,9 @@ void IndexGraph::GetSegmentCandidateForJoint(Segment const & parent, bool isOutg
|
||||
/// Shortly - in case of |isOutgoing| == false, method saves here the weights
|
||||
/// from parent to firstChildren.
|
||||
void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWeight> const & parentVertexData,
|
||||
Segment const & parent,
|
||||
SegmentListT const & firstChildren,
|
||||
PointIdListT const & lastPointIds,
|
||||
bool isOutgoing,
|
||||
JointEdgeListT & jointEdges,
|
||||
WeightListT & parentWeights,
|
||||
Segment const & parent, SegmentListT const & firstChildren,
|
||||
PointIdListT const & lastPointIds, bool isOutgoing,
|
||||
JointEdgeListT & jointEdges, WeightListT & parentWeights,
|
||||
Parents<JointSegment> const & parents) const
|
||||
{
|
||||
CHECK_EQUAL(firstChildren.size(), lastPointIds.size(), ());
|
||||
@@ -340,30 +317,20 @@ void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWe
|
||||
("Invariant violated, can not build JointSegment,"
|
||||
"started and ended in the same point."));
|
||||
|
||||
auto const increment = [currentPointId, lastPointId](uint32_t pointId) {
|
||||
return currentPointId < lastPointId ? pointId + 1 : pointId - 1;
|
||||
};
|
||||
auto const increment = [currentPointId, lastPointId](uint32_t pointId)
|
||||
{ return currentPointId < lastPointId ? pointId + 1 : pointId - 1; };
|
||||
|
||||
if (IsAccessNoForSure(firstChild.GetFeatureId(), weightTimeToParent,
|
||||
true /* useAccessConditional */))
|
||||
{
|
||||
if (IsAccessNoForSure(firstChild.GetFeatureId(), weightTimeToParent, true /* useAccessConditional */))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsAccessNoForSure(parent.GetRoadPoint(isOutgoing), weightTimeToParent,
|
||||
true /* useAccessConditional */))
|
||||
{
|
||||
if (IsAccessNoForSure(parent.GetRoadPoint(isOutgoing), weightTimeToParent, true /* useAccessConditional */))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IsUTurn(parent, firstChild) && IsUTurnAndRestricted(parent, firstChild, isOutgoing))
|
||||
continue;
|
||||
|
||||
if (IsRestricted(parentJoint, parent.GetFeatureId(), firstChild.GetFeatureId(),
|
||||
isOutgoing, parents))
|
||||
{
|
||||
if (IsRestricted(parentJoint, parent.GetFeatureId(), firstChild.GetFeatureId(), isOutgoing, parents))
|
||||
continue;
|
||||
}
|
||||
|
||||
RouteWeight summaryWeight;
|
||||
// Check current JointSegment for bad road access between segments.
|
||||
@@ -386,7 +353,8 @@ void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWe
|
||||
|
||||
start = increment(start);
|
||||
rp.SetPointId(start);
|
||||
} while (start != lastPointId);
|
||||
}
|
||||
while (start != lastPointId);
|
||||
|
||||
if (noRoadAccess)
|
||||
continue;
|
||||
@@ -397,8 +365,8 @@ void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWe
|
||||
|
||||
do
|
||||
{
|
||||
RouteWeight const weight = CalculateEdgeWeight(EdgeEstimator::Purpose::Weight, isOutgoing,
|
||||
prev, current, weightTimeToParent);
|
||||
RouteWeight const weight =
|
||||
CalculateEdgeWeight(EdgeEstimator::Purpose::Weight, isOutgoing, prev, current, weightTimeToParent);
|
||||
|
||||
if (isOutgoing || prev != parent)
|
||||
summaryWeight += weight;
|
||||
@@ -409,17 +377,16 @@ void IndexGraph::ReconstructJointSegment(astar::VertexData<JointSegment, RouteWe
|
||||
prev = current;
|
||||
current.Next(forward);
|
||||
currentPointId = increment(currentPointId);
|
||||
} while (currentPointId != lastPointId);
|
||||
}
|
||||
while (currentPointId != lastPointId);
|
||||
|
||||
jointEdges.emplace_back(isOutgoing ? JointSegment(firstChild, prev) :
|
||||
JointSegment(prev, firstChild),
|
||||
jointEdges.emplace_back(isOutgoing ? JointSegment(firstChild, prev) : JointSegment(prev, firstChild),
|
||||
summaryWeight);
|
||||
}
|
||||
}
|
||||
|
||||
void IndexGraph::GetNeighboringEdge(astar::VertexData<Segment, RouteWeight> const & fromVertexData,
|
||||
Segment const & to, bool isOutgoing,
|
||||
SegmentEdgeListT & edges, Parents<Segment> const & parents,
|
||||
void IndexGraph::GetNeighboringEdge(astar::VertexData<Segment, RouteWeight> const & fromVertexData, Segment const & to,
|
||||
bool isOutgoing, SegmentEdgeListT & edges, Parents<Segment> const & parents,
|
||||
bool useAccessConditional) const
|
||||
{
|
||||
auto const & from = fromVertexData.m_vertex;
|
||||
@@ -438,8 +405,7 @@ void IndexGraph::GetNeighboringEdge(astar::VertexData<Segment, RouteWeight> cons
|
||||
if (IsAccessNoForSure(rp, weightToFrom, useAccessConditional))
|
||||
return;
|
||||
|
||||
auto const weight =
|
||||
CalculateEdgeWeight(EdgeEstimator::Purpose::Weight, isOutgoing, from, to, weightToFrom);
|
||||
auto const weight = CalculateEdgeWeight(EdgeEstimator::Purpose::Weight, isOutgoing, from, to, weightToFrom);
|
||||
|
||||
edges.emplace_back(to, weight);
|
||||
}
|
||||
@@ -447,18 +413,17 @@ void IndexGraph::GetNeighboringEdge(astar::VertexData<Segment, RouteWeight> cons
|
||||
IndexGraph::PenaltyData IndexGraph::GetRoadPenaltyData(Segment const & segment) const
|
||||
{
|
||||
auto const & road = GetRoadGeometry(segment.GetFeatureId());
|
||||
return { road.IsPassThroughAllowed(), road.GetRoutingOptions().Has(RoutingOptions::Road::Ferry) };
|
||||
return {road.IsPassThroughAllowed(), road.GetRoutingOptions().Has(RoutingOptions::Road::Ferry)};
|
||||
}
|
||||
|
||||
RouteWeight IndexGraph::GetPenalties(EdgeEstimator::Purpose purpose, Segment const & u,
|
||||
Segment const & v, optional<RouteWeight> const & prevWeight) const
|
||||
RouteWeight IndexGraph::GetPenalties(EdgeEstimator::Purpose purpose, Segment const & u, Segment const & v,
|
||||
optional<RouteWeight> const & prevWeight) const
|
||||
{
|
||||
auto const & fromPenaltyData = GetRoadPenaltyData(u);
|
||||
auto const & toPenaltyData = GetRoadPenaltyData(v);
|
||||
// Route crosses border of pass-through/non-pass-through area if |u| and |v| have different
|
||||
// pass through restrictions.
|
||||
int8_t const passThroughPenalty =
|
||||
fromPenaltyData.m_passThroughAllowed == toPenaltyData.m_passThroughAllowed ? 0 : 1;
|
||||
int8_t const passThroughPenalty = fromPenaltyData.m_passThroughAllowed == toPenaltyData.m_passThroughAllowed ? 0 : 1;
|
||||
|
||||
int8_t accessPenalty = 0;
|
||||
int8_t accessConditionalPenalties = 0;
|
||||
@@ -467,16 +432,13 @@ RouteWeight IndexGraph::GetPenalties(EdgeEstimator::Purpose purpose, Segment con
|
||||
{
|
||||
// We do not distinguish between RoadAccess::Type::Private and RoadAccess::Type::Destination for
|
||||
// now.
|
||||
auto const [fromAccess, fromConfidence] =
|
||||
prevWeight ? m_roadAccess.GetAccess(u.GetFeatureId(), *prevWeight)
|
||||
: m_roadAccess.GetAccessWithoutConditional(u.GetFeatureId());
|
||||
auto const [fromAccess, fromConfidence] = prevWeight ? m_roadAccess.GetAccess(u.GetFeatureId(), *prevWeight)
|
||||
: m_roadAccess.GetAccessWithoutConditional(u.GetFeatureId());
|
||||
|
||||
auto const [toAccess, toConfidence] =
|
||||
prevWeight ? m_roadAccess.GetAccess(v.GetFeatureId(), *prevWeight)
|
||||
: m_roadAccess.GetAccessWithoutConditional(v.GetFeatureId());
|
||||
auto const [toAccess, toConfidence] = prevWeight ? m_roadAccess.GetAccess(v.GetFeatureId(), *prevWeight)
|
||||
: m_roadAccess.GetAccessWithoutConditional(v.GetFeatureId());
|
||||
|
||||
if (fromConfidence == RoadAccess::Confidence::Sure &&
|
||||
toConfidence == RoadAccess::Confidence::Sure)
|
||||
if (fromConfidence == RoadAccess::Confidence::Sure && toConfidence == RoadAccess::Confidence::Sure)
|
||||
{
|
||||
bool const fromAccessAllowed = fromAccess == RoadAccess::Type::Yes;
|
||||
bool const toAccessAllowed = toAccess == RoadAccess::Type::Yes;
|
||||
@@ -492,9 +454,8 @@ RouteWeight IndexGraph::GetPenalties(EdgeEstimator::Purpose purpose, Segment con
|
||||
|
||||
// RoadPoint between u and v is front of u.
|
||||
auto const rp = u.GetRoadPoint(true /* front */);
|
||||
auto const [rpAccessType, rpConfidence] = prevWeight
|
||||
? m_roadAccess.GetAccess(rp, *prevWeight)
|
||||
: m_roadAccess.GetAccessWithoutConditional(rp);
|
||||
auto const [rpAccessType, rpConfidence] =
|
||||
prevWeight ? m_roadAccess.GetAccess(rp, *prevWeight) : m_roadAccess.GetAccessWithoutConditional(rp);
|
||||
switch (rpConfidence)
|
||||
{
|
||||
case RoadAccess::Confidence::Sure:
|
||||
@@ -521,10 +482,12 @@ RouteWeight IndexGraph::GetPenalties(EdgeEstimator::Purpose purpose, Segment con
|
||||
0.0 /* transitTime */};
|
||||
}
|
||||
|
||||
WorldGraphMode IndexGraph::GetMode() const { return WorldGraphMode::Undefined; }
|
||||
WorldGraphMode IndexGraph::GetMode() const
|
||||
{
|
||||
return WorldGraphMode::Undefined;
|
||||
}
|
||||
|
||||
bool IndexGraph::IsUTurnAndRestricted(Segment const & parent, Segment const & child,
|
||||
bool isOutgoing) const
|
||||
bool IndexGraph::IsUTurnAndRestricted(Segment const & parent, Segment const & child, bool isOutgoing) const
|
||||
{
|
||||
ASSERT(IsUTurn(parent, child), ());
|
||||
|
||||
@@ -549,8 +512,8 @@ bool IndexGraph::IsUTurnAndRestricted(Segment const & parent, Segment const & ch
|
||||
return uTurn.m_atTheEnd && turnPoint == n - 1;
|
||||
}
|
||||
|
||||
RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool isOutgoing,
|
||||
Segment const & from, Segment const & to,
|
||||
RouteWeight IndexGraph::CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool isOutgoing, Segment const & from,
|
||||
Segment const & to,
|
||||
std::optional<RouteWeight const> const & prevWeight) const
|
||||
{
|
||||
auto const & segment = isOutgoing ? to : from;
|
||||
|
||||
@@ -52,22 +52,18 @@ public:
|
||||
RoutingOptions routingOptions = RoutingOptions());
|
||||
|
||||
// Put outgoing (or ingoing) egdes for segment to the 'edges' vector.
|
||||
void GetEdgeList(astar::VertexData<Segment, RouteWeight> const & vertexData, bool isOutgoing,
|
||||
bool useRoutingOptions, SegmentEdgeListT & edges,
|
||||
Parents<Segment> const & parents = {}) const;
|
||||
void GetEdgeList(Segment const & segment, bool isOutgoing, bool useRoutingOptions,
|
||||
SegmentEdgeListT & edges,
|
||||
void GetEdgeList(astar::VertexData<Segment, RouteWeight> const & vertexData, bool isOutgoing, bool useRoutingOptions,
|
||||
SegmentEdgeListT & edges, Parents<Segment> const & parents = {}) const;
|
||||
void GetEdgeList(Segment const & segment, bool isOutgoing, bool useRoutingOptions, SegmentEdgeListT & edges,
|
||||
Parents<Segment> const & parents = {}) const;
|
||||
|
||||
void GetEdgeList(astar::VertexData<JointSegment, RouteWeight> const & parentVertexData,
|
||||
Segment const & parent, bool isOutgoing, JointEdgeListT & edges,
|
||||
WeightListT & parentWeights, Parents<JointSegment> const & parents) const;
|
||||
void GetEdgeList(JointSegment const & parentJoint, Segment const & parent, bool isOutgoing,
|
||||
JointEdgeListT & edges, WeightListT & parentWeights,
|
||||
void GetEdgeList(astar::VertexData<JointSegment, RouteWeight> const & parentVertexData, Segment const & parent,
|
||||
bool isOutgoing, JointEdgeListT & edges, WeightListT & parentWeights,
|
||||
Parents<JointSegment> const & parents) const;
|
||||
void GetEdgeList(JointSegment const & parentJoint, Segment const & parent, bool isOutgoing, JointEdgeListT & edges,
|
||||
WeightListT & parentWeights, Parents<JointSegment> const & parents) const;
|
||||
|
||||
std::optional<JointEdge> GetJointEdgeByLastPoint(Segment const & parent,
|
||||
Segment const & firstChild, bool isOutgoing,
|
||||
std::optional<JointEdge> GetJointEdgeByLastPoint(Segment const & parent, Segment const & firstChild, bool isOutgoing,
|
||||
uint32_t lastPoint) const;
|
||||
|
||||
Joint::Id GetJointId(RoadPoint const & rp) const { return m_roadIndex.GetJointId(rp); }
|
||||
@@ -94,10 +90,7 @@ public:
|
||||
void SetUTurnRestrictions(std::vector<RestrictionUTurn> && noUTurnRestrictions);
|
||||
void SetRoadAccess(RoadAccess && roadAccess);
|
||||
|
||||
void PushFromSerializer(Joint::Id jointId, RoadPoint const & rp)
|
||||
{
|
||||
m_roadIndex.PushFromSerializer(jointId, rp);
|
||||
}
|
||||
void PushFromSerializer(Joint::Id jointId, RoadPoint const & rp) { m_roadIndex.PushFromSerializer(jointId, rp); }
|
||||
|
||||
template <typename F>
|
||||
void ForEachRoad(F && f) const
|
||||
@@ -113,8 +106,7 @@ public:
|
||||
|
||||
bool IsJoint(RoadPoint const & roadPoint) const;
|
||||
bool IsJointOrEnd(Segment const & segment, bool fromStart) const;
|
||||
void GetLastPointsForJoint(SegmentListT const & children, bool isOutgoing,
|
||||
PointIdListT & lastPoints) const;
|
||||
void GetLastPointsForJoint(SegmentListT const & children, bool isOutgoing, PointIdListT & lastPoints) const;
|
||||
|
||||
WorldGraphMode GetMode() const;
|
||||
ms::LatLon const & GetPoint(Segment const & segment, bool front) const
|
||||
@@ -126,9 +118,7 @@ public:
|
||||
/// We pass |parentFeatureId| and don't use |parent.GetFeatureId()| because
|
||||
/// |parent| can be fake sometimes but |parentFeatureId| is almost non-fake.
|
||||
template <typename ParentVertex>
|
||||
bool IsRestricted(ParentVertex const & parent,
|
||||
uint32_t parentFeatureId,
|
||||
uint32_t currentFeatureId, bool isOutgoing,
|
||||
bool IsRestricted(ParentVertex const & parent, uint32_t parentFeatureId, uint32_t currentFeatureId, bool isOutgoing,
|
||||
Parents<ParentVertex> const & parents) const;
|
||||
|
||||
bool IsUTurnAndRestricted(Segment const & parent, Segment const & child, bool isOutgoing) const;
|
||||
@@ -137,36 +127,35 @@ public:
|
||||
/// @param[in] prevWeight used for fetching access:conditional.
|
||||
/// I suppose :) its time when user will be at the end of |from| (|to| if \a isOutgoing == false) segment.
|
||||
/// @return Transition weight + |to| (|from| if \a isOutgoing == false) segment's weight.
|
||||
RouteWeight CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool isOutgoing,
|
||||
Segment const & from, Segment const & to,
|
||||
RouteWeight CalculateEdgeWeight(EdgeEstimator::Purpose purpose, bool isOutgoing, Segment const & from,
|
||||
Segment const & to,
|
||||
std::optional<RouteWeight const> const & prevWeight = std::nullopt) const;
|
||||
|
||||
template <typename T>
|
||||
void SetCurrentTimeGetter(T && t) { m_currentTimeGetter = std::forward<T>(t); }
|
||||
void SetCurrentTimeGetter(T && t)
|
||||
{
|
||||
m_currentTimeGetter = std::forward<T>(t);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetEdgeListImpl(astar::VertexData<Segment, RouteWeight> const & vertexData, bool isOutgoing,
|
||||
bool useRoutingOptions, bool useAccessConditional,
|
||||
SegmentEdgeListT & edges, Parents<Segment> const & parents) const;
|
||||
bool useRoutingOptions, bool useAccessConditional, SegmentEdgeListT & edges,
|
||||
Parents<Segment> const & parents) const;
|
||||
|
||||
void GetEdgeListImpl(astar::VertexData<JointSegment, RouteWeight> const & parentVertexData,
|
||||
Segment const & parent, bool isOutgoing, bool useAccessConditional,
|
||||
JointEdgeListT & edges, WeightListT & parentWeights,
|
||||
void GetEdgeListImpl(astar::VertexData<JointSegment, RouteWeight> const & parentVertexData, Segment const & parent,
|
||||
bool isOutgoing, bool useAccessConditional, JointEdgeListT & edges, WeightListT & parentWeights,
|
||||
Parents<JointSegment> const & parents) const;
|
||||
|
||||
void GetNeighboringEdges(astar::VertexData<Segment, RouteWeight> const & fromVertexData,
|
||||
RoadPoint const & rp, bool isOutgoing, bool useRoutingOptions,
|
||||
SegmentEdgeListT & edges, Parents<Segment> const & parents,
|
||||
bool useAccessConditional) const;
|
||||
void GetNeighboringEdge(astar::VertexData<Segment, RouteWeight> const & fromVertexData,
|
||||
Segment const & to, bool isOutgoing, SegmentEdgeListT & edges,
|
||||
Parents<Segment> const & parents, bool useAccessConditional) const;
|
||||
void GetNeighboringEdges(astar::VertexData<Segment, RouteWeight> const & fromVertexData, RoadPoint const & rp,
|
||||
bool isOutgoing, bool useRoutingOptions, SegmentEdgeListT & edges,
|
||||
Parents<Segment> const & parents, bool useAccessConditional) const;
|
||||
void GetNeighboringEdge(astar::VertexData<Segment, RouteWeight> const & fromVertexData, Segment const & to,
|
||||
bool isOutgoing, SegmentEdgeListT & edges, Parents<Segment> const & parents,
|
||||
bool useAccessConditional) const;
|
||||
|
||||
struct PenaltyData
|
||||
{
|
||||
PenaltyData(bool passThroughAllowed, bool isFerry)
|
||||
: m_passThroughAllowed(passThroughAllowed),
|
||||
m_isFerry(isFerry) {}
|
||||
PenaltyData(bool passThroughAllowed, bool isFerry) : m_passThroughAllowed(passThroughAllowed), m_isFerry(isFerry) {}
|
||||
|
||||
bool m_passThroughAllowed;
|
||||
bool m_isFerry;
|
||||
@@ -181,21 +170,17 @@ private:
|
||||
RouteWeight GetPenalties(EdgeEstimator::Purpose purpose, Segment const & u, Segment const & v,
|
||||
std::optional<RouteWeight> const & prevWeight) const;
|
||||
|
||||
void GetSegmentCandidateForRoadPoint(RoadPoint const & rp, NumMwmId numMwmId,
|
||||
bool isOutgoing, SegmentListT & children) const;
|
||||
void GetSegmentCandidateForRoadPoint(RoadPoint const & rp, NumMwmId numMwmId, bool isOutgoing,
|
||||
SegmentListT & children) const;
|
||||
void GetSegmentCandidateForJoint(Segment const & parent, bool isOutgoing, SegmentListT & children) const;
|
||||
void ReconstructJointSegment(astar::VertexData<JointSegment, RouteWeight> const & parentVertexData,
|
||||
Segment const & parent,
|
||||
SegmentListT const & firstChildren,
|
||||
PointIdListT const & lastPointIds,
|
||||
bool isOutgoing,
|
||||
JointEdgeListT & jointEdges,
|
||||
WeightListT & parentWeights,
|
||||
Parents<JointSegment> const & parents) const;
|
||||
Segment const & parent, SegmentListT const & firstChildren,
|
||||
PointIdListT const & lastPointIds, bool isOutgoing, JointEdgeListT & jointEdges,
|
||||
WeightListT & parentWeights, Parents<JointSegment> const & parents) const;
|
||||
|
||||
template <typename AccessPositionType>
|
||||
bool IsAccessNoForSure(AccessPositionType const & accessPositionType,
|
||||
RouteWeight const & weight, bool useAccessConditional) const;
|
||||
bool IsAccessNoForSure(AccessPositionType const & accessPositionType, RouteWeight const & weight,
|
||||
bool useAccessConditional) const;
|
||||
|
||||
std::shared_ptr<Geometry> m_geometry;
|
||||
std::shared_ptr<EdgeEstimator> m_estimator;
|
||||
@@ -221,27 +206,22 @@ private:
|
||||
RoadAccess m_roadAccess;
|
||||
RoutingOptions m_avoidRoutingOptions;
|
||||
|
||||
std::function<time_t()> m_currentTimeGetter = []() {
|
||||
return GetCurrentTimestamp();
|
||||
};
|
||||
std::function<time_t()> m_currentTimeGetter = []() { return GetCurrentTimestamp(); };
|
||||
};
|
||||
|
||||
template <typename AccessPositionType>
|
||||
bool IndexGraph::IsAccessNoForSure(AccessPositionType const & accessPositionType,
|
||||
RouteWeight const & weight, bool useAccessConditional) const
|
||||
bool IndexGraph::IsAccessNoForSure(AccessPositionType const & accessPositionType, RouteWeight const & weight,
|
||||
bool useAccessConditional) const
|
||||
{
|
||||
auto const [accessType, confidence] =
|
||||
useAccessConditional ? m_roadAccess.GetAccess(accessPositionType, weight)
|
||||
: m_roadAccess.GetAccessWithoutConditional(accessPositionType);
|
||||
auto const [accessType, confidence] = useAccessConditional
|
||||
? m_roadAccess.GetAccess(accessPositionType, weight)
|
||||
: m_roadAccess.GetAccessWithoutConditional(accessPositionType);
|
||||
return accessType == RoadAccess::Type::No && confidence == RoadAccess::Confidence::Sure;
|
||||
}
|
||||
|
||||
template <typename ParentVertex>
|
||||
bool IndexGraph::IsRestricted(ParentVertex const & parent,
|
||||
uint32_t parentFeatureId,
|
||||
uint32_t currentFeatureId,
|
||||
bool isOutgoing,
|
||||
Parents<ParentVertex> const & parents) const
|
||||
bool IndexGraph::IsRestricted(ParentVertex const & parent, uint32_t parentFeatureId, uint32_t currentFeatureId,
|
||||
bool isOutgoing, Parents<ParentVertex> const & parents) const
|
||||
{
|
||||
if (parentFeatureId == currentFeatureId)
|
||||
return false;
|
||||
@@ -295,11 +275,8 @@ bool IndexGraph::IsRestricted(ParentVertex const & parent,
|
||||
for (size_t i = 1; i < restriction.size(); ++i)
|
||||
{
|
||||
ASSERT_GREATER_OR_EQUAL(i, 1, ("Unexpected overflow."));
|
||||
if (i - 1 == parentsFromCurrent.size()
|
||||
&& !appendNextParent(parentsFromCurrent.back(), parentsFromCurrent))
|
||||
{
|
||||
if (i - 1 == parentsFromCurrent.size() && !appendNextParent(parentsFromCurrent.back(), parentsFromCurrent))
|
||||
break;
|
||||
}
|
||||
|
||||
if (parentsFromCurrent.back().GetFeatureId() != restriction[i])
|
||||
break;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
namespace routing
|
||||
{
|
||||
namespace
|
||||
@@ -72,9 +71,7 @@ private:
|
||||
SpeedCamerasMapT const & ReceiveSpeedCamsFromMwm(NumMwmId numMwmId);
|
||||
|
||||
RoutingOptions m_avoidRoutingOptions;
|
||||
std::function<time_t()> m_currentTimeGetter = [time = GetCurrentTimestamp()]() {
|
||||
return time;
|
||||
};
|
||||
std::function<time_t()> m_currentTimeGetter = [time = GetCurrentTimestamp()]() { return time; };
|
||||
};
|
||||
|
||||
IndexGraph & IndexGraphLoaderImpl::GetIndexGraph(NumMwmId numMwmId)
|
||||
@@ -115,10 +112,8 @@ vector<RouteSegment::SpeedCamera> IndexGraphLoaderImpl::GetSpeedCameraInfo(Segme
|
||||
return {};
|
||||
|
||||
auto cameras = it->second;
|
||||
base::SortUnique(cameras, std::less<RouteSegment::SpeedCamera>(), [](auto const & l, auto const & r)
|
||||
{
|
||||
return l.EqualCoef(r);
|
||||
});
|
||||
base::SortUnique(cameras, std::less<RouteSegment::SpeedCamera>(),
|
||||
[](auto const & l, auto const & r) { return l.EqualCoef(r); });
|
||||
|
||||
// Cameras stored from beginning to ending of segment. So if we go at segment in backward direction,
|
||||
// we should read cameras in reverse sequence too.
|
||||
@@ -147,7 +142,8 @@ IndexGraphLoaderImpl::GraphPtrT IndexGraphLoaderImpl::CreateIndexGraph(NumMwmId
|
||||
graph->SetCurrentTimeGetter(m_currentTimeGetter);
|
||||
DeserializeIndexGraph(*value, m_vehicleType, *graph);
|
||||
|
||||
LOG(LINFO, (ROUTING_FILE_TAG, "section for", value->GetCountryFileName(), "loaded in", timer.ElapsedSeconds(), "seconds"));
|
||||
LOG(LINFO,
|
||||
(ROUTING_FILE_TAG, "section for", value->GetCountryFileName(), "loaded in", timer.ElapsedSeconds(), "seconds"));
|
||||
return graph;
|
||||
}
|
||||
catch (RootException const & ex)
|
||||
@@ -166,9 +162,12 @@ IndexGraphLoaderImpl::GeometryPtrT IndexGraphLoaderImpl::CreateGeometry(NumMwmId
|
||||
return make_shared<Geometry>(GeometryLoader::Create(handle, std::move(vehicleModel), m_loadAltitudes));
|
||||
}
|
||||
|
||||
void IndexGraphLoaderImpl::Clear() { m_graphs.clear(); }
|
||||
void IndexGraphLoaderImpl::Clear()
|
||||
{
|
||||
m_graphs.clear();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
bool ReadSpeedCamsFromMwm(MwmValue const & mwmValue, SpeedCamerasMapT & camerasMap)
|
||||
{
|
||||
@@ -211,14 +210,13 @@ bool ReadRoadAccessFromMwm(MwmValue const & mwmValue, VehicleType vehicleType, R
|
||||
}
|
||||
|
||||
// static
|
||||
unique_ptr<IndexGraphLoader> IndexGraphLoader::Create(
|
||||
VehicleType vehicleType, bool loadAltitudes,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
shared_ptr<EdgeEstimator> estimator, MwmDataSource & dataSource,
|
||||
RoutingOptions routingOptions)
|
||||
unique_ptr<IndexGraphLoader> IndexGraphLoader::Create(VehicleType vehicleType, bool loadAltitudes,
|
||||
shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
shared_ptr<EdgeEstimator> estimator, MwmDataSource & dataSource,
|
||||
RoutingOptions routingOptions)
|
||||
{
|
||||
return make_unique<IndexGraphLoaderImpl>(vehicleType, loadAltitudes, vehicleModelFactory,
|
||||
estimator, dataSource, routingOptions);
|
||||
return make_unique<IndexGraphLoaderImpl>(vehicleType, loadAltitudes, vehicleModelFactory, estimator, dataSource,
|
||||
routingOptions);
|
||||
}
|
||||
|
||||
void DeserializeIndexGraph(MwmValue const & mwmValue, VehicleType vehicleType, IndexGraph & graph)
|
||||
|
||||
@@ -30,11 +30,10 @@ public:
|
||||
virtual std::vector<RouteSegment::SpeedCamera> GetSpeedCameraInfo(Segment const & segment) = 0;
|
||||
virtual void Clear() = 0;
|
||||
|
||||
static std::unique_ptr<IndexGraphLoader> Create(
|
||||
VehicleType vehicleType, bool loadAltitudes,
|
||||
std::shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
std::shared_ptr<EdgeEstimator> estimator, MwmDataSource & dataSource,
|
||||
RoutingOptions routingOptions = RoutingOptions());
|
||||
static std::unique_ptr<IndexGraphLoader> Create(VehicleType vehicleType, bool loadAltitudes,
|
||||
std::shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory,
|
||||
std::shared_ptr<EdgeEstimator> estimator, MwmDataSource & dataSource,
|
||||
RoutingOptions routingOptions = RoutingOptions());
|
||||
};
|
||||
|
||||
void DeserializeIndexGraph(MwmValue const & mwmValue, VehicleType vehicleType, IndexGraph & graph);
|
||||
|
||||
@@ -8,9 +8,9 @@ uint32_t constexpr IndexGraphSerializer::JointsFilter::kEmptyEntry;
|
||||
uint32_t constexpr IndexGraphSerializer::JointsFilter::kPushedEntry;
|
||||
|
||||
// IndexGraphSerializer::SectionSerializer ---------------------------------------------------------
|
||||
void IndexGraphSerializer::SectionSerializer::PreSerialize(
|
||||
IndexGraph const & graph, std::unordered_map<uint32_t, VehicleMask> const & masks,
|
||||
JointIdEncoder & jointEncoder)
|
||||
void IndexGraphSerializer::SectionSerializer::PreSerialize(IndexGraph const & graph,
|
||||
std::unordered_map<uint32_t, VehicleMask> const & masks,
|
||||
JointIdEncoder & jointEncoder)
|
||||
{
|
||||
m_buffer.clear();
|
||||
MemWriter<std::vector<uint8_t>> memWriter(m_buffer);
|
||||
@@ -28,7 +28,8 @@ void IndexGraphSerializer::SectionSerializer::PreSerialize(
|
||||
WriteGamma(writer, ConvertJointsNumber(road.GetJointsNumber()));
|
||||
|
||||
uint32_t prevPointId = -1;
|
||||
road.ForEachJoint([&](uint32_t pointId, Joint::Id jointId) {
|
||||
road.ForEachJoint([&](uint32_t pointId, Joint::Id jointId)
|
||||
{
|
||||
WriteGamma(writer, pointId - prevPointId);
|
||||
jointEncoder.Write(jointId, writer);
|
||||
prevPointId = pointId;
|
||||
@@ -54,8 +55,7 @@ void IndexGraphSerializer::JointsFilter::Push(Joint::Id jointIdInFile, RoadPoint
|
||||
break;
|
||||
case kPushedEntry: m_graph.PushFromSerializer(entry.second.jointId, rp); break;
|
||||
default:
|
||||
m_graph.PushFromSerializer(m_count,
|
||||
RoadPoint(entry.first /* featureId */, entry.second.pointId));
|
||||
m_graph.PushFromSerializer(m_count, RoadPoint(entry.first /* featureId */, entry.second.pointId));
|
||||
m_graph.PushFromSerializer(m_count, rp);
|
||||
entry.first = kPushedEntry;
|
||||
entry.second.jointId = m_count;
|
||||
@@ -89,9 +89,9 @@ uint32_t IndexGraphSerializer::ConvertJointsNumber(uint32_t jointsNumber)
|
||||
}
|
||||
|
||||
// static
|
||||
void IndexGraphSerializer::PrepareSectionSerializers(
|
||||
IndexGraph const & graph, std::unordered_map<uint32_t, VehicleMask> const & masks,
|
||||
std::vector<SectionSerializer> & serializers)
|
||||
void IndexGraphSerializer::PrepareSectionSerializers(IndexGraph const & graph,
|
||||
std::unordered_map<uint32_t, VehicleMask> const & masks,
|
||||
std::vector<SectionSerializer> & serializers)
|
||||
{
|
||||
size_t maskToIndex[kNumVehicleMasks] = {};
|
||||
// Car routing is most used routing: put car sections first.
|
||||
@@ -110,7 +110,8 @@ void IndexGraphSerializer::PrepareSectionSerializers(
|
||||
}
|
||||
}
|
||||
|
||||
graph.ForEachRoad([&](uint32_t featureId, RoadJointIds const & /* road */) {
|
||||
graph.ForEachRoad([&](uint32_t featureId, RoadJointIds const & /* road */)
|
||||
{
|
||||
VehicleMask const mask = GetRoadMask(masks, featureId);
|
||||
SectionSerializer & serializer = serializers[maskToIndex[mask]];
|
||||
CHECK_EQUAL(serializer.GetMask(), mask, ());
|
||||
|
||||
@@ -25,8 +25,7 @@ public:
|
||||
IndexGraphSerializer() = delete;
|
||||
|
||||
template <class Sink>
|
||||
static void Serialize(IndexGraph const & graph,
|
||||
std::unordered_map<uint32_t, VehicleMask> const & masks, Sink & sink)
|
||||
static void Serialize(IndexGraph const & graph, std::unordered_map<uint32_t, VehicleMask> const & masks, Sink & sink)
|
||||
{
|
||||
Header header(graph);
|
||||
JointIdEncoder jointEncoder;
|
||||
@@ -39,8 +38,11 @@ public:
|
||||
Joint::Id const begin = jointEncoder.GetCount();
|
||||
serializer.PreSerialize(graph, masks, jointEncoder);
|
||||
header.AddSection({
|
||||
serializer.GetBufferSize(), static_cast<uint32_t>(serializer.GetNumRoads()), begin,
|
||||
jointEncoder.GetCount(), serializer.GetMask(),
|
||||
serializer.GetBufferSize(),
|
||||
static_cast<uint32_t>(serializer.GetNumRoads()),
|
||||
begin,
|
||||
jointEncoder.GetCount(),
|
||||
serializer.GetMask(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -93,9 +95,8 @@ public:
|
||||
Joint::Id const jointId = jointIdDecoder.Read(reader);
|
||||
if (jointId >= section.GetEndJointId())
|
||||
{
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Invalid jointId =", jointId, ", end =", section.GetEndJointId(), ", mask =",
|
||||
mask, ", pointId =", pointId, ", featureId =", featureId));
|
||||
MYTHROW(CorruptedDataException, ("Invalid jointId =", jointId, ", end =", section.GetEndJointId(),
|
||||
", mask =", mask, ", pointId =", pointId, ", featureId =", featureId));
|
||||
}
|
||||
|
||||
jointsFilter.Push(jointId, RoadPoint(featureId, pointId));
|
||||
@@ -104,16 +105,14 @@ public:
|
||||
|
||||
if (jointIdDecoder.GetCount() != section.GetEndJointId())
|
||||
{
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Invalid decoder count =", jointIdDecoder.GetCount(), ", expected =",
|
||||
section.GetEndJointId(), ", mask =", mask));
|
||||
MYTHROW(CorruptedDataException, ("Invalid decoder count =", jointIdDecoder.GetCount(),
|
||||
", expected =", section.GetEndJointId(), ", mask =", mask));
|
||||
}
|
||||
|
||||
if (src.Pos() != expectedEndPos)
|
||||
{
|
||||
MYTHROW(CorruptedDataException,
|
||||
("Wrong position", src.Pos(), "after decoding section", mask, "expected",
|
||||
expectedEndPos, "section size =", section.GetSize()));
|
||||
MYTHROW(CorruptedDataException, ("Wrong position", src.Pos(), "after decoding section", mask, "expected",
|
||||
expectedEndPos, "section size =", section.GetSize()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,15 +150,13 @@ private:
|
||||
public:
|
||||
Section() = default;
|
||||
|
||||
Section(uint64_t size, uint32_t numRoads, Joint::Id beginJointId, Joint::Id endJointId,
|
||||
VehicleMask mask)
|
||||
Section(uint64_t size, uint32_t numRoads, Joint::Id beginJointId, Joint::Id endJointId, VehicleMask mask)
|
||||
: m_size(size)
|
||||
, m_numRoads(numRoads)
|
||||
, m_beginJointId(beginJointId)
|
||||
, m_endJointId(endJointId)
|
||||
, m_mask(mask)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
template <class Sink>
|
||||
void Serialize(Sink & sink) const
|
||||
@@ -200,10 +197,7 @@ private:
|
||||
public:
|
||||
Header() = default;
|
||||
|
||||
explicit Header(IndexGraph const & graph)
|
||||
: m_numRoads(graph.GetNumRoads()), m_numJoints(graph.GetNumJoints())
|
||||
{
|
||||
}
|
||||
explicit Header(IndexGraph const & graph) : m_numRoads(graph.GetNumRoads()), m_numJoints(graph.GetNumJoints()) {}
|
||||
|
||||
template <class Sink>
|
||||
void Serialize(Sink & sink) const
|
||||
@@ -266,8 +260,8 @@ private:
|
||||
{
|
||||
Joint::Id const convertedId = it->second;
|
||||
CHECK_LESS(convertedId, m_count,
|
||||
("Duplicate joint id should be less than count, convertedId =", convertedId,
|
||||
", count =", m_count, ", originalId =", originalId));
|
||||
("Duplicate joint id should be less than count, convertedId =", convertedId, ", count =", m_count,
|
||||
", originalId =", originalId));
|
||||
writer.Write(kRepeatJointIdBit, 1);
|
||||
// m_count - convertedId is less than convertedId in general.
|
||||
// So write this delta to save file space.
|
||||
@@ -346,7 +340,8 @@ private:
|
||||
|
||||
// Joints number is large.
|
||||
// Therefore point id and joint id are stored in same space to save some memory.
|
||||
union Point {
|
||||
union Point
|
||||
{
|
||||
uint32_t pointId;
|
||||
Joint::Id jointId;
|
||||
};
|
||||
@@ -385,8 +380,7 @@ private:
|
||||
std::vector<uint8_t> m_buffer;
|
||||
};
|
||||
|
||||
static VehicleMask GetRoadMask(std::unordered_map<uint32_t, VehicleMask> const & masks,
|
||||
uint32_t featureId);
|
||||
static VehicleMask GetRoadMask(std::unordered_map<uint32_t, VehicleMask> const & masks, uint32_t featureId);
|
||||
static uint32_t ConvertJointsNumber(uint32_t jointsNumber);
|
||||
static void PrepareSectionSerializers(IndexGraph const & graph,
|
||||
std::unordered_map<uint32_t, VehicleMask> const & masks,
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace routing
|
||||
{
|
||||
using namespace std;
|
||||
@@ -35,9 +34,8 @@ void IndexGraphStarter::CheckValidRoute(vector<Segment> const & segments)
|
||||
CHECK(IsFakeSegment(segments.back()), ());
|
||||
}
|
||||
|
||||
IndexGraphStarter::IndexGraphStarter(FakeEnding const & startEnding,
|
||||
FakeEnding const & finishEnding, uint32_t fakeNumerationStart,
|
||||
bool strictForward, WorldGraph & graph)
|
||||
IndexGraphStarter::IndexGraphStarter(FakeEnding const & startEnding, FakeEnding const & finishEnding,
|
||||
uint32_t fakeNumerationStart, bool strictForward, WorldGraph & graph)
|
||||
: m_graph(graph)
|
||||
{
|
||||
m_fakeNumerationStart = fakeNumerationStart;
|
||||
@@ -68,7 +66,10 @@ void IndexGraphStarter::Append(FakeEdgesContainer const & container)
|
||||
m_fakeNumerationStart += container.m_fake.GetSize();
|
||||
}
|
||||
|
||||
void IndexGraphStarter::SetGuides(GuidesGraph const & guides) { m_guides = guides; }
|
||||
void IndexGraphStarter::SetGuides(GuidesGraph const & guides)
|
||||
{
|
||||
m_guides = guides;
|
||||
}
|
||||
|
||||
void IndexGraphStarter::SetRegionsGraphMode(std::shared_ptr<RegionsSparseGraph> regionsSparseGraph)
|
||||
{
|
||||
@@ -108,13 +109,12 @@ LatLonWithAltitude const & IndexGraphStarter::GetJunction(Segment const & segmen
|
||||
return front ? vertex.GetJunctionTo() : vertex.GetJunctionFrom();
|
||||
}
|
||||
|
||||
LatLonWithAltitude const & IndexGraphStarter::GetRouteJunction(
|
||||
vector<Segment> const & segments, size_t pointIndex) const
|
||||
LatLonWithAltitude const & IndexGraphStarter::GetRouteJunction(vector<Segment> const & segments,
|
||||
size_t pointIndex) const
|
||||
{
|
||||
CHECK(!segments.empty(), ());
|
||||
CHECK_LESS_OR_EQUAL(
|
||||
pointIndex, segments.size(),
|
||||
("Point with index", pointIndex, "does not exist in route with size", segments.size()));
|
||||
CHECK_LESS_OR_EQUAL(pointIndex, segments.size(),
|
||||
("Point with index", pointIndex, "does not exist in route with size", segments.size()));
|
||||
if (pointIndex == segments.size())
|
||||
return GetJunction(segments[pointIndex - 1], true /* front */);
|
||||
return GetJunction(segments[pointIndex], false);
|
||||
@@ -165,15 +165,14 @@ bool IndexGraphStarter::CheckLength(RouteWeight const & weight)
|
||||
/// This additional penalty will be included in RouteWeight::GetIntegratedWeight().
|
||||
/// @see RussiaMoscowNotCrossingTollRoadTest
|
||||
|
||||
int8_t const changesAllowed = 2 + (HasNoPassThroughAllowed(m_start) ? 1 : 0) + (HasNoPassThroughAllowed(m_finish) ? 1 : 0);
|
||||
int8_t const changesAllowed =
|
||||
2 + (HasNoPassThroughAllowed(m_start) ? 1 : 0) + (HasNoPassThroughAllowed(m_finish) ? 1 : 0);
|
||||
|
||||
return weight.GetNumPassThroughChanges() <= changesAllowed &&
|
||||
m_graph.CheckLength(weight, m_startToFinishDistanceM);
|
||||
return weight.GetNumPassThroughChanges() <= changesAllowed && m_graph.CheckLength(weight, m_startToFinishDistanceM);
|
||||
}
|
||||
|
||||
void IndexGraphStarter::GetEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
bool isOutgoing, bool useAccessConditional,
|
||||
EdgeListT & edges) const
|
||||
void IndexGraphStarter::GetEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, bool isOutgoing,
|
||||
bool useAccessConditional, EdgeListT & edges) const
|
||||
{
|
||||
edges.clear();
|
||||
CHECK_NOT_EQUAL(m_graph.GetMode(), WorldGraphMode::LeapsOnly, ());
|
||||
@@ -199,23 +198,19 @@ void IndexGraphStarter::GetEdgesList(astar::VertexData<Vertex, Weight> const & v
|
||||
}
|
||||
else if (IsRegionsGraphMode())
|
||||
{
|
||||
m_regionsGraph->GetEdgeList(real, isOutgoing, edges,
|
||||
GetJunction(segment, true /* front */).GetLatLon());
|
||||
m_regionsGraph->GetEdgeList(real, isOutgoing, edges, GetJunction(segment, true /* front */).GetLatLon());
|
||||
}
|
||||
else
|
||||
{
|
||||
astar::VertexData const replacedFakeSegment(real, vertexData.m_realDistance);
|
||||
m_graph.GetEdgeList(replacedFakeSegment, isOutgoing, true /* useRoutingOptions */,
|
||||
useAccessConditional, edges);
|
||||
m_graph.GetEdgeList(replacedFakeSegment, isOutgoing, true /* useRoutingOptions */, useAccessConditional,
|
||||
edges);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const & s : m_fake.GetEdges(segment, isOutgoing))
|
||||
{
|
||||
edges.emplace_back(s, isOutgoing ? CalcSegmentWeight(s, EdgeEstimator::Purpose::Weight)
|
||||
: ingoingSegmentWeight);
|
||||
}
|
||||
edges.emplace_back(s, isOutgoing ? CalcSegmentWeight(s, EdgeEstimator::Purpose::Weight) : ingoingSegmentWeight);
|
||||
}
|
||||
else if (IsGuidesSegment(segment))
|
||||
{
|
||||
@@ -223,20 +218,17 @@ void IndexGraphStarter::GetEdgesList(astar::VertexData<Vertex, Weight> const & v
|
||||
}
|
||||
else if (IsRegionsGraphMode())
|
||||
{
|
||||
m_regionsGraph->GetEdgeList(segment, isOutgoing, edges,
|
||||
GetJunction(segment, true /* front */).GetLatLon());
|
||||
m_regionsGraph->GetEdgeList(segment, isOutgoing, edges, GetJunction(segment, true /* front */).GetLatLon());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_graph.GetEdgeList(vertexData, isOutgoing, true /* useRoutingOptions */, useAccessConditional,
|
||||
edges);
|
||||
m_graph.GetEdgeList(vertexData, isOutgoing, true /* useRoutingOptions */, useAccessConditional, edges);
|
||||
}
|
||||
|
||||
AddFakeEdges(segment, isOutgoing, edges);
|
||||
}
|
||||
|
||||
RouteWeight IndexGraphStarter::CalcGuidesSegmentWeight(Segment const & segment,
|
||||
EdgeEstimator::Purpose purpose) const
|
||||
RouteWeight IndexGraphStarter::CalcGuidesSegmentWeight(Segment const & segment, EdgeEstimator::Purpose purpose) const
|
||||
{
|
||||
if (purpose == EdgeEstimator::Purpose::Weight)
|
||||
return m_guides.CalcSegmentWeight(segment);
|
||||
@@ -245,8 +237,7 @@ RouteWeight IndexGraphStarter::CalcGuidesSegmentWeight(Segment const & segment,
|
||||
return m_graph.CalcOffroadWeight(from.GetLatLon(), to.GetLatLon(), purpose);
|
||||
}
|
||||
|
||||
RouteWeight IndexGraphStarter::CalcSegmentWeight(Segment const & segment,
|
||||
EdgeEstimator::Purpose purpose) const
|
||||
RouteWeight IndexGraphStarter::CalcSegmentWeight(Segment const & segment, EdgeEstimator::Purpose purpose) const
|
||||
{
|
||||
if (IsGuidesSegment(segment))
|
||||
return CalcGuidesSegmentWeight(segment, purpose);
|
||||
@@ -313,10 +304,7 @@ double IndexGraphStarter::CalculateETA(Segment const & from, Segment const & to)
|
||||
}
|
||||
|
||||
if (IsRegionsGraphMode())
|
||||
{
|
||||
return m_regionsGraph->CalcSegmentWeight(from).GetWeight() +
|
||||
m_regionsGraph->CalcSegmentWeight(to).GetWeight();
|
||||
}
|
||||
return m_regionsGraph->CalcSegmentWeight(from).GetWeight() + m_regionsGraph->CalcSegmentWeight(to).GetWeight();
|
||||
|
||||
return m_graph.CalculateETA(from, to);
|
||||
}
|
||||
@@ -362,10 +350,9 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding)
|
||||
{
|
||||
// Add projection edges
|
||||
auto const projectionSegment = GetFakeSegmentAndIncr();
|
||||
FakeVertex projectionVertex(projection.m_segment.GetMwmId(),
|
||||
isStart ? thisEnding.m_originJunction : projection.m_junction,
|
||||
isStart ? projection.m_junction : thisEnding.m_originJunction,
|
||||
FakeVertex::Type::PureFake);
|
||||
FakeVertex projectionVertex(
|
||||
projection.m_segment.GetMwmId(), isStart ? thisEnding.m_originJunction : projection.m_junction,
|
||||
isStart ? projection.m_junction : thisEnding.m_originJunction, FakeVertex::Type::PureFake);
|
||||
m_fake.AddVertex(fakeSegment, projectionSegment, projectionVertex, isStart /* isOutgoing */,
|
||||
false /* isPartOfReal */, dummy /* realSegment */);
|
||||
|
||||
@@ -401,26 +388,24 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding)
|
||||
frontJunction = backJunction = otherJunction;
|
||||
}
|
||||
|
||||
FakeVertex forwardPartOfReal(
|
||||
projection.m_segment.GetMwmId(), isStart ? projection.m_junction : backJunction,
|
||||
isStart ? frontJunction : projection.m_junction, FakeVertex::Type::PartOfReal);
|
||||
FakeVertex forwardPartOfReal(projection.m_segment.GetMwmId(), isStart ? projection.m_junction : backJunction,
|
||||
isStart ? frontJunction : projection.m_junction, FakeVertex::Type::PartOfReal);
|
||||
Segment fakeForwardSegment;
|
||||
if (!m_fake.FindSegment(forwardPartOfReal, fakeForwardSegment))
|
||||
fakeForwardSegment = GetFakeSegmentAndIncr();
|
||||
m_fake.AddVertex(projectionSegment, fakeForwardSegment, forwardPartOfReal,
|
||||
isStart /* isOutgoing */, true /* isPartOfReal */, projection.m_segment);
|
||||
m_fake.AddVertex(projectionSegment, fakeForwardSegment, forwardPartOfReal, isStart /* isOutgoing */,
|
||||
true /* isPartOfReal */, projection.m_segment);
|
||||
|
||||
if (!projection.m_isOneWay)
|
||||
{
|
||||
auto const backwardSegment = projection.m_segment.GetReversed();
|
||||
FakeVertex backwardPartOfReal(
|
||||
backwardSegment.GetMwmId(), isStart ? projection.m_junction : frontJunction,
|
||||
isStart ? backJunction : projection.m_junction, FakeVertex::Type::PartOfReal);
|
||||
FakeVertex backwardPartOfReal(backwardSegment.GetMwmId(), isStart ? projection.m_junction : frontJunction,
|
||||
isStart ? backJunction : projection.m_junction, FakeVertex::Type::PartOfReal);
|
||||
Segment fakeBackwardSegment;
|
||||
if (!m_fake.FindSegment(backwardPartOfReal, fakeBackwardSegment))
|
||||
fakeBackwardSegment = GetFakeSegmentAndIncr();
|
||||
m_fake.AddVertex(projectionSegment, fakeBackwardSegment, backwardPartOfReal,
|
||||
isStart /* isOutgoing */, true /* isPartOfReal */, backwardSegment);
|
||||
m_fake.AddVertex(projectionSegment, fakeBackwardSegment, backwardPartOfReal, isStart /* isOutgoing */,
|
||||
true /* isPartOfReal */, backwardSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,8 +413,8 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding)
|
||||
m_otherEndings.push_back(thisEnding);
|
||||
}
|
||||
|
||||
void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding, FakeEnding const & otherEnding,
|
||||
bool isStart, bool strictForward)
|
||||
void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding, FakeEnding const & otherEnding, bool isStart,
|
||||
bool strictForward)
|
||||
{
|
||||
Segment const dummy = Segment();
|
||||
|
||||
@@ -456,10 +441,9 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding, FakeEnding cons
|
||||
|
||||
// Add projection edges
|
||||
auto const projectionSegment = GetFakeSegmentAndIncr();
|
||||
FakeVertex projectionVertex(projection.m_segment.GetMwmId(),
|
||||
isStart ? thisEnding.m_originJunction : projection.m_junction,
|
||||
isStart ? projection.m_junction : thisEnding.m_originJunction,
|
||||
FakeVertex::Type::PureFake);
|
||||
FakeVertex projectionVertex(
|
||||
projection.m_segment.GetMwmId(), isStart ? thisEnding.m_originJunction : projection.m_junction,
|
||||
isStart ? projection.m_junction : thisEnding.m_originJunction, FakeVertex::Type::PureFake);
|
||||
m_fake.AddVertex(fakeSegment, projectionSegment, projectionVertex, isStart /* isOutgoing */,
|
||||
false /* isPartOfReal */, dummy /* realSegment */);
|
||||
|
||||
@@ -472,10 +456,8 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding, FakeEnding cons
|
||||
if (it != otherSegments.end())
|
||||
{
|
||||
auto const & otherJunction = it->second;
|
||||
auto const distBackToThis = ms::DistanceOnEarth(backJunction.GetLatLon(),
|
||||
projection.m_junction.GetLatLon());
|
||||
auto const distBackToOther = ms::DistanceOnEarth(backJunction.GetLatLon(),
|
||||
otherJunction.GetLatLon());
|
||||
auto const distBackToThis = ms::DistanceOnEarth(backJunction.GetLatLon(), projection.m_junction.GetLatLon());
|
||||
auto const distBackToOther = ms::DistanceOnEarth(backJunction.GetLatLon(), otherJunction.GetLatLon());
|
||||
if (distBackToThis < distBackToOther)
|
||||
frontJunction = otherJunction;
|
||||
else if (distBackToOther < distBackToThis)
|
||||
@@ -484,33 +466,31 @@ void IndexGraphStarter::AddEnding(FakeEnding const & thisEnding, FakeEnding cons
|
||||
frontJunction = backJunction = otherJunction;
|
||||
}
|
||||
|
||||
FakeVertex forwardPartOfReal(
|
||||
projection.m_segment.GetMwmId(), isStart ? projection.m_junction : backJunction,
|
||||
isStart ? frontJunction : projection.m_junction, FakeVertex::Type::PartOfReal);
|
||||
FakeVertex forwardPartOfReal(projection.m_segment.GetMwmId(), isStart ? projection.m_junction : backJunction,
|
||||
isStart ? frontJunction : projection.m_junction, FakeVertex::Type::PartOfReal);
|
||||
Segment fakeForwardSegment;
|
||||
if (!m_fake.FindSegment(forwardPartOfReal, fakeForwardSegment))
|
||||
fakeForwardSegment = GetFakeSegmentAndIncr();
|
||||
m_fake.AddVertex(projectionSegment, fakeForwardSegment, forwardPartOfReal,
|
||||
isStart /* isOutgoing */, true /* isPartOfReal */, projection.m_segment);
|
||||
m_fake.AddVertex(projectionSegment, fakeForwardSegment, forwardPartOfReal, isStart /* isOutgoing */,
|
||||
true /* isPartOfReal */, projection.m_segment);
|
||||
|
||||
if (!strictForward && !projection.m_isOneWay)
|
||||
{
|
||||
auto const backwardSegment = projection.m_segment.GetReversed();
|
||||
FakeVertex backwardPartOfReal(
|
||||
backwardSegment.GetMwmId(), isStart ? projection.m_junction : frontJunction,
|
||||
isStart ? backJunction : projection.m_junction, FakeVertex::Type::PartOfReal);
|
||||
FakeVertex backwardPartOfReal(backwardSegment.GetMwmId(), isStart ? projection.m_junction : frontJunction,
|
||||
isStart ? backJunction : projection.m_junction, FakeVertex::Type::PartOfReal);
|
||||
Segment fakeBackwardSegment;
|
||||
if (!m_fake.FindSegment(backwardPartOfReal, fakeBackwardSegment))
|
||||
fakeBackwardSegment = GetFakeSegmentAndIncr();
|
||||
m_fake.AddVertex(projectionSegment, fakeBackwardSegment, backwardPartOfReal,
|
||||
isStart /* isOutgoing */, true /* isPartOfReal */, backwardSegment);
|
||||
m_fake.AddVertex(projectionSegment, fakeBackwardSegment, backwardPartOfReal, isStart /* isOutgoing */,
|
||||
true /* isPartOfReal */, backwardSegment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IndexGraphStarter::ConnectLoopToGuideSegments(
|
||||
FakeVertex const & loop, Segment const & realSegment, LatLonWithAltitude realFrom,
|
||||
LatLonWithAltitude realTo, vector<pair<FakeVertex, Segment>> const & partsOfReal)
|
||||
void IndexGraphStarter::ConnectLoopToGuideSegments(FakeVertex const & loop, Segment const & realSegment,
|
||||
LatLonWithAltitude realFrom, LatLonWithAltitude realTo,
|
||||
vector<pair<FakeVertex, Segment>> const & partsOfReal)
|
||||
{
|
||||
m_fake.ConnectLoopToGuideSegments(loop, realSegment, realFrom, realTo, partsOfReal);
|
||||
}
|
||||
@@ -532,23 +512,23 @@ HighwayCategory IndexGraphStarter::GetHighwayCategory(Segment seg) const
|
||||
|
||||
switch (*hwType)
|
||||
{
|
||||
case HighwayType::HighwayMotorway: case HighwayType::HighwayMotorwayLink:
|
||||
case HighwayType::HighwayTrunk: case HighwayType::HighwayTrunkLink:
|
||||
return HighwayCategory::Major;
|
||||
case HighwayType::HighwayPrimary: case HighwayType::HighwayPrimaryLink:
|
||||
return HighwayCategory::Primary;
|
||||
case HighwayType::HighwaySecondary: case HighwayType::HighwaySecondaryLink:
|
||||
case HighwayType::HighwayTertiary: case HighwayType::HighwayTertiaryLink:
|
||||
return HighwayCategory::Usual;
|
||||
case HighwayType::RouteFerry: case HighwayType::RouteShuttleTrain:
|
||||
return HighwayCategory::Transit;
|
||||
default:
|
||||
return HighwayCategory::Minor;
|
||||
case HighwayType::HighwayMotorway:
|
||||
case HighwayType::HighwayMotorwayLink:
|
||||
case HighwayType::HighwayTrunk:
|
||||
case HighwayType::HighwayTrunkLink: return HighwayCategory::Major;
|
||||
case HighwayType::HighwayPrimary:
|
||||
case HighwayType::HighwayPrimaryLink: return HighwayCategory::Primary;
|
||||
case HighwayType::HighwaySecondary:
|
||||
case HighwayType::HighwaySecondaryLink:
|
||||
case HighwayType::HighwayTertiary:
|
||||
case HighwayType::HighwayTertiaryLink: return HighwayCategory::Usual;
|
||||
case HighwayType::RouteFerry:
|
||||
case HighwayType::RouteShuttleTrain: return HighwayCategory::Transit;
|
||||
default: return HighwayCategory::Minor;
|
||||
}
|
||||
}
|
||||
|
||||
void IndexGraphStarter::AddStart(FakeEnding const & startEnding, FakeEnding const & finishEnding,
|
||||
bool strictForward)
|
||||
void IndexGraphStarter::AddStart(FakeEnding const & startEnding, FakeEnding const & finishEnding, bool strictForward)
|
||||
{
|
||||
AddEnding(startEnding, finishEnding, true /* isStart */, strictForward);
|
||||
m_start.FillMwmIds();
|
||||
@@ -569,20 +549,17 @@ void IndexGraphStarter::AddFakeEdges(Segment const & segment, bool isOutgoing, E
|
||||
{
|
||||
// |segment| |s|
|
||||
// *------------>*----------->
|
||||
bool const sIsOutgoing =
|
||||
GetJunction(segment, true /* front */) == GetJunction(s, false /* front */);
|
||||
bool const sIsOutgoing = GetJunction(segment, true /* front */) == GetJunction(s, false /* front */);
|
||||
|
||||
// |s| |segment|
|
||||
// *------------>*----------->
|
||||
bool const sIsIngoing =
|
||||
GetJunction(s, true /* front */) == GetJunction(segment, false /* front */);
|
||||
bool const sIsIngoing = GetJunction(s, true /* front */) == GetJunction(segment, false /* front */);
|
||||
|
||||
if ((isOutgoing && sIsOutgoing) || (!isOutgoing && sIsIngoing))
|
||||
{
|
||||
// For ingoing edges we use source weight which is the same for |s| and for |edge| and is
|
||||
// already calculated.
|
||||
fakeEdges.emplace_back(s, isOutgoing ? CalcSegmentWeight(s, EdgeEstimator::Purpose::Weight)
|
||||
: edge.GetWeight());
|
||||
fakeEdges.emplace_back(s, isOutgoing ? CalcSegmentWeight(s, EdgeEstimator::Purpose::Weight) : edge.GetWeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -616,7 +593,6 @@ RouteWeight IndexGraphStarter::GetAStarWeightEpsilon()
|
||||
// We store points with |kMwmPointAccuracy|. In case of cross mwm routing we couldn't
|
||||
// distinguish the point geometry changing in |kMwmPointAccuracy| radius of the same segments from
|
||||
// mwms with different versions. So let's use such epsilon to maintain the A* invariant.
|
||||
return kEps +
|
||||
m_graph.HeuristicCostEstimate(ms::LatLon(0.0, 0.0), ms::LatLon(0.0, kMwmPointAccuracy));
|
||||
return kEps + m_graph.HeuristicCostEstimate(ms::LatLon(0.0, 0.0), ms::LatLon(0.0, kMwmPointAccuracy));
|
||||
}
|
||||
} // namespace routing
|
||||
|
||||
@@ -28,7 +28,12 @@ class RegionsSparseGraph;
|
||||
enum class HighwayCategory : uint8_t
|
||||
{
|
||||
// Do not change order!
|
||||
Major, Primary, Usual, Minor, Transit, Unknown
|
||||
Major,
|
||||
Primary,
|
||||
Usual,
|
||||
Minor,
|
||||
Transit,
|
||||
Unknown
|
||||
};
|
||||
|
||||
// IndexGraphStarter adds fake start and finish vertices for AStarAlgorithm.
|
||||
@@ -45,10 +50,7 @@ public:
|
||||
|
||||
static void CheckValidRoute(std::vector<Segment> const & segments);
|
||||
|
||||
static bool IsFakeSegment(Segment const & segment)
|
||||
{
|
||||
return segment.IsFakeCreated();
|
||||
}
|
||||
static bool IsFakeSegment(Segment const & segment) { return segment.IsFakeCreated(); }
|
||||
|
||||
static bool IsGuidesSegment(Segment const & segment)
|
||||
{
|
||||
@@ -58,8 +60,8 @@ public:
|
||||
// strictForward flag specifies which parts of real segment should be placed from the start
|
||||
// vertex. true: place exactly one fake edge to the m_segment indicated with m_forward. false:
|
||||
// place two fake edges to the m_segment with both directions.
|
||||
IndexGraphStarter(FakeEnding const & startEnding, FakeEnding const & finishEnding,
|
||||
uint32_t fakeNumerationStart, bool strictForward, WorldGraph & graph);
|
||||
IndexGraphStarter(FakeEnding const & startEnding, FakeEnding const & finishEnding, uint32_t fakeNumerationStart,
|
||||
bool strictForward, WorldGraph & graph);
|
||||
|
||||
void Append(FakeEdgesContainer const & container);
|
||||
|
||||
@@ -79,17 +81,13 @@ public:
|
||||
// Otherwise returns false and does not modify segment.
|
||||
bool ConvertToReal(Segment & segment) const;
|
||||
LatLonWithAltitude const & GetJunction(Segment const & segment, bool front) const;
|
||||
LatLonWithAltitude const & GetRouteJunction(std::vector<Segment> const & route,
|
||||
size_t pointIndex) const;
|
||||
LatLonWithAltitude const & GetRouteJunction(std::vector<Segment> const & route, size_t pointIndex) const;
|
||||
ms::LatLon const & GetPoint(Segment const & segment, bool front) const;
|
||||
|
||||
bool IsRoutingOptionsGood(Segment const & segment) const;
|
||||
RoutingOptions GetRoutingOptions(Segment const & segment) const;
|
||||
|
||||
uint32_t GetNumFakeSegments() const
|
||||
{
|
||||
return base::checked_cast<uint32_t>(m_fake.GetSize());
|
||||
}
|
||||
uint32_t GetNumFakeSegments() const { return base::checked_cast<uint32_t>(m_fake.GetSize()); }
|
||||
|
||||
std::set<NumMwmId> GetMwms() const;
|
||||
std::set<NumMwmId> const & GetStartMwms() const { return m_start.m_mwmIds; }
|
||||
@@ -99,43 +97,33 @@ public:
|
||||
// start and finish in pass-through/non-pass-through area and number of non-pass-through crosses.
|
||||
bool CheckLength(RouteWeight const & weight);
|
||||
|
||||
void GetEdgeList(astar::VertexData<JointSegment, Weight> const & parentVertexData,
|
||||
Segment const & segment, bool isOutgoing, JointEdgeListT & edges,
|
||||
WeightListT & parentWeights) const
|
||||
void GetEdgeList(astar::VertexData<JointSegment, Weight> const & parentVertexData, Segment const & segment,
|
||||
bool isOutgoing, JointEdgeListT & edges, WeightListT & parentWeights) const
|
||||
{
|
||||
return m_graph.GetEdgeList(parentVertexData, segment, isOutgoing,
|
||||
true /* useAccessConditional */, edges, parentWeights);
|
||||
return m_graph.GetEdgeList(parentVertexData, segment, isOutgoing, true /* useAccessConditional */, edges,
|
||||
parentWeights);
|
||||
}
|
||||
|
||||
// AStarGraph overridings:
|
||||
// @{
|
||||
void GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges) override
|
||||
void GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges) override
|
||||
{
|
||||
GetEdgesList(vertexData, true /* isOutgoing */, true /* useAccessConditional */, edges);
|
||||
}
|
||||
|
||||
void GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges) override
|
||||
void GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges) override
|
||||
{
|
||||
GetEdgesList(vertexData, false /* isOutgoing */, true /* useAccessConditional */, edges);
|
||||
}
|
||||
|
||||
RouteWeight HeuristicCostEstimate(Vertex const & from, Vertex const & to) override
|
||||
{
|
||||
return m_graph.HeuristicCostEstimate(GetPoint(from, true /* front */),
|
||||
GetPoint(to, true /* front */));
|
||||
return m_graph.HeuristicCostEstimate(GetPoint(from, true /* front */), GetPoint(to, true /* front */));
|
||||
}
|
||||
|
||||
void SetAStarParents(bool forward, Parents<Segment> & parents) override
|
||||
{
|
||||
m_graph.SetAStarParents(forward, parents);
|
||||
}
|
||||
void SetAStarParents(bool forward, Parents<Segment> & parents) override { m_graph.SetAStarParents(forward, parents); }
|
||||
|
||||
void DropAStarParents() override
|
||||
{
|
||||
m_graph.DropAStarParents();
|
||||
}
|
||||
void DropAStarParents() override { m_graph.DropAStarParents(); }
|
||||
|
||||
bool AreWavesConnectible(Parents<Segment> & forwardParents, Vertex const & commonVertex,
|
||||
Parents<Segment> & backwardParents) override
|
||||
@@ -157,17 +145,13 @@ public:
|
||||
}
|
||||
|
||||
RouteWeight CalcSegmentWeight(Segment const & segment, EdgeEstimator::Purpose purpose) const;
|
||||
RouteWeight CalcGuidesSegmentWeight(Segment const & segment,
|
||||
EdgeEstimator::Purpose purpose) const;
|
||||
RouteWeight CalcGuidesSegmentWeight(Segment const & segment, EdgeEstimator::Purpose purpose) const;
|
||||
double CalculateETA(Segment const & from, Segment const & to) const;
|
||||
double CalculateETAWithoutPenalty(Segment const & segment) const;
|
||||
|
||||
/// @name For compatibility with IndexGraphStarterJoints.
|
||||
/// @{
|
||||
void SetAStarParents(bool forward, Parents<JointSegment> & parents)
|
||||
{
|
||||
m_graph.SetAStarParents(forward, parents);
|
||||
}
|
||||
void SetAStarParents(bool forward, Parents<JointSegment> & parents) { m_graph.SetAStarParents(forward, parents); }
|
||||
|
||||
bool AreWavesConnectible(Parents<JointSegment> & forwardParents, JointSegment const & commonVertex,
|
||||
Parents<JointSegment> & backwardParents,
|
||||
@@ -209,8 +193,8 @@ public:
|
||||
// Creates fake edges for guides fake ending and adds them to the fake graph.
|
||||
void AddEnding(FakeEnding const & thisEnding);
|
||||
|
||||
void ConnectLoopToGuideSegments(FakeVertex const & loop, Segment const & realSegment,
|
||||
LatLonWithAltitude realFrom, LatLonWithAltitude realTo,
|
||||
void ConnectLoopToGuideSegments(FakeVertex const & loop, Segment const & realSegment, LatLonWithAltitude realFrom,
|
||||
LatLonWithAltitude realTo,
|
||||
std::vector<std::pair<FakeVertex, Segment>> const & partsOfReal);
|
||||
|
||||
HighwayCategory GetHighwayCategory(Segment seg) const;
|
||||
@@ -218,8 +202,7 @@ public:
|
||||
private:
|
||||
// Creates fake edges for fake ending and adds it to fake graph. |otherEnding| is used to
|
||||
// generate proper fake edges in case both endings have projections to the same segment.
|
||||
void AddEnding(FakeEnding const & thisEnding, FakeEnding const & otherEnding, bool isStart,
|
||||
bool strictForward);
|
||||
void AddEnding(FakeEnding const & thisEnding, FakeEnding const & otherEnding, bool isStart, bool strictForward);
|
||||
|
||||
static Segment GetFakeSegment(uint32_t segmentIdx)
|
||||
{
|
||||
@@ -231,11 +214,10 @@ private:
|
||||
|
||||
Segment GetFakeSegmentAndIncr();
|
||||
|
||||
void GetEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, bool isOutgoing,
|
||||
bool useAccessConditional, EdgeListT & edges) const;
|
||||
void GetEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, bool isOutgoing, bool useAccessConditional,
|
||||
EdgeListT & edges) const;
|
||||
|
||||
void AddStart(FakeEnding const & startEnding, FakeEnding const & finishEnding,
|
||||
bool strictForward);
|
||||
void AddStart(FakeEnding const & startEnding, FakeEnding const & finishEnding, bool strictForward);
|
||||
void AddFinish(FakeEnding const & finishEnding, FakeEnding const & startEnding);
|
||||
|
||||
// Adds fake edges of type PartOfReal which correspond real edges from |edges| and are connected
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace routing
|
||||
{
|
||||
enum class WorldGraphMode;
|
||||
@@ -28,12 +27,9 @@ class IndexGraphStarterJoints : public AStarGraph<JointSegment, JointEdge, Route
|
||||
{
|
||||
public:
|
||||
explicit IndexGraphStarterJoints(Graph & graph) : m_graph(graph) {}
|
||||
IndexGraphStarterJoints(Graph & graph,
|
||||
Segment const & startSegment,
|
||||
Segment const & endSegment);
|
||||
IndexGraphStarterJoints(Graph & graph, Segment const & startSegment, Segment const & endSegment);
|
||||
|
||||
IndexGraphStarterJoints(Graph & graph,
|
||||
Segment const & startSegment);
|
||||
IndexGraphStarterJoints(Graph & graph, Segment const & startSegment);
|
||||
|
||||
void Init(Segment const & startSegment, Segment const & endSegment);
|
||||
|
||||
@@ -48,30 +44,21 @@ public:
|
||||
// @{
|
||||
RouteWeight HeuristicCostEstimate(Vertex const & from, Vertex const & to) override;
|
||||
|
||||
void GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges) override
|
||||
void GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges) override
|
||||
{
|
||||
GetEdgeList(vertexData, true /* isOutgoing */, edges);
|
||||
}
|
||||
|
||||
void GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges) override
|
||||
void GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges) override
|
||||
{
|
||||
GetEdgeList(vertexData, false /* isOutgoing */, edges);
|
||||
}
|
||||
|
||||
void SetAStarParents(bool forward, Parents & parents) override
|
||||
{
|
||||
m_graph.SetAStarParents(forward, parents);
|
||||
}
|
||||
void SetAStarParents(bool forward, Parents & parents) override { m_graph.SetAStarParents(forward, parents); }
|
||||
|
||||
void DropAStarParents() override
|
||||
{
|
||||
m_graph.DropAStarParents();
|
||||
}
|
||||
void DropAStarParents() override { m_graph.DropAStarParents(); }
|
||||
|
||||
bool AreWavesConnectible(Parents & forwardParents, Vertex const & commonVertex,
|
||||
Parents & backwardParents) override
|
||||
bool AreWavesConnectible(Parents & forwardParents, Vertex const & commonVertex, Parents & backwardParents) override
|
||||
{
|
||||
auto const converter = [&](JointSegment & vertex)
|
||||
{
|
||||
@@ -99,10 +86,7 @@ public:
|
||||
|
||||
void Reset();
|
||||
|
||||
static bool IsRealSegment(Segment const & segment)
|
||||
{
|
||||
return !segment.IsFakeCreated();
|
||||
}
|
||||
static bool IsRealSegment(Segment const & segment) { return !segment.IsFakeCreated(); }
|
||||
|
||||
Segment const & GetSegmentOfFakeJoint(JointSegment const & joint, bool start) const
|
||||
{
|
||||
@@ -121,13 +105,9 @@ private:
|
||||
struct FakeJointSegment
|
||||
{
|
||||
FakeJointSegment() = default;
|
||||
FakeJointSegment(Segment const & start, Segment const & end)
|
||||
: m_start(start), m_end(end) {}
|
||||
FakeJointSegment(Segment const & start, Segment const & end) : m_start(start), m_end(end) {}
|
||||
|
||||
Segment const & GetSegment(bool start) const
|
||||
{
|
||||
return start ? m_start : m_end;
|
||||
}
|
||||
Segment const & GetSegment(bool start) const { return start ? m_start : m_end; }
|
||||
|
||||
Segment m_start;
|
||||
Segment m_end;
|
||||
@@ -137,30 +117,19 @@ private:
|
||||
|
||||
void AddFakeJoints(Segment const & segment, bool isOutgoing, EdgeListT & edges);
|
||||
|
||||
void GetEdgeList(astar::VertexData<Vertex, Weight> const & vertexData, bool isOutgoing,
|
||||
EdgeListT & edges);
|
||||
void GetEdgeList(astar::VertexData<Vertex, Weight> const & vertexData, bool isOutgoing, EdgeListT & edges);
|
||||
|
||||
JointSegment CreateFakeJoint(Segment const & from, Segment const & to, uint32_t featureId = kInvalidFeatureId);
|
||||
|
||||
bool IsJoint(Segment const & segment, bool fromStart) const
|
||||
{
|
||||
return m_graph.IsJoint(segment, fromStart);
|
||||
}
|
||||
bool IsJoint(Segment const & segment, bool fromStart) const { return m_graph.IsJoint(segment, fromStart); }
|
||||
|
||||
bool IsJointOrEnd(Segment const & segment, bool fromStart) const
|
||||
{
|
||||
return m_graph.IsJointOrEnd(segment, fromStart);
|
||||
}
|
||||
bool IsJointOrEnd(Segment const & segment, bool fromStart) const { return m_graph.IsJointOrEnd(segment, fromStart); }
|
||||
|
||||
using WeightListT = typename Graph::WeightListT;
|
||||
bool FillEdgesAndParentsWeights(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
bool isOutgoing,
|
||||
size_t & firstFakeId,
|
||||
EdgeListT & edges,
|
||||
WeightListT & parentWeights);
|
||||
bool FillEdgesAndParentsWeights(astar::VertexData<Vertex, Weight> const & vertexData, bool isOutgoing,
|
||||
size_t & firstFakeId, EdgeListT & edges, WeightListT & parentWeights);
|
||||
|
||||
std::optional<Segment> GetParentSegment(JointSegment const & vertex, bool isOutgoing,
|
||||
EdgeListT & edges);
|
||||
std::optional<Segment> GetParentSegment(JointSegment const & vertex, bool isOutgoing, EdgeListT & edges);
|
||||
|
||||
/// \brief Makes BFS from |startSegment| in direction |fromStart| and find the closest segments
|
||||
/// which end RoadPoints are joints. Thus we build fake joint segments graph.
|
||||
@@ -175,7 +144,7 @@ private:
|
||||
|
||||
return jointSegment.GetStartSegmentId() == jointSegment.GetEndSegmentId() &&
|
||||
(jointSegment.GetStartSegmentId() == kInvisibleStartId ||
|
||||
jointSegment.GetStartSegmentId() == kInvisibleEndId) &&
|
||||
jointSegment.GetStartSegmentId() == kInvisibleEndId) &&
|
||||
jointSegment.GetStartSegmentId() != kInvalidId;
|
||||
}
|
||||
|
||||
@@ -210,8 +179,7 @@ private:
|
||||
struct ReconstructedPath
|
||||
{
|
||||
ReconstructedPath() = default;
|
||||
ReconstructedPath(std::vector<Segment> && path, bool fromStart)
|
||||
: m_fromStart(fromStart), m_path(std::move(path)) {}
|
||||
ReconstructedPath(std::vector<Segment> && path, bool fromStart) : m_fromStart(fromStart), m_path(std::move(path)) {}
|
||||
|
||||
bool m_fromStart = true;
|
||||
std::vector<Segment> m_path;
|
||||
@@ -229,18 +197,19 @@ private:
|
||||
};
|
||||
|
||||
template <typename Graph>
|
||||
IndexGraphStarterJoints<Graph>::IndexGraphStarterJoints(Graph & graph,
|
||||
Segment const & startSegment,
|
||||
IndexGraphStarterJoints<Graph>::IndexGraphStarterJoints(Graph & graph, Segment const & startSegment,
|
||||
Segment const & endSegment)
|
||||
: m_graph(graph), m_startSegment(startSegment), m_endSegment(endSegment)
|
||||
: m_graph(graph)
|
||||
, m_startSegment(startSegment)
|
||||
, m_endSegment(endSegment)
|
||||
{
|
||||
Init(m_startSegment, m_endSegment);
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
IndexGraphStarterJoints<Graph>::IndexGraphStarterJoints(Graph & graph,
|
||||
Segment const & startSegment)
|
||||
: m_graph(graph), m_startSegment(startSegment)
|
||||
IndexGraphStarterJoints<Graph>::IndexGraphStarterJoints(Graph & graph, Segment const & startSegment)
|
||||
: m_graph(graph)
|
||||
, m_startSegment(startSegment)
|
||||
{
|
||||
InitEnding(startSegment, true /* start */);
|
||||
|
||||
@@ -294,8 +263,7 @@ void IndexGraphStarterJoints<Graph>::InitEnding(Segment const & ending, bool sta
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
RouteWeight IndexGraphStarterJoints<Graph>::HeuristicCostEstimate(JointSegment const & from,
|
||||
JointSegment const & to)
|
||||
RouteWeight IndexGraphStarterJoints<Graph>::HeuristicCostEstimate(JointSegment const & from, JointSegment const & to)
|
||||
{
|
||||
ASSERT(to == m_startJoint || to == m_endJoint, ("Invariant violated."));
|
||||
|
||||
@@ -355,8 +323,7 @@ std::vector<Segment> IndexGraphStarterJoints<Graph>::ReconstructJoint(JointSegme
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void IndexGraphStarterJoints<Graph>::AddFakeJoints(Segment const & segment, bool isOutgoing,
|
||||
EdgeListT & edges)
|
||||
void IndexGraphStarterJoints<Graph>::AddFakeJoints(Segment const & segment, bool isOutgoing, EdgeListT & edges)
|
||||
{
|
||||
// If |isOutgoing| is true, we need real segments, that are real parts
|
||||
// of fake joints, entered to finish and vice versa.
|
||||
@@ -381,8 +348,8 @@ void IndexGraphStarterJoints<Graph>::AddFakeJoints(Segment const & segment, bool
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
std::optional<Segment> IndexGraphStarterJoints<Graph>::GetParentSegment(
|
||||
JointSegment const & vertex, bool isOutgoing, EdgeListT & edges)
|
||||
std::optional<Segment> IndexGraphStarterJoints<Graph>::GetParentSegment(JointSegment const & vertex, bool isOutgoing,
|
||||
EdgeListT & edges)
|
||||
{
|
||||
std::optional<Segment> parentSegment;
|
||||
bool const opposite = !isOutgoing;
|
||||
@@ -430,10 +397,9 @@ std::optional<Segment> IndexGraphStarterJoints<Graph>::GetParentSegment(
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
bool IndexGraphStarterJoints<Graph>::FillEdgesAndParentsWeights(
|
||||
astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
bool isOutgoing, size_t & firstFakeId,
|
||||
EdgeListT & edges, WeightListT & parentWeights)
|
||||
bool IndexGraphStarterJoints<Graph>::FillEdgesAndParentsWeights(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
bool isOutgoing, size_t & firstFakeId,
|
||||
EdgeListT & edges, WeightListT & parentWeights)
|
||||
{
|
||||
auto const & vertex = vertexData.m_vertex;
|
||||
// Case of fake start or finish joints.
|
||||
@@ -480,9 +446,8 @@ bool IndexGraphStarterJoints<Graph>::FillEdgesAndParentsWeights(
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void IndexGraphStarterJoints<Graph>::GetEdgeList(
|
||||
astar::VertexData<Vertex, Weight> const & vertexData, bool isOutgoing,
|
||||
EdgeListT & edges)
|
||||
void IndexGraphStarterJoints<Graph>::GetEdgeList(astar::VertexData<Vertex, Weight> const & vertexData, bool isOutgoing,
|
||||
EdgeListT & edges)
|
||||
{
|
||||
CHECK(m_init, ("IndexGraphStarterJoints was not initialized."));
|
||||
|
||||
@@ -515,7 +480,8 @@ void IndexGraphStarterJoints<Graph>::GetEdgeList(
|
||||
auto & w = edges[i].GetWeight();
|
||||
auto const & t = edges[i].GetTarget();
|
||||
|
||||
// By VNG: Revert to the MM original code, since Cross-MWM borders penalty is assigned in the end of this function.
|
||||
// By VNG: Revert to the MM original code, since Cross-MWM borders penalty is assigned in the end of this
|
||||
// function.
|
||||
/// @todo I still have doubts on how we "fetch" weight for ingoing edges with m_savedWeight.
|
||||
m_savedWeight[t] = w;
|
||||
|
||||
@@ -555,7 +521,7 @@ void IndexGraphStarterJoints<Graph>::GetEdgeList(
|
||||
|
||||
template <typename Graph>
|
||||
JointSegment IndexGraphStarterJoints<Graph>::CreateFakeJoint(Segment const & from, Segment const & to,
|
||||
uint32_t featureId/* = kInvalidFeatureId*/)
|
||||
uint32_t featureId /* = kInvalidFeatureId*/)
|
||||
{
|
||||
JointSegment const result = JointSegment::MakeFake(m_fakeId++, featureId);
|
||||
m_fakeJointSegments.emplace(result, FakeJointSegment(from, to));
|
||||
@@ -563,8 +529,8 @@ JointSegment IndexGraphStarterJoints<Graph>::CreateFakeJoint(Segment const & fro
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
typename IndexGraphStarterJoints<Graph>::EdgeListT
|
||||
IndexGraphStarterJoints<Graph>::FindFirstJoints(Segment const & startSegment, bool fromStart)
|
||||
typename IndexGraphStarterJoints<Graph>::EdgeListT IndexGraphStarterJoints<Graph>::FindFirstJoints(
|
||||
Segment const & startSegment, bool fromStart)
|
||||
{
|
||||
Segment const & endSegment = fromStart ? m_endSegment : m_startSegment;
|
||||
|
||||
@@ -595,22 +561,19 @@ IndexGraphStarterJoints<Graph>::FindFirstJoints(Segment const & startSegment, bo
|
||||
auto const addFake = [&](Segment const & segment, Segment const & beforeConvert)
|
||||
{
|
||||
JointSegment fakeJoint;
|
||||
fakeJoint = fromStart ? CreateFakeJoint(startSegment, segment, firstFeatureId) :
|
||||
CreateFakeJoint(segment, startSegment);
|
||||
fakeJoint =
|
||||
fromStart ? CreateFakeJoint(startSegment, segment, firstFeatureId) : CreateFakeJoint(segment, startSegment);
|
||||
result.emplace_back(fakeJoint, weight[beforeConvert]);
|
||||
|
||||
std::vector<Segment> path = reconstructPath(beforeConvert, fromStart);
|
||||
m_reconstructedFakeJoints.emplace(fakeJoint,
|
||||
ReconstructedPath(std::move(path), fromStart));
|
||||
m_reconstructedFakeJoints.emplace(fakeJoint, ReconstructedPath(std::move(path), fromStart));
|
||||
};
|
||||
|
||||
auto const isEndOfSegment = [&](Segment const & fake, Segment const & segment, bool fromStart)
|
||||
{
|
||||
bool const hasSameFront =
|
||||
m_graph.GetPoint(fake, true /* front */) == m_graph.GetPoint(segment, true);
|
||||
bool const hasSameFront = m_graph.GetPoint(fake, true /* front */) == m_graph.GetPoint(segment, true);
|
||||
|
||||
bool const hasSameBack =
|
||||
m_graph.GetPoint(fake, false /* front */) == m_graph.GetPoint(segment, false);
|
||||
bool const hasSameBack = m_graph.GetPoint(fake, false /* front */) == m_graph.GetPoint(segment, false);
|
||||
|
||||
return (fromStart && hasSameFront) || (!fromStart && hasSameBack);
|
||||
};
|
||||
@@ -621,8 +584,8 @@ IndexGraphStarterJoints<Graph>::FindFirstJoints(Segment const & startSegment, bo
|
||||
queue.pop();
|
||||
Segment beforeConvert = segment;
|
||||
|
||||
bool const isRealPart = !IsRealSegment(segment) && m_graph.ConvertToReal(segment) &&
|
||||
isEndOfSegment(beforeConvert, segment, fromStart);
|
||||
bool const isRealPart =
|
||||
!IsRealSegment(segment) && m_graph.ConvertToReal(segment) && isEndOfSegment(beforeConvert, segment, fromStart);
|
||||
|
||||
// Get first real feature id and assign it below into future fake joint, that will pass over this feature.
|
||||
// Its important for IndexGraph::IsRestricted. See https://github.com/organicmaps/organicmaps/issues/1565.
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
namespace routing
|
||||
{
|
||||
IndexRoadGraph::IndexRoadGraph(IndexGraphStarter & starter, std::vector<Segment> const & segments,
|
||||
std::vector<geometry::PointWithAltitude> const & junctions,
|
||||
MwmDataSource & dataSource)
|
||||
: m_dataSource(dataSource), m_starter(starter), m_segments(segments)
|
||||
std::vector<geometry::PointWithAltitude> const & junctions, MwmDataSource & dataSource)
|
||||
: m_dataSource(dataSource)
|
||||
, m_starter(starter)
|
||||
, m_segments(segments)
|
||||
{
|
||||
// j0 j1 j2 j3
|
||||
// *--s0--*--s1--*--s2--*
|
||||
@@ -31,14 +32,12 @@ IndexRoadGraph::IndexRoadGraph(IndexGraphStarter & starter, std::vector<Segment>
|
||||
}
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetOutgoingEdges(geometry::PointWithAltitude const & junction,
|
||||
EdgeListT & edges) const
|
||||
void IndexRoadGraph::GetOutgoingEdges(geometry::PointWithAltitude const & junction, EdgeListT & edges) const
|
||||
{
|
||||
GetEdges(junction, true, edges);
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetIngoingEdges(geometry::PointWithAltitude const & junction,
|
||||
EdgeListT & edges) const
|
||||
void IndexRoadGraph::GetIngoingEdges(geometry::PointWithAltitude const & junction, EdgeListT & edges) const
|
||||
{
|
||||
GetEdges(junction, false, edges);
|
||||
}
|
||||
@@ -69,8 +68,7 @@ void IndexRoadGraph::GetEdgeTypes(Edge const & edge, feature::TypesHolder & type
|
||||
types = feature::TypesHolder(*ft);
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetJunctionTypes(geometry::PointWithAltitude const & junction,
|
||||
feature::TypesHolder & types) const
|
||||
void IndexRoadGraph::GetJunctionTypes(geometry::PointWithAltitude const & junction, feature::TypesHolder & types) const
|
||||
{
|
||||
types = feature::TypesHolder();
|
||||
}
|
||||
@@ -82,19 +80,16 @@ void IndexRoadGraph::GetRouteEdges(EdgeVector & edges) const
|
||||
|
||||
for (Segment const & segment : m_segments)
|
||||
{
|
||||
auto const & junctionFrom =
|
||||
m_starter.GetJunction(segment, false /* front */).ToPointWithAltitude();
|
||||
auto const & junctionTo =
|
||||
m_starter.GetJunction(segment, true /* front */).ToPointWithAltitude();
|
||||
auto const & junctionFrom = m_starter.GetJunction(segment, false /* front */).ToPointWithAltitude();
|
||||
auto const & junctionTo = m_starter.GetJunction(segment, true /* front */).ToPointWithAltitude();
|
||||
|
||||
if (IndexGraphStarter::IsFakeSegment(segment) || TransitGraph::IsTransitSegment(segment))
|
||||
{
|
||||
Segment real = segment;
|
||||
if (m_starter.ConvertToReal(real))
|
||||
{
|
||||
edges.push_back(Edge::MakeFakeWithRealPart({ m_dataSource.GetMwmId(real.GetMwmId()), real.GetFeatureId() },
|
||||
segment.GetSegmentIdx(),
|
||||
real.IsForward(), real.GetSegmentIdx(),
|
||||
edges.push_back(Edge::MakeFakeWithRealPart({m_dataSource.GetMwmId(real.GetMwmId()), real.GetFeatureId()},
|
||||
segment.GetSegmentIdx(), real.IsForward(), real.GetSegmentIdx(),
|
||||
junctionFrom, junctionTo));
|
||||
}
|
||||
else
|
||||
@@ -104,14 +99,13 @@ void IndexRoadGraph::GetRouteEdges(EdgeVector & edges) const
|
||||
}
|
||||
else
|
||||
{
|
||||
edges.push_back(Edge::MakeReal({ m_dataSource.GetMwmId(segment.GetMwmId()), segment.GetFeatureId() },
|
||||
edges.push_back(Edge::MakeReal({m_dataSource.GetMwmId(segment.GetMwmId()), segment.GetFeatureId()},
|
||||
segment.IsForward(), segment.GetSegmentIdx(), junctionFrom, junctionTo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IndexRoadGraph::GetEdges(geometry::PointWithAltitude const & junction, bool isOutgoing,
|
||||
EdgeListT & edges) const
|
||||
void IndexRoadGraph::GetEdges(geometry::PointWithAltitude const & junction, bool isOutgoing, EdgeListT & edges) const
|
||||
{
|
||||
edges.clear();
|
||||
|
||||
@@ -126,22 +120,21 @@ void IndexRoadGraph::GetEdges(geometry::PointWithAltitude const & junction, bool
|
||||
if (IndexGraphStarter::IsFakeSegment(segment))
|
||||
continue;
|
||||
|
||||
edges.push_back(Edge::MakeReal({ m_dataSource.GetMwmId(segment.GetMwmId()), segment.GetFeatureId() },
|
||||
segment.IsForward(), segment.GetSegmentIdx(),
|
||||
m_starter.GetJunction(segment, false /* front */).ToPointWithAltitude(),
|
||||
m_starter.GetJunction(segment, true /* front */).ToPointWithAltitude()));
|
||||
edges.push_back(Edge::MakeReal({m_dataSource.GetMwmId(segment.GetMwmId()), segment.GetFeatureId()},
|
||||
segment.IsForward(), segment.GetSegmentIdx(),
|
||||
m_starter.GetJunction(segment, false /* front */).ToPointWithAltitude(),
|
||||
m_starter.GetJunction(segment, true /* front */).ToPointWithAltitude()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IndexRoadGraph::SegmentListT const & IndexRoadGraph::GetSegments(
|
||||
geometry::PointWithAltitude const & junction, bool isOutgoing) const
|
||||
IndexRoadGraph::SegmentListT const & IndexRoadGraph::GetSegments(geometry::PointWithAltitude const & junction,
|
||||
bool isOutgoing) const
|
||||
{
|
||||
auto const & junctionToSegment = isOutgoing ? m_endToSegment : m_beginToSegment;
|
||||
|
||||
auto const it = junctionToSegment.find(junction);
|
||||
CHECK(it != junctionToSegment.cend(),
|
||||
("junctionToSegment doesn't contain", junction, ", isOutgoing =", isOutgoing));
|
||||
CHECK(it != junctionToSegment.cend(), ("junctionToSegment doesn't contain", junction, ", isOutgoing =", isOutgoing));
|
||||
return it->second;
|
||||
}
|
||||
} // namespace routing
|
||||
|
||||
@@ -20,14 +20,11 @@ class IndexRoadGraph : public RoadGraphBase
|
||||
{
|
||||
public:
|
||||
IndexRoadGraph(IndexGraphStarter & starter, std::vector<Segment> const & segments,
|
||||
std::vector<geometry::PointWithAltitude> const & junctions,
|
||||
MwmDataSource & dataSource);
|
||||
std::vector<geometry::PointWithAltitude> const & junctions, MwmDataSource & dataSource);
|
||||
|
||||
// IRoadGraphBase overrides:
|
||||
virtual void GetOutgoingEdges(geometry::PointWithAltitude const & junction,
|
||||
EdgeListT & edges) const override;
|
||||
virtual void GetIngoingEdges(geometry::PointWithAltitude const & junction,
|
||||
EdgeListT & edges) const override;
|
||||
virtual void GetOutgoingEdges(geometry::PointWithAltitude const & junction, EdgeListT & edges) const override;
|
||||
virtual void GetIngoingEdges(geometry::PointWithAltitude const & junction, EdgeListT & edges) const override;
|
||||
virtual void GetEdgeTypes(Edge const & edge, feature::TypesHolder & types) const override;
|
||||
virtual void GetJunctionTypes(geometry::PointWithAltitude const & junction,
|
||||
feature::TypesHolder & types) const override;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,10 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace traffic { class TrafficCache; }
|
||||
namespace traffic
|
||||
{
|
||||
class TrafficCache;
|
||||
}
|
||||
|
||||
namespace routing
|
||||
{
|
||||
@@ -65,8 +68,7 @@ public:
|
||||
m2::PointD const m_direction;
|
||||
};
|
||||
|
||||
IndexRouter(VehicleType vehicleType, bool loadAltitudes,
|
||||
CountryParentNameGetterFn const & countryParentNameGetterFn,
|
||||
IndexRouter(VehicleType vehicleType, bool loadAltitudes, CountryParentNameGetterFn const & countryParentNameGetterFn,
|
||||
TCountryFileFn const & countryFileFn, CountryRectFn const & countryRectFn,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds, std::unique_ptr<m4::Tree<NumMwmId>> numMwmTree,
|
||||
traffic::TrafficCache const & trafficCache, DataSource & dataSource);
|
||||
@@ -78,43 +80,36 @@ public:
|
||||
void ClearState() override;
|
||||
|
||||
void SetGuides(GuidesTracks && guides) override;
|
||||
RouterResultCode CalculateRoute(Checkpoints const & checkpoints,
|
||||
m2::PointD const & startDirection, bool adjustToPrevRoute,
|
||||
RouterDelegate const & delegate, Route & route) override;
|
||||
RouterResultCode CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & startDirection,
|
||||
bool adjustToPrevRoute, RouterDelegate const & delegate, Route & route) override;
|
||||
|
||||
bool FindClosestProjectionToRoad(m2::PointD const & point, m2::PointD const & direction,
|
||||
double radius, EdgeProj & proj) override;
|
||||
bool FindClosestProjectionToRoad(m2::PointD const & point, m2::PointD const & direction, double radius,
|
||||
EdgeProj & proj) override;
|
||||
|
||||
bool GetBestOutgoingEdges(m2::PointD const & checkpoint, WorldGraph & graph, std::vector<Edge> & edges);
|
||||
|
||||
VehicleType GetVehicleType() const { return m_vehicleType; }
|
||||
|
||||
private:
|
||||
RouterResultCode CalculateSubrouteJointsMode(IndexGraphStarter & starter,
|
||||
RouterDelegate const & delegate,
|
||||
RouterResultCode CalculateSubrouteJointsMode(IndexGraphStarter & starter, RouterDelegate const & delegate,
|
||||
std::shared_ptr<AStarProgress> const & progress,
|
||||
std::vector<Segment> & subroute);
|
||||
RouterResultCode CalculateSubrouteNoLeapsMode(IndexGraphStarter & starter,
|
||||
RouterDelegate const & delegate,
|
||||
RouterResultCode CalculateSubrouteNoLeapsMode(IndexGraphStarter & starter, RouterDelegate const & delegate,
|
||||
std::shared_ptr<AStarProgress> const & progress,
|
||||
std::vector<Segment> & subroute);
|
||||
RouterResultCode CalculateSubrouteLeapsOnlyMode(Checkpoints const & checkpoints,
|
||||
size_t subrouteIdx, IndexGraphStarter & starter,
|
||||
RouterDelegate const & delegate,
|
||||
RouterResultCode CalculateSubrouteLeapsOnlyMode(Checkpoints const & checkpoints, size_t subrouteIdx,
|
||||
IndexGraphStarter & starter, RouterDelegate const & delegate,
|
||||
std::shared_ptr<AStarProgress> const & progress,
|
||||
std::vector<Segment> & subroute);
|
||||
|
||||
RouterResultCode DoCalculateRoute(Checkpoints const & checkpoints,
|
||||
m2::PointD const & startDirection,
|
||||
RouterResultCode DoCalculateRoute(Checkpoints const & checkpoints, m2::PointD const & startDirection,
|
||||
RouterDelegate const & delegate, Route & route);
|
||||
RouterResultCode CalculateSubroute(Checkpoints const & checkpoints, size_t subrouteIdx,
|
||||
RouterDelegate const & delegate,
|
||||
std::shared_ptr<AStarProgress> const & progress,
|
||||
RouterDelegate const & delegate, std::shared_ptr<AStarProgress> const & progress,
|
||||
IndexGraphStarter & graph, std::vector<Segment> & subroute,
|
||||
bool guidesActive = false);
|
||||
|
||||
RouterResultCode AdjustRoute(Checkpoints const & checkpoints,
|
||||
m2::PointD const & startDirection,
|
||||
RouterResultCode AdjustRoute(Checkpoints const & checkpoints, m2::PointD const & startDirection,
|
||||
RouterDelegate const & delegate, Route & route);
|
||||
|
||||
std::unique_ptr<WorldGraph> MakeWorldGraph();
|
||||
@@ -186,8 +181,8 @@ private:
|
||||
std::vector<Segment> & bestSegments, bool & bestSegmentIsAlmostCodirectional);
|
||||
|
||||
bool FindBestEdges(m2::PointD const & checkpoint, m2::PointD const & direction, bool isOutgoing,
|
||||
double closestEdgesRadiusM,
|
||||
std::vector<Edge> & bestEdges, bool & bestSegmentIsAlmostCodirectional);
|
||||
double closestEdgesRadiusM, std::vector<Edge> & bestEdges,
|
||||
bool & bestSegmentIsAlmostCodirectional);
|
||||
};
|
||||
|
||||
using RoutingResultT = RoutingResult<Segment, RouteWeight>;
|
||||
@@ -199,34 +194,32 @@ private:
|
||||
|
||||
public:
|
||||
RoutesCalculator(IndexGraphStarter & starter, RouterDelegate const & delegate)
|
||||
: m_starter(starter), m_delegate(delegate) {}
|
||||
: m_starter(starter)
|
||||
, m_delegate(delegate)
|
||||
{}
|
||||
|
||||
using ProgressPtrT = std::shared_ptr<AStarProgress>;
|
||||
RoutingResultT const * Calc(Segment const & beg, Segment const & end,
|
||||
ProgressPtrT const & progress, double progressCoef);
|
||||
RoutingResultT const * Calc(Segment const & beg, Segment const & end, ProgressPtrT const & progress,
|
||||
double progressCoef);
|
||||
// Makes JointSingleMwm first and Joints then, if first attempt was failed.
|
||||
RoutingResultT const * Calc2Times(Segment const & beg, Segment const & end,
|
||||
ProgressPtrT const & progress, double progressCoef);
|
||||
RoutingResultT const * Calc2Times(Segment const & beg, Segment const & end, ProgressPtrT const & progress,
|
||||
double progressCoef);
|
||||
};
|
||||
|
||||
// Input route may contains 'leaps': shortcut edges from mwm border enter to exit.
|
||||
// ProcessLeaps replaces each leap with calculated route through mwm.
|
||||
RouterResultCode ProcessLeapsJoints(std::vector<Segment> const & input,
|
||||
IndexGraphStarter & starter,
|
||||
std::shared_ptr<AStarProgress> const & progress,
|
||||
RoutesCalculator & calculator,
|
||||
RouterResultCode ProcessLeapsJoints(std::vector<Segment> const & input, IndexGraphStarter & starter,
|
||||
std::shared_ptr<AStarProgress> const & progress, RoutesCalculator & calculator,
|
||||
RoutingResultT & result);
|
||||
|
||||
RouterResultCode RedressRoute(std::vector<Segment> const & segments,
|
||||
base::Cancellable const & cancellable, IndexGraphStarter & starter,
|
||||
Route & route);
|
||||
RouterResultCode RedressRoute(std::vector<Segment> const & segments, base::Cancellable const & cancellable,
|
||||
IndexGraphStarter & starter, Route & route);
|
||||
|
||||
bool AreSpeedCamerasProhibited(NumMwmId mwmID) const;
|
||||
bool AreMwmsNear(IndexGraphStarter const & starter) const;
|
||||
bool DoesTransitSectionExist(NumMwmId numMwmId);
|
||||
|
||||
RouterResultCode ConvertTransitResult(std::set<NumMwmId> const & mwmIds,
|
||||
RouterResultCode resultCode);
|
||||
RouterResultCode ConvertTransitResult(std::set<NumMwmId> const & mwmIds, RouterResultCode resultCode);
|
||||
|
||||
/// \brief Fills |speedcamProhibitedMwms| with mwms which are crossed by |segments|
|
||||
/// where speed cameras are prohibited.
|
||||
@@ -255,17 +248,15 @@ private:
|
||||
}
|
||||
|
||||
void SetupAlgorithmMode(IndexGraphStarter & starter, bool guidesActive = false) const;
|
||||
uint32_t ConnectTracksOnGuidesToOsm(std::vector<m2::PointD> const & checkpoints,
|
||||
WorldGraph & graph);
|
||||
uint32_t ConnectTracksOnGuidesToOsm(std::vector<m2::PointD> const & checkpoints, WorldGraph & graph);
|
||||
|
||||
void ConnectCheckpointsOnGuidesToOsm(std::vector<m2::PointD> const & checkpoints,
|
||||
WorldGraph & graph);
|
||||
void ConnectCheckpointsOnGuidesToOsm(std::vector<m2::PointD> const & checkpoints, WorldGraph & graph);
|
||||
|
||||
void AddGuidesOsmConnectionsToGraphStarter(size_t checkpointIdxFrom, size_t checkpointIdxTo,
|
||||
IndexGraphStarter & starter);
|
||||
|
||||
void AppendPartsOfReal(LatLonWithAltitude const & point1, LatLonWithAltitude const & point2,
|
||||
uint32_t & startIdx, ConnectionToOsm & link);
|
||||
void AppendPartsOfReal(LatLonWithAltitude const & point1, LatLonWithAltitude const & point2, uint32_t & startIdx,
|
||||
ConnectionToOsm & link);
|
||||
|
||||
std::vector<Segment> GetBestOutgoingSegments(m2::PointD const & checkpoint, WorldGraph & graph);
|
||||
|
||||
|
||||
@@ -15,8 +15,10 @@ void JointIndex::Build(RoadIndex const & roadIndex, uint32_t numJoints)
|
||||
// Calculate sizes.
|
||||
// Example for numJoints = 6:
|
||||
// 2, 5, 3, 4, 2, 3, 0
|
||||
roadIndex.ForEachRoad([this, numJoints](uint32_t /* featureId */, RoadJointIds const & road) {
|
||||
road.ForEachJoint([this, numJoints](uint32_t /* pointId */, Joint::Id jointId) {
|
||||
roadIndex.ForEachRoad([this, numJoints](uint32_t /* featureId */, RoadJointIds const & road)
|
||||
{
|
||||
road.ForEachJoint([this, numJoints](uint32_t /* pointId */, Joint::Id jointId)
|
||||
{
|
||||
UNUSED_VALUE(numJoints);
|
||||
ASSERT_LESS(jointId, numJoints, ());
|
||||
++m_offsets[jointId];
|
||||
@@ -33,8 +35,10 @@ void JointIndex::Build(RoadIndex const & roadIndex, uint32_t numJoints)
|
||||
// Now fill points.
|
||||
// Offsets after this operation are begin bounds:
|
||||
// 0, 2, 7, 10, 14, 16, 19
|
||||
roadIndex.ForEachRoad([this](uint32_t featureId, RoadJointIds const & road) {
|
||||
road.ForEachJoint([this, featureId](uint32_t pointId, Joint::Id jointId) {
|
||||
roadIndex.ForEachRoad([this](uint32_t featureId, RoadJointIds const & road)
|
||||
{
|
||||
road.ForEachJoint([this, featureId](uint32_t pointId, Joint::Id jointId)
|
||||
{
|
||||
uint32_t & offset = m_offsets[jointId];
|
||||
--offset;
|
||||
m_points[offset] = {featureId, pointId};
|
||||
|
||||
@@ -40,7 +40,7 @@ void JointSegment::AssignID(JointSegment const & seg)
|
||||
m_featureId = seg.m_featureId;
|
||||
}
|
||||
|
||||
JointSegment JointSegment::MakeFake(uint32_t fakeId, uint32_t featureId/* = kInvalidFeatureId*/)
|
||||
JointSegment JointSegment::MakeFake(uint32_t fakeId, uint32_t featureId /* = kInvalidFeatureId*/)
|
||||
{
|
||||
JointSegment res;
|
||||
res.m_featureId = featureId;
|
||||
@@ -58,7 +58,7 @@ bool JointSegment::IsFake() const
|
||||
if (result)
|
||||
{
|
||||
// Try if m_featureId can be real in a fake JointSegment.
|
||||
//ASSERT_EQUAL(m_featureId, kInvalidFeatureId, ());
|
||||
// ASSERT_EQUAL(m_featureId, kInvalidFeatureId, ());
|
||||
|
||||
ASSERT_EQUAL(m_startSegmentId, m_endSegmentId, ());
|
||||
ASSERT_EQUAL(m_forward, false, ());
|
||||
@@ -91,9 +91,8 @@ bool JointSegment::operator<(JointSegment const & rhs) const
|
||||
|
||||
bool JointSegment::operator==(JointSegment const & rhs) const
|
||||
{
|
||||
return m_featureId == rhs.m_featureId && m_forward == rhs.m_forward &&
|
||||
m_startSegmentId == rhs.m_startSegmentId && m_endSegmentId == rhs.m_endSegmentId &&
|
||||
m_numMwmId == rhs.m_numMwmId;
|
||||
return m_featureId == rhs.m_featureId && m_forward == rhs.m_forward && m_startSegmentId == rhs.m_startSegmentId &&
|
||||
m_endSegmentId == rhs.m_endSegmentId && m_numMwmId == rhs.m_numMwmId;
|
||||
}
|
||||
|
||||
std::string DebugPrint(JointSegment const & jointSegment)
|
||||
@@ -102,8 +101,7 @@ std::string DebugPrint(JointSegment const & jointSegment)
|
||||
if (jointSegment.IsFake())
|
||||
out << "[FAKE]";
|
||||
|
||||
out << std::boolalpha
|
||||
<< "JointSegment(" << jointSegment.GetMwmId() << ", " << jointSegment.GetFeatureId() << ", "
|
||||
out << std::boolalpha << "JointSegment(" << jointSegment.GetMwmId() << ", " << jointSegment.GetFeatureId() << ", "
|
||||
<< "[" << jointSegment.GetStartSegmentId() << " => " << jointSegment.GetEndSegmentId() << "], "
|
||||
<< jointSegment.IsForward() << ")";
|
||||
return out.str();
|
||||
@@ -112,8 +110,7 @@ std::string DebugPrint(JointSegment const & jointSegment)
|
||||
|
||||
namespace std
|
||||
{
|
||||
size_t
|
||||
std::hash<routing::JointSegment>::operator()(routing::JointSegment const & jointSegment) const
|
||||
size_t std::hash<routing::JointSegment>::operator()(routing::JointSegment const & jointSegment) const
|
||||
{
|
||||
size_t seed = 0;
|
||||
boost::hash_combine(seed, jointSegment.GetMwmId());
|
||||
|
||||
@@ -35,10 +35,7 @@ public:
|
||||
|
||||
bool operator<(JointSegment const & rhs) const;
|
||||
bool operator==(JointSegment const & rhs) const;
|
||||
bool operator!=(JointSegment const & rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
bool operator!=(JointSegment const & rhs) const { return !(*this == rhs); }
|
||||
|
||||
private:
|
||||
uint32_t m_featureId = kInvalidFeatureId;
|
||||
@@ -53,9 +50,8 @@ private:
|
||||
class JointEdge
|
||||
{
|
||||
public:
|
||||
JointEdge() = default; // needed for buffer_vector only
|
||||
JointEdge(JointSegment const & target, RouteWeight const & weight)
|
||||
: m_target(target), m_weight(weight) {}
|
||||
JointEdge() = default; // needed for buffer_vector only
|
||||
JointEdge(JointSegment const & target, RouteWeight const & weight) : m_target(target), m_weight(weight) {}
|
||||
|
||||
JointSegment const & GetTarget() const { return m_target; }
|
||||
JointSegment & GetTarget() { return m_target; }
|
||||
|
||||
@@ -10,17 +10,17 @@ namespace routing
|
||||
|
||||
#ifdef DEBUG
|
||||
// Leaps algorithm.
|
||||
void DebugRoutingState(Segment const & vertex, std::optional<Segment> const & parent,
|
||||
RouteWeight const & heuristic, RouteWeight const & distance)
|
||||
void DebugRoutingState(Segment const & vertex, std::optional<Segment> const & parent, RouteWeight const & heuristic,
|
||||
RouteWeight const & distance)
|
||||
{
|
||||
// 1. Dump current processing vertex.
|
||||
// std::cout << DebugPrint(vertex);
|
||||
// std::cout << std::setprecision(8) << "; H = " << heuristic << "; D = " << distance;
|
||||
// std::cout << DebugPrint(vertex);
|
||||
// std::cout << std::setprecision(8) << "; H = " << heuristic << "; D = " << distance;
|
||||
|
||||
// 2. Dump parent vertex.
|
||||
// std::cout << "; P = " << (parent ? DebugPrint(*parent) : std::string("NO"));
|
||||
// std::cout << "; P = " << (parent ? DebugPrint(*parent) : std::string("NO"));
|
||||
|
||||
// std::cout << std::endl;
|
||||
// std::cout << std::endl;
|
||||
}
|
||||
|
||||
// Joints algorithm.
|
||||
@@ -28,29 +28,29 @@ void DebugRoutingState(JointSegment const & vertex, std::optional<JointSegment>
|
||||
RouteWeight const & heuristic, RouteWeight const & distance)
|
||||
{
|
||||
// 1. Dump current processing vertex.
|
||||
// std::cout << DebugPrint(vertex);
|
||||
// std::cout << std::setprecision(8) << "; H = " << heuristic << "; D = " << distance;
|
||||
// std::cout << DebugPrint(vertex);
|
||||
// std::cout << std::setprecision(8) << "; H = " << heuristic << "; D = " << distance;
|
||||
|
||||
// 2. Dump parent vertex.
|
||||
// std::cout << "; P = " << (parent ? DebugPrint(*parent) : std::string("NO"));
|
||||
// std::cout << "; P = " << (parent ? DebugPrint(*parent) : std::string("NO"));
|
||||
|
||||
// std::cout << std::endl;
|
||||
// std::cout << std::endl;
|
||||
|
||||
// 3. Set breakpoint on a specific vertex.
|
||||
// if (vertex.GetMwmId() == 400 && vertex.GetFeatureId() == 2412 &&
|
||||
// vertex.GetEndSegmentId() == 0)
|
||||
// {
|
||||
// int noop = 0;
|
||||
// }
|
||||
// if (vertex.GetMwmId() == 400 && vertex.GetFeatureId() == 2412 &&
|
||||
// vertex.GetEndSegmentId() == 0)
|
||||
// {
|
||||
// int noop = 0;
|
||||
// }
|
||||
|
||||
// 4. Set breakpoint when MWM was changed.
|
||||
// if (parent)
|
||||
// {
|
||||
// auto const & p = *parent;
|
||||
// if (!p.IsFake() && !vertex.IsFake() && p.GetMwmId() != vertex.GetMwmId())
|
||||
// int noop = 0;
|
||||
// }
|
||||
// if (parent)
|
||||
// {
|
||||
// auto const & p = *parent;
|
||||
// if (!p.IsFake() && !vertex.IsFake() && p.GetMwmId() != vertex.GetMwmId())
|
||||
// int noop = 0;
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace routing
|
||||
} // namespace routing
|
||||
|
||||
@@ -19,8 +19,8 @@ inline void DebugRoutingState(...) {}
|
||||
class JointSegment;
|
||||
class RouteWeight;
|
||||
class Segment;
|
||||
void DebugRoutingState(Segment const & vertex, std::optional<Segment> const & parent,
|
||||
RouteWeight const & heuristic, RouteWeight const & distance);
|
||||
void DebugRoutingState(Segment const & vertex, std::optional<Segment> const & parent, RouteWeight const & heuristic,
|
||||
RouteWeight const & distance);
|
||||
void DebugRoutingState(JointSegment const & vertex, std::optional<JointSegment> const & parent,
|
||||
RouteWeight const & heuristic, RouteWeight const & distance);
|
||||
#endif
|
||||
@@ -33,7 +33,10 @@ public:
|
||||
|
||||
JunctionVisitor(Graph & graph, RouterDelegate const & delegate, uint32_t visitPeriod,
|
||||
std::shared_ptr<AStarProgress> const & progress = nullptr)
|
||||
: m_graph(graph), m_delegate(delegate), m_visitPeriod(visitPeriod), m_progress(progress)
|
||||
: m_graph(graph)
|
||||
, m_delegate(delegate)
|
||||
, m_visitPeriod(visitPeriod)
|
||||
, m_progress(progress)
|
||||
{
|
||||
if (progress)
|
||||
m_lastProgressPercent = progress->GetLastPercent();
|
||||
@@ -41,7 +44,8 @@ public:
|
||||
|
||||
/// @param[in] p { Current state, Step context } pair.
|
||||
/// @param[in] to End vertex (final for forward and start for backward waves).
|
||||
template <class StateContextPair> void operator()(StateContextPair const & p, Vertex const & to)
|
||||
template <class StateContextPair>
|
||||
void operator()(StateContextPair const & p, Vertex const & to)
|
||||
{
|
||||
auto const & state = p.first;
|
||||
#ifdef DEBUG
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace routing
|
||||
std::string DebugPrint(LatLonWithAltitude const & latLonWithAltitude)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "LatLonWithAltitude(" << DebugPrint(latLonWithAltitude.GetLatLon()) << ", "
|
||||
<< latLonWithAltitude.GetAltitude() << ")";
|
||||
ss << "LatLonWithAltitude(" << DebugPrint(latLonWithAltitude.GetLatLon()) << ", " << latLonWithAltitude.GetAltitude()
|
||||
<< ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,7 @@ class LatLonWithAltitude
|
||||
{
|
||||
public:
|
||||
LatLonWithAltitude() = default;
|
||||
LatLonWithAltitude(ms::LatLon const & latlon, geometry::Altitude altitude)
|
||||
: m_latlon(latlon), m_altitude(altitude)
|
||||
{
|
||||
}
|
||||
LatLonWithAltitude(ms::LatLon const & latlon, geometry::Altitude altitude) : m_latlon(latlon), m_altitude(altitude) {}
|
||||
|
||||
bool operator==(LatLonWithAltitude const & rhs) const;
|
||||
bool operator<(LatLonWithAltitude const & rhs) const;
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
namespace routing
|
||||
{
|
||||
LeapsGraph::LeapsGraph(IndexGraphStarter & starter, MwmHierarchyHandler && hierarchyHandler)
|
||||
: m_starter(starter), m_hierarchyHandler(std::move(hierarchyHandler))
|
||||
: m_starter(starter)
|
||||
, m_hierarchyHandler(std::move(hierarchyHandler))
|
||||
{
|
||||
m_startPoint = m_starter.GetPoint(m_starter.GetStartSegment(), true /* front */);
|
||||
m_finishPoint = m_starter.GetPoint(m_starter.GetFinishSegment(), true /* front */);
|
||||
@@ -19,14 +20,12 @@ LeapsGraph::LeapsGraph(IndexGraphStarter & starter, MwmHierarchyHandler && hiera
|
||||
m_finishSegment = m_starter.GetFinishSegment();
|
||||
}
|
||||
|
||||
void LeapsGraph::GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges)
|
||||
void LeapsGraph::GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges)
|
||||
{
|
||||
GetEdgesList(vertexData.m_vertex, true /* isOutgoing */, edges);
|
||||
}
|
||||
|
||||
void LeapsGraph::GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges)
|
||||
void LeapsGraph::GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges)
|
||||
{
|
||||
GetEdgesList(vertexData.m_vertex, false /* isOutgoing */, edges);
|
||||
}
|
||||
|
||||
@@ -21,10 +21,8 @@ public:
|
||||
|
||||
// AStarGraph overrides:
|
||||
// @{
|
||||
void GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges) override;
|
||||
void GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData,
|
||||
EdgeListT & edges) override;
|
||||
void GetOutgoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges) override;
|
||||
void GetIngoingEdgesList(astar::VertexData<Vertex, Weight> const & vertexData, EdgeListT & edges) override;
|
||||
RouteWeight HeuristicCostEstimate(Segment const & from, Segment const & to) override;
|
||||
RouteWeight GetAStarWeightEpsilon() override;
|
||||
// @}
|
||||
|
||||
@@ -25,10 +25,7 @@ public:
|
||||
m_intervals.emplace_back(pathInterval);
|
||||
}
|
||||
|
||||
std::vector<LeapsPostProcessor::PathInterval> && StealIntervals()
|
||||
{
|
||||
return std::move(m_intervals);
|
||||
}
|
||||
std::vector<LeapsPostProcessor::PathInterval> && StealIntervals() { return std::move(m_intervals); }
|
||||
|
||||
private:
|
||||
base::NonIntersectingIntervals<size_t> m_nonIntersectingIntervals;
|
||||
@@ -52,10 +49,9 @@ size_t const LeapsPostProcessor::kMaxStep = 5;
|
||||
/// Thus if we look at the first s1, we will find out that a jump to second s1 exists
|
||||
/// and we will skip all segments between first and second s1 and the result path will be:
|
||||
/// s1, s11, s12, ... , s100
|
||||
LeapsPostProcessor::LeapsPostProcessor(std::vector<Segment> const & path,
|
||||
IndexGraphStarter & starter)
|
||||
: m_starter(starter),
|
||||
m_bfs(starter)
|
||||
LeapsPostProcessor::LeapsPostProcessor(std::vector<Segment> const & path, IndexGraphStarter & starter)
|
||||
: m_starter(starter)
|
||||
, m_bfs(starter)
|
||||
{
|
||||
std::map<size_t, size_t> jumps;
|
||||
std::map<Segment, size_t> segmentToIndex;
|
||||
@@ -173,36 +169,36 @@ auto LeapsPostProcessor::CalculateIntervalsToRelax() -> std::set<PathInterval, P
|
||||
return result;
|
||||
}
|
||||
|
||||
void LeapsPostProcessor::FillIngoingPaths(
|
||||
Segment const & start, std::map<Segment, LeapsPostProcessor::SegmentData> & segmentsData)
|
||||
void LeapsPostProcessor::FillIngoingPaths(Segment const & start,
|
||||
std::map<Segment, LeapsPostProcessor::SegmentData> & segmentsData)
|
||||
{
|
||||
m_bfs.Run(start, false /* isOutgoing */,
|
||||
[&segmentsData, this](BFS<IndexGraphStarter>::State const & state)
|
||||
{
|
||||
if (segmentsData.count(state.m_vertex) != 0)
|
||||
return false;
|
||||
m_bfs.Run(start, false /* isOutgoing */, [&segmentsData, this](BFS<IndexGraphStarter>::State const & state)
|
||||
{
|
||||
if (segmentsData.count(state.m_vertex) != 0)
|
||||
return false;
|
||||
|
||||
auto const & parent = segmentsData[state.m_parent];
|
||||
ASSERT_LESS_OR_EQUAL(parent.m_steps, kMaxStep, ());
|
||||
if (parent.m_steps == kMaxStep)
|
||||
return false;
|
||||
auto const & parent = segmentsData[state.m_parent];
|
||||
ASSERT_LESS_OR_EQUAL(parent.m_steps, kMaxStep, ());
|
||||
if (parent.m_steps == kMaxStep)
|
||||
return false;
|
||||
|
||||
auto & current = segmentsData[state.m_vertex];
|
||||
current.m_summaryETA =
|
||||
parent.m_summaryETA + m_starter.CalculateETAWithoutPenalty(state.m_vertex);
|
||||
auto & current = segmentsData[state.m_vertex];
|
||||
current.m_summaryETA = parent.m_summaryETA + m_starter.CalculateETAWithoutPenalty(state.m_vertex);
|
||||
|
||||
current.m_steps = parent.m_steps + 1;
|
||||
current.m_steps = parent.m_steps + 1;
|
||||
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
LeapsPostProcessor::SegmentData::SegmentData(size_t steps, double eta)
|
||||
: m_steps(steps), m_summaryETA(eta) {}
|
||||
LeapsPostProcessor::SegmentData::SegmentData(size_t steps, double eta) : m_steps(steps), m_summaryETA(eta) {}
|
||||
|
||||
LeapsPostProcessor::PathInterval::PathInterval(double weight, size_t left, size_t right,
|
||||
std::vector<Segment> && path)
|
||||
: m_winWeight(weight), m_left(left), m_right(right), m_path(std::move(path)) {}
|
||||
LeapsPostProcessor::PathInterval::PathInterval(double weight, size_t left, size_t right, std::vector<Segment> && path)
|
||||
: m_winWeight(weight)
|
||||
, m_left(left)
|
||||
, m_right(right)
|
||||
, m_path(std::move(path))
|
||||
{}
|
||||
|
||||
bool LeapsPostProcessor::PathInterval::GreaterByWeight::operator()(PathInterval const & lhs,
|
||||
PathInterval const & rhs) const
|
||||
@@ -212,8 +208,7 @@ bool LeapsPostProcessor::PathInterval::GreaterByWeight::operator()(PathInterval
|
||||
|
||||
bool LeapsPostProcessor::PathInterval::operator<(PathInterval const & rhs) const
|
||||
{
|
||||
CHECK(m_left > rhs.m_right || m_right < rhs.m_left ||
|
||||
(m_left == rhs.m_left && m_right == rhs.m_right),
|
||||
CHECK(m_left > rhs.m_right || m_right < rhs.m_left || (m_left == rhs.m_left && m_right == rhs.m_right),
|
||||
("Intervals shouldn't intersect.", *this, rhs));
|
||||
|
||||
return m_right < rhs.m_left;
|
||||
@@ -222,8 +217,7 @@ bool LeapsPostProcessor::PathInterval::operator<(PathInterval const & rhs) const
|
||||
std::string DebugPrint(LeapsPostProcessor::PathInterval const & interval)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "[" << interval.m_left << ", " << interval.m_right << "], weight = "
|
||||
<< interval.m_winWeight;
|
||||
ss << "[" << interval.m_left << ", " << interval.m_right << "], weight = " << interval.m_winWeight;
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "routing/road_point.hpp"
|
||||
#include "routing/turns.hpp"
|
||||
#include "routing/segment.hpp"
|
||||
#include "routing/route.hpp"
|
||||
#include "routing/maxspeeds.hpp"
|
||||
#include "routing/road_point.hpp"
|
||||
#include "routing/route.hpp"
|
||||
#include "routing/segment.hpp"
|
||||
#include "routing/turns.hpp"
|
||||
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
|
||||
@@ -25,7 +25,7 @@ struct LoadedPathSegment
|
||||
std::vector<geometry::PointWithAltitude> m_path;
|
||||
std::vector<turns::SingleLaneInfo> m_lanes;
|
||||
RouteSegment::RoadNameInfo m_roadNameInfo;
|
||||
//double m_weight = 0.0; /*!< Time in seconds to pass the segment. */
|
||||
// double m_weight = 0.0; /*!< Time in seconds to pass the segment. */
|
||||
SegmentRange m_segmentRange;
|
||||
std::vector<Segment> m_segments; /*!< Traffic segments for |m_path|. */
|
||||
ftypes::HighwayClass m_highwayClass = ftypes::HighwayClass::Undefined;
|
||||
|
||||
@@ -33,12 +33,11 @@ Maxspeed Maxspeeds::GetMaxspeed(uint32_t fid) const
|
||||
}
|
||||
|
||||
// Bidirectional maxspeeds.
|
||||
auto const range = std::equal_range(
|
||||
m_bidirectionalMaxspeeds.cbegin(), m_bidirectionalMaxspeeds.cend(),
|
||||
fid, FeatureMaxspeed::Less());
|
||||
auto const range = std::equal_range(m_bidirectionalMaxspeeds.cbegin(), m_bidirectionalMaxspeeds.cend(), fid,
|
||||
FeatureMaxspeed::Less());
|
||||
|
||||
if (range.second == range.first)
|
||||
return Maxspeed(); // No maxspeed for |fid| is set. Returns an invalid Maxspeed instance.
|
||||
return Maxspeed(); // No maxspeed for |fid| is set. Returns an invalid Maxspeed instance.
|
||||
|
||||
CHECK_EQUAL(range.second - range.first, 1, ());
|
||||
return range.first->GetMaxspeed();
|
||||
@@ -76,8 +75,7 @@ std::unique_ptr<Maxspeeds> LoadMaxspeeds(MwmSet::MwmHandle const & handle)
|
||||
}
|
||||
catch (Reader::Exception const & e)
|
||||
{
|
||||
LOG(LERROR, ("File", value->GetCountryFileName(), "Error while reading", MAXSPEEDS_FILE_TAG,
|
||||
"section.", e.Msg()));
|
||||
LOG(LERROR, ("File", value->GetCountryFileName(), "Error while reading", MAXSPEEDS_FILE_TAG, "section.", e.Msg()));
|
||||
return std::make_unique<Maxspeeds>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,11 @@
|
||||
#include "coding/simple_dense_coding.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "3party/succinct/elias_fano.hpp"
|
||||
|
||||
|
||||
namespace routing
|
||||
{
|
||||
class MaxspeedsSerializer;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace routing
|
||||
{
|
||||
std::vector<uint8_t> MaxspeedsSerializer::GetForwardMaxspeeds(
|
||||
std::vector<FeatureSpeedMacro> const & speeds, uint32_t & maxFeatureID)
|
||||
std::vector<uint8_t> MaxspeedsSerializer::GetForwardMaxspeeds(std::vector<FeatureSpeedMacro> const & speeds,
|
||||
uint32_t & maxFeatureID)
|
||||
{
|
||||
std::vector<uint8_t> result;
|
||||
for (auto const & s : speeds)
|
||||
|
||||
@@ -49,7 +49,9 @@ public:
|
||||
struct FeatureSpeedMacro
|
||||
{
|
||||
FeatureSpeedMacro(uint32_t featureID, SpeedMacro forward, SpeedMacro backward = SpeedMacro::Undefined)
|
||||
: m_featureID(featureID), m_forward(forward), m_backward(backward)
|
||||
: m_featureID(featureID)
|
||||
, m_forward(forward)
|
||||
, m_backward(backward)
|
||||
{
|
||||
// We store bidirectional speeds only if they are not equal,
|
||||
// see Maxspeed::IsBidirectional() comments.
|
||||
@@ -69,14 +71,12 @@ public:
|
||||
static int constexpr DEFAULT_SPEEDS_COUNT = Maxspeeds::DEFAULT_SPEEDS_COUNT;
|
||||
|
||||
template <class Sink>
|
||||
static void Serialize(std::vector<FeatureSpeedMacro> const & featureSpeeds,
|
||||
HW2SpeedMap typeSpeeds[], Sink & sink)
|
||||
static void Serialize(std::vector<FeatureSpeedMacro> const & featureSpeeds, HW2SpeedMap typeSpeeds[], Sink & sink)
|
||||
{
|
||||
CHECK(base::IsSortedAndUnique(featureSpeeds.cbegin(), featureSpeeds.cend(),
|
||||
[](FeatureSpeedMacro const & l, FeatureSpeedMacro const & r)
|
||||
{
|
||||
return l.m_featureID < r.m_featureID;
|
||||
}), ());
|
||||
{ return l.m_featureID < r.m_featureID; }),
|
||||
());
|
||||
|
||||
// Version
|
||||
auto const startOffset = sink.Pos();
|
||||
@@ -98,10 +98,8 @@ public:
|
||||
{
|
||||
succinct::elias_fano::elias_fano_builder builder(maxFeatureID + 1, forwardCount);
|
||||
for (auto const & e : featureSpeeds)
|
||||
{
|
||||
if (!e.IsBidirectional())
|
||||
builder.push_back(e.m_featureID);
|
||||
}
|
||||
|
||||
coding::FreezeVisitor<Writer> visitor(sink);
|
||||
succinct::elias_fano(&builder).map(visitor);
|
||||
@@ -152,11 +150,10 @@ public:
|
||||
sink.Seek(endOffset);
|
||||
|
||||
// Print statistics.
|
||||
LOG(LINFO, ("Serialized", forwardCount, "forward maxspeeds and",
|
||||
header.m_bidirectionalMaxspeedNumber,
|
||||
LOG(LINFO, ("Serialized", forwardCount, "forward maxspeeds and", header.m_bidirectionalMaxspeedNumber,
|
||||
"bidirectional maxspeeds. Section size:", endOffset - startOffset, "bytes."));
|
||||
LOG(LINFO, ("Succinct EF compression ratio:",
|
||||
forwardCount * (4 + 1) / double(header.m_bidirectionalMaxspeedOffset)));
|
||||
LOG(LINFO,
|
||||
("Succinct EF compression ratio:", forwardCount * (4 + 1) / double(header.m_bidirectionalMaxspeedOffset)));
|
||||
}
|
||||
|
||||
template <class Source>
|
||||
@@ -180,8 +177,8 @@ public:
|
||||
std::vector<uint8_t> forwardTableData(header.m_forwardMaxspeedOffset);
|
||||
src.Read(forwardTableData.data(), forwardTableData.size());
|
||||
maxspeeds.m_forwardMaxspeedTableRegion = std::make_unique<CopiedMemoryRegion>(std::move(forwardTableData));
|
||||
coding::Map(maxspeeds.m_forwardMaxspeedsTable,
|
||||
maxspeeds.m_forwardMaxspeedTableRegion->ImmutableData(), "ForwardMaxspeedsTable");
|
||||
coding::Map(maxspeeds.m_forwardMaxspeedsTable, maxspeeds.m_forwardMaxspeedTableRegion->ImmutableData(),
|
||||
"ForwardMaxspeedsTable");
|
||||
|
||||
std::vector<uint8_t> forwardData(header.m_bidirectionalMaxspeedOffset - header.m_forwardMaxspeedOffset);
|
||||
src.Read(forwardData.data(), forwardData.size());
|
||||
@@ -233,7 +230,7 @@ public:
|
||||
auto const type = static_cast<HighwayType>(ReadVarUint<uint32_t>(src));
|
||||
auto const speed = converter.MacroToSpeed(static_cast<SpeedMacro>(ReadPrimitiveFromSource<uint8_t>(src)));
|
||||
// Constraint should be met, but unit tests use different input Units. No problem here.
|
||||
//ASSERT_EQUAL(speed.GetUnits(), measurement_utils::Units::Metric, ());
|
||||
// ASSERT_EQUAL(speed.GetUnits(), measurement_utils::Units::Metric, ());
|
||||
maxspeeds.m_defaultSpeeds[ind][type] = speed.GetSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,18 +14,14 @@ inline size_t constexpr kCrossCountryPenaltyS = 60 * 60 * 2;
|
||||
using CountrySetT = std::unordered_set<std::string_view>;
|
||||
|
||||
// The Eurasian Economic Union (EAEU) list of countries.
|
||||
CountrySetT kEAEU = {
|
||||
"Armenia", "Belarus", "Kazakhstan", "Kyrgyzstan", "Russian Federation"
|
||||
};
|
||||
CountrySetT kEAEU = {"Armenia", "Belarus", "Kazakhstan", "Kyrgyzstan", "Russian Federation"};
|
||||
|
||||
// The Schengen Area list of countries.
|
||||
CountrySetT kSchengenArea = {
|
||||
"Austria", "Belgium", "Czech Republic", "Denmark", "Estonia", "Finland",
|
||||
"France", "Germany", "Greece", "Hungary", "Iceland", "Italy",
|
||||
"Latvia", "Liechtenstein", "Lithuania", "Luxembourg", "Malta", "Netherlands",
|
||||
"Norway", "Poland", "Portugal", "Slovakia", "Slovenia", "Spain",
|
||||
"Sweden", "Switzerland", "Croatia"
|
||||
};
|
||||
CountrySetT kSchengenArea = {"Austria", "Belgium", "Czech Republic", "Denmark", "Estonia", "Finland",
|
||||
"France", "Germany", "Greece", "Hungary", "Iceland", "Italy",
|
||||
"Latvia", "Liechtenstein", "Lithuania", "Luxembourg", "Malta", "Netherlands",
|
||||
"Norway", "Poland", "Portugal", "Slovakia", "Slovenia", "Spain",
|
||||
"Sweden", "Switzerland", "Croatia"};
|
||||
|
||||
std::string_view kIreland = "Ireland";
|
||||
std::string_view kNorthernIrelandMwm = "UK_Northern Ireland";
|
||||
@@ -33,15 +29,14 @@ std::string_view kNorthernIrelandMwm = "UK_Northern Ireland";
|
||||
// In fact, there is no _total_ border control on major roads between Israel and Palestine (UN boundary), except:
|
||||
// - Gaza, strict access/barrier restrictions should be mapped, no transit traffic.
|
||||
// - West bank wall (https://www.openstreetmap.org/relation/1410327), access/barrier restrictions should be mapped.
|
||||
CountrySetT kIsraelAndPalestine = { "Israel Region", "Palestine Region" };
|
||||
CountrySetT kIsraelAndPalestine = {"Israel Region", "Palestine Region"};
|
||||
std::string_view kJerusalemMwm = "Jerusalem";
|
||||
|
||||
bool IsInSet(CountrySetT const & theSet, std::string const & country)
|
||||
{
|
||||
return theSet.find(country) != theSet.end();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
} // namespace
|
||||
|
||||
/// @return Top level hierarchy name for MWMs \a mwmName.
|
||||
/// @note May be empty for the disputed territories.
|
||||
@@ -62,11 +57,10 @@ std::string GetCountryByMwmName(std::string const & mwmName, CountryParentNameGe
|
||||
return country;
|
||||
}
|
||||
|
||||
MwmHierarchyHandler::MwmHierarchyHandler(std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
CountryParentNameGetterFn parentGetterFn)
|
||||
: m_numMwmIds(std::move(numMwmIds)), m_countryParentNameGetterFn(std::move(parentGetterFn))
|
||||
{
|
||||
}
|
||||
MwmHierarchyHandler::MwmHierarchyHandler(std::shared_ptr<NumMwmIds> numMwmIds, CountryParentNameGetterFn parentGetterFn)
|
||||
: m_numMwmIds(std::move(numMwmIds))
|
||||
, m_countryParentNameGetterFn(std::move(parentGetterFn))
|
||||
{}
|
||||
|
||||
std::string MwmHierarchyHandler::GetMwmName(NumMwmId mwmId) const
|
||||
{
|
||||
@@ -112,11 +106,8 @@ bool MwmHierarchyHandler::HasCrossBorderPenalty(NumMwmId mwmId1, NumMwmId mwmId2
|
||||
if (country1 == country2)
|
||||
return false;
|
||||
|
||||
if ((country1 == kIreland && mwm2 == kNorthernIrelandMwm) ||
|
||||
(country2 == kIreland && mwm1 == kNorthernIrelandMwm))
|
||||
{
|
||||
if ((country1 == kIreland && mwm2 == kNorthernIrelandMwm) || (country2 == kIreland && mwm1 == kNorthernIrelandMwm))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsInSet(kIsraelAndPalestine, country1) && IsInSet(kIsraelAndPalestine, country2))
|
||||
return false;
|
||||
|
||||
@@ -19,8 +19,7 @@ public:
|
||||
// Used in tests only.
|
||||
MwmHierarchyHandler() = default;
|
||||
// Used in IndexRouter.
|
||||
MwmHierarchyHandler(std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
CountryParentNameGetterFn countryParentNameGetterFn);
|
||||
MwmHierarchyHandler(std::shared_ptr<NumMwmIds> numMwmIds, CountryParentNameGetterFn countryParentNameGetterFn);
|
||||
|
||||
bool HasCrossBorderPenalty(NumMwmId mwmId1, NumMwmId mwmId2);
|
||||
RouteWeight GetCrossBorderPenalty(NumMwmId mwmId1, NumMwmId mwmId2);
|
||||
|
||||
@@ -10,9 +10,9 @@ namespace routing
|
||||
using namespace std;
|
||||
|
||||
NearestEdgeFinder::NearestEdgeFinder(m2::PointD const & point, IsEdgeProjGood const & isEdgeProjGood)
|
||||
: m_point(point), m_isEdgeProjGood(isEdgeProjGood)
|
||||
{
|
||||
}
|
||||
: m_point(point)
|
||||
, m_isEdgeProjGood(isEdgeProjGood)
|
||||
{}
|
||||
|
||||
void NearestEdgeFinder::AddInformationSource(IRoadGraph::FullRoadInfo const & roadInfo)
|
||||
{
|
||||
@@ -26,8 +26,7 @@ void NearestEdgeFinder::AddInformationSource(IRoadGraph::FullRoadInfo const & ro
|
||||
ASSERT_GREATER(count, 1, ());
|
||||
for (size_t i = 1; i < count; ++i)
|
||||
{
|
||||
m2::ParametrizedSegment<m2::PointD> segment(junctions[i - 1].GetPoint(),
|
||||
junctions[i].GetPoint());
|
||||
m2::ParametrizedSegment<m2::PointD> segment(junctions[i - 1].GetPoint(), junctions[i].GetPoint());
|
||||
|
||||
m2::PointD const closestPoint = segment.ClosestPointTo(m_point);
|
||||
double const squaredDist = m_point.SquaredLength(closestPoint);
|
||||
@@ -48,8 +47,7 @@ void NearestEdgeFinder::AddInformationSource(IRoadGraph::FullRoadInfo const & ro
|
||||
geometry::PointWithAltitude const & segEnd = junctions[idx];
|
||||
geometry::Altitude const startAlt = segStart.GetAltitude();
|
||||
geometry::Altitude const endAlt = segEnd.GetAltitude();
|
||||
m2::ParametrizedSegment<m2::PointD> segment(junctions[idx - 1].GetPoint(),
|
||||
junctions[idx].GetPoint());
|
||||
m2::ParametrizedSegment<m2::PointD> segment(junctions[idx - 1].GetPoint(), junctions[idx].GetPoint());
|
||||
m2::PointD const closestPoint = segment.ClosestPointTo(m_point);
|
||||
|
||||
double const segLenM = mercator::DistanceOnEarth(segStart.GetPoint(), segEnd.GetPoint());
|
||||
@@ -62,8 +60,7 @@ void NearestEdgeFinder::AddInformationSource(IRoadGraph::FullRoadInfo const & ro
|
||||
{
|
||||
double const distFromStartM = mercator::DistanceOnEarth(segStart.GetPoint(), closestPoint);
|
||||
ASSERT_LESS_OR_EQUAL(distFromStartM, segLenM, (roadInfo.m_featureId));
|
||||
projPointAlt =
|
||||
startAlt + static_cast<geometry::Altitude>((endAlt - startAlt) * distFromStartM / segLenM);
|
||||
projPointAlt = startAlt + static_cast<geometry::Altitude>((endAlt - startAlt) * distFromStartM / segLenM);
|
||||
}
|
||||
|
||||
res.m_fid = roadInfo.m_featureId;
|
||||
@@ -80,10 +77,8 @@ void NearestEdgeFinder::AddInformationSource(IRoadGraph::FullRoadInfo const & ro
|
||||
|
||||
void NearestEdgeFinder::MakeResult(vector<EdgeProjectionT> & res, size_t maxCountFeatures)
|
||||
{
|
||||
sort(m_candidates.begin(), m_candidates.end(), [](Candidate const & r1, Candidate const & r2)
|
||||
{
|
||||
return r1.m_squaredDist < r2.m_squaredDist;
|
||||
});
|
||||
sort(m_candidates.begin(), m_candidates.end(),
|
||||
[](Candidate const & r1, Candidate const & r2) { return r1.m_squaredDist < r2.m_squaredDist; });
|
||||
|
||||
res.clear();
|
||||
res.reserve(maxCountFeatures);
|
||||
@@ -114,7 +109,7 @@ void NearestEdgeFinder::AddResIf(Candidate const & candidate, bool forward, size
|
||||
geometry::PointWithAltitude const & start = forward ? candidate.m_segStart : candidate.m_segEnd;
|
||||
geometry::PointWithAltitude const & end = forward ? candidate.m_segEnd : candidate.m_segStart;
|
||||
|
||||
Edge const edge = Edge::MakeReal(candidate.m_fid, forward, candidate.m_segId, start,end);
|
||||
Edge const edge = Edge::MakeReal(candidate.m_fid, forward, candidate.m_segId, start, end);
|
||||
EdgeProjectionT const edgeProj(edge, candidate.m_projPoint);
|
||||
if (m_isEdgeProjGood && !m_isEdgeProjGood(edgeProj))
|
||||
return;
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "geometry/point_with_altitude.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
@@ -38,7 +38,7 @@ osmoh::RuleSequence GetTwentyFourHourRule()
|
||||
bool ShouldSkipYear(uint16_t startYear, uint16_t endYear, uint16_t currentYear)
|
||||
{
|
||||
if (startYear > endYear)
|
||||
return true; // Wrong data. |startYear| is later than |endYear|.
|
||||
return true; // Wrong data. |startYear| is later than |endYear|.
|
||||
|
||||
// returns true if |startYear| and |endYear| are too old and false otherwise.
|
||||
return endYear < currentYear;
|
||||
@@ -131,16 +131,13 @@ OpeningHoursSerDes::Header OpeningHoursSerDes::CreateHeader(osmoh::RuleSequence
|
||||
bool OpeningHoursSerDes::NotSupported(osmoh::RuleSequence const & rule)
|
||||
{
|
||||
for (auto const unsupportedFeature : m_unsupportedFeatures)
|
||||
{
|
||||
if (ExistsFeatureInOpeningHours(unsupportedFeature, rule))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OpeningHoursSerDes::ExistsFeatureInOpeningHours(Header::Bits feature,
|
||||
osmoh::RuleSequence const & rule) const
|
||||
bool OpeningHoursSerDes::ExistsFeatureInOpeningHours(Header::Bits feature, osmoh::RuleSequence const & rule) const
|
||||
{
|
||||
switch (feature)
|
||||
{
|
||||
@@ -152,10 +149,8 @@ bool OpeningHoursSerDes::ExistsFeatureInOpeningHours(Header::Bits feature,
|
||||
return true;
|
||||
|
||||
for (auto const & monthRange : rule.GetMonths())
|
||||
{
|
||||
if (monthRange.GetStart().HasYear() && monthRange.GetEnd().HasYear())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -184,7 +179,8 @@ bool OpeningHoursSerDes::CheckSupportedFeatures() const
|
||||
|
||||
std::vector<osmoh::RuleSequence> OpeningHoursSerDes::DecomposeOh(osmoh::OpeningHours const & oh)
|
||||
{
|
||||
auto const apply = [&](auto & rules, auto const & ranges, auto const & rangeSetter) {
|
||||
auto const apply = [&](auto & rules, auto const & ranges, auto const & rangeSetter)
|
||||
{
|
||||
if (ranges.empty())
|
||||
return;
|
||||
|
||||
@@ -222,48 +218,45 @@ std::vector<osmoh::RuleSequence> OpeningHoursSerDes::DecomposeOh(osmoh::OpeningH
|
||||
continue;
|
||||
|
||||
bool badRule = false;
|
||||
apply(rules, rule.GetYears(),
|
||||
[&](osmoh::YearRange const & range, osmoh::RuleSequence & item) {
|
||||
if (ShouldSkipYear(range, m_currentYear))
|
||||
badRule = true;
|
||||
apply(rules, rule.GetYears(), [&](osmoh::YearRange const & range, osmoh::RuleSequence & item)
|
||||
{
|
||||
if (ShouldSkipYear(range, m_currentYear))
|
||||
badRule = true;
|
||||
|
||||
item.SetYears({range});
|
||||
});
|
||||
item.SetYears({range});
|
||||
});
|
||||
|
||||
apply(rules, rule.GetMonths(),
|
||||
[&](osmoh::MonthdayRange const & range, osmoh::RuleSequence & item) {
|
||||
if (ShouldSkipYear(range, m_currentYear))
|
||||
badRule = true;
|
||||
apply(rules, rule.GetMonths(), [&](osmoh::MonthdayRange const & range, osmoh::RuleSequence & item)
|
||||
{
|
||||
if (ShouldSkipYear(range, m_currentYear))
|
||||
badRule = true;
|
||||
|
||||
item.SetMonths({range});
|
||||
});
|
||||
item.SetMonths({range});
|
||||
});
|
||||
|
||||
if (badRule)
|
||||
continue;
|
||||
|
||||
apply(rules, rule.GetWeekdays().GetWeekdayRanges(),
|
||||
[](osmoh::WeekdayRange const & range, osmoh::RuleSequence & item) {
|
||||
osmoh::Weekdays weekdays;
|
||||
weekdays.SetWeekdayRanges({range});
|
||||
item.SetWeekdays(weekdays);
|
||||
});
|
||||
[](osmoh::WeekdayRange const & range, osmoh::RuleSequence & item)
|
||||
{
|
||||
osmoh::Weekdays weekdays;
|
||||
weekdays.SetWeekdayRanges({range});
|
||||
item.SetWeekdays(weekdays);
|
||||
});
|
||||
|
||||
apply(rules, rule.GetWeekdays().GetHolidays(),
|
||||
[](osmoh::Holiday const & holiday, osmoh::RuleSequence & item) {
|
||||
auto weekdays = item.GetWeekdays();
|
||||
weekdays.SetHolidays({holiday});
|
||||
item.SetWeekdays(weekdays);
|
||||
});
|
||||
apply(rules, rule.GetWeekdays().GetHolidays(), [](osmoh::Holiday const & holiday, osmoh::RuleSequence & item)
|
||||
{
|
||||
auto weekdays = item.GetWeekdays();
|
||||
weekdays.SetHolidays({holiday});
|
||||
item.SetWeekdays(weekdays);
|
||||
});
|
||||
|
||||
apply(rules, rule.GetTimes(),
|
||||
[](osmoh::Timespan const & range, osmoh::RuleSequence & item) {
|
||||
item.SetTimes({range});
|
||||
});
|
||||
[](osmoh::Timespan const & range, osmoh::RuleSequence & item) { item.SetTimes({range}); });
|
||||
|
||||
apply(rules, std::vector<osmoh::RuleSequence::Modifier>{rule.GetModifier()},
|
||||
[](osmoh::RuleSequence::Modifier modifier, osmoh::RuleSequence & item) {
|
||||
item.SetModifier(modifier);
|
||||
});
|
||||
[](osmoh::RuleSequence::Modifier modifier, osmoh::RuleSequence & item) { item.SetModifier(modifier); });
|
||||
|
||||
finalRules.insert(finalRules.end(), rules.begin(), rules.end());
|
||||
}
|
||||
@@ -280,16 +273,13 @@ std::vector<osmoh::RuleSequence> OpeningHoursSerDes::DecomposeOh(osmoh::OpeningH
|
||||
return filteredRules;
|
||||
}
|
||||
|
||||
bool OpeningHoursSerDes::HaveSameHeaders(
|
||||
std::vector<osmoh::RuleSequence> const & decomposedOhs) const
|
||||
bool OpeningHoursSerDes::HaveSameHeaders(std::vector<osmoh::RuleSequence> const & decomposedOhs) const
|
||||
{
|
||||
CHECK(!decomposedOhs.empty(), ());
|
||||
Header const header = CreateHeader(decomposedOhs.front());
|
||||
for (auto const & oh : decomposedOhs)
|
||||
{
|
||||
if (header != CreateHeader(oh))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -311,8 +301,7 @@ uint8_t OpeningHoursSerDes::GetBitsNumber(Header::Bits type) const
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
bool OpeningHoursSerDes::CheckYearRange(osmoh::MonthDay::TYear start,
|
||||
osmoh::MonthDay::TYear end) const
|
||||
bool OpeningHoursSerDes::CheckYearRange(osmoh::MonthDay::TYear start, osmoh::MonthDay::TYear end) const
|
||||
{
|
||||
if (start < kYearBias || end < kYearBias)
|
||||
return false;
|
||||
@@ -327,14 +316,12 @@ bool OpeningHoursSerDes::IsTwentyFourHourRule(osmoh::RuleSequence const & rule)
|
||||
static auto const kTwentyFourHourStart = osmoh::HourMinutes(osmoh::HourMinutes::THours(0));
|
||||
static auto const kTwentyFourHourEnd = osmoh::HourMinutes(osmoh::HourMinutes::THours(24));
|
||||
|
||||
return rule.GetModifier() != osmoh::RuleSequence::Modifier::Closed &&
|
||||
rule.GetYears().empty() && rule.GetWeekdays().GetWeekdayRanges().empty() &&
|
||||
rule.GetMonths().empty() && rule.GetTimes().size() == 1 &&
|
||||
return rule.GetModifier() != osmoh::RuleSequence::Modifier::Closed && rule.GetYears().empty() &&
|
||||
rule.GetWeekdays().GetWeekdayRanges().empty() && rule.GetMonths().empty() && rule.GetTimes().size() == 1 &&
|
||||
rule.GetTimes().back().GetStart() == kTwentyFourHourStart &&
|
||||
rule.GetTimes().back().GetEnd() == kTwentyFourHourEnd;
|
||||
}
|
||||
|
||||
|
||||
bool OpeningHoursSerDes::IsSerializable(osmoh::OpeningHours const & openingHours)
|
||||
{
|
||||
std::vector<uint8_t> buffer;
|
||||
|
||||
@@ -54,24 +54,23 @@ public:
|
||||
using HeaderType = uint16_t;
|
||||
enum class Bits : HeaderType
|
||||
{
|
||||
Year = 1U << 0U,
|
||||
Month = 1U << 1U,
|
||||
Year = 1U << 0U,
|
||||
Month = 1U << 1U,
|
||||
MonthDay = 1U << 2U,
|
||||
WeekDay = 1U << 3U,
|
||||
Hours = 1U << 4U,
|
||||
Minutes = 1U << 5U,
|
||||
Off = 1U << 6U,
|
||||
Holiday = 1U << 7U,
|
||||
WeekDay = 1U << 3U,
|
||||
Hours = 1U << 4U,
|
||||
Minutes = 1U << 5U,
|
||||
Off = 1U << 6U,
|
||||
Holiday = 1U << 7U,
|
||||
|
||||
Max = 1U << 8U
|
||||
Max = 1U << 8U
|
||||
};
|
||||
|
||||
static inline uint8_t constexpr kBitsSize = 8;
|
||||
static_assert(base::Underlying(Bits::Max) == 1U << kBitsSize,
|
||||
"It's seems header's size has been changed. Need to change |kBitsSize| member.");
|
||||
|
||||
static_assert(kBitsSize <= 8,
|
||||
"Header's size is more than 1 byte, be careful about section weight.");
|
||||
static_assert(kBitsSize <= 8, "Header's size is more than 1 byte, be careful about section weight.");
|
||||
|
||||
/// \brief Returns true if feature takes only two values (0 or 1).
|
||||
static bool IsBinaryFeature(Header::Bits feature);
|
||||
@@ -155,8 +154,7 @@ private:
|
||||
|
||||
// OpeningHoursSerDes::Header ----------------------------------------------------------------------
|
||||
template <typename Writer>
|
||||
void OpeningHoursSerDes::Header::Serialize(BitWriter<Writer> & writer,
|
||||
OpeningHoursSerDes::Header header)
|
||||
void OpeningHoursSerDes::Header::Serialize(BitWriter<Writer> & writer, OpeningHoursSerDes::Header header)
|
||||
{
|
||||
writer.Write(header.GetValue(), Header::GetBitsSize());
|
||||
}
|
||||
@@ -169,8 +167,7 @@ OpeningHoursSerDes::Header OpeningHoursSerDes::Header::Deserialize(BitReader<Rea
|
||||
|
||||
// OpeningHoursSerDes ------------------------------------------------------------------------------
|
||||
template <typename Writer>
|
||||
bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer,
|
||||
osmoh::OpeningHours const & openingHours)
|
||||
bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer, osmoh::OpeningHours const & openingHours)
|
||||
{
|
||||
if (!IsSerializable(openingHours))
|
||||
return false;
|
||||
@@ -179,8 +176,7 @@ bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer,
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer,
|
||||
std::string const & openingHoursString)
|
||||
bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer, std::string const & openingHoursString)
|
||||
{
|
||||
osmoh::OpeningHours const oh(openingHoursString);
|
||||
if (!oh.IsValid())
|
||||
@@ -190,8 +186,7 @@ bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer,
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
bool OpeningHoursSerDes::SerializeImpl(BitWriter<Writer> & writer,
|
||||
osmoh::OpeningHours const & openingHours)
|
||||
bool OpeningHoursSerDes::SerializeImpl(BitWriter<Writer> & writer, osmoh::OpeningHours const & openingHours)
|
||||
{
|
||||
CheckSupportedFeatures();
|
||||
|
||||
@@ -248,10 +243,8 @@ osmoh::OpeningHours OpeningHoursSerDes::Deserialize(BitReader<Reader> & reader)
|
||||
|
||||
osmoh::RuleSequence rule;
|
||||
for (auto const supportedFeature : m_supportedFeatures)
|
||||
{
|
||||
if (header.IsSet(supportedFeature))
|
||||
Deserialize(reader, supportedFeature, rule);
|
||||
}
|
||||
|
||||
rules.emplace_back(std::move(rule));
|
||||
}
|
||||
@@ -266,8 +259,7 @@ osmoh::OpeningHours OpeningHoursSerDes::Deserialize(BitReader<Reader> & reader)
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer, Header::Bits type,
|
||||
osmoh::RuleSequence const & rule)
|
||||
bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer, Header::Bits type, osmoh::RuleSequence const & rule)
|
||||
{
|
||||
uint8_t start = 0;
|
||||
uint8_t end = 0;
|
||||
@@ -375,8 +367,7 @@ bool OpeningHoursSerDes::Serialize(BitWriter<Writer> & writer, Header::Bits type
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
void OpeningHoursSerDes::Deserialize(BitReader<Reader> & reader,
|
||||
OpeningHoursSerDes::Header::Bits type,
|
||||
void OpeningHoursSerDes::Deserialize(BitReader<Reader> & reader, OpeningHoursSerDes::Header::Bits type,
|
||||
osmoh::RuleSequence & rule)
|
||||
{
|
||||
uint8_t const start = reader.Read(GetBitsNumber(type));
|
||||
@@ -500,8 +491,7 @@ void OpeningHoursSerDes::Deserialize(BitReader<Reader> & reader,
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
bool OpeningHoursSerDes::SerializeValue(BitWriter<Writer> & writer, Header::Bits type,
|
||||
uint8_t value)
|
||||
bool OpeningHoursSerDes::SerializeValue(BitWriter<Writer> & writer, Header::Bits type, uint8_t value)
|
||||
{
|
||||
uint8_t const bitsNumber = GetBitsNumber(type);
|
||||
if (value >= 1U << bitsNumber)
|
||||
@@ -512,8 +502,7 @@ bool OpeningHoursSerDes::SerializeValue(BitWriter<Writer> & writer, Header::Bits
|
||||
}
|
||||
|
||||
template <typename Writer>
|
||||
void OpeningHoursSerDes::SerializeRuleHeader(BitWriter<Writer> & writer,
|
||||
osmoh::RuleSequence const & rule)
|
||||
void OpeningHoursSerDes::SerializeRuleHeader(BitWriter<Writer> & writer, osmoh::RuleSequence const & rule)
|
||||
{
|
||||
Header const header = CreateHeader(rule);
|
||||
Header::Serialize(writer, header);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "routing/pedestrian_directions.hpp"
|
||||
|
||||
#include "routing/turns_generator.hpp"
|
||||
#include "routing/turns.hpp"
|
||||
#include "routing/turns_generator.hpp"
|
||||
#include "routing/turns_generator_utils.hpp"
|
||||
|
||||
#include <utility>
|
||||
@@ -13,16 +13,15 @@ using namespace turns;
|
||||
|
||||
PedestrianDirectionsEngine::PedestrianDirectionsEngine(MwmDataSource & dataSource, shared_ptr<NumMwmIds> numMwmIds)
|
||||
: DirectionsEngine(dataSource, std::move(numMwmIds))
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
// Angles in degrees for finding route segments with no actual forks.
|
||||
double constexpr kMaxForwardAngleCandidates = 95.0;
|
||||
double constexpr kMaxForwardAngleActual = 60.0;
|
||||
|
||||
size_t PedestrianDirectionsEngine::GetTurnDirection(IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds,
|
||||
RoutingSettings const & vehicleSettings, TurnItem & turn)
|
||||
NumMwmIds const & numMwmIds,
|
||||
RoutingSettings const & vehicleSettings, TurnItem & turn)
|
||||
{
|
||||
if (outgoingSegmentIndex == result.GetSegments().size())
|
||||
{
|
||||
@@ -31,7 +30,7 @@ size_t PedestrianDirectionsEngine::GetTurnDirection(IRoutingResult const & resul
|
||||
}
|
||||
|
||||
// See comment for the same in CarDirectionsEngine::GetTurnDirection().
|
||||
if (outgoingSegmentIndex == 2) // The same as turnItem.m_index == 2.
|
||||
if (outgoingSegmentIndex == 2) // The same as turnItem.m_index == 2.
|
||||
return 0;
|
||||
|
||||
TurnInfo turnInfo;
|
||||
@@ -78,7 +77,8 @@ size_t PedestrianDirectionsEngine::GetTurnDirection(IRoutingResult const & resul
|
||||
// there is no possibility of leaving the route.
|
||||
if (nodes.candidates.size() <= 1)
|
||||
turn.m_pedestrianTurn = PedestrianDirection::None;
|
||||
if (fabs(CalcOneSegmentTurnAngle(turnInfo)) < kMaxForwardAngleActual && HasSingleForwardTurn(nodes, kMaxForwardAngleCandidates))
|
||||
if (fabs(CalcOneSegmentTurnAngle(turnInfo)) < kMaxForwardAngleActual &&
|
||||
HasSingleForwardTurn(nodes, kMaxForwardAngleCandidates))
|
||||
turn.m_pedestrianTurn = PedestrianDirection::None;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -16,8 +16,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual size_t GetTurnDirection(turns::IRoutingResult const & result, size_t const outgoingSegmentIndex,
|
||||
NumMwmIds const & numMwmIds,
|
||||
RoutingSettings const & vehicleSettings, turns::TurnItem & turn);
|
||||
NumMwmIds const & numMwmIds, RoutingSettings const & vehicleSettings,
|
||||
turns::TurnItem & turn);
|
||||
virtual void FixupTurns(std::vector<RouteSegment> & routeSegments);
|
||||
};
|
||||
} // namespace routing
|
||||
|
||||
@@ -14,8 +14,7 @@ double constexpr PositionAccumulator::kMaxValidSegmentLengthM;
|
||||
|
||||
void PositionAccumulator::PushNextPoint(m2::PointD const & point)
|
||||
{
|
||||
double const lenM =
|
||||
m_points.empty() ? 0.0 : mercator::DistanceOnEarth(point, m_points.back());
|
||||
double const lenM = m_points.empty() ? 0.0 : mercator::DistanceOnEarth(point, m_points.back());
|
||||
|
||||
// If the last segment is too long it tells nothing about an end user direction.
|
||||
// And the history is not actual.
|
||||
@@ -77,4 +76,4 @@ m2::PointD PositionAccumulator::GetDirection() const
|
||||
|
||||
return m_points.back() - m_points.front();
|
||||
}
|
||||
} // routing
|
||||
} // namespace routing
|
||||
|
||||
@@ -40,4 +40,4 @@ private:
|
||||
std::deque<m2::PointD> m_points;
|
||||
double m_trackLengthM = 0.0;
|
||||
};
|
||||
} // routing
|
||||
} // namespace routing
|
||||
|
||||
@@ -14,4 +14,4 @@ using CountryRectFn = std::function<m2::RectD(std::string const & countryId)>;
|
||||
|
||||
class Checkpoints;
|
||||
class NumMwmIds;
|
||||
} // namespace routing
|
||||
} // namespace routing
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "routing/regions_router.hpp"
|
||||
|
||||
#include "routing/dummy_world_graph.hpp"
|
||||
#include "routing/index_graph_starter.hpp"
|
||||
#include "routing/index_graph_loader.hpp"
|
||||
#include "routing/index_graph_starter.hpp"
|
||||
#include "routing/junction_visitor.hpp"
|
||||
#include "routing/regions_sparse_graph.hpp"
|
||||
#include "routing/routing_helpers.hpp"
|
||||
@@ -11,9 +11,8 @@
|
||||
|
||||
namespace routing
|
||||
{
|
||||
RegionsRouter::RegionsRouter(CountryFileGetterFn const & countryFileGetter,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds, DataSource & dataSource,
|
||||
RouterDelegate const & delegate, Checkpoints const & checkpoints)
|
||||
RegionsRouter::RegionsRouter(CountryFileGetterFn const & countryFileGetter, std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
DataSource & dataSource, RouterDelegate const & delegate, Checkpoints const & checkpoints)
|
||||
: m_countryFileGetterFn(countryFileGetter)
|
||||
, m_numMwmIds(std::move(numMwmIds))
|
||||
, m_dataSource(dataSource)
|
||||
@@ -24,8 +23,7 @@ RegionsRouter::RegionsRouter(CountryFileGetterFn const & countryFileGetter,
|
||||
}
|
||||
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
RouterResultCode RegionsRouter::ConvertResult(
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result result) const
|
||||
RouterResultCode RegionsRouter::ConvertResult(typename AStarAlgorithm<Vertex, Edge, Weight>::Result result) const
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
@@ -47,8 +45,8 @@ RouterResultCode RegionsRouter::CalculateSubrouteNoLeapsMode(IndexGraphStarter &
|
||||
|
||||
double constexpr almostZeroContribution = 1e-7;
|
||||
auto progress = std::make_shared<AStarProgress>();
|
||||
AStarSubProgress subProgress(mercator::ToLatLon(startCheckpoint),
|
||||
mercator::ToLatLon(finishCheckpoint), almostZeroContribution);
|
||||
AStarSubProgress subProgress(mercator::ToLatLon(startCheckpoint), mercator::ToLatLon(finishCheckpoint),
|
||||
almostZeroContribution);
|
||||
|
||||
progress->AppendSubProgress(subProgress);
|
||||
SCOPE_GUARD(eraseProgress, [&progress]() { progress->PushAndDropLastSubProgress(); });
|
||||
@@ -58,8 +56,8 @@ RouterResultCode RegionsRouter::CalculateSubrouteNoLeapsMode(IndexGraphStarter &
|
||||
Visitor visitor(starter, m_delegate, kVisitPeriod, progress);
|
||||
|
||||
AStarAlgorithm<Vertex, Edge, Weight>::Params<Visitor, AStarLengthChecker> params(
|
||||
starter, starter.GetStartSegment(), starter.GetFinishSegment(),
|
||||
m_delegate.GetCancellable(), std::move(visitor), AStarLengthChecker(starter));
|
||||
starter, starter.GetStartSegment(), starter.GetFinishSegment(), m_delegate.GetCancellable(), std::move(visitor),
|
||||
AStarLengthChecker(starter));
|
||||
|
||||
params.m_badReducedWeight = [](Weight const & reduced, Weight const & current)
|
||||
{
|
||||
@@ -97,19 +95,16 @@ void RegionsRouter::Do()
|
||||
if (GetCheckpointRegion(i).second == GetCheckpointRegion(i + 1).second)
|
||||
continue;
|
||||
|
||||
std::optional<FakeEnding> const startFakeEnding =
|
||||
sparseGraph->GetFakeEnding(m_checkpoints.GetPoint(i));
|
||||
std::optional<FakeEnding> const startFakeEnding = sparseGraph->GetFakeEnding(m_checkpoints.GetPoint(i));
|
||||
if (!startFakeEnding)
|
||||
return;
|
||||
|
||||
std::optional<FakeEnding> const finishFakeEnding =
|
||||
sparseGraph->GetFakeEnding(m_checkpoints.GetPoint(i + 1));
|
||||
std::optional<FakeEnding> const finishFakeEnding = sparseGraph->GetFakeEnding(m_checkpoints.GetPoint(i + 1));
|
||||
if (!finishFakeEnding)
|
||||
return;
|
||||
|
||||
IndexGraphStarter subrouteStarter(*startFakeEnding, *finishFakeEnding,
|
||||
0 /* fakeNumerationStart */, false /* isStartSegmentStrictForward */,
|
||||
*graph);
|
||||
IndexGraphStarter subrouteStarter(*startFakeEnding, *finishFakeEnding, 0 /* fakeNumerationStart */,
|
||||
false /* isStartSegmentStrictForward */, *graph);
|
||||
|
||||
subrouteStarter.GetGraph().SetMode(WorldGraphMode::NoLeaps);
|
||||
|
||||
@@ -117,8 +112,8 @@ void RegionsRouter::Do()
|
||||
|
||||
std::vector<Segment> subroute;
|
||||
|
||||
auto const result = CalculateSubrouteNoLeapsMode(
|
||||
subrouteStarter, subroute, m_checkpoints.GetPoint(i), m_checkpoints.GetPoint(i + 1));
|
||||
auto const result = CalculateSubrouteNoLeapsMode(subrouteStarter, subroute, m_checkpoints.GetPoint(i),
|
||||
m_checkpoints.GetPoint(i + 1));
|
||||
|
||||
if (result != RouterResultCode::NoError)
|
||||
return;
|
||||
@@ -139,7 +134,10 @@ void RegionsRouter::Do()
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> const & RegionsRouter::GetMwmNames() const { return m_mwmNames; }
|
||||
std::unordered_set<std::string> const & RegionsRouter::GetMwmNames() const
|
||||
{
|
||||
return m_mwmNames;
|
||||
}
|
||||
|
||||
std::pair<m2::PointD, std::string> RegionsRouter::GetCheckpointRegion(size_t index) const
|
||||
{
|
||||
|
||||
@@ -21,8 +21,7 @@ class RegionsRouter : public threads::IRoutine
|
||||
{
|
||||
public:
|
||||
RegionsRouter(CountryFileGetterFn const & countryFileGetter, std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
DataSource & dataSource, RouterDelegate const & delegate,
|
||||
Checkpoints const & checkpoints);
|
||||
DataSource & dataSource, RouterDelegate const & delegate, Checkpoints const & checkpoints);
|
||||
|
||||
void Do() override;
|
||||
|
||||
@@ -30,11 +29,9 @@ public:
|
||||
|
||||
private:
|
||||
template <typename Vertex, typename Edge, typename Weight>
|
||||
RouterResultCode ConvertResult(
|
||||
typename AStarAlgorithm<Vertex, Edge, Weight>::Result result) const;
|
||||
RouterResultCode ConvertResult(typename AStarAlgorithm<Vertex, Edge, Weight>::Result result) const;
|
||||
|
||||
RouterResultCode CalculateSubrouteNoLeapsMode(IndexGraphStarter & starter,
|
||||
std::vector<Segment> & subroute,
|
||||
RouterResultCode CalculateSubrouteNoLeapsMode(IndexGraphStarter & starter, std::vector<Segment> & subroute,
|
||||
m2::PointD const & startCheckpoint,
|
||||
m2::PointD const & finishCheckpoint);
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
namespace routing
|
||||
{
|
||||
RegionsSparseGraph::RegionsSparseGraph(CountryFileGetterFn const & countryFileGetter,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
DataSource & dataSource)
|
||||
: m_countryFileGetterFn(countryFileGetter), m_numMwmIds(numMwmIds), m_dataSource(dataSource)
|
||||
{
|
||||
}
|
||||
std::shared_ptr<NumMwmIds> numMwmIds, DataSource & dataSource)
|
||||
: m_countryFileGetterFn(countryFileGetter)
|
||||
, m_numMwmIds(numMwmIds)
|
||||
, m_dataSource(dataSource)
|
||||
{}
|
||||
|
||||
void RegionsSparseGraph::LoadRegionsSparseGraph()
|
||||
{
|
||||
@@ -66,65 +66,53 @@ std::optional<FakeEnding> RegionsSparseGraph::GetFakeEnding(m2::PointD const & p
|
||||
|
||||
auto const & projectedJunction = CalcProjectionToSegment(backJunction, frontJunction, point);
|
||||
|
||||
Segment const segment(data.m_start.m_numMwmId, segmentId /* featureId */, 0 /* segmentIdx */,
|
||||
true /* isForward */);
|
||||
Segment const segment(data.m_start.m_numMwmId, segmentId /* featureId */, 0 /* segmentIdx */, true /* isForward */);
|
||||
|
||||
ending.m_projections.emplace_back(segment, oneWay, frontJunction, backJunction,
|
||||
projectedJunction);
|
||||
ending.m_projections.emplace_back(segment, oneWay, frontJunction, backJunction, projectedJunction);
|
||||
}
|
||||
|
||||
return ending;
|
||||
}
|
||||
|
||||
double GetWeight(CrossBorderSegment const & toSeg, LatLonWithAltitude const & coordFrom,
|
||||
NumMwmId fromMwm)
|
||||
double GetWeight(CrossBorderSegment const & toSeg, LatLonWithAltitude const & coordFrom, NumMwmId fromMwm)
|
||||
{
|
||||
auto const & coordTo =
|
||||
toSeg.m_start.m_numMwmId == fromMwm ? toSeg.m_start.m_point : toSeg.m_end.m_point;
|
||||
auto const & coordTo = toSeg.m_start.m_numMwmId == fromMwm ? toSeg.m_start.m_point : toSeg.m_end.m_point;
|
||||
CHECK(toSeg.m_start.m_numMwmId == fromMwm || toSeg.m_end.m_numMwmId == fromMwm,
|
||||
(fromMwm, toSeg.m_start.m_numMwmId, toSeg.m_end.m_numMwmId, coordTo));
|
||||
return toSeg.m_weight + ms::DistanceOnEarth(coordFrom.GetLatLon(), coordTo.GetLatLon());
|
||||
}
|
||||
|
||||
void RegionsSparseGraph::GetEdgeList(Segment const & segment, bool isOutgoing,
|
||||
EdgeListT & edges,
|
||||
void RegionsSparseGraph::GetEdgeList(Segment const & segment, bool isOutgoing, EdgeListT & edges,
|
||||
ms::LatLon const & prevSegFront) const
|
||||
{
|
||||
auto const & data = GetDataById(segment.GetFeatureId());
|
||||
|
||||
NumMwmId const targetMwm =
|
||||
(segment.IsForward() == isOutgoing) ? data.m_end.m_numMwmId : data.m_start.m_numMwmId;
|
||||
NumMwmId const targetMwm = (segment.IsForward() == isOutgoing) ? data.m_end.m_numMwmId : data.m_start.m_numMwmId;
|
||||
|
||||
auto it = m_graph.m_mwms.find(targetMwm);
|
||||
if (it == m_graph.m_mwms.end())
|
||||
return;
|
||||
|
||||
LatLonWithAltitude const & segCoord =
|
||||
(segment.IsForward() == isOutgoing) ? data.m_end.m_point : data.m_start.m_point;
|
||||
LatLonWithAltitude const & segCoord = (segment.IsForward() == isOutgoing) ? data.m_end.m_point : data.m_start.m_point;
|
||||
|
||||
for (auto const & id : it->second)
|
||||
{
|
||||
auto const outData = GetDataById(id);
|
||||
if (id == segment.GetFeatureId())
|
||||
continue;
|
||||
LatLonWithAltitude const segFront =
|
||||
segment.IsForward() ? outData.m_end.m_point : outData.m_start.m_point;
|
||||
LatLonWithAltitude const segFront = segment.IsForward() ? outData.m_end.m_point : outData.m_start.m_point;
|
||||
|
||||
auto const weight = isOutgoing
|
||||
? RouteWeight(GetWeight(outData, segCoord, targetMwm))
|
||||
: RouteWeight(ms::DistanceOnEarth(segFront.GetLatLon(), prevSegFront));
|
||||
auto const weight = isOutgoing ? RouteWeight(GetWeight(outData, segCoord, targetMwm))
|
||||
: RouteWeight(ms::DistanceOnEarth(segFront.GetLatLon(), prevSegFront));
|
||||
|
||||
auto const outMwm = targetMwm == outData.m_start.m_numMwmId ? outData.m_end.m_numMwmId
|
||||
: outData.m_start.m_numMwmId;
|
||||
auto const outMwm = targetMwm == outData.m_start.m_numMwmId ? outData.m_end.m_numMwmId : outData.m_start.m_numMwmId;
|
||||
|
||||
Segment const edge(outMwm, id /* featureId */, 0 /* segmentIdx */,
|
||||
segment.IsForward() /* isForward */);
|
||||
Segment const edge(outMwm, id /* featureId */, 0 /* segmentIdx */, segment.IsForward() /* isForward */);
|
||||
edges.emplace_back(edge, weight);
|
||||
}
|
||||
}
|
||||
|
||||
routing::LatLonWithAltitude const & RegionsSparseGraph::GetJunction(Segment const & segment,
|
||||
bool front) const
|
||||
routing::LatLonWithAltitude const & RegionsSparseGraph::GetJunction(Segment const & segment, bool front) const
|
||||
{
|
||||
auto const & data = GetDataById(segment.GetFeatureId());
|
||||
return segment.IsForward() == front ? data.m_end.m_point : data.m_start.m_point;
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace routing
|
||||
class RegionsSparseGraph
|
||||
{
|
||||
public:
|
||||
RegionsSparseGraph(CountryFileGetterFn const & countryFileGetter,
|
||||
std::shared_ptr<NumMwmIds> numMwmIds, DataSource & dataSource);
|
||||
RegionsSparseGraph(CountryFileGetterFn const & countryFileGetter, std::shared_ptr<NumMwmIds> numMwmIds,
|
||||
DataSource & dataSource);
|
||||
|
||||
// Loads data from mwm section.
|
||||
void LoadRegionsSparseGraph();
|
||||
@@ -27,8 +27,7 @@ public:
|
||||
std::optional<FakeEnding> GetFakeEnding(m2::PointD const & point) const;
|
||||
|
||||
using EdgeListT = SmallList<SegmentEdge>;
|
||||
void GetEdgeList(Segment const & segment, bool isOutgoing, EdgeListT & edges,
|
||||
ms::LatLon const & prevSegFront) const;
|
||||
void GetEdgeList(Segment const & segment, bool isOutgoing, EdgeListT & edges, ms::LatLon const & prevSegFront) const;
|
||||
|
||||
routing::LatLonWithAltitude const & GetJunction(Segment const & segment, bool front) const;
|
||||
|
||||
|
||||
@@ -50,19 +50,14 @@ RestrictionLoader::RestrictionLoader(MwmValue const & mwmValue, IndexGraph & gra
|
||||
|
||||
try
|
||||
{
|
||||
m_reader =
|
||||
std::make_unique<FilesContainerR::TReader>(mwmValue.m_cont.GetReader(RESTRICTIONS_FILE_TAG));
|
||||
m_reader = std::make_unique<FilesContainerR::TReader>(mwmValue.m_cont.GetReader(RESTRICTIONS_FILE_TAG));
|
||||
ReaderSource<FilesContainerR::TReader> src(*m_reader);
|
||||
m_header.Deserialize(src);
|
||||
|
||||
RestrictionVec restrictionsOnly;
|
||||
std::vector<RestrictionUTurn> restrictionsOnlyUTurn;
|
||||
RestrictionSerializer::Deserialize(m_header,
|
||||
m_restrictions /* restriction No, without no_u_turn */,
|
||||
restrictionsOnly,
|
||||
m_noUTurnRestrictions,
|
||||
restrictionsOnlyUTurn,
|
||||
src);
|
||||
RestrictionSerializer::Deserialize(m_header, m_restrictions /* restriction No, without no_u_turn */,
|
||||
restrictionsOnly, m_noUTurnRestrictions, restrictionsOnlyUTurn, src);
|
||||
|
||||
ConvertRestrictionsOnlyToNo(graph, restrictionsOnly, m_restrictions);
|
||||
ConvertRestrictionsOnlyUTurnToNo(graph, restrictionsOnlyUTurn, m_restrictions);
|
||||
@@ -70,8 +65,7 @@ RestrictionLoader::RestrictionLoader(MwmValue const & mwmValue, IndexGraph & gra
|
||||
catch (Reader::OpenException const & e)
|
||||
{
|
||||
m_header.Reset();
|
||||
LOG(LERROR,
|
||||
("File", m_countryFileName, "Error while reading", RESTRICTIONS_FILE_TAG, "section.", e.Msg()));
|
||||
LOG(LERROR, ("File", m_countryFileName, "Error while reading", RESTRICTIONS_FILE_TAG, "section.", e.Msg()));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@@ -94,10 +88,8 @@ std::vector<RestrictionUTurn> && RestrictionLoader::StealNoUTurnRestrictions()
|
||||
bool IsRestrictionFromRoads(IndexGraph const & graph, std::vector<uint32_t> const & restriction)
|
||||
{
|
||||
for (auto const & featureId : restriction)
|
||||
{
|
||||
if (!graph.IsRoad(featureId))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -112,8 +104,7 @@ bool IsRestrictionFromRoads(IndexGraph const & graph, std::vector<uint32_t> cons
|
||||
/// We create restrictionNo from features:
|
||||
/// featureId_1, ... , featureId_(M - 1), featureId_K
|
||||
/// where featureId_K - has common joint with featureId_(M - 1) and featureId_M.
|
||||
void ConvertRestrictionsOnlyToNo(IndexGraph const & graph,
|
||||
RestrictionVec const & restrictionsOnly,
|
||||
void ConvertRestrictionsOnlyToNo(IndexGraph const & graph, RestrictionVec const & restrictionsOnly,
|
||||
RestrictionVec & restrictionsNo)
|
||||
{
|
||||
for (std::vector<uint32_t> const & restriction : restrictionsOnly)
|
||||
@@ -129,8 +120,7 @@ void ConvertRestrictionsOnlyToNo(IndexGraph const & graph,
|
||||
auto const prevFeatureId = restriction[i - 1];
|
||||
|
||||
// Looking for a joint of an intersection of prev and cur features.
|
||||
Joint::Id const common =
|
||||
GetCommonEndJoint(graph.GetRoad(curFeatureId), graph.GetRoad(prevFeatureId));
|
||||
Joint::Id const common = GetCommonEndJoint(graph.GetRoad(curFeatureId), graph.GetRoad(prevFeatureId));
|
||||
|
||||
if (common == Joint::kInvalidId)
|
||||
break;
|
||||
@@ -139,21 +129,19 @@ void ConvertRestrictionsOnlyToNo(IndexGraph const & graph,
|
||||
commonFeatures.resize(i + 1);
|
||||
std::copy(restriction.begin(), restriction.begin() + i, commonFeatures.begin());
|
||||
|
||||
graph.ForEachPoint(common,
|
||||
[&](RoadPoint const & rp)
|
||||
{
|
||||
if (rp.GetFeatureId() != curFeatureId)
|
||||
{
|
||||
commonFeatures.back() = rp.GetFeatureId();
|
||||
restrictionsNo.emplace_back(commonFeatures);
|
||||
}
|
||||
});
|
||||
graph.ForEachPoint(common, [&](RoadPoint const & rp)
|
||||
{
|
||||
if (rp.GetFeatureId() != curFeatureId)
|
||||
{
|
||||
commonFeatures.back() = rp.GetFeatureId();
|
||||
restrictionsNo.emplace_back(commonFeatures);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertRestrictionsOnlyUTurnToNo(IndexGraph & graph,
|
||||
std::vector<RestrictionUTurn> const & restrictionsOnlyUTurn,
|
||||
void ConvertRestrictionsOnlyUTurnToNo(IndexGraph & graph, std::vector<RestrictionUTurn> const & restrictionsOnlyUTurn,
|
||||
RestrictionVec & restrictionsNo)
|
||||
{
|
||||
for (auto const & uTurnRestriction : restrictionsOnlyUTurn)
|
||||
@@ -164,21 +152,19 @@ void ConvertRestrictionsOnlyUTurnToNo(IndexGraph & graph,
|
||||
|
||||
uint32_t const n = graph.GetRoadGeometry(featureId).GetPointsCount();
|
||||
RoadJointIds const & joints = graph.GetRoad(uTurnRestriction.m_featureId);
|
||||
Joint::Id const joint = uTurnRestriction.m_viaIsFirstPoint ? joints.GetJointId(0)
|
||||
: joints.GetJointId(n - 1);
|
||||
Joint::Id const joint = uTurnRestriction.m_viaIsFirstPoint ? joints.GetJointId(0) : joints.GetJointId(n - 1);
|
||||
|
||||
if (joint == Joint::kInvalidId)
|
||||
continue;
|
||||
|
||||
graph.ForEachPoint(joint,
|
||||
[&](RoadPoint const & rp)
|
||||
{
|
||||
if (rp.GetFeatureId() != featureId)
|
||||
{
|
||||
std::vector<uint32_t> fromToRestriction = {featureId, rp.GetFeatureId()};
|
||||
restrictionsNo.emplace_back(std::move(fromToRestriction));
|
||||
}
|
||||
});
|
||||
graph.ForEachPoint(joint, [&](RoadPoint const & rp)
|
||||
{
|
||||
if (rp.GetFeatureId() != featureId)
|
||||
{
|
||||
std::vector<uint32_t> fromToRestriction = {featureId, rp.GetFeatureId()};
|
||||
restrictionsNo.emplace_back(std::move(fromToRestriction));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} // namespace routing
|
||||
|
||||
@@ -29,11 +29,9 @@ private:
|
||||
std::string const m_countryFileName;
|
||||
};
|
||||
|
||||
void ConvertRestrictionsOnlyToNo(IndexGraph const & graph,
|
||||
RestrictionVec const & restrictionsOnly,
|
||||
void ConvertRestrictionsOnlyToNo(IndexGraph const & graph, RestrictionVec const & restrictionsOnly,
|
||||
RestrictionVec & restrictionsNo);
|
||||
|
||||
void ConvertRestrictionsOnlyUTurnToNo(IndexGraph & graph,
|
||||
std::vector<RestrictionUTurn> const & restrictionsOnlyUTurn,
|
||||
void ConvertRestrictionsOnlyUTurnToNo(IndexGraph & graph, std::vector<RestrictionUTurn> const & restrictionsOnlyUTurn,
|
||||
RestrictionVec & restrictionsNo);
|
||||
} // namespace routing
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user