diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index d1a6f00fe9..a5ae3bad74 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -56,6 +56,18 @@ void ScreenBase::UpdateDependentParameters() m_ClipRect = m_GlobalRect.GetGlobalRect(); } +void ScreenBase::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect) +{ + double hScale = glbRect.GetLocalRect().SizeX() / pxRect.SizeX(); + double vScale = glbRect.GetLocalRect().SizeY() / pxRect.SizeY(); + + m_Scale = max(hScale, vScale); + m_Angle = glbRect.angle(); + m_Org = glbRect.GlobalCenter(); + + UpdateDependentParameters(); +} + void ScreenBase::SetFromRect(m2::AnyRectD const & GlobalRect) { double hScale = GlobalRect.GetLocalRect().SizeX() / m_PixelRect.SizeX(); diff --git a/geometry/screenbase.hpp b/geometry/screenbase.hpp index d23d9c00f4..38f786cb39 100644 --- a/geometry/screenbase.hpp +++ b/geometry/screenbase.hpp @@ -45,6 +45,7 @@ public: ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect); void SetFromRect(m2::AnyRectD const & rect); + void SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect); void SetOrg(m2::PointD const & p); void Move(double dx, double dy); diff --git a/map/basic_render_policy.hpp b/map/basic_render_policy.hpp index 76375b8e61..f572ffa987 100644 --- a/map/basic_render_policy.hpp +++ b/map/basic_render_policy.hpp @@ -48,4 +48,6 @@ public: void SetEmptyModelFn(TEmptyModelFn const & checkFn); bool NeedRedraw() const; + + m2::RectD const ScaleEtalonRect() const; }; diff --git a/map/basic_tiling_render_policy.cpp b/map/basic_tiling_render_policy.cpp index 96ae2a7655..37d9ce432c 100644 --- a/map/basic_tiling_render_policy.cpp +++ b/map/basic_tiling_render_policy.cpp @@ -152,3 +152,8 @@ bool BasicTilingRenderPolicy::NeedRedraw() const return false; } +size_t BasicTilingRenderPolicy::ScaleEtalonSize() const +{ + return m_resourceManager->params().m_renderTargetTexturesParams.m_texWidth; +} + diff --git a/map/basic_tiling_render_policy.hpp b/map/basic_tiling_render_policy.hpp index e9da609586..e4b1d5714a 100644 --- a/map/basic_tiling_render_policy.hpp +++ b/map/basic_tiling_render_policy.hpp @@ -58,4 +58,5 @@ public: bool IsTiling() const; bool IsEmptyModel() const; int GetDrawScale(ScreenBase const & s) const; + size_t ScaleEtalonSize() const; }; diff --git a/map/framework.cpp b/map/framework.cpp index ede319fdaf..137a5ce19c 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -457,18 +457,40 @@ void Framework::SetViewportCenter(m2::PointD const & pt) static int const theMetersFactor = 6; -void Framework::ShowRect(m2::RectD rect) +void Framework::CheckMinGlobalRect(m2::RectD & rect) { m2::RectD const minRect = MercatorBounds::RectByCenterXYAndSizeInMeters( rect.Center(), theMetersFactor * m_metresMinWidth); if (minRect.IsRectInside(rect)) rect = minRect; +} + +void Framework::ShowRect(m2::RectD const & r) +{ + m2::RectD rect(r); + CheckMinGlobalRect(rect); m_navigator.SetFromRect(m2::AnyRectD(rect)); Invalidate(); } +void Framework::ShowRectFixed(m2::RectD const & r) +{ + m2::RectD rect(r); + CheckMinGlobalRect(rect); + + m2::RectD etalonRect(0, 0, m_renderPolicy->ScaleEtalonSize(), m_renderPolicy->ScaleEtalonSize()); + etalonRect.Offset(-etalonRect.SizeX() / 2, -etalonRect.SizeY()); + + m2::PointD pxCenter = m_navigator.Screen().PixelRect().Center(); + + etalonRect.Offset(pxCenter); + + m_navigator.SetFromRects(m2::AnyRectD(rect), etalonRect); + Invalidate(); +} + void Framework::DrawPlacemark(m2::PointD const & pt) { m_drawPlacemark = true; @@ -766,10 +788,10 @@ void Framework::ShowSearchResult(search::Result const & res) { m2::PointD const c = r.Center(); if (!m_model.IsCountryLoaded(c)) - r = scales::GetRectForLevelFix(9, c); + r = scales::GetRectForLevel(scales::GetUpperWorldScale(), c, 1.0); } - ShowRect(r); + ShowRectFixed(r); DrawPlacemark(res.GetFeatureCenter()); } diff --git a/map/framework.hpp b/map/framework.hpp index f710371da4..ff184091c0 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -156,6 +156,9 @@ public: private: inline m2::RectD GetCurrentViewport() const { return m_navigator.Screen().ClipRect(); } search::Engine * GetSearchEngine(); + + void CheckMinGlobalRect(m2::RectD & r); + public: void PrepareSearch(bool hasPt, double lat = 0.0, double lon = 0.0); void Search(search::SearchParams const & params); @@ -201,7 +204,8 @@ public: virtual void EndPaint(shared_ptr const & e); - void ShowRect(m2::RectD rect); + void ShowRect(m2::RectD const & rect); + void ShowRectFixed(m2::RectD const & rect); void DrawPlacemark(m2::PointD const & pt); void DisablePlacemark(); diff --git a/map/navigator.cpp b/map/navigator.cpp index 1606c89f11..8cdfd278ab 100644 --- a/map/navigator.cpp +++ b/map/navigator.cpp @@ -47,6 +47,18 @@ void Navigator::SetMinScreenParams(unsigned pxMinWidth, double metresMinWidth) m_metresMinWidth = metresMinWidth; } +void Navigator::SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect) +{ + m_Screen.SetFromRects(glbRect, pxRect); + m_Screen = ScaleInto(m_Screen, m_worldRect); + + if (!m_InAction) + { + m_StartScreen.SetFromRects(glbRect, pxRect); + m_StartScreen = ScaleInto(m_StartScreen, m_worldRect); + } +} + void Navigator::SetFromRect(m2::AnyRectD const & r) { m_Screen.SetFromRect(r); diff --git a/map/navigator.hpp b/map/navigator.hpp index 45dd79077e..d1d156ed2a 100644 --- a/map/navigator.hpp +++ b/map/navigator.hpp @@ -15,6 +15,7 @@ public: void SetMinScreenParams(unsigned pxMinWidth, double metresMinWidth); void SetFromRect(m2::AnyRectD const & r); void CenterViewport(m2::PointD const & p); + void SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect); void SaveState(); /// @return false if can't load previously saved values diff --git a/map/render_policy.cpp b/map/render_policy.cpp index cc11bbdc36..44ca09b31a 100644 --- a/map/render_policy.cpp +++ b/map/render_policy.cpp @@ -164,6 +164,11 @@ int RenderPolicy::GetDrawScale(ScreenBase const & s) const return scales::GetScaleLevel(glbRect); } +size_t RenderPolicy::ScaleEtalonSize() const +{ + return GetPlatform().ScaleEtalonSize(); +} + RenderPolicy * CreateRenderPolicy(VideoTimer * videoTimer, bool useDefaultFB, yg::ResourceManager::Params const & rmParams, diff --git a/map/render_policy.hpp b/map/render_policy.hpp index c38e036294..349fd8e77c 100644 --- a/map/render_policy.hpp +++ b/map/render_policy.hpp @@ -99,6 +99,7 @@ public: shared_ptr const & GetDrawer() const; shared_ptr const & GetWindowHandle() const; + virtual size_t ScaleEtalonSize() const; }; RenderPolicy * CreateRenderPolicy(VideoTimer * videoTimer,