forked from organicmaps/organicmaps
Requesting traffic info for mwm under current possition and near current possition.
This commit is contained in:
parent
657bd88190
commit
5a89f88c03
2 changed files with 117 additions and 73 deletions
|
@ -8,6 +8,8 @@
|
|||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/scales.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "3party/Alohalytics/src/alohalytics.h"
|
||||
|
@ -120,8 +122,10 @@ void TrafficManager::Clear()
|
|||
{
|
||||
m_currentCacheSizeBytes = 0;
|
||||
m_mwmCache.clear();
|
||||
m_lastMwmsByRect.clear();
|
||||
m_activeMwms.clear();
|
||||
m_lastDrapeMwmsByRect.clear();
|
||||
m_lastRoutingMwmsByRect.clear();
|
||||
m_activeDrapeMwms.clear();
|
||||
m_activeRoutingMwms.clear();
|
||||
m_requestedMwms.clear();
|
||||
}
|
||||
|
||||
|
@ -168,7 +172,8 @@ void TrafficManager::Invalidate()
|
|||
if (!IsEnabled())
|
||||
return;
|
||||
|
||||
m_lastMwmsByRect.clear();
|
||||
m_lastDrapeMwmsByRect.clear();
|
||||
m_lastRoutingMwmsByRect.clear();
|
||||
|
||||
if (m_currentModelView.second)
|
||||
UpdateViewport(m_currentModelView.first);
|
||||
|
@ -176,6 +181,44 @@ void TrafficManager::Invalidate()
|
|||
UpdateMyPosition(m_currentPosition.first);
|
||||
}
|
||||
|
||||
void TrafficManager::UpdateActiveMwms(m2::RectD const & rect,
|
||||
vector<MwmSet::MwmId> & lastMwmsByRect,
|
||||
set<MwmSet::MwmId> & activeMwms)
|
||||
{
|
||||
auto mwms = m_getMwmsByRectFn(rect);
|
||||
if (lastMwmsByRect == mwms)
|
||||
return;
|
||||
lastMwmsByRect = mwms;
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(m_mutex);
|
||||
activeMwms.clear();
|
||||
for (auto const & mwm : mwms)
|
||||
{
|
||||
if (mwm.IsAlive())
|
||||
activeMwms.insert(mwm);
|
||||
}
|
||||
RequestTrafficData();
|
||||
}
|
||||
}
|
||||
|
||||
void TrafficManager::UpdateMyPosition(MyPosition const & myPosition)
|
||||
{
|
||||
// Side of square around |myPosition|. Every mwm which is covered by the square
|
||||
// will get traffic info.
|
||||
double const kSquareSideM = 5000;
|
||||
m_currentPosition = {myPosition, true /* initialized */};
|
||||
|
||||
if (!IsEnabled() || IsInvalidState())
|
||||
return;
|
||||
|
||||
m2::RectD const rect = MercatorBounds::RectByCenterXYAndSizeInMeters(myPosition.m_position, kSquareSideM);
|
||||
// Request traffic.
|
||||
UpdateActiveMwms(rect, m_lastRoutingMwmsByRect, m_activeRoutingMwms);
|
||||
|
||||
// @TODO Do all routing stuff.
|
||||
}
|
||||
|
||||
void TrafficManager::UpdateViewport(ScreenBase const & screen)
|
||||
{
|
||||
m_currentModelView = {screen, true /* initialized */};
|
||||
|
@ -187,37 +230,7 @@ void TrafficManager::UpdateViewport(ScreenBase const & screen)
|
|||
return;
|
||||
|
||||
// Request traffic.
|
||||
auto mwms = m_getMwmsByRectFn(screen.ClipRect());
|
||||
if (m_lastMwmsByRect == mwms)
|
||||
return;
|
||||
m_lastMwmsByRect = mwms;
|
||||
|
||||
{
|
||||
lock_guard<mutex> lock(m_mutex);
|
||||
|
||||
m_activeMwms.clear();
|
||||
for (auto const & mwm : mwms)
|
||||
{
|
||||
if (mwm.IsAlive())
|
||||
m_activeMwms.insert(mwm);
|
||||
}
|
||||
|
||||
RequestTrafficData();
|
||||
}
|
||||
}
|
||||
|
||||
void TrafficManager::UpdateMyPosition(MyPosition const & myPosition)
|
||||
{
|
||||
m_currentPosition = {myPosition, true /* initialized */};
|
||||
|
||||
if (!IsEnabled() || IsInvalidState())
|
||||
return;
|
||||
|
||||
// 1. Determine mwm's nearby "my position".
|
||||
|
||||
// 2. Request traffic for this mwm's.
|
||||
|
||||
// 3. Do all routing stuff.
|
||||
UpdateActiveMwms(screen.ClipRect(), m_lastDrapeMwmsByRect, m_activeDrapeMwms);
|
||||
}
|
||||
|
||||
void TrafficManager::ThreadRoutine()
|
||||
|
@ -300,14 +313,16 @@ void TrafficManager::RequestTrafficData(MwmSet::MwmId const & mwmId, bool force)
|
|||
|
||||
void TrafficManager::RequestTrafficData()
|
||||
{
|
||||
if (m_activeMwms.empty() || !IsEnabled() || IsInvalidState())
|
||||
return;
|
||||
|
||||
for (auto const & mwmId : m_activeMwms)
|
||||
if ((m_activeDrapeMwms.empty() && m_activeRoutingMwms.empty())
|
||||
|| !IsEnabled() || IsInvalidState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ForEachActiveMwm([this](MwmSet::MwmId const & mwmId){
|
||||
ASSERT(mwmId.IsAlive(), ());
|
||||
RequestTrafficData(mwmId, false /* force */);
|
||||
}
|
||||
});
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
|
@ -325,7 +340,8 @@ void TrafficManager::OnTrafficRequestFailed(traffic::TrafficInfo && info)
|
|||
if (info.GetAvailability() == traffic::TrafficInfo::Availability::Unknown &&
|
||||
!it->second.m_isLoaded)
|
||||
{
|
||||
if (m_activeMwms.find(info.GetMwmId()) != m_activeMwms.end())
|
||||
if (m_activeDrapeMwms.find(info.GetMwmId()) != m_activeDrapeMwms.cend()
|
||||
|| m_activeRoutingMwms.find(info.GetMwmId()) != m_activeRoutingMwms.cend())
|
||||
{
|
||||
if (it->second.m_retriesCount < kMaxRetriesCount)
|
||||
RequestTrafficData(info.GetMwmId(), true /* force */);
|
||||
|
@ -376,9 +392,20 @@ void TrafficManager::OnTrafficDataResponse(traffic::TrafficInfo && info)
|
|||
}
|
||||
}
|
||||
|
||||
void TrafficManager::UniteActiveMwms(set<MwmSet::MwmId> & activeMwms) const
|
||||
{
|
||||
activeMwms.insert(m_activeDrapeMwms.cbegin(), m_activeDrapeMwms.cend());
|
||||
activeMwms.insert(m_activeRoutingMwms.cbegin(), m_activeRoutingMwms.cend());
|
||||
}
|
||||
|
||||
void TrafficManager::CheckCacheSize()
|
||||
{
|
||||
if (m_currentCacheSizeBytes > m_maxCacheSizeBytes && m_mwmCache.size() > m_activeMwms.size())
|
||||
// Calculating number of different active mwms.
|
||||
set<MwmSet::MwmId> activeMwms;
|
||||
UniteActiveMwms(activeMwms);
|
||||
size_t const activeMwmsSize = m_activeDrapeMwms.size();
|
||||
|
||||
if (m_currentCacheSizeBytes > m_maxCacheSizeBytes && m_mwmCache.size() > activeMwmsSize)
|
||||
{
|
||||
std::multimap<time_point<steady_clock>, MwmSet::MwmId> seenTimings;
|
||||
for (auto const & mwmInfo : m_mwmCache)
|
||||
|
@ -386,7 +413,7 @@ void TrafficManager::CheckCacheSize()
|
|||
|
||||
auto itSeen = seenTimings.begin();
|
||||
while (m_currentCacheSizeBytes > m_maxCacheSizeBytes &&
|
||||
m_mwmCache.size() > m_activeMwms.size())
|
||||
m_mwmCache.size() > activeMwmsSize)
|
||||
{
|
||||
ClearCache(itSeen->second);
|
||||
++itSeen;
|
||||
|
@ -438,7 +465,7 @@ void TrafficManager::UpdateState()
|
|||
bool expiredData = false;
|
||||
bool noData = false;
|
||||
|
||||
for (auto const & mwmId : m_activeMwms)
|
||||
ForEachActiveMwm([&](MwmSet::MwmId const & mwmId)
|
||||
{
|
||||
auto it = m_mwmCache.find(mwmId);
|
||||
ASSERT(it != m_mwmCache.end(), ());
|
||||
|
@ -464,7 +491,7 @@ void TrafficManager::UpdateState()
|
|||
{
|
||||
networkError = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (networkError || maxPassedTime >= kNetworkErrorTimeout)
|
||||
ChangeState(TrafficState::NetworkError);
|
||||
|
|
|
@ -86,34 +86,10 @@ private:
|
|||
void OnTrafficDataResponse(traffic::TrafficInfo && info);
|
||||
void OnTrafficRequestFailed(traffic::TrafficInfo && info);
|
||||
|
||||
void UpdateActiveMwms(m2::RectD const & rect, vector<MwmSet::MwmId> & lastMwmsByRect,
|
||||
set<MwmSet::MwmId> & activeMwms);
|
||||
|
||||
private:
|
||||
// This is a group of methods that haven't their own synchronization inside.
|
||||
void RequestTrafficData();
|
||||
void RequestTrafficData(MwmSet::MwmId const & mwmId, bool force);
|
||||
|
||||
void Clear();
|
||||
void ClearCache(MwmSet::MwmId const & mwmId);
|
||||
void CheckCacheSize();
|
||||
|
||||
void UpdateState();
|
||||
void ChangeState(TrafficState newState);
|
||||
|
||||
bool IsInvalidState() const;
|
||||
bool IsEnabled() const;
|
||||
|
||||
GetMwmsByRectFn m_getMwmsByRectFn;
|
||||
traffic::TrafficObserver & m_observer;
|
||||
|
||||
ref_ptr<df::DrapeEngine> m_drapeEngine;
|
||||
atomic<int64_t> m_currentDataVersion;
|
||||
|
||||
// These fields have a flag of their initialization.
|
||||
pair<MyPosition, bool> m_currentPosition = {MyPosition(), false};
|
||||
pair<ScreenBase, bool> m_currentModelView = {ScreenBase(), false};
|
||||
|
||||
atomic<TrafficState> m_state;
|
||||
TrafficStateChangedFn m_onStateChangedFn;
|
||||
|
||||
struct CacheEntry
|
||||
{
|
||||
CacheEntry();
|
||||
|
@ -132,6 +108,44 @@ private:
|
|||
traffic::TrafficInfo::Availability m_lastAvailability;
|
||||
};
|
||||
|
||||
// This is a group of methods that haven't their own synchronization inside.
|
||||
void RequestTrafficData();
|
||||
void RequestTrafficData(MwmSet::MwmId const & mwmId, bool force);
|
||||
|
||||
void Clear();
|
||||
void ClearCache(MwmSet::MwmId const & mwmId);
|
||||
void CheckCacheSize();
|
||||
|
||||
void UpdateState();
|
||||
void ChangeState(TrafficState newState);
|
||||
|
||||
bool IsInvalidState() const;
|
||||
bool IsEnabled() const;
|
||||
|
||||
void UniteActiveMwms(set<MwmSet::MwmId> & activeMwms) const;
|
||||
|
||||
template <class F>
|
||||
void ForEachActiveMwm(F && f) const
|
||||
{
|
||||
set<MwmSet::MwmId> activeMwms;
|
||||
UniteActiveMwms(activeMwms);
|
||||
for (MwmSet::MwmId const & mwmId : activeMwms)
|
||||
f(mwmId);
|
||||
}
|
||||
|
||||
GetMwmsByRectFn m_getMwmsByRectFn;
|
||||
traffic::TrafficObserver & m_observer;
|
||||
|
||||
ref_ptr<df::DrapeEngine> m_drapeEngine;
|
||||
atomic<int64_t> m_currentDataVersion;
|
||||
|
||||
// These fields have a flag of their initialization.
|
||||
pair<MyPosition, bool> m_currentPosition = {MyPosition(), false};
|
||||
pair<ScreenBase, bool> m_currentModelView = {ScreenBase(), false};
|
||||
|
||||
atomic<TrafficState> m_state;
|
||||
TrafficStateChangedFn m_onStateChangedFn;
|
||||
|
||||
size_t m_maxCacheSizeBytes;
|
||||
size_t m_currentCacheSizeBytes = 0;
|
||||
|
||||
|
@ -140,8 +154,11 @@ private:
|
|||
bool m_isRunning;
|
||||
condition_variable m_condition;
|
||||
|
||||
vector<MwmSet::MwmId> m_lastMwmsByRect;
|
||||
set<MwmSet::MwmId> m_activeMwms;
|
||||
vector<MwmSet::MwmId> m_lastDrapeMwmsByRect;
|
||||
set<MwmSet::MwmId> m_activeDrapeMwms;
|
||||
vector<MwmSet::MwmId> m_lastRoutingMwmsByRect;
|
||||
set<MwmSet::MwmId> m_activeRoutingMwms;
|
||||
|
||||
// The ETag or entity tag is part of HTTP, the protocol for the World Wide Web.
|
||||
// It is one of several mechanisms that HTTP provides for web cache validation,
|
||||
// which allows a client to make conditional requests.
|
||||
|
|
Loading…
Add table
Reference in a new issue