Qt Virtual Chart Table (QVCT)
COverlayPoint.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 #include <QPointF>
26 
27 // QVCT
28 #include "QVCTRuntime.hpp"
31 #include "charts/CChart.hpp"
32 #include "overlays/COverlay.hpp"
34 #include "units/CUnitBearing.hpp"
35 #include "units/CUnitDistance.hpp"
36 #include "units/CUnitElevation.hpp"
37 #include "units/CUnitPosition.hpp"
38 #include "units/CUnitTime.hpp"
39 
40 
41 //------------------------------------------------------------------------------
42 // CONSTRUCTORS / DESTRUCTOR
43 //------------------------------------------------------------------------------
44 
45 COverlayPoint::COverlayPoint( const QString& _rqsName )
46  : COverlayItem( COverlayObject::ITEM, _rqsName )
48  , CDataPosition()
49 {}
50 
51 COverlayPoint::COverlayPoint( const QString& _rqsName, const CDataPosition& _roDataPosition )
52  : COverlayItem( COverlayObject::ITEM, _rqsName )
54  , CDataPosition( _roDataPosition )
55 {}
56 
57 
58 //------------------------------------------------------------------------------
59 // CONSTANTS / STATIC
60 //------------------------------------------------------------------------------
61 
62 int COverlayPoint::getPositionBox( const QTreeWidgetItem* _pqTreeWidgetItem,
63  CDataPosition* _poDataPositionLower, CDataPosition* _poDataPositionUpper,
64  int _iIndexMin, int _iIndexMax )
65 {
66 
67  // Input bounding box
68  // ... longitude
69  double __fdLongitudeLower = _poDataPositionLower->getLongitude();
70  if( __fdLongitudeLower == CDataPosition::UNDEFINED_LONGITUDE ) __fdLongitudeLower = -180;
71  double __fdLongitudeUpper = _poDataPositionUpper->getLongitude();
72  if( __fdLongitudeUpper == CDataPosition::UNDEFINED_LONGITUDE ) __fdLongitudeUpper = 180;
73  if( __fdLongitudeLower > __fdLongitudeUpper )
74  {
75  double __fd = __fdLongitudeLower;
76  __fdLongitudeUpper = __fdLongitudeLower;
77  __fdLongitudeLower = __fd;
78  }
79  // ... latitude
80  double __fdLatitudeLower = _poDataPositionLower->getLatitude();
81  if( __fdLatitudeLower == CDataPosition::UNDEFINED_LATITUDE ) __fdLatitudeLower = -90;
82  double __fdLatitudeUpper = _poDataPositionUpper->getLatitude();
83  if( __fdLatitudeUpper == CDataPosition::UNDEFINED_LATITUDE ) __fdLatitudeUpper = 90;
84  if( __fdLatitudeLower > __fdLatitudeUpper )
85  {
86  double __fd = __fdLatitudeLower;
87  __fdLatitudeUpper = __fdLatitudeLower;
88  __fdLatitudeLower = __fd;
89  }
90  // ... elevation
91  double __fdElevationLower = _poDataPositionLower->getElevation();
92  if( __fdElevationLower == CDataPosition::UNDEFINED_ELEVATION ) __fdElevationLower = -999999;
93  double __fdElevationUpper = _poDataPositionUpper->getElevation();
94  if( __fdElevationUpper == CDataPosition::UNDEFINED_ELEVATION ) __fdElevationUpper = 999999;
95  if( __fdElevationLower > __fdElevationUpper )
96  {
97  double __fd = __fdElevationLower;
98  __fdElevationUpper = __fdElevationLower;
99  __fdElevationLower = __fd;
100  }
101  // ... indices
102  int __iIndexMax = _iIndexMax >= 0 ? _iIndexMax : _pqTreeWidgetItem->childCount()-1;
103 
104  // Output bounding box
105  int __iCountValid = 0;
106  double __fdLongitudeMin = 180, __fdLongitudeMax = -180;
107  double __fdLatitudeMin = 90, __fdLatitudeMax = -90;
108  double __fdElevationMin = 9999999, __fdElevationMax = -9999999;
109  for( int __i = _iIndexMin; __i <= __iIndexMax; __i++ )
110  {
111  CDataPosition* __poDataPosition = (CDataPosition*)(COverlayPoint*)_pqTreeWidgetItem->child( __i );
112  if( *__poDataPosition == CDataPosition::UNDEFINED ) continue;
113  double __fdLongitude = __poDataPosition->getLongitude();
114  if( __fdLongitude < __fdLongitudeLower || __fdLongitude > __fdLongitudeUpper ) continue;
115  double __fdLatitude = __poDataPosition->getLatitude();
116  if( __fdLatitude < __fdLatitudeLower || __fdLatitude > __fdLatitudeUpper ) continue;
117  double __fdElevation = __poDataPosition->getElevation();
118  if( __fdElevation != CDataPosition::UNDEFINED_ELEVATION
119  && ( __fdElevation < __fdElevationLower || __fdElevation > __fdElevationUpper ) ) continue;
120  __iCountValid++;
121  if( __fdLongitude < __fdLongitudeMin ) __fdLongitudeMin = __fdLongitude;
122  if( __fdLongitude > __fdLongitudeMax ) __fdLongitudeMax = __fdLongitude;
123  if( __fdLatitude < __fdLatitudeMin ) __fdLatitudeMin = __fdLatitude;
124  if( __fdLatitude > __fdLatitudeMax ) __fdLatitudeMax = __fdLatitude;
125  if( __fdElevation != CDataPosition::UNDEFINED_ELEVATION )
126  {
127  if( __fdElevation < __fdElevationMin ) __fdElevationMin = __fdElevation;
128  if( __fdElevation > __fdElevationMax ) __fdElevationMax = __fdElevation;
129  }
130  }
131  _poDataPositionLower->resetPosition();
132  _poDataPositionUpper->resetPosition();
133  if( __iCountValid )
134  {
135  _poDataPositionLower->setPosition( __fdLongitudeMin, __fdLatitudeMin, __fdElevationMin > -9999999 ? __fdElevationMin : CDataPosition::UNDEFINED_ELEVATION );
136  _poDataPositionUpper->setPosition( __fdLongitudeMax, __fdLatitudeMax, __fdElevationMax < 9999999 ? __fdElevationMax : CDataPosition::UNDEFINED_ELEVATION );
137  }
138  return __iCountValid;
139 }
140 
141 
142 //------------------------------------------------------------------------------
143 // METHODS: COverlayObject (implement/override)
144 //------------------------------------------------------------------------------
145 
146 void COverlayPoint::serialize( QDataStream& _rqDataStream ) const
147 {
148  COverlayItem::serialize( _rqDataStream );
149  CDataPosition::serialize( _rqDataStream );
150 }
151 
152 void COverlayPoint::unserialize( QDataStream& _rqDataStream )
153 {
154  COverlayItem::unserialize( _rqDataStream );
155  CDataPosition::unserialize( _rqDataStream );
156 }
157 
158 
159 //------------------------------------------------------------------------------
160 // METHODS
161 //------------------------------------------------------------------------------
162 
163 //
164 // OTHER
165 //
166 
167 void COverlayPoint::drawText( const CChart* _poChart, QPainter* _pqPainter,
168  const QString& _rqsText, const QPointF& _rqPointFScrPosition,
169  bool _bItalic )
170 {
171  // Constant drawing resources
172  static const QSizeF __qSizeFRect(200,14), __qSizeRBackgroundGrow( 4, 0 );
173  static const QPointF __qPointFBackOffset(2,0);
174 
175  // Retrieve drawing parameters
176  double __fdZoom = _poChart->getZoom();
177  if( __fdZoom < 0.5 ) return;
178  else if( __fdZoom > 2.0 ) __fdZoom = 2.0;
179  __fdZoom *= QVCTRuntime::useSettings()->getScreenDpi() / 96.0 ;
180  QString __qsText = _rqsText;
181 
182  // Draw
183  COverlay* __poOverlay = useOverlay();
184  QFont __qFont = __poOverlay->getFont();
185  __qFont.setPixelSize( __qFont.pixelSize() * __fdZoom );
186  __qFont.setBold( false );
187  __qFont.setItalic( _bItalic );
188  _pqPainter->setFont( __qFont );
189 
190  // Draw: first pass (find out bounding rect)
191  QRectF __qRectFBackground;
192  _pqPainter->setPen( QPen( Qt::transparent ) );
193  _pqPainter->drawText( QRectF( _rqPointFScrPosition, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, __qsText, &__qRectFBackground );
194  // Draw: second pass (actually draw)
195  _pqPainter->setBrush( __poOverlay->getBrushText() );
196  __qRectFBackground.setSize( __qRectFBackground.size() + __qSizeRBackgroundGrow );
197  __qRectFBackground.moveCenter( _rqPointFScrPosition );
198  // ... background
199  _pqPainter->drawRect( __qRectFBackground );
200  _pqPainter->setPen( __poOverlay->getPenText() );
201  // ... text
202  _pqPainter->drawText( QRectF( __qRectFBackground.topLeft()+__qPointFBackOffset, __qRectFBackground.size() ), Qt::AlignHCenter|Qt::AlignTop, __qsText );
203 }
204 
205 void COverlayPoint::drawMarker( const CChart* _poChart, QPainter* _pqPainter, const CDataPositionValidity* _poDataPositionValidity, bool _bSelected )
206 {
207  // Constant drawing resources
208  static const QPointF __qPointFCrosshairA1(6,0), __qPointFCrosshairA2(12,0);
209  static const QPointF __qPointFCrosshairB1(0,6), __qPointFCrosshairB2(0,12);
210  static const QPointF __qPointFCrosshairC1(-6,0), __qPointFCrosshairC2(-12,0);
211  static const QPointF __qPointFCrosshairD1(0,-6), __qPointFCrosshairD2(0,-12);
212  static const QSize __qSizeSelect(32,32);
213  static const QPixmap __qPixmapSelect( ":icons/32x32/select.png" );
214 
215  // Exit if we're not visible
216  if( CDataPosition::operator==( CDataPosition::UNDEFINED ) || !bVisible ) return;
217 
218  // Retrieve drawing parameters
219  double __fdZoom = _poChart->getZoom();
220  if( __fdZoom < 0.5 ) __fdZoom = 0.5;
221  else if( __fdZoom > 2.0 ) __fdZoom = 2.0;
222  __fdZoom *= QVCTRuntime::useSettings()->getScreenDpi() / 96.0 ;
223  QPointF __qPointF = _poChart->toDrawPosition( *this );
224 
225  // Draw
226  COverlay* __poOverlay = useOverlay();
227  QPen __qPen = __poOverlay->getPenMarker();
228  __qPen.setWidth( __qPen.width() * __fdZoom );
229  if( _poDataPositionValidity && !_poDataPositionValidity->isValidPosition() ) __qPen.setStyle( Qt::DotLine );
230  // ... marker
231  if( _bSelected )
232  {
233  QPen __qPenSelected = __poOverlay->getPenMarkerSelected();
234  __qPenSelected.setWidth( __qPenSelected.width() * __fdZoom );
235  _pqPainter->setPen( __qPenSelected );
236  _pqPainter->setBrush( __poOverlay->getBrushMarkerSelected() );
237  _pqPainter->drawEllipse( __qPointF, 15*__fdZoom, 15*__fdZoom );
238  }
239  _pqPainter->setPen( __qPen );
240  _pqPainter->setBrush( __poOverlay->getBrushMarker() );
241  _pqPainter->drawEllipse( __qPointF, 9*__fdZoom, 9*__fdZoom );
242  _pqPainter->drawPoint( __qPointF );
243  _pqPainter->drawLine( __qPointF + __qPointFCrosshairA1*__fdZoom, __qPointF + __qPointFCrosshairA2*__fdZoom );
244  _pqPainter->drawLine( __qPointF + __qPointFCrosshairB1*__fdZoom, __qPointF + __qPointFCrosshairB2*__fdZoom );
245  _pqPainter->drawLine( __qPointF + __qPointFCrosshairC1*__fdZoom, __qPointF + __qPointFCrosshairC2*__fdZoom );
246  _pqPainter->drawLine( __qPointF + __qPointFCrosshairD1*__fdZoom, __qPointF + __qPointFCrosshairD2*__fdZoom );
247  // ... multi-select
248  if( !isMultiSelected() || __fdZoom <= 0.5 ) return;
249  _pqPainter->drawPixmap( __qPointF, __qPixmapSelect.scaled( __qSizeSelect*(__fdZoom/2.0), Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
250 }
251 
252 void COverlayPoint::drawSymbol( const CChart* _poChart, QPainter* _pqPainter, const QString& _rqsSymbol )
253 {
254  // Constant drawing resources
255  static const QPointF __qPointFSymbol(-32,-32);
256  static const QSize __qSizeSymbol(32,32);
257 
258  // Exit if we're not visible
259  if( CDataPosition::operator==( CDataPosition::UNDEFINED ) || !bVisible ) return;
260  // ... or no matching symbol exists
261  CMainWindow* __poMainWindow = QVCTRuntime::useMainWindow();
262  if( !QVCTRuntime::useSettings()->isVisibleSymbols() || !__poMainWindow->symbolExists( _rqsSymbol ) ) return;
263 
264  // Retrieve drawing parameters
265  double __fdZoom = _poChart->getZoom();
266  if( __fdZoom <= 0.5 ) return;
267  if( __fdZoom > 2.0 ) __fdZoom = 2.0;
268 
269  // Draw
270  _pqPainter->drawPixmap( _poChart->toDrawPosition( *this )+__qPointFSymbol*(__fdZoom/2.0), __poMainWindow->symbolPixmap( _rqsSymbol ).scaled( __qSizeSymbol*(__fdZoom/2.0), Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
271 }
272 
273 void COverlayPoint::drawTag( const CChart* _poChart, QPainter* _pqPainter, ETagPosition _eTagPosition,
274  const CDataTimeValidity* _poDataTimeValidity, const CDataPositionValidity* _poDataPositionValidity )
275 {
276  // Exit if we're not visible
277  if( CDataPosition::operator==( CDataPosition::UNDEFINED ) || !bVisible || !bVisibleName ) return;
278 
279  // Retrieve drawing parameters
280  double __fdZoom = _poChart->getZoom();
281  if( __fdZoom <= 0.5 ) return;
282  else if( __fdZoom > 2.0 ) __fdZoom = 2.0;
283  __fdZoom *= QVCTRuntime::useSettings()->getScreenDpi() / 96.0 ;
284  QPointF __qPointF = _poChart->toDrawPosition( *this );
285  QString __qsName = getName();
286  if( __qsName.length() > 20 ) { __qsName.truncate( 19 ); __qsName += QString::fromUtf8("…"); }
287 
288  // Draw
289  COverlay* __poOverlay = useOverlay();
290  QFont __qFont = __poOverlay->getFont();
291  int __iFontSize = __qFont.pixelSize() * __fdZoom;
292  __qFont.setPixelSize( __iFontSize );
293 
294  // Draw: first pass (find out bounding rect)
295  QPointF __qPointFaux = __qPointF;
296  QSizeF __qSizeFRect( __iFontSize*20, __iFontSize+4 ), __qSizeRBackgroundGrow( __iFontSize/2, 0 );
297  QPointF __qPointFBackOffset( __iFontSize/4, 0 ), __qPointFTextOffset( 0, __iFontSize );
298  QRectF __qRectFBounding, __qRectFBackground;
299  _pqPainter->setPen( QPen( Qt::transparent ) );
300  // ... name
301  __qFont.setBold( true ); __qFont.setItalic( false ); _pqPainter->setFont( __qFont );
302  _pqPainter->drawText( QRectF( __qPointFaux, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, __qsName, &__qRectFBounding );
303  __qRectFBackground = __qRectFBounding;
304  if( bVisiblePosition )
305  {
306  __qFont.setBold( false );
307  // ... time
309  {
310  __qFont.setItalic( !_poDataTimeValidity || _poDataTimeValidity->isValidTime() ? false : true );
311  _pqPainter->setFont( __qFont );
312  __qPointFaux += __qPointFTextOffset;
313  _pqPainter->drawText( QRectF( __qPointFaux, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, CUnitTime::toString( CDataTime::getTime() ), &__qRectFBounding );
314  __qRectFBackground = __qRectFBackground.united( __qRectFBounding );
315  }
316  // ... position
317  __qFont.setItalic( !_poDataPositionValidity || _poDataPositionValidity->isValidPosition() ? false : true );
318  _pqPainter->setFont( __qFont );
319  __qPointFaux += __qPointFTextOffset;
320  _pqPainter->drawText( QRectF( __qPointFaux, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, CUnitPosition::toString( CDataPosition::getLongitude(), CUnitPosition::LONGITUDE ), &__qRectFBounding );
321  __qRectFBackground = __qRectFBackground.united( __qRectFBounding );
322  __qPointFaux += __qPointFTextOffset;
323  _pqPainter->drawText( QRectF( __qPointFaux, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, CUnitPosition::toString( CDataPosition::getLatitude(), CUnitPosition::LATITUDE ), &__qRectFBounding );
324  __qRectFBackground = __qRectFBackground.united( __qRectFBounding );
325  // ... elevation
327  {
328  __qFont.setItalic( !_poDataPositionValidity || _poDataPositionValidity->isValidElevation() ? false : true );
329  _pqPainter->setFont( __qFont );
330  __qPointFaux += __qPointFTextOffset;
331  _pqPainter->drawText( QRectF( __qPointFaux, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, CUnitElevation::toString( CDataPosition::getElevation() ), &__qRectFBounding );
332  __qRectFBackground = __qRectFBackground.united( __qRectFBounding );
333  }
334  }
335 
336  // Position
337  QPointF __qPointFPositionOffset = QPointF( 20*__fdZoom, -20*__fdZoom );
338  __qRectFBackground.setSize( __qRectFBackground.size() + __qSizeRBackgroundGrow );
339  if( _eTagPosition == TAG_AUTO )
340  _eTagPosition = __qPointF.x() + __qPointFPositionOffset.x() + __qRectFBackground.width() < _poChart->getDrawArea().width()
341  ? TAG_RIGHT
342  : TAG_LEFT;
343  if( _eTagPosition == TAG_RIGHT )
344  {
345  __qPointF += __qPointFPositionOffset;
346  __qRectFBackground.moveTopLeft( __qPointF );
347  }
348  else if( _eTagPosition == TAG_LEFT )
349  {
350  __qPointFPositionOffset += QPointF( __qRectFBackground.width(), 0 );
351  __qPointF += QPointF( -__qPointFPositionOffset.x(), __qPointFPositionOffset.y() );
352  __qRectFBackground.moveTopLeft( __qPointF );
353  }
354  __qPointF += __qPointFBackOffset;
355 
356  // Draw: second pass (actually draw)
357  _pqPainter->setBrush( __poOverlay->getBrushText() );
358  // ... background
359  _pqPainter->drawRect( __qRectFBackground );
360  _pqPainter->setPen( __poOverlay->getPenText() );
361  // ... name
362  __qFont.setBold( true ); __qFont.setItalic( false ); _pqPainter->setFont( __qFont );
363  _pqPainter->drawText( QRectF( __qPointF, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, __qsName );
364  if( bVisiblePosition )
365  {
366  __qFont.setBold( false );
367  // ... time
369  {
370  __qFont.setItalic( !_poDataTimeValidity || _poDataTimeValidity->isValidTime() ? false : true );
371  _pqPainter->setFont( __qFont );
372  __qPointF += __qPointFTextOffset;
373  _pqPainter->drawText( QRectF( __qPointF, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, CUnitTime::toString( CDataTime::getTime() ) );
374  }
375  // ... position
376  __qFont.setItalic( !_poDataPositionValidity || _poDataPositionValidity->isValidPosition() ? false : true );
377  _pqPainter->setFont( __qFont );
378  __qPointF += __qPointFTextOffset;
379  _pqPainter->drawText( QRectF( __qPointF, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, CUnitPosition::toString( CDataPosition::getLongitude(), CUnitPosition::LONGITUDE ) );
380  __qPointF += __qPointFTextOffset;
381  _pqPainter->drawText( QRectF( __qPointF, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, CUnitPosition::toString( CDataPosition::getLatitude(), CUnitPosition::LATITUDE ) );
382  // ... elevation
384  {
385  __qFont.setItalic( !_poDataPositionValidity || _poDataPositionValidity->isValidElevation() ? false : true );
386  _pqPainter->setFont( __qFont );
387  __qPointF += __qPointFTextOffset;
388  _pqPainter->drawText( QRectF( __qPointF, __qSizeFRect ), Qt::AlignLeft|Qt::AlignTop, CUnitElevation::toString( CDataPosition::getElevation() ) );
389  }
390  }
391 }
392 
393 void COverlayPoint::drawLine( const CChart* _poChart, QPainter* _pqPainter, const COverlayPoint* _poOverlayPoint )
394 {
395  // Exit if we're not visible
396  if( CDataPosition::operator==( CDataPosition::UNDEFINED ) || !bVisible
397  || _poOverlayPoint->CDataPosition::operator==( CDataPosition::UNDEFINED ) || !_poOverlayPoint->bVisible ) return;
398 
399  // Retrieve drawing parameters
400  double __fdZoom = _poChart->getZoom();
401  if( __fdZoom < 0.5 ) __fdZoom = 0.5;
402  else if( __fdZoom > 2.0 ) __fdZoom = 2.0;
403  __fdZoom *= QVCTRuntime::useSettings()->getScreenDpi() / 96.0 ;
404  QPointF __qPointFFrom = _poChart->toDrawPosition( *this );
405  QPointF __qPointFTo = _poChart->toDrawPosition( *_poOverlayPoint );
406  QPointF __qPointFDelta = __qPointFTo - __qPointFFrom;
407 
408  // Draw
409  COverlay* __poOverlay = useOverlay();
410  QPen __qPen = __poOverlay->getPenLine();
411  __qPen.setWidth( __qPen.width() * __fdZoom );
412  // ... line
413  _pqPainter->setPen( __qPen );
414  _pqPainter->drawLine( __qPointFFrom, __qPointFTo );
415  // ... course data
416  double __fdBearingTo = CDataPosition::bearingRL( *this, *_poOverlayPoint );
417  double __fdDeltaLimit = ( 100.0 + 100.0*fabs( pow( sin( __fdBearingTo*QVCT::DEG2RAD ), 3 ) ) ) * __fdZoom;
418  if( ( !bVisibleRouting && !_poOverlayPoint->bVisibleRouting )
419  || __qPointFDelta.x()*__qPointFDelta.x() + __qPointFDelta.y()*__qPointFDelta.y() < __fdDeltaLimit*__fdDeltaLimit
420  || __fdZoom <= 0.5 ) return;
421  double __fdDistance = CDataPosition::distanceRL( *this, *_poOverlayPoint );
422  QString __qsDistance = CUnitDistance::toString( __fdDistance );
423  drawText( _poChart, _pqPainter, __qsDistance, 0.5 * __qPointFFrom + 0.5 * __qPointFTo );
424  if( bVisibleRouting || _poOverlayPoint->bVisibleRouting )
425  {
426  double __fdBearingFrom = __fdBearingTo + 180.0;
427  if( __fdBearingFrom > 360.0 ) __fdBearingFrom -= 360.0;
428  QString __qsBearingTo = CUnitBearing::toString( __fdBearingTo );
429  QString __qsBearingFrom = CUnitBearing::toString( __fdBearingFrom );
430  __fdBearingFrom *= QVCT::DEG2RAD;
431  __fdBearingTo *= QVCT::DEG2RAD;
432  double __fdBearingOffset = ( 35.0 + 25.0*fabs( pow( sin( __fdBearingTo ), 3 ) ) ) * __fdZoom;
433  if( bVisibleRouting ) drawText( _poChart, _pqPainter, __qsBearingTo+QString::fromUtf8("·")+__qsBearingFrom, __qPointFFrom+QPointF( __fdBearingOffset*sin( __fdBearingTo ), -__fdBearingOffset*cos( __fdBearingTo ) ) );
434  if( _poOverlayPoint->bVisibleRouting ) drawText( _poChart, _pqPainter, __qsBearingFrom+QString::fromUtf8("·")+__qsBearingTo, __qPointFTo+QPointF( __fdBearingOffset*sin( __fdBearingFrom ), -__fdBearingOffset*cos( __fdBearingFrom ) ) );
435  }
436 }
437 
438 bool COverlayPoint::matchScrPosition( const CChart* _poChart, const QPointF& _rqPointFScrPosition ) const
439 {
440  // Exit if we're not visible
441  if( CDataPosition::operator==( CDataPosition::UNDEFINED ) || !bVisible ) return false;
442 
443  // Retrieve drawing parameters
444  double __fdZoom = _poChart->getZoom();
445  if( __fdZoom < 0.5 ) __fdZoom = 0.5;
446  else if( __fdZoom > 2.0 ) __fdZoom = 2.0;
447  __fdZoom *= QVCTRuntime::useSettings()->getScreenDpi() / 96.0;
448  QPointF __qPointF = _poChart->toDrawPosition( *this );
449 
450  // Match
451  __qPointF -= _rqPointFScrPosition;
452  return( __qPointF.x()*__qPointF.x() + __qPointF.y()*__qPointF.y() <= 100*__fdZoom*__fdZoom );
453 }
[UI] Chart (view)
Definition: CChart.hpp:44
double getZoom() const
Returns the current zoom factor.
Definition: CChart.hpp:139
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
Position data validity.
bool isValidPosition() const
Returns the position's (global) validity status.
bool isValidElevation() const
Returns the elevation's (global) validity status.
(Geographical) Position data [long,lat,elev]
double getLongitude() const
Returns this position's longitude, in degrees.
static constexpr double UNDEFINED_LATITUDE
Specific value for an undefined latitude.
void resetPosition()
Resets all coordinates (to an undefined position)
double getElevation() const
Returns this position's elevation, in meters.
static double bearingRL(const CDataPosition &_roPosition1, const CDataPosition &_roPosition2)
Returns the rhumb-line (constant) bearing between two points, in degrees.
static double distanceRL(const CDataPosition &_roPosition1, const CDataPosition &_roPosition2)
Returns the rhumb-line distance between two points, in meters.
double getLatitude() const
Returns this position's latitude, in degrees.
static const CDataPosition UNDEFINED
Specific value for an undefined position.
static constexpr double UNDEFINED_LONGITUDE
Specific value for an undefined longitude.
void serialize(QDataStream &_rqDataStream) const
Serializes (store) this object's data to binary format.
void setPosition(double _fdLongitude, double _fdLatitude, double _fdElevation=UNDEFINED_ELEVATION)
Sets new coordinates.
static constexpr double UNDEFINED_ELEVATION
Specific value for an undefined elevation.
void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
Time data validity.
bool isValidTime() const
Returns the time's (global) validity status.
double getTime() const
Returns this time's time, in seconds from Unix epoch.
Definition: CDataTime.hpp:89
static constexpr double UNDEFINED_TIME
Specific value for an undefined time.
Definition: CDataTime.hpp:44
[UI] Application main window
Definition: CMainWindow.hpp:36
QPixmap symbolPixmap(const QString &_rqsSymbol)
Returns pixmap matching the given symbol (loaded from the application's symbol directory)
bool symbolExists(const QString &_rqsSymbol)
Returns whether the given symbol exists (in the application's symbol directory)
Generic overlay item.
bool isMultiSelected() const
Returns this item's selection status.
Generic overlay object.
virtual COverlay * useOverlay()=0
Returns this object's (base) overlay.
virtual void serialize(QDataStream &_rqDataStream) const
Serializes (store) this object's data to binary format.
QString getName() const
Returns this object's name.
virtual void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
Generic overlay point.
virtual bool matchScrPosition(const CChart *_poChart, const QPointF &_rqPointFScrPosition) const
Returns whether this point matches the given screen position.
static int getPositionBox(const QTreeWidgetItem *_pqTreeWidgetItem, CDataPosition *_poDataPositionLower, CDataPosition *_poDataPositionUpper, int _iIndexMin=0, int _iIndexMax=-1)
Returns the minimal geographical positions box containing the points in the given overlay/container.
virtual void drawSymbol(const CChart *_poChart, QPainter *_pqPainter, const QString &_rqsSymbol)
Draws the symbol (user-defined)
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 drawTag(const CChart *_poChart, QPainter *_pqPainter, ETagPosition _eTagPosition=TAG_AUTO, const CDataTimeValidity *_poDataTimeValidity=0, const CDataPositionValidity *_poDataPositionValidity=0)
Draws the tag (name)
virtual void drawMarker(const CChart *_poChart, QPainter *_pqPainter, const CDataPositionValidity *_poDataPositionValidity=0, bool _bSelected=false)
Draws the point (marker)
virtual void unserialize(QDataStream &_rqDataStream)
Unserializes (restore) this object's data from binary format.
virtual void serialize(QDataStream &_rqDataStream) const
Serializes (store) this object's data to binary format.
COverlayPoint(const QString &_rqsName)
virtual void drawLine(const CChart *_poChart, QPainter *_pqPainter, const COverlayPoint *_poOverlayPoint)
Draws a line (between this and the other specified point), including distance/bearing data.
Generic overlay visibility.
bool bVisibleRouting
Routing's (data) visibility status.
bool bVisible
Global (marker) visibility status.
bool bVisiblePosition
Position's visibility status.
bool bVisibleName
Name's (tag) visibility status.
Generic overlay.
Definition: COverlay.hpp:45
const QBrush & getBrushText() const
Definition: COverlay.hpp:123
const QBrush & getBrushMarker() const
Definition: COverlay.hpp:125
const QPen & getPenText() const
Definition: COverlay.hpp:124
const QPen & getPenMarkerSelected() const
Definition: COverlay.hpp:128
const QPen & getPenLine() const
Definition: COverlay.hpp:129
const QBrush & getBrushMarkerSelected() const
Definition: COverlay.hpp:127
const QFont & getFont() const
Definition: COverlay.hpp:122
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...
static QString toString(double _fdValue, EType _eType, 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, CUnitTimeZone::EUnit _eUnitTimeZone, EUnit _eUnit, int _iPrecision=0)
Returns the formatted represention of the given value, using the specified format/unit and decimal pr...
Definition: CUnitTime.cpp:79
static CMainWindow * useMainWindow()
static CSettings * useSettings()
static constexpr double DEG2RAD
Definition: QVCT.hpp:46