From 1fa977fc6faa20c39c1af47f462eefe5d7e60829 Mon Sep 17 00:00:00 2001 From: rachytski Date: Sat, 15 Jan 2011 23:42:28 +0200 Subject: [PATCH] refactored additional information display. --- indexer/mercator.cpp | 1 + indexer/mercator.hpp | 5 +- iphone/Maps/Classes/MapViewController.mm | 2 +- map/drawer_yg.cpp | 15 - map/drawer_yg.hpp | 2 - map/framework.hpp | 212 +++++--------- map/information_display.cpp | 339 +++++++++++++++++++++++ map/information_display.hpp | 81 ++++++ map/map.pro | 2 + qt/draw_widget.cpp | 2 +- skin_generator/main.cpp | 2 +- skin_generator/skin_generator.cpp | 2 +- yg/geometry_batcher.hpp | 2 +- yg/pen_info.cpp | 2 + yg/skin.cpp | 2 +- yg/skin_loader.hpp | 3 +- 16 files changed, 500 insertions(+), 174 deletions(-) create mode 100644 map/information_display.cpp create mode 100644 map/information_display.hpp diff --git a/indexer/mercator.cpp b/indexer/mercator.cpp index 3bc3f9f486..e7834e5600 100644 --- a/indexer/mercator.cpp +++ b/indexer/mercator.cpp @@ -4,3 +4,4 @@ double MercatorBounds::minX = -180; double MercatorBounds::maxX = 180; double MercatorBounds::minY = -180; double MercatorBounds::maxY = 180; +double const MercatorBounds::degreeInMetres = 1.0 / 111111.0; diff --git a/indexer/mercator.hpp b/indexer/mercator.hpp index 026cec97d8..52659c521e 100644 --- a/indexer/mercator.hpp +++ b/indexer/mercator.hpp @@ -32,12 +32,13 @@ struct MercatorBounds return lon; } + static double const degreeInMetres; + /// @return mercator bound points in rect inline static m2::RectD ErrorToRadius(double lon, double lat, double errorInMetres) { // We use approximate number of metres per degree - static double const metresInDegree = 1.0 / 111111.0; - double const offset = errorInMetres / 2.0 * metresInDegree; + double const offset = errorInMetres / 2.0 * degreeInMetres; return m2::RectD(LonToX(lon - offset), LatToY(lat - offset), LonToX(lon + offset), LatToY(lat + offset)); } diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index 749d23284b..c9ff838262 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -58,7 +58,7 @@ typedef FrameWork frame shared_ptr windowHandle = [(EAGLView*)self.view windowHandle]; shared_ptr resourceManager = [(EAGLView*)self.view resourceManager]; - m_framework = new framework_t(windowHandle); + m_framework = new framework_t(windowHandle, 40); m_framework->Init(m_storage); m_StickyThreshold = 10; diff --git a/map/drawer_yg.cpp b/map/drawer_yg.cpp index 50903e90ce..3969b8eeed 100644 --- a/map/drawer_yg.cpp +++ b/map/drawer_yg.cpp @@ -280,18 +280,3 @@ void DrawerYG::Draw(di::DrawInfo const * pInfo, rule_ptr_t pRule, int depth) } } } - -void DrawerYG::drawStats(double duration, int scale, double lat, double lng, m2::PointD const & pt, bool log2vis) -{ - ostringstream out; - out << "SPF: " << duration; - if (duration == 0.0) - out << " FPS: inf"; - else - out << " FPS: " << 1.0 / duration; - m_pScreen->drawText(pt + m2::PointD(10, 20), 0, 10, out.str().c_str(), yg::maxDepth, true, log2vis); - - out.str(""); - out << "(" << lat << ", " << lng << ") Scale: " << scale; - m_pScreen->drawText(pt + m2::PointD(10, 40), 0, 10, out.str().c_str(), yg::maxDepth, true, log2vis); -} diff --git a/map/drawer_yg.hpp b/map/drawer_yg.hpp index dd4d0310c0..4243582bdc 100644 --- a/map/drawer_yg.hpp +++ b/map/drawer_yg.hpp @@ -96,8 +96,6 @@ public: void onSize(int w, int h); - void drawStats(double duration, int scale, double lat, double lng, m2::PointD const & startPt = m2::PointD(0, 0), bool log2vis = false); - shared_ptr screen() const; void SetVisualScale(double visualScale); diff --git a/map/framework.hpp b/map/framework.hpp index fa14d95b20..08fe03f646 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -3,6 +3,7 @@ #include "events.hpp" #include "drawer_yg.hpp" #include "render_queue.hpp" +#include "information_display.hpp" #include "../indexer/drawing_rule_def.hpp" #include "../indexer/mercator.hpp" @@ -94,21 +95,11 @@ class FrameWork navigator_t m_navigator; shared_ptr m_windowHandle; RenderQueue m_renderQueue; - - bool m_isHeadingEnabled; - double m_trueHeading; - double m_magneticHeading; - double m_headingAccuracy; - - bool m_isPositionEnabled; - m2::PointD m_position; - double m_confidenceRadius; + InformationDisplay m_informationDisplay; /// is AddRedrawCommand enabled? bool m_isRedrawEnabled; - m2::PointD m_DebugPts[2]; - void Invalidate() { m_windowHandle->invalidate(); @@ -168,15 +159,21 @@ class FrameWork } public: - FrameWork(shared_ptr windowHandle) + FrameWork(shared_ptr windowHandle, size_t bottomShift) : m_windowHandle(windowHandle), m_renderQueue(GetPlatform().SkinName(), GetPlatform().IsMultiSampled(), GetPlatform().DoPeriodicalUpdate()), - m_isHeadingEnabled(false), - m_isPositionEnabled(false), m_isRedrawEnabled(true) { - m_DebugPts[0] = m2::PointD(0, 0); - m_DebugPts[1] = m2::PointD(0, 0); + m_informationDisplay.setBottomShift(bottomShift); +#ifdef DRAW_TOUCH_POINTS + m_informationDisplay.enableDebugPoints(true); +#endif + m_informationDisplay.enableCenter(true); + m_informationDisplay.enableRuler(true); +#ifdef DEBUG + m_informationDisplay.enableDebugInfo(true); +#endif + m_informationDisplay.setVisualScale(GetPlatform().VisualScale()); m_renderQueue.AddWindowHandle(m_windowHandle); } @@ -199,6 +196,11 @@ public: boost::bind(&FrameWork::RemoveMap, this, _1)); } + bool IsEmptyModel() + { + return m_model.GetWorldRect() == m2::RectD::GetEmptyRect(); + } + // Cleanup. void Clean() { @@ -230,6 +232,8 @@ public: m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); + m_informationDisplay.setDisplayRect(m2::RectI(ptShift, ptShift + m2::PointD(w, h))); + m_navigator.OnSize(ptShift.x, ptShift.y, w, h); UpdateNow(); @@ -246,6 +250,7 @@ public: void SetOrientation(EOrientation orientation) { m_navigator.SetOrientation(orientation); + m_informationDisplay.setOrientation(orientation); UpdateNow(); } @@ -307,156 +312,73 @@ public: DrawerYG * pDrawer = e->drawer().get(); - threads::MutexGuard guard(*m_renderQueue.renderState().m_mutex.get()); + m_informationDisplay.setScreen(m_navigator.Screen()); + m_informationDisplay.setDebugInfo(m_renderQueue.renderState().m_duration, GetCurrentScale()); + + m_informationDisplay.enableRuler(!IsEmptyModel()); + + m2::PointD const center = m_navigator.Screen().ClipRect().Center(); + m_informationDisplay.setCenter(m2::PointD(MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x))); - if (m_renderQueue.renderState().m_actualTarget.get() != 0) { - e->drawer()->screen()->beginFrame(); - e->drawer()->screen()->clear(/*yg::Color(255, 0, 0, 255)*/); + threads::MutexGuard guard(*m_renderQueue.renderState().m_mutex.get()); - m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false); - - OGLCHECK(glMatrixMode(GL_MODELVIEW)); - OGLCHECK(glPushMatrix()); - OGLCHECK(glTranslatef(-ptShift.x, -ptShift.y, 0)); - - pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget, - m_renderQueue.renderState().m_actualScreen, - m_navigator.Screen(), - yg::Color(0, 255, 0, 255), - m2::RectI(0, 0, - m_renderQueue.renderState().m_actualTarget->width(), - m_renderQueue.renderState().m_actualTarget->height()), - m2::RectU(0, 0, - m_renderQueue.renderState().m_actualTarget->width(), - m_renderQueue.renderState().m_actualTarget->height())); - - m2::PointD const center = m_navigator.Screen().ClipRect().Center(); - -#ifdef DRAW_TOUCH_POINTS - - if (m_DebugPts[0] != m2::PointD(0, 0)) + if (m_renderQueue.renderState().m_actualTarget.get() != 0) { - pDrawer->screen()->drawArc(m_DebugPts[0], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 32), yg::maxDepth); - pDrawer->screen()->fillSector(m_DebugPts[0], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 32), yg::maxDepth); - } + e->drawer()->screen()->beginFrame(); + e->drawer()->screen()->clear(/*yg::Color(255, 0, 0, 255)*/); - if (m_DebugPts[1] != m2::PointD(0, 0)) - { - pDrawer->screen()->drawArc(m_DebugPts[1], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 64), yg::maxDepth); - pDrawer->screen()->fillSector(m_DebugPts[1], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 32), yg::maxDepth); - } -#endif + m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false); - DrawPosition(pDrawer); + OGLCHECK(glMatrixMode(GL_MODELVIEW)); + OGLCHECK(glPushMatrix()); + OGLCHECK(glTranslatef(-ptShift.x, -ptShift.y, 0)); - pDrawer->drawStats(m_renderQueue.renderState().m_duration, GetCurrentScale(), - MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x), - ptShift); + pDrawer->screen()->blit(m_renderQueue.renderState().m_actualTarget, + m_renderQueue.renderState().m_actualScreen, + m_navigator.Screen(), + yg::Color(0, 255, 0, 255), + m2::RectI(0, 0, + m_renderQueue.renderState().m_actualTarget->width(), + m_renderQueue.renderState().m_actualTarget->height()), + m2::RectU(0, 0, + m_renderQueue.renderState().m_actualTarget->width(), + m_renderQueue.renderState().m_actualTarget->height())); - e->drawer()->screen()->endFrame(); - OGLCHECK(glPopMatrix()); + m_informationDisplay.doDraw(pDrawer); - } - } + e->drawer()->screen()->endFrame(); - void DrawPosition(DrawerYG * pDrawer) - { - if (m_isPositionEnabled) - { - m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false); - /// Drawing position and heading - m2::PointD pxPosition = m_navigator.Screen().GtoP(m_position); - pDrawer->drawSymbol(pxPosition, "current-position", yg::maxDepth); - - double pxConfidenceRadius = pxPosition.Length(m_navigator.Screen().GtoP(m_position + m2::PointD(m_confidenceRadius, 0))); - - pDrawer->screen()->drawArc(pxPosition, 0, math::pi * 2, pxConfidenceRadius, yg::Color(0, 0, 255, 64), yg::maxDepth - 2); - pDrawer->screen()->fillSector(pxPosition, 0, math::pi * 2, pxConfidenceRadius, yg::Color(0, 0, 255, 32), yg::maxDepth - 3); - - if (m_isHeadingEnabled) - { - double trueHeadingRad = m_trueHeading / 180 * math::pi; - double magneticHeadingRad = m_magneticHeading / 180 * math::pi; - double headingAccuracyRad = m_headingAccuracy / 180 * math::pi; - - /// true heading - pDrawer->screen()->drawSector(pxPosition, - trueHeadingRad - headingAccuracyRad, - trueHeadingRad + headingAccuracyRad, - pxConfidenceRadius, - yg::Color(255, 0, 0, 64), - yg::maxDepth); - pDrawer->screen()->fillSector(pxPosition, - trueHeadingRad - headingAccuracyRad, - trueHeadingRad + headingAccuracyRad, - pxConfidenceRadius, - yg::Color(255, 0, 0, 32), - yg::maxDepth - 1); -/* /// magnetic heading - pDrawer->screen()->drawSector(pxPosition, - magneticHeadingRad - headingAccuracyRad, - magneticHeadingRad + headingAccuracyRad, - pxConfidenceRadius, - yg::Color(0, 255, 0, 64), - yg::maxDepth); - pDrawer->screen()->fillSector(pxPosition, - magneticHeadingRad - headingAccuracyRad, - magneticHeadingRad + headingAccuracyRad, - pxConfidenceRadius, - yg::Color(0, 255, 0, 32), - yg::maxDepth - 1); - */ + OGLCHECK(glPopMatrix()); } } } - void DrawScaleLiner(DrawerYG * pDrawer) - { - /// Compute Scaler - /// scaler should be between minPixSize and maxPixSize - int minPixSize = 40; - int maxPixSize = 80; - - m2::PointD lowerBoundPt = m2::PointD(0, m_renderQueue.renderState().m_surfaceHeight) - + m_renderQueue.renderState().coordSystemShift(); - - double minMetersSize = m_navigator.Screen().PtoG(lowerBoundPt + m2::PointD(minPixSize, 0)).x; - double maxMetersSize = m_navigator.Screen().PtoG(lowerBoundPt + m2::PointD(maxPixSize, 0)).x; - } void DisableMyPositionAndHeading() { - m_isPositionEnabled = false; - m_isHeadingEnabled = false; + m_informationDisplay.enablePosition(false); + m_informationDisplay.enableHeading(false); UpdateNow(); } void SetPosition(m2::PointD const & mercatorPos, double confidenceRadius) { - m_isPositionEnabled = true; - - m_position = mercatorPos; - m_confidenceRadius = confidenceRadius; - + m_informationDisplay.setPosition(mercatorPos, confidenceRadius); UpdateNow(); } void CenterViewport() { - m_navigator.CenterViewport(m_position); + m_navigator.CenterViewport(m_informationDisplay.position()); UpdateNow(); } void SetHeading(double trueHeading, double magneticHeading, double accuracy) { - m_isHeadingEnabled = true; - m_trueHeading = trueHeading; - m_magneticHeading = magneticHeading; - m_headingAccuracy = accuracy; - + m_informationDisplay.setHeading(trueHeading, magneticHeading, accuracy); UpdateNow(); } @@ -467,12 +389,6 @@ public: UpdateNow(); } - //void ShowFeature(Feature const & f) - //{ - // m_navigator.SetFromRect(f.GetLimitRect()); - // Repaint(); - //} - void Repaint() { AddRedrawCommandSure(); @@ -496,7 +412,7 @@ public: GetPlatform().TimeInSec()); #ifdef DRAW_TOUCH_POINTS - m_DebugPts[0] = pos; + m_informationDisplay.setDebugPoint(0, pos); #endif Invalidate(); @@ -510,7 +426,7 @@ public: GetPlatform().TimeInSec()); #ifdef DRAW_TOUCH_POINTS - m_DebugPts[0] = pos; + m_informationDisplay.setDebugPoint(0, pos); #endif Invalidate(); @@ -526,7 +442,7 @@ public: true); #ifdef DRAW_TOUCH_POINTS - m_DebugPts[0] = m2::PointD(0, 0); + m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0)); #endif UpdateNow(); @@ -575,12 +491,13 @@ public: m_navigator.StartScale(pt1, pt2, GetPlatform().TimeInSec()); #ifdef DRAW_TOUCH_POINTS - m_DebugPts[0] = pt1; - m_DebugPts[1] = pt2; + m_informationDisplay.setDebugPoint(0, pt1); + m_informationDisplay.setDebugPoint(1, pt2); #endif Invalidate(); } + void DoScale(ScaleEvent const & e) { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); @@ -591,12 +508,13 @@ public: m_navigator.DoScale(pt1, pt2, GetPlatform().TimeInSec()); #ifdef DRAW_TOUCH_POINTS - m_DebugPts[0] = pt1; - m_DebugPts[1] = pt2; + m_informationDisplay.setDebugPoint(0, pt1); + m_informationDisplay.setDebugPoint(1, pt2); #endif Invalidate(); } + void StopScale(ScaleEvent const & e) { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); @@ -607,8 +525,8 @@ public: m_navigator.StopScale(pt1, pt2, GetPlatform().TimeInSec()); #ifdef DRAW_TOUCH_POINTS - m_DebugPts[0] = m2::PointD(0, 0); - m_DebugPts[1] = m2::PointD(0, 0); + m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0)); + m_informationDisplay.setDebugPoint(0, m2::PointD(0, 0)); #endif UpdateNow(); diff --git a/map/information_display.cpp b/map/information_display.cpp new file mode 100644 index 0000000000..3b2628f09e --- /dev/null +++ b/map/information_display.cpp @@ -0,0 +1,339 @@ +#include "../base/SRC_FIRST.hpp" + +#include "information_display.hpp" +#include "drawer_yg.hpp" + +#include "../indexer/mercator.hpp" +#include "../base/string_utils.hpp" +#include "../yg/defines.hpp" +#include "../yg/skin.hpp" + +#include "../base/logging.hpp" + +InformationDisplay::InformationDisplay() + : m_headingOrientation(-math::pi / 2) +{ + enablePosition(false); + enableHeading(false); + enableDebugPoints(false); + enableRuler(false); + enableCenter(false); + enableDebugInfo(false); + + for (int i = 0; i < sizeof(m_DebugPts) / sizeof(m2::PointD); ++i) + m_DebugPts[i] = m2::PointD(0, 0); +} + +void InformationDisplay::setScreen(ScreenBase const & screen) +{ + m_screen = screen; +} + +void InformationDisplay::setBottomShift(double bottomShift) +{ + m_bottomShift = bottomShift; +} + +void InformationDisplay::setOrientation(EOrientation orientation) +{ + switch (orientation) + { + case EOrientation0: + m_headingOrientation = -math::pi / 2; + break; + case EOrientation90: + m_headingOrientation = math::pi; + break; + case EOrientation180: + m_headingOrientation = math::pi / 2; + break; + case EOrientation270: + m_headingOrientation = 0; + break; + } +} + +void InformationDisplay::setDisplayRect(m2::RectI const & rect) +{ + m_displayRect = rect; +} + +void InformationDisplay::enablePosition(bool doEnable) +{ + m_isPositionEnabled = doEnable; +} + +void InformationDisplay::setPosition(m2::PointD const & mercatorPos, double confidenceRadius) +{ + enablePosition(true); + m_position = mercatorPos; + m_confidenceRadius = confidenceRadius; +} + +m2::PointD const & InformationDisplay::position() const +{ + return m_position; +} + +void InformationDisplay::drawPosition(DrawerYG * pDrawer) +{ + /// Drawing position and heading + m2::PointD pxPosition = m_screen.GtoP(m_position); + pDrawer->drawSymbol(pxPosition, "current-position", yg::maxDepth); + + double pxConfidenceRadius = pxPosition.Length(m_screen.GtoP(m_position + m2::PointD(m_confidenceRadius, 0))); + + pDrawer->screen()->drawArc(pxPosition, 0, math::pi * 2, pxConfidenceRadius, yg::Color(0, 0, 255, 64), yg::maxDepth - 2); + pDrawer->screen()->fillSector(pxPosition, 0, math::pi * 2, pxConfidenceRadius, yg::Color(0, 0, 255, 32), yg::maxDepth - 3); +} + +void InformationDisplay::enableHeading(bool doEnable) +{ + m_isHeadingEnabled = doEnable; +} + +void InformationDisplay::setHeading(double trueHeading, double magneticHeading, double accuracy) +{ + enableHeading(true); + m_trueHeading = trueHeading; + m_magneticHeading = magneticHeading; + m_headingAccuracy = accuracy; +} + +void InformationDisplay::drawHeading(DrawerYG *pDrawer) +{ + double trueHeadingRad = m_trueHeading / 180 * math::pi; + double headingAccuracyRad = m_headingAccuracy / 180 * math::pi; + + m2::PointD pxPosition = m_screen.GtoP(m_position); + + double pxConfidenceRadius = pxPosition.Length(m_screen.GtoP(m_position + m2::PointD(m_confidenceRadius, 0))); + + /// true heading + pDrawer->screen()->drawSector(pxPosition, + trueHeadingRad + m_headingOrientation - headingAccuracyRad, + trueHeadingRad + m_headingOrientation + headingAccuracyRad, + pxConfidenceRadius, + yg::Color(255, 0, 0, 64), + yg::maxDepth); + pDrawer->screen()->fillSector(pxPosition, + trueHeadingRad + m_headingOrientation - headingAccuracyRad, + trueHeadingRad + m_headingOrientation + headingAccuracyRad, + pxConfidenceRadius, + yg::Color(255, 0, 0, 32), + yg::maxDepth - 1); + /* /// magnetic heading + double magneticHeadingRad = m_magneticHeading / 180 * math::pi; + pDrawer->screen()->drawSector(pxPosition, + magneticHeadingRad + m_headingOrientation - headingAccuracyRad, + magneticHeadingRad + m_headingOrientation + headingAccuracyRad, + pxConfidenceRadius, + yg::Color(0, 255, 0, 64), + yg::maxDepth); + pDrawer->screen()->fillSector(pxPosition, + magneticHeadingRad + m_headingOrientation - headingAccuracyRad, + magneticHeadingRad + m_headingOrientation + headingAccuracyRad, + pxConfidenceRadius, + yg::Color(0, 255, 0, 32), + yg::maxDepth - 1); + */ +} + +void InformationDisplay::enableDebugPoints(bool doEnable) +{ + m_isDebugPointsEnabled = doEnable; +} + +void InformationDisplay::setDebugPoint(int pos, m2::PointD const & pt) +{ + m_DebugPts[pos] = pt; +} + +void InformationDisplay::drawDebugPoints(DrawerYG * pDrawer) +{ + for (int i = 0; i < sizeof(m_DebugPts) / sizeof(m2::PointD); ++i) + if (m_DebugPts[i] != m2::PointD(0, 0)) + { + pDrawer->screen()->drawArc(m_DebugPts[i], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 32), yg::maxDepth); + pDrawer->screen()->fillSector(m_DebugPts[i], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 32), yg::maxDepth); + } +} + +void InformationDisplay::enableRuler(bool doEnable) +{ + m_isRulerEnabled = doEnable; +} + +void InformationDisplay::drawRuler(DrawerYG * pDrawer) +{ + /// Compute Scaler + /// scaler should be between minPixSize and maxPixSize + int minPixSize = 80; + + 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; + + /// finding the closest higher metric value + unsigned curFirstDigit = 2; + unsigned curVal = 20; + unsigned maxVal = 1000000; + bool lessThanMin = false; + bool isInfinity = false; + + if (metresDiff > maxVal) + { + isInfinity = true; + curVal = maxVal; + } + else + if (metresDiff < curVal) + lessThanMin = true; + else + while (true) + { + unsigned nextVal = curFirstDigit == 2 ? (curVal * 5 / 2) : curVal * 2; + unsigned nextFirstDigit = curFirstDigit == 2 ? (curFirstDigit * 5 / 2) : curFirstDigit * 2; + + if (nextFirstDigit >= 10) + nextFirstDigit /= 10; + + if ((curVal <= metresDiff) && (nextVal > metresDiff)) + { + curVal = nextVal; + curFirstDigit = nextFirstDigit; + break; + } + + curVal = nextVal; + curFirstDigit = nextFirstDigit; + } + + /// translating meters to pixels + double scalerWidthLatDiff = (double)curVal * MercatorBounds::degreeInMetres; + double scalerWidthXDiff = MercatorBounds::LatToY(pt0.x + scalerWidthLatDiff) - MercatorBounds::LatToY(pt0.x); + + double scalerWidthInPx = m_screen.GtoP(pt0).x - m_screen.GtoP(pt0 + m2::PointD(scalerWidthXDiff, 0)).x; + scalerWidthInPx = (lessThanMin || isInfinity) ? minPixSize : fabs(my::rounds(scalerWidthInPx)); + + string scalerText; + + if (isInfinity) + scalerText = ">"; + else + if (lessThanMin) + scalerText = "<"; + + if (curVal >= 1000) + scalerText += utils::to_string(curVal / 1000) + " km"; + else + scalerText += utils::to_string(curVal) + " m"; + + m2::PointD scalerOrg = m2::PointD(m_displayRect.minX(), m_displayRect.maxY() - m_bottomShift * m_visualScale) + m2::PointD(10 * m_visualScale, -10 * m_visualScale); + + m2::PointD scalerPts[4]; + scalerPts[0] = scalerOrg + m2::PointD(0, -14 * m_visualScale); + scalerPts[1] = scalerOrg; + scalerPts[2] = scalerOrg + m2::PointD(scalerWidthInPx, 0); + scalerPts[3] = scalerPts[2] + m2::PointD(0, -14 * m_visualScale); + + pDrawer->screen()->drawPath( + scalerPts, 4, + pDrawer->screen()->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 0, 255), 2, 0, 0, 0)), + yg::maxDepth); + + m2::RectD textRect = pDrawer->screen()->textRect(scalerText.c_str(), 10, false); + pDrawer->screen()->drawText(scalerPts[1] + m2::PointD(7, -7), + 0, + 10, + scalerText.c_str(), + yg::maxDepth, + true, + false); + +/* m2::PointD minPixPath[4]; + minPixPath[0] = scalerOrg + m2::PointD(0, -14); + minPixPath[1] = scalerOrg; + minPixPath[2] = scalerOrg + m2::PointD(minPixSize, 0); + minPixPath[3] = minPixPath[2] + m2::PointD(0, -14); + + pDrawer->screen()->drawPath( + minPixPath, 4, + pDrawer->screen()->skin()->mapPenInfo(yg::PenInfo(yg::Color(255, 0, 0, 255), 4, 0, 0, 0)), + yg::maxDepth); + */ +} + +void InformationDisplay::setVisualScale(double visualScale) +{ + m_visualScale = visualScale; +} + +void InformationDisplay::enableCenter(bool doEnable) +{ + m_isCenterEnabled = doEnable; +} + +void InformationDisplay::setCenter(m2::PointD const & pt) +{ + m_centerPt = pt; +} + +void InformationDisplay::drawCenter(DrawerYG * drawer) +{ + ostringstream out; + out << "(" << m_centerPt.x << ", " << m_centerPt.y << ") Scale : " << m_currentScale; + drawer->screen()->drawText( + m2::PointD(m_displayRect.minX(), m_displayRect.minY()) + m2::PointD(10, m_isDebugInfoEnabled ? 40 : 20), + 0, 10, + out.str().c_str(), + yg::maxDepth, + true, + false); +} + +void InformationDisplay::enableDebugInfo(bool doEnable) +{ + m_isDebugInfoEnabled = doEnable; +} + +void InformationDisplay::setDebugInfo(double frameDuration, int currentScale) +{ + m_frameDuration = frameDuration; + m_currentScale = currentScale; +} + +void InformationDisplay::drawDebugInfo(DrawerYG * drawer) +{ + ostringstream out; + out << "SPF: " << m_frameDuration; + if (m_frameDuration == 0.0) + out << " FPS: inf"; + else + out << " FPS: " << 1.0 / m_frameDuration; + + drawer->screen()->drawText(m2::PointD(m_displayRect.minX(), m_displayRect.minY()) + m2::PointD(10, 20), + 0, 10, + out.str().c_str(), + yg::maxDepth, + true, + false); +} + +void InformationDisplay::doDraw(DrawerYG *drawer) +{ + if (m_isHeadingEnabled) + drawHeading(drawer); + if (m_isPositionEnabled) + drawPosition(drawer); + if (m_isDebugPointsEnabled) + drawDebugPoints(drawer); + if (m_isRulerEnabled) + drawRuler(drawer); + if (m_isCenterEnabled) + drawCenter(drawer); + if (m_isDebugInfoEnabled) + drawDebugInfo(drawer); +} diff --git a/map/information_display.hpp b/map/information_display.hpp new file mode 100644 index 0000000000..cae410eb91 --- /dev/null +++ b/map/information_display.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include "../geometry/point2d.hpp" +#include "../geometry/rect2d.hpp" +#include "../geometry/screenbase.hpp" + +class DrawerYG; + +/// Class, which displays additional information on the primary layer. +/// like rules, coordinates, GPS position and heading +class InformationDisplay +{ +private: + + ScreenBase m_screen; + m2::RectI m_displayRect; + + double m_headingOrientation; + + bool m_isHeadingEnabled; + double m_trueHeading; + double m_magneticHeading; + double m_headingAccuracy; + + bool m_isPositionEnabled; + m2::PointD m_position; + double m_confidenceRadius; + + /// for debugging purposes + /// up to 10 debugging points + bool m_isDebugPointsEnabled; + m2::PointD m_DebugPts[10]; + + bool m_isRulerEnabled; + m2::PointD m_basePoint; + + bool m_isCenterEnabled; + m2::PointD m_centerPt; + int m_currentScale; + + bool m_isDebugInfoEnabled; + double m_frameDuration; + double m_bottomShift; + double m_visualScale; + +public: + + InformationDisplay(); + + void setScreen(ScreenBase const & screen); + void setDisplayRect(m2::RectI const & rect); + void setBottomShift(double bottomShift); + void setVisualScale(double visualScale); + void setOrientation(EOrientation orientation); + + void enablePosition(bool doEnable); + void setPosition(m2::PointD const & mercatorPos, double confidenceRadius); + m2::PointD const & position() const; + void drawPosition(DrawerYG * pDrawer); + + void enableHeading(bool doEnable); + void setHeading(double trueHeading, double magneticHeading, double accuracy); + void drawHeading(DrawerYG * pDrawer); + + void enableDebugPoints(bool doEnable); + void setDebugPoint(int pos, m2::PointD const & pt); + void drawDebugPoints(DrawerYG * pDrawer); + + void enableRuler(bool doEnable); + void drawRuler(DrawerYG * pDrawer); + + void enableCenter(bool doEnable); + void setCenter(m2::PointD const & latLongPt); + void drawCenter(DrawerYG * pDrawer); + + void enableDebugInfo(bool doEnable); + void setDebugInfo(double frameDuration, int currentScale); + void drawDebugInfo(DrawerYG * pDrawer); + + void doDraw(DrawerYG * drawer); +}; diff --git a/map/map.pro b/map/map.pro index a1cbd82243..29bb4f983b 100644 --- a/map/map.pro +++ b/map/map.pro @@ -20,6 +20,7 @@ HEADERS += \ window_handle.hpp \ render_queue.hpp \ render_queue_routine.hpp \ + information_display.hpp SOURCES += \ feature_vec_model.cpp \ @@ -29,6 +30,7 @@ SOURCES += \ draw_processor.cpp \ render_queue.cpp \ render_queue_routine.cpp \ + information_display.cpp !iphonesimulator-g++42 { !iphonedevice-g++42 { diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index bf1b531397..22c36330b5 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -15,7 +15,7 @@ namespace qt DrawWidget::DrawWidget(QWidget * pParent, Storage & storage) : base_type(pParent), m_handle(new handle_t(this)), - m_framework(m_handle), + m_framework(m_handle, 0), m_isDrag(false), m_redrawInterval(100), m_pScale(0) diff --git a/skin_generator/main.cpp b/skin_generator/main.cpp index add5c9fc55..dc5795487d 100644 --- a/skin_generator/main.cpp +++ b/skin_generator/main.cpp @@ -8,7 +8,7 @@ #include "../3party/gflags/src/gflags/gflags.h" -DEFINE_string(fontFileName, "../../data/fonts/DejaVu/DejaVuSans.ttf", "path to TrueType font file"); +DEFINE_string(fontFileName, "../../data/dejavusans.ttf", "path to TrueType font file"); DEFINE_string(symbolsFile, "../../data/results.unicode", "file with 2bytes symbols for which the skin should be generated"); DEFINE_string(symbolsDir, "../../data/styles/symbols", "directory with svg symbol files"); DEFINE_int32(symbolWidth, 24, "width of the rendered symbol"); diff --git a/skin_generator/skin_generator.cpp b/skin_generator/skin_generator.cpp index a84ad71a51..47844eaba3 100644 --- a/skin_generator/skin_generator.cpp +++ b/skin_generator/skin_generator.cpp @@ -59,7 +59,7 @@ namespace tools void SkinGenerator::processFont(string const & fileName, string const & skinName, vector const & fontSizes, int symbolScale) { - string symbols(" 0123456789abcdefjhigklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ;:'\"/?.,`~!@#$%^&*()-_+="); + string symbols(" 0123456789abcdefjhigklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ;:'\"/?.,`~!@#$%^&*()-_+=<>"); FT_Library lib; FT_Error error; diff --git a/yg/geometry_batcher.hpp b/yg/geometry_batcher.hpp index 169363929f..b7e6821a29 100644 --- a/yg/geometry_batcher.hpp +++ b/yg/geometry_batcher.hpp @@ -135,7 +135,7 @@ namespace yg string const & utf8Text, double depth, bool fixedFont = false, - bool log2vis = false); + bool log2vis = true); m2::RectD const textRect(string const & utf8Text, uint8_t fontSize, diff --git a/yg/pen_info.cpp b/yg/pen_info.cpp index 0157170aa6..9b394c8e65 100644 --- a/yg/pen_info.cpp +++ b/yg/pen_info.cpp @@ -61,6 +61,8 @@ namespace yg bool operator < (PenInfo const & l, PenInfo const & r) { + if (l.m_isSolid != r.m_isSolid) + return l.m_isSolid < r.m_isSolid; if (l.m_color != r.m_color) return l.m_color < r.m_color; if (l.m_w != r.m_w) diff --git a/yg/skin.cpp b/yg/skin.cpp index b8e21bc487..9ff3b2a019 100644 --- a/yg/skin.cpp +++ b/yg/skin.cpp @@ -25,7 +25,7 @@ namespace yg size_t textPagesCount) : m_pages(pages), m_dynamicPagesCount(dynamicPagesCount), - m_textPagesCount(dynamicPagesCount), + m_textPagesCount(textPagesCount), m_staticPagesCount(pages.size()), m_resourceManager(resourceManager) { diff --git a/yg/skin_loader.hpp b/yg/skin_loader.hpp index c637e06acb..9c5593a6d7 100644 --- a/yg/skin_loader.hpp +++ b/yg/skin_loader.hpp @@ -104,11 +104,10 @@ namespace yg TStylesList m_stylesList; shared_ptr m_resourceManager; + Skin * m_skin; size_t m_dynamicPagesCount; size_t m_textPagesCount; - Skin * m_skin; - public: SkinLoader(shared_ptr const & resourceManager,