Qt Virtual Chart Table (QVCT)
COverlayCourse.cpp
Go to the documentation of this file.
1 // INDENTING (emacs/vi): -*- mode:c++; tab-width:2; c-basic-offset:2; intent-tabs-mode:nil; -*- ex: set tabstop=2 expandtab:
2 
3 /*
4  * Qt Virtual Chart Table (QVCT)
5  * Copyright (C) 2012 Cedric Dufour <http://cedric.dufour.name>
6  * Author: Cedric Dufour <http://cedric.dufour.name>
7  *
8  * The Qt Virtual Chart Table (QVCT) is free software:
9  * you can redistribute it and/or modify it under the terms of the GNU General
10  * Public License as published by the Free Software Foundation, Version 3.
11  *
12  * The Qt Virtual Chart Table (QVCT) is distributed in the hope
13  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * See the GNU General Public License for more details.
17  */
18 
19 // C/C++
20 #include <cmath>
21 
22 // QT
23 #include <QDataStream>
24 #include <QPainter>
25 
26 // QVCT
27 #include "QVCTRuntime.hpp"
30 #include "charts/CChart.hpp"
31 #include "overlays/COverlay.hpp"
33 #include "units/CUnitBearing.hpp"
34 #include "units/CUnitSpeed.hpp"
36 
37 
38 //------------------------------------------------------------------------------
39 // CONSTRUCTORS / DESTRUCTOR
40 //------------------------------------------------------------------------------
41 
42 COverlayCourse::COverlayCourse( const QString& _rqsName )
43  : COverlayPoint( _rqsName )
44  , CDataCourseGA()
45 {}
46 
47 COverlayCourse::COverlayCourse( const QString& _rqsName, const CDataPosition& _roDataPosition )
48  : COverlayPoint( _rqsName, _roDataPosition )
49  , CDataCourseGA()
50 {}
51 
52 COverlayCourse::COverlayCourse( const QString& _rqsName, const CDataPosition& _roDataPosition,
53  const CDataCourse& _roGroundGeoCourse, const CDataCourse& _roApparentGeoCourse )
54  : COverlayPoint( _rqsName, _roDataPosition )
55  , CDataCourseGA( _roGroundGeoCourse, _roApparentGeoCourse )
56 {}
57 
58 
59 //------------------------------------------------------------------------------
60 // METHODS: COverlayObject (implement/override)
61 //------------------------------------------------------------------------------
62 
63 void COverlayCourse::serialize( QDataStream& _rqDataStream ) const
64 {
65  COverlayPoint::serialize( _rqDataStream );
66  CDataCourseGA::serialize( _rqDataStream );
67 }
68 
69 void COverlayCourse::unserialize( QDataStream& _rqDataStream )
70 {
71  COverlayItem::unserialize( _rqDataStream );
72  CDataCourseGA::unserialize( _rqDataStream );
73 }
74 
75 
76 //------------------------------------------------------------------------------
77 // METHODS: COverlayPoint (implement/override)
78 //------------------------------------------------------------------------------
79 
80 
81 void COverlayCourse::drawMarker( const CChart* _poChart, QPainter* _pqPainter, const CDataPositionValidity* _poDataPositionValidity, bool _bSelected )
82 {
83  // Constant drawing resources
84  static const QSize __qSizeSelect(32,32);
85  static const QPixmap __qPixmapSelect( ":icons/32x32/select.png" );
86 
87  // Exit if we're not visible
88  if( CDataPosition::operator==( CDataPosition::UNDEFINED ) || !bVisible ) return;
89 
90  // Retrieve and adjust drawing parameters
91  double __fdZoom = _poChart->getZoom();
92  if( __fdZoom < 0.5 ) __fdZoom = 0.5;
93  else if( __fdZoom > 2.0 ) __fdZoom = 2.0;
94  __fdZoom *= QVCTRuntime::useSettings()->getScreenDpi() / 96.0;
95  QPointF __qPointF = _poChart->toDrawPosition( *this );
96 
97  // Draw
98  COverlay* __poOverlay = useOverlay();
99  QPen __qPen = __poOverlay->getPenMarker();
100  __qPen.setWidth( __qPen.width() * __fdZoom );
101  // ... marker
102  double __fdRadius = 11.0 * __fdZoom;
103  if( _bSelected )
104  {
105  QPen __qPenSelected = __poOverlay->getPenMarkerSelected();
106  __qPenSelected.setWidth( __qPenSelected.width() * __fdZoom );
107  _pqPainter->setPen( __qPenSelected );
108  _pqPainter->setBrush( __poOverlay->getBrushMarkerSelected() );
109  _pqPainter->drawEllipse( __qPointF, 1.5*__fdRadius, 1.5*__fdRadius );
110  }
111  if( _poDataPositionValidity && !_poDataPositionValidity->isValidPosition() ) __qPen.setStyle( Qt::DotLine );
112  _pqPainter->setPen( __qPen );
113  _pqPainter->setBrush( __poOverlay->getBrushMarker() );
114  _pqPainter->drawEllipse( __qPointF, __fdRadius, __fdRadius );
115  _pqPainter->drawPoint( __qPointF );
116  double __fdGroundBearing = CDataCourseGA::GroundCourse.getBearing();
117  if( __fdGroundBearing == CDataCourse::UNDEFINED_BEARING ) __fdGroundBearing = 0;
118  else __fdGroundBearing *= QVCT::DEG2RAD;
119  __fdRadius = 16.0 * __fdZoom;
120  QPointF __qPointFTip = __qPointF + __fdRadius * QPointF( sin( __fdGroundBearing ), -cos( __fdGroundBearing ) );
121  _pqPainter->drawLine( __qPointFTip, __qPointF + __fdRadius * QPointF( sin( __fdGroundBearing+2.5 ), -cos( __fdGroundBearing+2.5 ) ) );
122  _pqPainter->drawLine( __qPointFTip, __qPointF + __fdRadius * QPointF( sin( __fdGroundBearing-2.5 ), -cos( __fdGroundBearing-2.5 ) ) );
123  // ... multi-select
124  if( !isMultiSelected() || __fdZoom <= 0.5 ) return;
125  _pqPainter->drawPixmap( __qPointF, __qPixmapSelect.scaled( __qSizeSelect*(__fdZoom/2.0), Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
126 }
127 
128 //------------------------------------------------------------------------------
129 // METHODS
130 //------------------------------------------------------------------------------
131 
132 //
133 // OTHER
134 //
135 
136 void COverlayCourse::drawVector( const CChart* _poChart, QPainter* _pqPainter, const CDataCourseValidityGA* _poDataCourseValidityGA )
137 {
138  // Exit if we're not visible
139  if( CDataPosition::operator==( CDataPosition::UNDEFINED ) || !bVisible || !bVisibleCourse ) return;
140 
141  // Retrieve drawing parameters
142  double __fdZoom = _poChart->getZoom();
143  if( __fdZoom < 0.5 ) __fdZoom = 0.5;
144  else if( __fdZoom > 2.0 ) __fdZoom = 2.0;
145  __fdZoom *= QVCTRuntime::useSettings()->getScreenDpi() / 96.0;
146  QPointF __qPointF = _poChart->toDrawPosition( *this );
147 
148  // Draw
149  COverlay* __poOverlay = useOverlay();
150  QPen __qPen = __poOverlay->getPenVector();
151  double __fdLength = _poChart->getDrawArea().width() + _poChart->getDrawArea().height();
152 
153  // ... ground course
154  double __fdGroundBearing = CDataCourseGA::GroundCourse.getBearing();
155  if( __fdGroundBearing != CDataCourse::UNDEFINED_BEARING )
156  {
157  // ... bearing line
158  QString __qsGroundBearing = CUnitBearing::toString( __fdGroundBearing );
159  __fdGroundBearing *= QVCT::DEG2RAD;
160  QPointF __qPointFBearing = QPointF( sin( __fdGroundBearing ), -cos( __fdGroundBearing ) );
161  QPointF __qPointFGround = __qPointF + __fdLength * __qPointFBearing;
162  bool __bInvalid = false;
163  if( _poDataCourseValidityGA && !_poDataCourseValidityGA->GroundCourseValidity.isValidBearing() )
164  {
165  __bInvalid = true;
166  __qPen.setStyle( Qt::DotLine );
167  }
168  __qPen.setWidth( 3.0 * __fdZoom );
169  _pqPainter->setPen( __qPen );
170  _pqPainter->drawLine( __qPointF, __qPointFGround );
171 
172  // ... speed tick
173  double __fdGroundSpeed = CDataCourseGA::GroundCourse.getSpeed();
174  QString __qsGroundSpeed = "-";
175  if( __fdGroundSpeed != CDataCourse::UNDEFINED_SPEED )
176  {
177  __qsGroundSpeed = CUnitSpeed::toString( __fdGroundSpeed );
178  QBrush __qBrush = __poOverlay->getBrushMarker();
179  __qBrush.setStyle( Qt::SolidPattern );
180  if( _poDataCourseValidityGA && !_poDataCourseValidityGA->GroundCourseValidity.isValidSpeed() )
181  {
182  __bInvalid = true;
183  __qBrush.setStyle( Qt::Dense4Pattern );
184  }
185  _pqPainter->setBrush( __qBrush );
186  _pqPainter->setPen( QPen( Qt::transparent ) );
187  double __fdLengthMinute = __fdGroundSpeed * 60.0 * _poChart->getZoom() / _poChart->getResolution();
188  if( __fdLengthMinute >= 10 )
189  {
190  for( int __i = 0; __i < 5; __i++ )
191  {
192  double __fdLengthTick = (__i+1)*__fdLengthMinute;
193  if( __fdLengthTick > __fdLength ) break;
194  double __fdRadius = ( 10.0 - __i ) * __fdZoom;
195  _pqPainter->drawEllipse( __qPointF + __fdLengthTick * __qPointFBearing, __fdRadius, __fdRadius );
196  }
197  }
198  }
199 
200  // ... course data
201  double __fdGroundSpeedVertical = CDataCourseGA::GroundCourse.getSpeedVertical();
202  QString __qsGroundSpeedVertical = "-";
203  if( __fdGroundSpeedVertical != CDataCourse::UNDEFINED_SPEED )
204  {
205  __qsGroundSpeedVertical = CUnitSpeedVertical::toString( __fdGroundSpeedVertical );
206  if( _poDataCourseValidityGA && !_poDataCourseValidityGA->GroundCourseValidity.isValidSpeedVertical() ) __bInvalid = true;
207  }
208  double __fdBearingOffset = ( 40.0 + 20.0*fabs( pow( sin( __fdGroundBearing ), 3 ) ) ) * __fdZoom;
209  drawText( _poChart, _pqPainter, __qsGroundBearing+QString::fromUtf8("ยท")+__qsGroundSpeed+"\n"+__qsGroundSpeedVertical, __qPointF+QPointF( __fdBearingOffset*sin( __fdGroundBearing ), -__fdBearingOffset*cos( __fdGroundBearing ) ), __bInvalid );
210  }
211 
212  // ... apparent course
213  double __fdApparentBearing = CDataCourseGA::ApparentCourse.getBearing();
214  if( __fdApparentBearing != CDataCourse::UNDEFINED_BEARING )
215  {
216  __fdApparentBearing *= QVCT::DEG2RAD;
217  QPointF __qPointFApparent = __qPointF + __fdLength * QPointF( sin( __fdApparentBearing ), -cos( __fdApparentBearing ) );
218  if( _poDataCourseValidityGA && !_poDataCourseValidityGA->ApparentCourseValidity.isValidBearing() ) __qPen.setStyle( Qt::DotLine );
219  __qPen.setWidth( 2.0 * __fdZoom );
220  _pqPainter->setPen( __qPen );
221  _pqPainter->drawLine( __qPointF, __qPointFApparent );
222  }
223 }
[UI] Chart (view)
Definition: CChart.hpp:44
double getZoom() const
Returns the current zoom factor.
Definition: CChart.hpp:139
double getResolution() const
Returns the resolution of the chart at its current position, in meters per pixel [m/px].
Definition: CChart.cpp:176
QRectF getDrawArea() const
Returns the viewport draw area.
Definition: CChart.hpp:127
QPointF toDrawPosition(const CDataPosition &_roGeoPosition) const
Converts the given (geographical) position [long,lat,elev] to chart draw point [px].
Definition: CChart.cpp:192
Ground and apparent geographical courses container.
void serialize(QDataStream &_rqDataStream) const
Serializes (store) this object's data to binary format.
void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
CDataCourse ApparentCourse
Apparent course.
CDataCourse GroundCourse
Ground course.
Ground and apparent geographical courses validity container.
CDataCourseValidity GroundCourseValidity
Ground course validity.
CDataCourseValidity ApparentCourseValidity
Apparent course validity.
bool isValidSpeedVertical() const
Returns the vertical speed's (global) validity status.
bool isValidSpeed() const
Returns the horizontal speed's (global) validity status.
bool isValidBearing() const
Returns the bearing's (global) validity status.
(Geographical) Course data [bearing, horizontal/vertical speeds]
Definition: CDataCourse.hpp:34
double getSpeedVertical() const
Returns this course's vertical speed, in meters per second.
static constexpr double UNDEFINED_BEARING
Specific value for an undefined bearing.
Definition: CDataCourse.hpp:42
static constexpr double UNDEFINED_SPEED
Specific value for an undefined speed.
Definition: CDataCourse.hpp:44
double getBearing() const
Returns this course's bearing, in degrees.
double getSpeed() const
Returns this course's horizontal speed, in meters per second.
Position data validity.
bool isValidPosition() const
Returns the position's (global) validity status.
(Geographical) Position data [long,lat,elev]
static const CDataPosition UNDEFINED
Specific value for an undefined position.
virtual void drawVector(const CChart *_poChart, QPainter *_pqPainter, const CDataCourseValidityGA *_poDataCourseValidityGA=0)
Draws the course vectors (ground and apparent)
virtual void serialize(QDataStream &_rqDataStream) const
Serializes (store) this object's data to binary format.
COverlayCourse(const QString &_rqsName)
virtual void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
virtual void drawMarker(const CChart *_poChart, QPainter *_pqPainter, const CDataPositionValidity *_poDataPositionValidity=0, bool _bSelected=false)
Draws the point (marker)
bool isMultiSelected() const
Returns this item's selection status.
virtual COverlay * useOverlay()=0
Returns this object's (base) overlay.
virtual void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
Generic overlay point.
virtual void drawText(const CChart *_poChart, QPainter *_pqPainter, const QString &_rqsText, const QPointF &_rqPointFScrPosition, bool _bItalic=false)
Draws the given text, at the given screen position.
virtual void serialize(QDataStream &_rqDataStream) const
Serializes (store) this object's data to binary format.
bool bVisible
Global (marker) visibility status.
bool bVisibleCourse
Course's visibility status.
Generic overlay.
Definition: COverlay.hpp:45
const QBrush & getBrushMarker() const
Definition: COverlay.hpp:125
const QPen & getPenMarkerSelected() const
Definition: COverlay.hpp:128
const QPen & getPenVector() const
Definition: COverlay.hpp:130
const QBrush & getBrushMarkerSelected() const
Definition: COverlay.hpp:127
const QPen & getPenMarker() const
Definition: COverlay.hpp:126
int getScreenDpi()
[Misc] Returns the screen Dots-per-Inch (DPI)
Definition: CSettings.hpp:429
static QString toString(double _fdValue, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
static QString toString(double _fdValue, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
static QString toString(double _fdValue, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
Definition: CUnitSpeed.cpp:78
static CSettings * useSettings()
static constexpr double DEG2RAD
Definition: QVCT.hpp:46