diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 98d8bebcd6..7bf86d1522 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -1731,13 +1731,15 @@ Java_com_mapswithme_maps_Framework_nativeIsTransitSchemeEnabled(JNIEnv * env, jc JNIEXPORT void JNICALL Java_com_mapswithme_maps_Framework_nativeSetIsolinesLayerEnabled(JNIEnv * env, jclass, jboolean enabled) { - frm()->EnableIsolines(static_cast(enabled)); + auto const isolinesEnabled = static_cast(enabled); + frm()->GetIsolinesManager().SetEnabled(isolinesEnabled); + frm()->SaveIsolonesEnabled(isolinesEnabled); } JNIEXPORT jboolean JNICALL Java_com_mapswithme_maps_Framework_nativeIsIsolinesLayerEnabled(JNIEnv * env, jclass) { - return static_cast(frm()->IsolinesEnabled()); + return static_cast(frm()->LoadIsolinesEnabled()); } JNIEXPORT void JNICALL diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index 2201de465a..51f012aaf1 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -35,6 +35,7 @@ BackendRenderer::BackendRenderer(Params && params) , m_model(params.m_model) , m_readManager(make_unique_dp(params.m_commutator, m_model, params.m_allow3dBuildings, params.m_trafficEnabled, + params.m_isolinesEnabled, std::move(params.m_isUGCFn))) , m_transitBuilder(make_unique_dp( std::bind(&BackendRenderer::FlushTransitRenderData, this, _1))) @@ -520,6 +521,16 @@ void BackendRenderer::AcceptMessage(ref_ptr message) MessagePriority::Normal); break; } + case Message::Type::EnableIsolines: + { + ref_ptr msg = message; + m_readManager->SetIsolinesEnabled(msg->IsEnabled()); + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(msg->IsEnabled()), + MessagePriority::Normal); + break; + } + case Message::Type::DrapeApiAddLines: { ref_ptr msg = message; diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp index 247bc77366..10f4d142e6 100644 --- a/drape_frontend/backend_renderer.hpp +++ b/drape_frontend/backend_renderer.hpp @@ -44,7 +44,7 @@ public: ref_ptr factory, ref_ptr texMng, MapDataProvider const & model, TUpdateCurrentCountryFn const & updateCurrentCountryFn, ref_ptr requestedTiles, bool allow3dBuildings, bool trafficEnabled, - bool simplifiedTrafficColors, TIsUGCFn && isUGCFn, + bool isolinesEnabled, bool simplifiedTrafficColors, TIsUGCFn && isUGCFn, OnGraphicsContextInitialized const & onGraphicsContextInitialized) : BaseRenderer::Params(apiVersion, commutator, factory, texMng, onGraphicsContextInitialized) , m_model(model) @@ -52,6 +52,7 @@ public: , m_requestedTiles(requestedTiles) , m_allow3dBuildings(allow3dBuildings) , m_trafficEnabled(trafficEnabled) + , m_isolinesEnabled(isolinesEnabled) , m_simplifiedTrafficColors(simplifiedTrafficColors) , m_isUGCFn(std::move(isUGCFn)) {} @@ -61,6 +62,7 @@ public: ref_ptr m_requestedTiles; bool m_allow3dBuildings; bool m_trafficEnabled; + bool m_isolinesEnabled; bool m_simplifiedTrafficColors; TIsUGCFn m_isUGCFn; }; diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index e5cdf41a65..e8c7ce0213 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -102,6 +102,7 @@ DrapeEngine::DrapeEngine(Params && params) make_ref(m_requestedTiles), params.m_allow3dBuildings, params.m_trafficEnabled, + params.m_isolinesEnabled, params.m_simplifiedTrafficColors, std::move(params.m_isUGCFn), params.m_onGraphicsContextInitialized); @@ -805,6 +806,13 @@ void DrapeEngine::UpdateTransitScheme(TransitDisplayInfos && transitDisplayInfos MessagePriority::Normal); } +void DrapeEngine::EnableIsolines(bool enable) +{ + m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(enable), + MessagePriority::Normal); +} + void DrapeEngine::SetFontScaleFactor(double scaleFactor) { double const kMinScaleFactor = 0.5; diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 75551ec837..1aa29b91cd 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -63,6 +63,7 @@ public: location::TMyPositionModeChanged && myPositionModeChanged, bool allow3dBuildings, bool trafficEnabled, + bool isolinesEnabled, bool blockTapEvents, bool showChoosePositionMark, std::vector && boundAreaTriangles, @@ -84,6 +85,7 @@ public: , m_myPositionModeChanged(std::move(myPositionModeChanged)) , m_allow3dBuildings(allow3dBuildings) , m_trafficEnabled(trafficEnabled) + , m_isolinesEnabled(isolinesEnabled) , m_blockTapEvents(blockTapEvents) , m_showChoosePositionMark(showChoosePositionMark) , m_boundAreaTriangles(std::move(boundAreaTriangles)) @@ -107,6 +109,7 @@ public: location::TMyPositionModeChanged m_myPositionModeChanged; bool m_allow3dBuildings; bool m_trafficEnabled; + bool m_isolinesEnabled; bool m_blockTapEvents; bool m_showChoosePositionMark; std::vector m_boundAreaTriangles; @@ -222,6 +225,8 @@ public: void ClearTransitSchemeCache(MwmSet::MwmId const & mwmId); void ClearAllTransitSchemeCache(); + void EnableIsolines(bool enable); + void SetFontScaleFactor(double scaleFactor); void RunScenario(ScenarioManager::ScenarioData && scenarioData, diff --git a/drape_frontend/engine_context.cpp b/drape_frontend/engine_context.cpp index 0c359e9d6c..2fcdabf5da 100644 --- a/drape_frontend/engine_context.cpp +++ b/drape_frontend/engine_context.cpp @@ -14,6 +14,7 @@ EngineContext::EngineContext(TileKey tileKey, CustomFeaturesContextWeakPtr customFeaturesContext, bool is3dBuildingsEnabled, bool isTrafficEnabled, + bool isolinesEnabled, int displacementMode, TIsUGCFn const & isUGCFn) : m_tileKey(tileKey) @@ -23,6 +24,7 @@ EngineContext::EngineContext(TileKey tileKey, , m_customFeaturesContext(customFeaturesContext) , m_3dBuildingsEnabled(is3dBuildingsEnabled) , m_trafficEnabled(isTrafficEnabled) + , m_isolinesEnabled(isolinesEnabled) , m_displacementMode(displacementMode) , m_isUGCFn(isUGCFn) {} diff --git a/drape_frontend/engine_context.hpp b/drape_frontend/engine_context.hpp index 7dfd19e27f..363bd7c7f1 100644 --- a/drape_frontend/engine_context.hpp +++ b/drape_frontend/engine_context.hpp @@ -32,12 +32,14 @@ public: CustomFeaturesContextWeakPtr customFeaturesContext, bool is3dBuildingsEnabled, bool isTrafficEnabled, + bool isolinesEnabled, int displacementMode, TIsUGCFn const & isUGCFn); TileKey const & GetTileKey() const { return m_tileKey; } bool Is3dBuildingsEnabled() const { return m_3dBuildingsEnabled; } bool IsTrafficEnabled() const { return m_trafficEnabled; } + bool IsolinesEnabled() const { return m_isolinesEnabled; } bool IsUGC(FeatureID const & fid) { return m_isUGCFn ? m_isUGCFn(fid) : false; } int GetDisplacementMode() const { return m_displacementMode; } CustomFeaturesContextWeakPtr GetCustomFeaturesContext() const { return m_customFeaturesContext; } @@ -60,6 +62,7 @@ private: CustomFeaturesContextWeakPtr m_customFeaturesContext; bool m_3dBuildingsEnabled; bool m_trafficEnabled; + bool m_isolinesEnabled; int m_displacementMode; TIsUGCFn m_isUGCFn; }; diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 1ff7f0c9a6..2cacd92866 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -921,6 +921,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) case Message::Type::SetDisplacementMode: case Message::Type::UpdateMetalines: case Message::Type::EnableUGCRendering: + case Message::Type::EnableIsolines: { m_forceUpdateScene = true; break; diff --git a/drape_frontend/message.cpp b/drape_frontend/message.cpp index 310fe45feb..5cc8792a8b 100644 --- a/drape_frontend/message.cpp +++ b/drape_frontend/message.cpp @@ -101,6 +101,7 @@ std::string DebugPrint(Message::Type msgType) case Message::Type::ShowDebugInfo: return "ShowDebugInfo"; case Message::Type::NotifyRenderThread: return "NotifyRenderThread"; case Message::Type::NotifyGraphicsReady: return "NotifyGraphicsReady"; + case Message::Type::EnableIsolines: return "EnableIsolines"; } ASSERT(false, ("Unknown message type.")); return "Unknown type"; diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index 481700c785..96b632c518 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -102,6 +102,7 @@ public: ShowDebugInfo, NotifyRenderThread, NotifyGraphicsReady, + EnableIsolines, }; virtual ~Message() = default; diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index ad15a36688..25db51fc10 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -1118,6 +1118,21 @@ private: bool const m_isSimplified; }; +class EnableIsolinesMessage : public Message +{ +public: + explicit EnableIsolinesMessage(bool isEnabled) + : m_isEnabled(isEnabled) + {} + + Type GetType() const override { return Type::EnableIsolines; } + + bool IsEnabled() { return m_isEnabled; } + +private: + bool m_isEnabled = false; +}; + class EnableTransitSchemeMessage : public Message { public: diff --git a/drape_frontend/read_manager.cpp b/drape_frontend/read_manager.cpp index ca2a9f51be..74f3fae3fd 100755 --- a/drape_frontend/read_manager.cpp +++ b/drape_frontend/read_manager.cpp @@ -44,12 +44,14 @@ bool ReadManager::LessByTileInfo::operator()(std::shared_ptr const & l } ReadManager::ReadManager(ref_ptr commutator, MapDataProvider & model, - bool allow3dBuildings, bool trafficEnabled, EngineContext::TIsUGCFn && isUGCFn) + bool allow3dBuildings, bool trafficEnabled, bool isolinesEnabled, + EngineContext::TIsUGCFn && isUGCFn) : m_commutator(commutator) , m_model(model) , m_have3dBuildings(false) , m_allow3dBuildings(allow3dBuildings) , m_trafficEnabled(trafficEnabled) + , m_isolinesEnabled(isolinesEnabled) , m_displacementMode(dp::displacement::kDefaultMode) , m_modeChanged(false) , m_ugcRenderingEnabled(false) @@ -233,11 +235,13 @@ void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey, ref_ptr metalineMng) { ASSERT(m_pool != nullptr, ()); - auto context = make_unique_dp(TileKey(tileKey, m_generationCounter, m_userMarksGenerationCounter), + auto context = make_unique_dp(TileKey(tileKey, m_generationCounter, + m_userMarksGenerationCounter), m_commutator, texMng, metalineMng, m_customFeaturesContext, m_have3dBuildings && m_allow3dBuildings, - m_trafficEnabled, m_displacementMode, + m_trafficEnabled, m_isolinesEnabled, + m_displacementMode, m_ugcRenderingEnabled ? m_isUGCFn : nullptr); std::shared_ptr tileInfo = std::make_shared(std::move(context)); m_tileInfos.insert(tileInfo); @@ -331,6 +335,15 @@ void ReadManager::SetTrafficEnabled(bool trafficEnabled) } } +void ReadManager::SetIsolinesEnabled(bool isolinesEnabled) +{ + if (m_isolinesEnabled != isolinesEnabled) + { + m_modeChanged = true; + m_isolinesEnabled = isolinesEnabled; + } +} + void ReadManager::SetDisplacementMode(int displacementMode) { if (m_displacementMode != displacementMode) diff --git a/drape_frontend/read_manager.hpp b/drape_frontend/read_manager.hpp index 58c3cc687f..ef98ca432b 100755 --- a/drape_frontend/read_manager.hpp +++ b/drape_frontend/read_manager.hpp @@ -33,7 +33,8 @@ class ReadManager { public: ReadManager(ref_ptr commutator, MapDataProvider & model, - bool allow3dBuildings, bool trafficEnabled, EngineContext::TIsUGCFn && isUGCFn); + bool allow3dBuildings, bool trafficEnabled, bool isolinesEnabled, + EngineContext::TIsUGCFn && isUGCFn); void Start(); void Stop(); @@ -50,6 +51,7 @@ public: void Allow3dBuildings(bool allow3dBuildings); void SetTrafficEnabled(bool trafficEnabled); + void SetIsolinesEnabled(bool isolinesEnabled); void SetDisplacementMode(int displacementMode); @@ -81,6 +83,7 @@ private: bool m_have3dBuildings; bool m_allow3dBuildings; bool m_trafficEnabled; + bool m_isolinesEnabled; int m_displacementMode; bool m_modeChanged; bool m_ugcRenderingEnabled; diff --git a/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.mm b/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.mm index b70be6eae8..cbe86504a4 100644 --- a/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.mm +++ b/iphone/CoreApi/CoreApi/Traffic/MWMMapOverlayManager.mm @@ -97,7 +97,7 @@ } + (BOOL)isoLinesEnabled { - return GetFramework().IsolinesEnabled(); + return GetFramework().LoadIsolinesEnabled(); } + (void)setTrafficEnabled:(BOOL)enable { @@ -128,7 +128,10 @@ [self setTransitEnabled:false]; } - GetFramework().EnableIsolines(enable); + auto &f = GetFramework(); + f.GetIsolinesManager().SetEnabled(enable); + f.SaveIsolonesEnabled(enable); + for (id observer in [MWMMapOverlayManager manager].observers) { if ([observer respondsToSelector:@selector(onIsoLinesStateUpdated)]) { [observer onIsoLinesStateUpdated]; diff --git a/map/CMakeLists.txt b/map/CMakeLists.txt index 9dd125bca2..bfbda0806d 100644 --- a/map/CMakeLists.txt +++ b/map/CMakeLists.txt @@ -69,6 +69,8 @@ set( gps_track.hpp gps_tracker.cpp gps_tracker.hpp + isolines_manager.cpp + isolines_manager.hpp local_ads_manager.cpp local_ads_manager.hpp local_ads_mark.cpp diff --git a/map/framework.cpp b/map/framework.cpp index d1d1afe68d..a4095af258 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -313,6 +313,11 @@ TransitReadManager & Framework::GetTransitManager() return m_transitManager; } +IsolinesManager & Framework::GetIsolinesManager() +{ + return m_isolinesManager; +} + void Framework::OnUserPositionChanged(m2::PointD const & position, bool hasPosition) { GetBookmarkManager().MyPositionMark().SetUserPosition(position, hasPosition); @@ -339,6 +344,7 @@ void Framework::OnViewportChanged(ScreenBase const & screen) m_trafficManager.UpdateViewport(m_currentModelView); m_localAdsManager.UpdateViewport(m_currentModelView); m_transitManager.UpdateViewport(m_currentModelView); + m_isolinesManager.UpdateViewport(m_currentModelView); if (m_viewportChangedFn != nullptr) m_viewportChangedFn(screen); @@ -356,6 +362,8 @@ Framework::Framework(FrameworkParams const & params) return m_featuresFetcher.ReadFeatures(fn, features); }, bind(&Framework::GetMwmsByRect, this, _1, false /* rough */)) + , m_isolinesManager(m_featuresFetcher.GetDataSource(), + bind(&Framework::GetMwmsByRect, this, _1, false /* rough */)) , m_routingManager( RoutingManager::Callbacks( [this]() -> DataSource & { return m_featuresFetcher.GetDataSource(); }, @@ -498,6 +506,8 @@ Framework::Framework(FrameworkParams const & params) m_trafficManager.SetSimplifiedColorScheme(LoadTrafficSimplifiedColors()); m_trafficManager.SetEnabled(LoadTrafficEnabled()); + m_isolinesManager.SetEnabled(LoadIsolinesEnabled()); + m_adsEngine = make_unique(); InitTransliteration(); @@ -625,6 +635,7 @@ void Framework::OnCountryFileDownloaded(storage::CountryId const & countryId, } m_trafficManager.Invalidate(); m_transitManager.Invalidate(); + m_isolinesManager.Invalidate(); m_localAdsManager.OnDownloadCountry(countryId); InvalidateRect(rect); GetSearchAPI().ClearCaches(); @@ -662,6 +673,7 @@ void Framework::OnMapDeregistered(platform::LocalCountryFile const & localFile) { m_localAdsManager.OnMwmDeregistered(localFile); m_transitManager.OnMwmDeregistered(localFile); + m_isolinesManager.OnMwmDeregistered(localFile); m_trafficManager.OnMwmDeregistered(localFile); m_popularityLoader.OnMwmDeregistered(localFile); @@ -1872,6 +1884,7 @@ void Framework::CreateDrapeEngine(ref_ptr contextFac bool const isAutozoomEnabled = LoadAutoZoom(); bool const trafficEnabled = m_trafficManager.IsEnabled(); + auto const isolinesEnabled = m_isolinesManager.IsEnabled(); bool const simplifiedTrafficColors = m_trafficManager.HasSimplifiedColorScheme(); double const fontsScaleFactor = LoadLargeFontsSize() ? kLargeFontsScaleFactor : 1.0; @@ -1882,7 +1895,7 @@ void Framework::CreateDrapeEngine(ref_ptr contextFac move(isCountryLoadedByNameFn), move(updateCurrentCountryFn)), params.m_hints, params.m_visualScale, fontsScaleFactor, move(params.m_widgetsInitInfo), make_pair(params.m_initialMyPositionState, params.m_hasMyPositionState), - move(myPositionModeChangedFn), allow3dBuildings, trafficEnabled, + move(myPositionModeChangedFn), allow3dBuildings, trafficEnabled, isolinesEnabled, params.m_isChoosePositionMode, params.m_isChoosePositionMode, GetSelectedFeatureTriangles(), m_routingManager.IsRoutingActive() && m_routingManager.IsRoutingFollowing(), isAutozoomEnabled, simplifiedTrafficColors, move(overlaysShowStatsFn), move(isUGCFn), @@ -1928,12 +1941,13 @@ void Framework::CreateDrapeEngine(ref_ptr contextFac m_routingManager.SetDrapeEngine(make_ref(m_drapeEngine), allow3d); m_trafficManager.SetDrapeEngine(make_ref(m_drapeEngine)); m_transitManager.SetDrapeEngine(make_ref(m_drapeEngine)); + m_isolinesManager.SetDrapeEngine(make_ref(m_drapeEngine)); m_localAdsManager.SetDrapeEngine(make_ref(m_drapeEngine)); m_searchMarks.SetDrapeEngine(make_ref(m_drapeEngine)); InvalidateUserMarks(); - bool const transitSchemeEnabled = LoadTransitSchemeEnabled(); + auto const transitSchemeEnabled = LoadTransitSchemeEnabled(); m_transitManager.EnableTransitSchemeMode(transitSchemeEnabled); // Show debug info if it's enabled in the config. @@ -1961,6 +1975,7 @@ void Framework::OnRecoverSurface(int width, int height, bool recreateContextDepe m_trafficManager.OnRecoverSurface(); m_transitManager.Invalidate(); + m_isolinesManager.Invalidate(); m_localAdsManager.Invalidate(); } @@ -1994,6 +2009,7 @@ void Framework::DestroyDrapeEngine() m_routingManager.SetDrapeEngine(nullptr, false); m_trafficManager.SetDrapeEngine(nullptr); m_transitManager.SetDrapeEngine(nullptr); + m_isolinesManager.SetDrapeEngine(nullptr); m_localAdsManager.SetDrapeEngine(nullptr); m_searchMarks.SetDrapeEngine(nullptr); GetBookmarkManager().SetDrapeEngine(nullptr); @@ -2846,13 +2862,7 @@ void Framework::SaveTransitSchemeEnabled(bool enabled) settings::Set(kTransitSchemeEnabledKey, enabled); } -void Framework::EnableIsolines(bool enable) -{ - // TODO(darina): Implement. - settings::Set(kIsolinesEnabledKey, enable); -} - -bool Framework::IsolinesEnabled() const +bool Framework::LoadIsolinesEnabled() { bool enabled; if (!settings::Get(kIsolinesEnabledKey, enabled)) @@ -2860,6 +2870,11 @@ bool Framework::IsolinesEnabled() const return enabled; } +void Framework::SaveIsolonesEnabled(bool enabled) +{ + settings::Set(kIsolinesEnabledKey, enabled); +} + void Framework::EnableChoosePositionMode(bool enable, bool enableBounds, bool applyPosition, m2::PointD const & position) { @@ -2984,6 +2999,16 @@ bool Framework::ParseDrapeDebugCommand(string const & query) m_transitManager.EnableTransitSchemeMode(false /* enable */); return true; } + if (query == "?isolines") + { + m_isolinesManager.SetEnabled(true /* enable */); + return true; + } + if (query == "?no-isolines") + { + m_isolinesManager.SetEnabled(false /* enable */); + return true; + } if (query == "?debug-info") { m_drapeEngine->ShowDebugInfo(true /* shown */); diff --git a/map/framework.hpp b/map/framework.hpp index 0fc2c45440..cf4ec1e855 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -9,6 +9,7 @@ #include "map/discovery/discovery_manager.hpp" #include "map/displacement_mode_manager.hpp" #include "map/features_fetcher.hpp" +#include "map/isolines_manager.hpp" #include "map/local_ads_manager.hpp" #include "map/mwm_url.hpp" #include "map/notifications/notification_manager.hpp" @@ -238,6 +239,7 @@ protected: power_management::PowerManager m_powerManager; TransitReadManager m_transitManager; + IsolinesManager m_isolinesManager; // Note. |m_routingManager| should be declared before |m_trafficManager| RoutingManager m_routingManager; @@ -759,6 +761,8 @@ public: TransitReadManager & GetTransitManager(); + IsolinesManager & GetIsolinesManager(); + bool LoadTrafficEnabled(); void SaveTrafficEnabled(bool trafficEnabled); @@ -768,8 +772,8 @@ public: bool LoadTransitSchemeEnabled(); void SaveTransitSchemeEnabled(bool enabled); - void EnableIsolines(bool enable); - bool IsolinesEnabled() const; + bool LoadIsolinesEnabled(); + void SaveIsolonesEnabled(bool enabled); dp::ApiVersion LoadPreferredGraphicsAPI(); void SavePreferredGraphicsAPI(dp::ApiVersion apiVersion); diff --git a/map/isolines_manager.cpp b/map/isolines_manager.cpp new file mode 100644 index 0000000000..8bfa4981cf --- /dev/null +++ b/map/isolines_manager.cpp @@ -0,0 +1,165 @@ +#include "map/isolines_manager.hpp" + +// TODO: Uncomment later. +//#include "generator/isolines_info.hpp" + +#include "drape_frontend/drape_engine.hpp" +#include "drape_frontend/visual_params.hpp" + +#include "base/assert.hpp" +#include "base/logging.hpp" + +int constexpr kMinIsolinesZoom = 11; + +// TODO: Update value. +int64_t constexpr kMinDataVersion = 0; + +IsolinesManager::IsolinesManager(DataSource & dataSource, GetMwmsByRectFn const & getMwmsByRectFn) + : m_dataSource(dataSource) + , m_getMwmsByRectFn(getMwmsByRectFn) +{ + CHECK(m_getMwmsByRectFn != nullptr, ()); +} + +void IsolinesManager::SetStateListener(IsolinesStateChangedFn const & onStateChangedFn) +{ + m_onStateChangedFn = onStateChangedFn; +} + +void IsolinesManager::ChangeState(IsolinesState newState) +{ + if (m_state == newState) + return; + m_state = newState; + if (m_onStateChangedFn != nullptr) + m_onStateChangedFn(newState); +} + +void IsolinesManager::SetDrapeEngine(ref_ptr engine) +{ + m_drapeEngine.Set(engine); +} + +void IsolinesManager::SetEnabled(bool enabled) +{ + ChangeState(enabled ? IsolinesState::Enabled : IsolinesState::Disabled); + m_drapeEngine.SafeCall(&df::DrapeEngine::EnableIsolines, enabled); + if (enabled) + { + Invalidate(); + } + else + { + m_lastMwms.clear(); + m_mwmCache.clear(); + } +} + +bool IsolinesManager::IsEnabled() const +{ + return m_state != IsolinesState::Disabled; +} + +void IsolinesManager::UpdateViewport(ScreenBase const & screen) +{ + m_currentModelView.reset(screen); + if (!IsEnabled()) + return; + + if (df::GetZoomLevel(screen.GetScale()) < kMinIsolinesZoom) + { + ChangeState(IsolinesState::Enabled); + return; + } + + auto mwms = m_getMwmsByRectFn(screen.ClipRect()); + if (m_lastMwms == mwms) + return; + m_lastMwms = std::move(mwms); + for (auto const & mwmId : m_lastMwms) + { + if (!mwmId.IsAlive()) + continue; + auto it = m_mwmCache.find(mwmId); + if (it == m_mwmCache.end()) + { + Availability status = Availability::NoData; + if (mwmId.GetInfo()->GetVersion() < kMinDataVersion) + { + status = Availability::ExpiredData; + } + else + { + // TODO: Uncomment later. + //isolines::IsolinesInfo info; + //if (isolines::LoadIsolinesInfo(m_dataSource, mwmId, info)) + //{ + // LOG(LINFO, ("Isolines min altitude", info.m_minAltitude, + // "max altitude", info.m_maxAltitude, "altitude step", info.m_altStep)); + // status = Availability::Available; + //} + } + m_mwmCache.insert(std::make_pair(mwmId, status)); + } + } + UpdateState(); +} + +void IsolinesManager::UpdateState() +{ + bool available = false; + bool expired = false; + bool noData = false; + for (auto const & mwmId : m_lastMwms) + { + if (!mwmId.IsAlive()) + continue; + auto const it = m_mwmCache.find(mwmId); + CHECK(it != m_mwmCache.end(), ()); + switch (it->second) + { + case Availability::Available: available = true; break; + case Availability::ExpiredData: expired = true; break; + case Availability::NoData: noData = true; break; + } + } + + if (expired) + ChangeState(IsolinesState::ExpiredData); + else if (!available && noData) + ChangeState(IsolinesState::NoData); + ChangeState(IsolinesState::Enabled); +} + +void IsolinesManager::Invalidate() +{ + if (!IsEnabled()) + return; + m_lastMwms.clear(); + if (m_currentModelView) + UpdateViewport(m_currentModelView.get()); +} + +void IsolinesManager::OnMwmDeregistered(platform::LocalCountryFile const & countryFile) +{ + for (auto it = m_mwmCache.begin(); it != m_mwmCache.end(); ++it) + { + if (it->first.IsDeregistered(countryFile)) + { + m_mwmCache.erase(it); + break; + } + } +} + +std::string DebugPrint(IsolinesManager::IsolinesState state) +{ + switch (state) + { + case IsolinesManager::IsolinesState::Disabled: return "Disabled"; + case IsolinesManager::IsolinesState::Enabled: return "Enabled"; + case IsolinesManager::IsolinesState::ExpiredData: return "ExpiredData"; + case IsolinesManager::IsolinesState::NoData: return "NoData"; + } + UNREACHABLE(); +} diff --git a/map/isolines_manager.hpp b/map/isolines_manager.hpp new file mode 100644 index 0000000000..1813c94061 --- /dev/null +++ b/map/isolines_manager.hpp @@ -0,0 +1,72 @@ +#pragma once + +#include "drape_frontend/drape_engine_safe_ptr.hpp" + +#include "indexer/data_source.hpp" +#include "indexer/mwm_set.hpp" + +#include "platform/local_country_file.hpp" + +#include "geometry/rect2d.hpp" +#include "geometry/screenbase.hpp" + +#include +#include +#include +#include + +#include + +class IsolinesManager final +{ +public: + enum class IsolinesState + { + Disabled, + Enabled, + ExpiredData, + NoData + }; + + using IsolinesStateChangedFn = std::function; + using GetMwmsByRectFn = std::function(m2::RectD const &)>; + + IsolinesManager(DataSource & dataSource, GetMwmsByRectFn const & getMwmsByRectFn); + + void SetStateListener(IsolinesStateChangedFn const & onStateChangedFn); + void SetDrapeEngine(ref_ptr engine); + + void SetEnabled(bool enabled); + bool IsEnabled() const; + + void UpdateViewport(ScreenBase const & screen); + void Invalidate(); + + void OnMwmDeregistered(platform::LocalCountryFile const & countryFile); + +private: + void UpdateState(); + void ChangeState(IsolinesState newState); + + enum class Availability + { + Available, + NoData, + ExpiredData + }; + + IsolinesState m_state = IsolinesState::Disabled; + IsolinesStateChangedFn m_onStateChangedFn; + + DataSource & m_dataSource; + GetMwmsByRectFn m_getMwmsByRectFn; + + df::DrapeEngineSafePtr m_drapeEngine; + + boost::optional m_currentModelView; + + std::vector m_lastMwms; + std::map m_mwmCache; +}; + +std::string DebugPrint(IsolinesManager::IsolinesState state); diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index 1c904b5689..f5176745b8 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -92,13 +92,7 @@ void TrafficManager::SetEnabled(bool enabled) { std::lock_guard lock(m_mutex); if (enabled == IsEnabled()) - { - LOG(LWARNING, ("Invalid attempt to", enabled ? "enable" : "disable", - "traffic manager, it's already", enabled ? "enabled" : "disabled", - ", doing nothing.")); return; - } - Clear(); ChangeState(enabled ? TrafficState::Enabled : TrafficState::Disabled); }