Qt Virtual Chart Table (QVCT)
CUnitPosition.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 <QMap>
24 #include <QRegExp>
25 #include <QString>
26 
27 // QVCT
28 #include "QVCTRuntime.hpp"
29 #include "units/CUnitPosition.hpp"
30 
31 
32 //------------------------------------------------------------------------------
33 // CONSTANTS / STATIC
34 //------------------------------------------------------------------------------
35 
38 
39 const QMap<CUnitPosition::EUnit,QString> &CUnitPosition::symbols()
40 {
42 }
43 
45 {
46  return oUnitPositionSymbols.qMapSymbols.value( _eUnit, "?" );
47 }
48 
50 {
51  return oUnitPositionSymbols.qMapSymbols.key( _rqString, UNDEFINED );
52 }
53 
54 const QMap<CUnitPosition::EUnit,QString> &CUnitPosition::codes()
55 {
57 }
58 
60 {
61  return oUnitPositionCodes.qMapCodes.value( _eUnit, "undef" );
62 }
63 
64 CUnitPosition::EUnit CUnitPosition::fromCode( const QString& _rqString )
65 {
66  return oUnitPositionCodes.qMapCodes.key( _rqString, UNDEFINED );
67 }
68 
69 QString CUnitPosition::toString( double _fdValue, EType _eType, CUnitPosition::EUnit _eUnit, int _iPrecision )
70 {
71  QString __qString;
72  switch( _eUnit )
73  {
74 
75  case DMS:
76  {
77  double __fdDeg;
78  double __fdMin = modf( fabs( _fdValue ), &__fdDeg ) * 60;
79  double __fdSec = modf( __fdMin, &__fdMin ) * 60;
80  QString __qsSec = QString::number( __fdSec, 'f', _iPrecision ).prepend( "0" ).right( 2+( _iPrecision>0 ? _iPrecision+1 : 0 ) ); // WARNING: rounding-up may occur!
81  if( __qsSec[0] == '6' ) { __fdMin += 1; __qsSec[0] = '0'; } // fix rounding-up
82  QString __qsMin = QString::number( __fdMin, 'f', 0 ).prepend( "0" ).right( 2 );
83  if( __qsMin[0] == '6' ) { __fdDeg += 1; __qsMin[0] = '0'; } // fix rounding-up
84  __qString = QString::number( __fdDeg, 'f', 0 )+QString::fromUtf8("°")+__qsMin+"'"+__qsSec+"\"";
85  }
86  break;
87 
88  case DM:
89  {
90  double __fdDeg;
91  double __fdMin = modf( fabs( _fdValue ), &__fdDeg ) * 60;
92  QString __qsMin = QString::number( __fdMin, 'f', _iPrecision ).prepend( "0" ).right( 2+( _iPrecision>0 ? _iPrecision+1 : 0 ) ); // WARNING: rounding-up may occur!
93  if( __qsMin[0] == '6' ) { __fdDeg += 1; __qsMin[0] = '0'; } // fix rounding-up
94  __qString = QString::number( __fdDeg, 'f', 0 )+QString::fromUtf8("°")+__qsMin+"'";
95  }
96  break;
97 
98  case DEG:
99  __qString = QString::number( fabs( _fdValue ), 'f', _iPrecision )+QString::fromUtf8("°");
100  break;
101 
102  case RAD:
103  __qString = QString::number( fabs( _fdValue ) * QVCT::PI / 180.0, 'f', _iPrecision )+QString::fromUtf8("°r");
104  break;
105 
106  case GRAD:
107  __qString = QString::number( fabs( _fdValue ) / 0.9, 'f', _iPrecision )+QString::fromUtf8("°g");
108  break;
109 
110  default:
111  return "?";
112 
113  }
114  __qString += _fdValue >= 0 ? ( _eType == LONGITUDE ? "E" : "N" ) : ( _eType == LONGITUDE ? "W" : "S" );
115  return __qString;
116 }
117 
118 QString CUnitPosition::toString( double _fdValue, EType _eType )
119 {
120  CSettings* __poSettings = QVCTRuntime::useSettings();
121  return toString( _fdValue, _eType, __poSettings->getUnitPosition(), __poSettings->getPrecisionPosition() );
122 }
123 
124 double CUnitPosition::fromString( const QString& _rqString, bool* _pbOK )
125 {
126  static const QRegExp __qRegExpDMS( QString::fromUtf8( "^\\s*(-?\\d+)\\s*°([0-5]?[0-9])\\s*'([0-5]?[0-9](\\.\\d+)?)\\s*\"?\\s*([NnEeSsWw])?\\s*$" ) );
127  static const QRegExp __qRegExpDM( QString::fromUtf8( "^\\s*(-?\\d+)\\s*°([0-5]?[0-9](\\.\\d+)?)\\s*'?\\s*([NnEeSsWw])?\\s*$" ) );
128  static const QRegExp __qRegExpDEG( QString::fromUtf8( "^\\s*(-?\\d+(\\.\\d+)?)\\s*°?\\s*([NnEeSsWw])?\\s*$" ) );
129  static const QRegExp __qRegExpRAD( QString::fromUtf8( "^\\s*(-?\\d+(\\.\\d+)?)\\s*°?r(ad)?\\s*([NnEeSsWw])?\\s*$" ) );
130  static const QRegExp __qRegExpGRAD( QString::fromUtf8( "^\\s*(-?\\d+(\\.\\d+)?)\\s*°?g(rad)?\\s*([NnEeSsWw])?\\s*$" ) );
131 
132  if( _pbOK ) *_pbOK = false;
133  bool __bOK;
134  double __fdValue;
135  QString __qsDirection;
136  if( __qRegExpDMS.exactMatch( _rqString ) )
137  {
138  __fdValue = __qRegExpDMS.cap(1).toDouble( &__bOK );
139  if( !__bOK ) return 0.0;
140  __fdValue += __qRegExpDMS.cap(2).toDouble( &__bOK ) / 60.0;
141  if( !__bOK ) return 0.0;
142  __fdValue += __qRegExpDMS.cap(3).toDouble( &__bOK ) / 3600.0;
143  if( !__bOK ) return 0.0;
144  __qsDirection = __qRegExpDMS.cap(5).toUpper();
145  }
146  else if( __qRegExpDM.exactMatch( _rqString ) )
147  {
148  __fdValue = __qRegExpDM.cap(1).toDouble( &__bOK );
149  if( !__bOK ) return 0.0;
150  __fdValue += __qRegExpDM.cap(2).toDouble( &__bOK ) / 60.0;
151  if( !__bOK ) return 0.0;
152  __qsDirection = __qRegExpDM.cap(4).toUpper();
153  }
154  else if( __qRegExpDEG.exactMatch( _rqString ) )
155  {
156  __fdValue = __qRegExpDEG.cap(1).toDouble( &__bOK );
157  if( !__bOK ) return 0.0;
158  __qsDirection = __qRegExpDEG.cap(3).toUpper();
159  }
160  else if( __qRegExpRAD.exactMatch( _rqString ) )
161  {
162  __fdValue = __qRegExpDEG.cap(1).toDouble( &__bOK );
163  if( !__bOK ) return 0.0;
164  __fdValue = __fdValue * 0.9;
165  __qsDirection = __qRegExpDEG.cap(4).toUpper();
166  }
167  else if( __qRegExpGRAD.exactMatch( _rqString ) )
168  {
169  __fdValue = __qRegExpDEG.cap(1).toDouble( &__bOK );
170  if( !__bOK ) return 0.0;
171  __fdValue = __fdValue * 180.0 / QVCT::PI;
172  __qsDirection = __qRegExpDEG.cap(4).toUpper();
173  }
174  else return 0.0;
175  if( !__qsDirection.isEmpty() && __fdValue < 0 ) return 0.0;
176  if( __qsDirection == "W" || __qsDirection == "S" ) __fdValue = -__fdValue;
177  if( _pbOK ) *_pbOK = true;
178  return __fdValue;
179 }
[UI] Container for the application's settings
Definition: CSettings.hpp:51
CUnitPosition::EUnit getUnitPosition()
[Unit] Returns the position format/unit
Definition: CSettings.hpp:347
int getPrecisionPosition()
[Precision] Returns the position decimal precision
Definition: CSettings.hpp:364
Container class for supported machine-friendly format/unit codes.
QMap< CUnitPosition::EUnit, QString > qMapCodes
Container class for supported human-readable format/unit symbols.
QMap< CUnitPosition::EUnit, QString > qMapSymbols
EType
Position coordinate type ID.
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 const CUnitPositionCodes oUnitPositionCodes
Container for supported machine-friendly format/unit codes.
static const QMap< EUnit, QString > & codes()
Returns the list of supported machine-friendly format/unit codes.
EUnit
Format/unit ID.
@ UNDEFINED
undefined format/unit
@ DM
degrees, minutes
@ DMS
degrees, minutes, seconds
static const QMap< EUnit, QString > & symbols()
Returns the list of supported human-readable format/unit symbols.
static QString toCode(EUnit _eUnit)
Returns the machine-friendly code corresponding to the given format/unit ID.
static QString toSymbol(EUnit _eUnit)
Returns the human-readable symbol corresponding to the given format/unit ID.
static double fromString(const QString &_rqString, bool *_pbOK=0)
Returns the numeric value corresponding (parsed) from the string.
static EUnit fromSymbol(const QString &_rqsSymbol)
Returns the format/unit ID corresponding to the given human-readable symbol.
static const CUnitPositionSymbols oUnitPositionSymbols
Container for supported human-readable format/unit symbols.
static EUnit fromCode(const QString &_rqsCode)
Returns the format/unit ID corresponding to the given machine-friendly code.
static CSettings * useSettings()
static constexpr double PI
Definition: QVCT.hpp:45