From b8f6f73964aee38700eac8053ac9c9811ed2e06b Mon Sep 17 00:00:00 2001 From: rachytski Date: Tue, 15 Mar 2011 01:45:13 +0200 Subject: [PATCH] limiting max and min global rect. --- map/framework.hpp | 6 +++-- map/information_display.cpp | 16 ++++++++---- map/information_display.hpp | 3 +++ map/navigator.cpp | 50 ++++++++++++++++++++++++++----------- map/navigator.hpp | 10 +++++++- 5 files changed, 63 insertions(+), 22 deletions(-) diff --git a/map/framework.hpp b/map/framework.hpp index e776e41a83..ffb936a8ed 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -175,6 +175,8 @@ public: m_informationDisplay.enableCenter(false); m_informationDisplay.enableGlobalRect(!m_isBenchmarking); m_informationDisplay.enableRuler(true); + m_informationDisplay.setRulerParams(80, 20); + m_navigator.SetMinScreenParams(80, 20); #ifdef DEBUG m_informationDisplay.enableDebugInfo(true); @@ -378,7 +380,7 @@ public: m2::PointD const center = m_navigator.Screen().ClipRect().Center(); m_informationDisplay.setGlobalRect(m_navigator.Screen().GlobalRect()); - m_informationDisplay.setCenter(m2::PointD(MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x))); + m_informationDisplay.setCenter(m2::PointD(MercatorBounds::XToLon(center.x), MercatorBounds::YToLat(center.y))); { threads::MutexGuard guard(*m_renderQueue.renderState().m_mutex.get()); @@ -387,7 +389,7 @@ public: { m2::PointD const center = m_renderQueue.renderState().m_actualScreen.ClipRect().Center(); m_informationDisplay.setScreen(m_renderQueue.renderState().m_actualScreen); - m_informationDisplay.setCenter(m2::PointD(MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x))); + m_informationDisplay.setCenter(m2::PointD(MercatorBounds::XToLon(center.x), MercatorBounds::YToLat(center.y))); if (m_benchmarks.empty()) { diff --git a/map/information_display.cpp b/map/information_display.cpp index f3436713ea..e43c0188a0 100644 --- a/map/information_display.cpp +++ b/map/information_display.cpp @@ -171,21 +171,27 @@ void InformationDisplay::enableRuler(bool doEnable) m_isRulerEnabled = doEnable; } +void InformationDisplay::setRulerParams(unsigned pxMinWidth, double metresMinWidth) +{ + m_pxMinWidth = pxMinWidth; + m_metresMinWidth = metresMinWidth; +} + void InformationDisplay::drawRuler(DrawerYG * pDrawer) { /// Compute Scaler /// scaler should be between minPixSize and maxPixSize - int minPixSize = 80; + int minPixSize = m_pxMinWidth; m2::PointD pt0 = m_centerPt; m2::PointD pt1 = m_screen.PtoG(m_screen.GtoP(m_centerPt) + m2::PointD(minPixSize, 0)); - double latDiff = fabs(MercatorBounds::YToLat(pt1.x) - MercatorBounds::YToLat(pt0.x)); - double metresDiff = latDiff / MercatorBounds::degreeInMetres; + double lonDiff = fabs(MercatorBounds::XToLon(pt1.x) - MercatorBounds::XToLon(pt0.x)); + double metresDiff = lonDiff / MercatorBounds::degreeInMetres; /// finding the closest higher metric value unsigned curFirstDigit = 2; - unsigned curVal = 20; + unsigned curVal = m_metresMinWidth; unsigned maxVal = 1000000; bool lessThanMin = false; bool isInfinity = false; @@ -220,7 +226,7 @@ void InformationDisplay::drawRuler(DrawerYG * pDrawer) /// translating meters to pixels double scalerWidthLatDiff = (double)curVal * MercatorBounds::degreeInMetres; - double scalerWidthXDiff = MercatorBounds::LatToY(pt0.x + scalerWidthLatDiff) - MercatorBounds::LatToY(pt0.x); + double scalerWidthXDiff = MercatorBounds::LonToX(pt0.x + scalerWidthLatDiff) - MercatorBounds::LonToX(pt0.x); double scalerWidthInPx = m_screen.GtoP(pt0).x - m_screen.GtoP(pt0 + m2::PointD(scalerWidthXDiff, 0)).x; scalerWidthInPx = (lessThanMin || isInfinity) ? minPixSize : abs(my::rounds(scalerWidthInPx)); diff --git a/map/information_display.hpp b/map/information_display.hpp index 11655c21b6..f0f5822cf6 100644 --- a/map/information_display.hpp +++ b/map/information_display.hpp @@ -37,6 +37,8 @@ private: bool m_isRulerEnabled; m2::PointD m_basePoint; + unsigned m_pxMinWidth; + double m_metresMinWidth; bool m_isCenterEnabled; m2::PointD m_centerPt; @@ -96,6 +98,7 @@ public: void enableRuler(bool doEnable); void drawRuler(DrawerYG * pDrawer); + void setRulerParams(unsigned pxMinWidth, double metresMinWidth); void enableCenter(bool doEnable); void setCenter(m2::PointD const & latLongPt); diff --git a/map/navigator.cpp b/map/navigator.cpp index f7332cfaea..e1d2bd30f3 100644 --- a/map/navigator.cpp +++ b/map/navigator.cpp @@ -29,6 +29,12 @@ Navigator::Navigator(ScreenBase const & screen) { } +void Navigator::SetMinScreenParams(unsigned pxMinWidth, double metresMinWidth) +{ + m_pxMinWidth = pxMinWidth; + m_metresMinWidth = metresMinWidth; +} + void Navigator::SetFromRect(m2::RectD const & r) { m_Screen.SetFromRect(r); @@ -148,23 +154,37 @@ void Navigator::ScaleToPoint(m2::PointD const & pt, double factor, double /*time endPt.y = m_Screen.PixelRect().minY(); } - ScaleImpl(pt, endPt, pt, startPt); + ScaleImpl(pt, endPt, pt, startPt, factor > 1); } -namespace +bool Navigator::CheckMaxScale(ScreenBase const & screen) { - bool CheckMaxScale(ScreenBase const & screen) - { - m2::RectD const r = screen.GlobalRect(); + m2::RectD const r0 = screen.GlobalRect(); + m2::RectD const r1 = screen.ClipRect(); + m2::RectD r; - // multiple by 2 to allow scale on zero level - double const maxSize = 2.0 * (MercatorBounds::maxX - MercatorBounds::minX); - return (r.SizeX() <= maxSize || r.SizeY() <= maxSize); - } + if ((r0.SizeX() > r1.SizeX()) || (r0.SizeY() > r1.SizeY())) + r = r0; + else + r = r1; + + // multiple by 2 to allow scale on zero level + double const maxSize = (MercatorBounds::maxX - MercatorBounds::minX); + return (r.SizeX() <= maxSize || r.SizeY() <= maxSize); +} + +bool Navigator::CheckMinScale(ScreenBase const & screen) +{ + m2::PointD const pt0 = screen.GlobalRect().Center(); + m2::PointD const pt1 = screen.PtoG(screen.GtoP(pt0) + m2::PointD(m_pxMinWidth, 0)); + double lonDiff = fabs(MercatorBounds::XToLon(pt1.x) - MercatorBounds::XToLon(pt0.x)); + double metresDiff = lonDiff / MercatorBounds::degreeInMetres; + return metresDiff >= m_metresMinWidth - 1; } void Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, - m2::PointD const & oldPt1, m2::PointD const & oldPt2) + m2::PointD const & oldPt1, m2::PointD const & oldPt2, + bool skipMaxScaleCheck) { math::Matrix newM = m_Screen.GtoPMatrix() * ScreenBase::CalcTransform(oldPt1, oldPt2, newPt1, newPt2); @@ -172,8 +192,10 @@ void Navigator::ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, tmp.SetGtoPMatrix(newM); tmp.Rotate(tmp.GetAngle()); - // limit max scale to MercatorBounds - if (CheckMaxScale(tmp)) + if ((!skipMaxScaleCheck) && (!CheckMaxScale(tmp))) + return; + + if (CheckMinScale(tmp)) m_Screen = tmp; } @@ -186,7 +208,7 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double / return; m_Screen = m_StartScreen; - ScaleImpl(pt1, pt2, m_StartPt1, m_StartPt2); + ScaleImpl(pt1, pt2, m_StartPt1, m_StartPt2, pt1.Length(pt2) / m_StartPt1.Length(m_StartPt2) > 1); m_LastPt1 = pt1; m_LastPt2 = pt2; @@ -209,7 +231,7 @@ void Navigator::Scale(double scale) tmp.Scale(scale); // limit max scale to MercatorBounds - if (CheckMaxScale(tmp)) + if (CheckMaxScale(tmp) && CheckMinScale(tmp)) m_Screen = tmp; } diff --git a/map/navigator.hpp b/map/navigator.hpp index 9d57ea810a..c62abc7b1e 100644 --- a/map/navigator.hpp +++ b/map/navigator.hpp @@ -17,6 +17,7 @@ public: Navigator(); explicit Navigator(ScreenBase const & screen); + void SetMinScreenParams(unsigned pxMinWidth, double metresMinWidth); void SetFromRect(m2::RectD const & r); void CenterViewport(m2::PointD const & p); @@ -60,6 +61,13 @@ public: private: + + + unsigned m_pxMinWidth; + double m_metresMinWidth; + bool CheckMinScale(ScreenBase const & screen); + bool CheckMaxScale(ScreenBase const & screen); + // Internal screen corresponding to the state when navigation began with StartDrag or StartScale. ScreenBase m_StartScreen; // Internal screen to do GtoP() and PtoG() calculations. It is always up to date with navigation. @@ -85,7 +93,7 @@ private: // Device orientation EOrientation m_orientation; // Used in DoScale and ScaleByPoint - void ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, m2::PointD const & oldPt1, m2::PointD const & oldPt2); + void ScaleImpl(m2::PointD const & newPt1, m2::PointD const & newPt2, m2::PointD const & oldPt1, m2::PointD const & oldPt2, bool skipMaxScaleCheck); }; #include "../base/stop_mem_debug.hpp"