diff options
author | Dmitry Kunin <dkunin@mapswith.me> | 2013-07-29 17:03:55 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:04:12 +0300 |
commit | 237acea1779c39308c6d81e40620198e71c2e474 (patch) | |
tree | 896daedf8dc41e0195a582a72ea19d00a7324891 /map/track.cpp | |
parent | 129178ca622dbe1dfec60ff8972795a7e7e35350 (diff) |
[tracks] Base tracks stuff.
[track] Draw only points in screen rect.
[track] DisplayList drawing.
[track] Tracks now have separate screen.
[track] Removed stub data.
[track] LineString parsing from .kml.
[track] Serialization to .kml
Diffstat (limited to 'map/track.cpp')
-rw-r--r-- | map/track.cpp | 100 |
1 files changed, 80 insertions, 20 deletions
diff --git a/map/track.cpp b/map/track.cpp index bf6a082961..449130e9b5 100644 --- a/map/track.cpp +++ b/map/track.cpp @@ -3,34 +3,94 @@ #include "../graphics/pen.hpp" #include "../graphics/depth_constants.hpp" #include "drawer.hpp" -#include "../geometry/screenbase.hpp" +#include "../base/timer.hpp" + +Track::~Track() +{ + DeleteDisplayList(); +} + +void Track::DeleteDisplayList() +{ + if (HasDisplayList()) + { + delete m_dList; + m_dList = 0; + LOG(LDEBUG, ("DisplayList deleted for track", m_name)); + } +} void Track::Draw(shared_ptr<PaintEvent> const & e) { - // do not draw degenerated points - if (Size() < 2) + if (HasDisplayList()) + { + graphics::Screen * screen = e->drawer()->screen(); + screen->drawDisplayList(m_dList, math::Identity<double, 3>()); + LOG(LDEBUG, ("Drawing track:", GetName())); + } +} + +void Track::UpdateDisplayList(Navigator & navigator, graphics::Screen * dListScreen) +{ + const bool isIntersect = navigator.Screen().GlobalRect().IsIntersect(m2::AnyRectD(GetLimitRect())); + if ( !(IsVisible() && isIntersect) ) + { + LOG(LDEBUG, ("No intresection, deleting dlist", GetName())); + DeleteDisplayList(); return; + } - graphics::Screen * screen = e->drawer()->screen(); - ScreenBase sb; - // pen - graphics::Pen::Info info(m_color, m_width); - uint32_t resId = screen->mapInfo(info); + if (!HasDisplayList() || IsViewportChanged(navigator.Screen())) + { + m_screenBase = navigator.Screen(); + m2::AnyRectD const & screenRect = m_screenBase.GlobalRect(); - // depth - const double depth = graphics::debugDepth; + DeleteDisplayList(); + m_dList = dListScreen->createDisplayList(); - // offset - const size_t offset = 0; + dListScreen->beginFrame(); + dListScreen->setDisplayList(m_dList); + // Clip and transform points + /// @todo can we optimize memory allocation? + vector<m2::PointD> pixPoints(m_polyline.m_points.size()); + int countInRect = 0; + bool lastSuccessed = false; + for (int i = 1; i < m_polyline.m_points.size(); ++i) + { + m2::PointD & left = m_polyline.m_points[i-1]; + m2::PointD & right = m_polyline.m_points[i]; + m2::RectD segRect(left, right); - // points - vector<m2::PointD> pixPoints(m_polyline.m_points.size()); - for (int i=0; i < pixPoints.size(); ++i) - pixPoints[i] = sb.GtoP(m_polyline.m_points[i]); - // add matrix? + if (m2::AnyRectD(segRect).IsIntersect(screenRect)) + { + if (!lastSuccessed) + pixPoints[countInRect++] = navigator.GtoP(m_polyline.m_points[i-1]); + /// @todo add only visible segments drawing to avoid phanot segments + pixPoints[countInRect++] = navigator.GtoP(m_polyline.m_points[i]); + lastSuccessed = true; + } + else + lastSuccessed = false; + } + LOG(LDEBUG, ("Number of points in rect = ", countInRect)); + // Draw + if (countInRect >= 2) + { + graphics::Pen::Info info(m_color, m_width); + uint32_t resId = dListScreen->mapInfo(info); + /// @todo add simplification + dListScreen->drawPath(&pixPoints[0], countInRect, 0, resId, graphics::tracksDepth); + } + dListScreen->setDisplayList(0); + dListScreen->endFrame(); + } +} - screen->drawPath(&pixPoints[0], pixPoints.size(), offset, resId, depth); +bool Track::IsViewportChanged(ScreenBase const & sb) +{ + // check if viewport changed + return m_screenBase != sb; } -m2::RectD Track::GetLimitRect() { return m_polyline.GetLimitRect(); } -size_t Track::Size() { return m_polyline.m_points.size(); } +m2::RectD Track::GetLimitRect() const { return m_polyline.GetLimitRect(); } +size_t Track::Size() const { return m_polyline.m_points.size(); } |