diff options
Diffstat (limited to 'map/traffic_manager.cpp')
-rw-r--r-- | map/traffic_manager.cpp | 122 |
1 files changed, 98 insertions, 24 deletions
diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index 6f6c91af2d..17007cabf1 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -6,6 +6,32 @@ #include "indexer/scales.hpp" +TrafficManager::TrafficManager(Index const & index, + GetMwmsByRectFn const & getMwmsByRectFn) + : m_isEnabled(true) //TODO: true is temporary + , m_index(index) + , m_getMwmsByRectFn(getMwmsByRectFn) + , m_isRunning(true) + , m_thread(&TrafficManager::ThreadRoutine, this) +{ + CHECK(m_getMwmsByRectFn != nullptr, ()); +} + +TrafficManager::~TrafficManager() +{ + { + lock_guard<mutex> lock(m_requestedMwmsLock); + m_isRunning = false; + } + m_condition.notify_one(); + m_thread.join(); +} + +void TrafficManager::SetEnabled(bool enabled) +{ + m_isEnabled = enabled; +} + void TrafficManager::SetDrapeEngine(ref_ptr<df::DrapeEngine> engine) { m_drapeEngine = engine; @@ -13,34 +39,27 @@ void TrafficManager::SetDrapeEngine(ref_ptr<df::DrapeEngine> engine) void TrafficManager::UpdateViewport(ScreenBase const & screen) { - // 1. Determine mwm's inside viewport. + if (!m_isEnabled) + return; - // 2. Request traffic for this mwm's. + // Request traffic. + auto mwms = m_getMwmsByRectFn(screen.ClipRect()); - // 3. Cache geometry for rendering if it's necessary. - //MwmSet::MwmId mwmId; - //if (m_mwmIds.find(mwmId) == m_mwmIds.end()) - //{ - // df::TrafficSegmentsGeometry geometry; - // traffic::TrafficInfo info; - // CalculateSegmentsGeometry(info, geometry); - // m_mwmIds.insert(mwmId); - // m_drapeEngine->CacheTrafficSegmentsGeometry(geometry); - //} - - // 4. Update traffic colors. - //df::TrafficSegmentsColoring coloring; - //traffic::TrafficInfo info; - //CalculateSegmentsColoring(info, coloring); - //m_drapeEngine->UpdateTraffic(coloring); - - // 5. Remove some mwm's from cache. + // TODO: request new mwms, update old ones by timer. + + for (auto const & mwm : mwms) + RequestTrafficData(mwm); + + // TODO: Remove some mwm's from cache. //MwmSet::MwmId mwmId; //m_drapeEngine->ClearTrafficCache(mwmId); } void TrafficManager::UpdateMyPosition(MyPosition const & myPosition) { + if (!m_isEnabled) + return; + // 1. Determine mwm's nearby "my position". // 2. Request traffic for this mwm's. @@ -71,16 +90,20 @@ void TrafficManager::CalculateSegmentsGeometry(traffic::TrafficInfo const & traf { m2::PolylineD polyline; ft.ForEachPoint([&polyline](m2::PointD const & pt) { polyline.Add(pt); }, kScale); - polylines[fid] = polyline; + if (polyline.GetSize() != 0) + polylines[fid] = polyline; } }; m_index.ReadFeatures(featureReader, features); for (auto const & c : trafficInfo.GetColoring()) { - output.push_back(make_pair(df::TrafficSegmentID(trafficInfo.GetMwmId(), c.first), - polylines[c.first.m_fid].ExtractSegment(c.first.m_idx, - c.first.m_dir == 1))); + auto it = polylines.find(c.first.m_fid); + if (it == polylines.end()) + continue; + bool const isReversed = (c.first.m_dir == traffic::TrafficInfo::RoadSegmentId::kReverseDirection); + output.emplace_back(df::TrafficSegmentID(trafficInfo.GetMwmId(), c.first), + it->second.ExtractSegment(c.first.m_idx, isReversed)); } } @@ -93,3 +116,54 @@ void TrafficManager::CalculateSegmentsColoring(traffic::TrafficInfo const & traf output.emplace_back(sid, c.second); } } + +void TrafficManager::ThreadRoutine() +{ + vector<MwmSet::MwmId> mwms; + while (WaitForRequest(mwms)) + { + for (auto const & mwm : mwms) + { + traffic::TrafficInfo info(mwm); + if (info.ReceiveTrafficData("Russia_Moscow.traff")) // TODO: temporary name + OnTrafficDataResponse(info); + else + LOG(LDEBUG, ("Traffic request failed. Mwm =", mwm)); + } + mwms.clear(); + } +} + +bool TrafficManager::WaitForRequest(vector<MwmSet::MwmId> & mwms) +{ + unique_lock<mutex> lock(m_requestedMwmsLock); + m_condition.wait(lock, [this] { return !m_isRunning || !m_requestedMwms.empty(); }); + if (!m_isRunning) + return false; + mwms.swap(m_requestedMwms); + return true; +} + +void TrafficManager::RequestTrafficData(MwmSet::MwmId const & mwmId) +{ + lock_guard<mutex> lock(m_requestedMwmsLock); + m_requestedMwms.push_back(mwmId); + m_condition.notify_one(); +} + +void TrafficManager::OnTrafficDataResponse(traffic::TrafficInfo const & info) +{ + // Cache geometry for rendering if it's necessary. + if (m_mwmIds.find(info.GetMwmId()) == m_mwmIds.end()) + { + df::TrafficSegmentsGeometry geometry; + CalculateSegmentsGeometry(info, geometry); + m_mwmIds.insert(info.GetMwmId()); + m_drapeEngine->CacheTrafficSegmentsGeometry(geometry); + } + + // Update traffic colors. + df::TrafficSegmentsColoring coloring; + CalculateSegmentsColoring(info, coloring); + m_drapeEngine->UpdateTraffic(coloring); +} |