Individual (per object) conversion as well as per unit (class) now possible, this is required for sexagesimal conversion (degrees) and will be required for geo-positions. Further classed for avionics.

This commit is contained in:
Klaus Basan
2013-04-05 02:29:52 +02:00
parent 943872ff67
commit eb102372f1
18 changed files with 622 additions and 98 deletions

66
src/blackmisc/aviobase.h Normal file
View File

@@ -0,0 +1,66 @@
#ifndef AVIOBASE_H
#define AVIOBASE_H
#include "blackmisc/pqconstants.h"
namespace BlackMisc {
/*!
* \brief Base class for avionics
*/
class CAvionicsBase
{
/*!
* Stream operator for debugging
* \brief operator <<
* \param debug
* \param avionic
* \return
* \remarks Has to be in the header files to avoid template link errors
*/
friend QDebug operator<<(QDebug debug, const CAvionicsBase &avionic) {
QString v = avionic.stringForStreamingOperator();
debug << v;
return debug;
}
/*!
* Stream operator for log messages
* \brief operator <<
* \param log
* \param avionic
* \return
* \remarks Has to be in the header files to avoid template link errors
*/
friend CLogMessage operator<<(CLogMessage log, const CAvionicsBase &avionic) {
QString v = avionic.stringForStreamingOperator();
log << v;
return log;
}
protected:
/*!
* \brief Default constructor
*/
CAvionicsBase() {}
/*!
* \brief Meaningful string representation
* \return
*/
virtual QString stringForStreamingOperator() const = 0;
/*!
* \brief Are the set values valid / in range
* \return
*/
virtual bool validValues() { return true; }
public:
/**
* @brief Virtual destructor
*/
virtual ~CAvionicsBase() {}
};
} // namespace
#endif // AVIOBASE_H

View File

@@ -0,0 +1,146 @@
#ifndef AVIOCOMUNIT_H
#define AVIOCOMUNIT_H
#include "blackmisc/aviomodulator.h"
namespace BlackMisc {
/*!
* \brief COM system (aka "radio")
*/
class CComSystem : public CModulator<CComSystem>
{
private:
/*!
* \brief Valid civil aviation frequency?
* \param f
* \return
*/
bool isValidCivilAviationFrequency(CFrequency f) { double fr = f.valueRounded(CFrequencyUnit::MHz(), this->m_digits); return fr >= 118.0 && fr <= 136.975; }
/*!
* \brief Valid military aviation frequency?
* \param f
* \return
*/
bool isValidMilitaryFrequency(CFrequency f) { double fr = f.valueRounded(CFrequencyUnit::MHz(), this->m_digits); return fr >= 220.0 && fr <= 399.95; }
public:
/*!
* Default constructor
*/
CComSystem() : CModulator() {}
/*!
* \brief Copy constructor
* \param otherUnit
*/
CComSystem(const CComSystem &otherUnit) : CModulator(otherUnit) {}
/*!
* \brief Constructor
* \param name
* \param activeFrequency
* \param standbyFrequency
* \param digits
*/
CComSystem(const QString &name, const CFrequency &activeFrequency, const CFrequency &standbyFrequency, int digits =3):
CModulator(name, activeFrequency, standbyFrequency, digits) {}
/*!
* \brief Set active frequency
* \param frequencyMHz
*/
void setFrequencyActiveMHz(double frequencyMHz) { CModulator::setFrequencyActiveMHz(frequencyMHz); }
/*!
* \brief Set standby frequency
* \param frequencyMHz
*/
void setFrequencyStandbyMHz(double frequencyMHz) { CModulator::setFrequencyStandbyMHz(frequencyMHz); }
/*!
* \brief Set UNICOM frequency as active
*/
void setActiveUnicom() { this->toggleActiveStandby(); this->setFrequencyActive(CPhysicalQuantitiesConstants::FrequencyUnicom());}
/*!
* \brief Set International Air Distress 121.5MHz
*/
void setActiveInternationalAirDistress() { this->toggleActiveStandby(); this->setFrequencyActive(CPhysicalQuantitiesConstants::FrequencyInternationalAirDistress());}
/*!
* \brief Assigment operator =
* \param otherSystem
* \return
*/
CComSystem& operator =(const CComSystem &otherSystem) { CModulator::operator =(otherSystem); return (*this); }
/*!
* \brief operator ==
* \param otherSystem
* \return
*/
bool operator ==(const CComSystem &otherSystem) const { return CModulator::operator ==(otherSystem); }
/*!
* \brief operator ==
* \param otherSystem
* \return
*/
bool operator !=(const CComSystem &otherSystem) const { return CModulator::operator !=(otherSystem); }
/*!
* \brief Are the set values valid / in range?
* \return
*/
virtual bool validValues() {
return
this->isValidCivilAviationFrequency(this->getFrequencyActive()) &&
this->isValidMilitaryFrequency(this->getFrequencyActive()) &&
this->isValidCivilAviationFrequency(this->getFrequencyStandby()) &&
this->isValidMilitaryFrequency(this->getFrequencyStandby());
}
/*!
* \brief COM1 unit
* \param activeFrequencyMHz
* \param standbyFrequencyMHz
* \return
*/
static CComSystem getCom1Unit(double activeFrequencyMHz, double standbyFrequencyMHz = -1) {
return CComSystem(CModulator::NameCom1(), CFrequency(activeFrequencyMHz, CFrequencyUnit::MHz()), CFrequency(standbyFrequencyMHz < 0 ? activeFrequencyMHz : standbyFrequencyMHz,CFrequencyUnit::MHz()));}
/*!
* \brief COM1 unit
* \param activeFrequency
* \param standbyFrequency
* \return
*/
static CComSystem getCom1Unit(CFrequency activeFrequency, CFrequency standbyFrequency = CModulator::FrequencyNotSet()) {
return CComSystem(CModulator::NameCom1(), activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency);}
/*!
* \brief COM2 unit
* \param activeFrequencyMHz
* \param standbyFrequencyMHz
* \return
*/
static CComSystem getCom2Unit(double activeFrequencyMHz, double standbyFrequencyMHz = -1) {
return CComSystem(CModulator::NameCom2(), CFrequency(activeFrequencyMHz, CFrequencyUnit::MHz()), CFrequency(standbyFrequencyMHz < 0 ? activeFrequencyMHz : standbyFrequencyMHz,CFrequencyUnit::MHz()));}
/*!
* \brief COM2 unit
* \param activeFrequency
* \param standbyFrequency
* \return
*/
static CComSystem getCom2Unit(CFrequency activeFrequency, CFrequency standbyFrequency = CModulator::FrequencyNotSet()) {
return CComSystem(CModulator::NameCom2(), activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency);}
/*!
* \brief COM3 unit
* \param activeFrequencyMHz
* \param standbyFrequencyMHz
* \return
*/
static CComSystem getCom3Unit(double activeFrequencyMHz, double standbyFrequencyMHz = -1) {
return CComSystem(CModulator::NameCom3(), CFrequency(activeFrequencyMHz, CFrequencyUnit::MHz()), CFrequency(standbyFrequencyMHz < 0 ? activeFrequencyMHz : standbyFrequencyMHz,CFrequencyUnit::MHz()));}
/*!
* \brief COM3 unit
* \param activeFrequency
* \param standbyFrequency
* \return
*/
static CComSystem getCom3Unit(CFrequency activeFrequency, CFrequency standbyFrequency = CModulator::FrequencyNotSet()) {
return CComSystem(CModulator::NameCom3(), activeFrequency, standbyFrequency == CModulator::FrequencyNotSet() ? activeFrequency : standbyFrequency);}
};
} // namespace
#endif // AVIOCOMUNIT_H

View File

@@ -0,0 +1,64 @@
#include "blackmisc/aviomodulator.h"
#include "blackmisc/aviocomsystem.h"
namespace BlackMisc {
/**
* Toggle standby <-> active
*/
template <class AVIO> void CModulator<AVIO>::toggleActiveStandby()
{
CFrequency a = this->m_frequencyActive;
this->m_frequencyActive = this->m_frequencyStandby;
this->m_frequencyStandby = a;
}
/**
* String representation
*/
template <class AVIO> QString CModulator<AVIO>::stringForStreamingOperator() const
{
QString s(this->m_name);
s.append(" Active: ").append(this->m_frequencyActive.unitValueRoundedWithUnit(3));
s.append(" Standby: ").append(this->m_frequencyStandby.unitValueRoundedWithUnit(3));
return s;
}
/**
* Assigment operator =
*/
template <class AVIO> CModulator<AVIO>& CModulator<AVIO>::operator=(const CModulator<AVIO> &otherModulator) {
if (this == &otherModulator) return *this; // Same object?
this->m_frequencyActive = otherModulator.m_frequencyActive;
this->m_frequencyStandby = otherModulator.m_frequencyStandby;
this->m_name = otherModulator.m_name;
this->m_digits = otherModulator.m_digits;
return *this;
}
/**
* Equal operator ==
*/
template <class AVIO> bool CModulator<AVIO>::operator ==(const CModulator<AVIO> &otherModulator) const
{
if(this == &otherModulator) return true;
return (this->m_name == otherModulator.m_name &&
this->m_frequencyActive == otherModulator.m_frequencyActive &&
this->m_frequencyStandby == otherModulator.m_frequencyStandby);
}
/**
* Equal operator !=
*/
template <class AVIO> bool CModulator<AVIO>::operator !=(const CModulator<AVIO> &otherModulator) const
{
return !(otherModulator == (*this));
}
// see here for the reason of thess forward instantiations
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
template class CModulator<CComSystem>;
} // namespace

View File

@@ -0,0 +1,167 @@
#ifndef AVIOMODULATORUNIT_H
#define AVIOMODULATORUNIT_H
#include "blackmisc/aviobase.h"
namespace BlackMisc {
/*!
* \brief Base class for COM, NAV, Squawk units.
*/
template <class AVIO> class CModulator : public CAvionicsBase
{
private:
CFrequency m_frequencyActive; //!< active frequency
CFrequency m_frequencyStandby; //!< standby frequency
QString m_name; //!< name of the unit
protected:
int m_digits; //!< digits used
/*!
* \brief Default constructor
*/
CModulator() {}
/*!
* \brief Copy constructor
* \param otherUnit
*/
CModulator(const CModulator &otherUnit) :
m_frequencyActive(otherUnit.m_frequencyActive), m_frequencyStandby(otherUnit.m_frequencyStandby),
m_name(otherUnit.m_name), m_digits(otherUnit.m_digits) {}
/*!
* \brief Constructor
* \param name
* \param activeFrequency
* \param standbyFrequency
*/
CModulator(const QString &name, const CFrequency &activeFrequency, const CFrequency &standbyFrequency, int digits) :
m_name(name), m_frequencyActive(activeFrequency),
m_digits(digits), m_frequencyStandby(standbyFrequency) {}
/*!
* \brief Meaningful string representation
* \return
*/
virtual QString stringForStreamingOperator() const;
/*!
* \brief Set active frequency
* \param frequencyKHz
*/
void setFrequencyActiveKHz(double frequencyKHz) { this->m_frequencyActive = CFrequency(frequencyKHz, CFrequencyUnit::kHz()); }
/*!
* \brief Set standby frequency
* \param frequencyKHz
*/
void setFrequencyStandbyKHz(double frequencyKHz) { this->m_frequencyStandby = CFrequency(frequencyKHz, CFrequencyUnit::kHz()); }
/*!
* \brief Set active frequency
* \param frequencyMHz
*/
void setFrequencyActiveMHz(double frequencyMHz) { this->m_frequencyActive = CFrequency(frequencyMHz, CFrequencyUnit::MHz()); }
/*!
* \brief Set standby frequency
* \param frequencyMHz
*/
void setFrequencyStandbyMHz(double frequencyMHz) { this->m_frequencyStandby = CFrequency(frequencyMHz, CFrequencyUnit::MHz()); }
/*!
* \brief Assigment operator =
* \param otherModulator
* \return
*/
CModulator& operator =(const CModulator &otherModulator);
/*!
* \brief operator ==
* \param otherModulator
* \return
*/
bool operator ==(const CModulator &otherModulator) const;
/*!
* \brief operator !=
* \param otherModulator
* \return
*/
bool operator !=(const CModulator &otherModulator) const;
/*!
* \brief COM1
* \return
*/
static const QString& NameCom1() { static QString n("COM1"); return n; }
/*!
* \brief COM2
* \return
*/
static const QString& NameCom2() { static QString n("COM2"); return n; }
/*!
* \brief COM3
* \return
*/
static const QString& NameCom3() { static QString n("COM3"); return n; }
/*!
* \brief NAV1
* \return
*/
static const QString& NameNav1() { static QString n("NAV1"); return n; }
/*!
* \brief NAV2
* \return
*/
static const QString& NameNav2() { static QString n("NAV2"); return n; }
/*!
* \brief NAV2
* \return
*/
static const QString& NameNav3() { static QString n("NAV2"); return n; }
/*!
* \brief ADF1
* \return
*/
static const QString& NameAdf1() { static QString n("ADF1"); return n; }
/*!
* \brief ADF2
* \return
*/
static const QString& NameAdf2() { static QString n("ADF2"); return n; }
/*!
* \brief Frequency not set
* \return
*/
static const CFrequency& FrequencyNotSet() { static CFrequency f; return f; }
public:
/*!
* \brief Virtual destructor
*/
virtual ~CModulator() {}
/*!
* \brief Toggle active and standby frequencies
*/
void toggleActiveStandby();
/*!
* \brief Name
* \return
*/
QString getName() const { return this->m_name; }
/*!
* \brief Active frequency
* \return
*/
CFrequency getFrequencyActive() const { return this->m_frequencyActive; }
/*!
* \brief Standby frequency
* \return
*/
CFrequency getFrequencyStandby() const { return this->m_frequencyActive; }
/*!
* \brief Set active frequency
* \param frequency
*/
void setFrequencyActive(const CFrequency &frequency) { this->m_frequencyActive = frequency; }
/*!
* \brief Set standby frequency
* \param frequency
*/
void setFrequencyStandby(const CFrequency &frequency) { this->m_frequencyStandby = frequency; }
};
} // namespace
#endif // AVIOMODULATORUNIT_H

View File

@@ -0,0 +1,12 @@
#include "aviobase.h"
namespace BlackMisc {
/**
* Defaultc
*/
CAvionicsBase::CAvionicsBase()
{
}
} // namespace

View File

@@ -52,7 +52,10 @@ HEADERS += \
avheading.h \
avtrack.h \
avaltitude.h \
avverticalpositions.h
avverticalpositions.h \
aviobase.h \
aviomodulator.h \
aviocomsystem.h
SOURCES += \
logmessage.cpp \
@@ -79,6 +82,7 @@ SOURCES += \
avheading.cpp \
avtrack.cpp \
avaltitude.cpp \
avverticalpositions.cpp
avverticalpositions.cpp \
aviomodulator.cpp
DESTDIR = ../../lib

View File

@@ -94,9 +94,12 @@ CLogMessage operator<<(CLogMessage log, const CMeasurementPrefix &multiplier)
/**
* Constructor
*/
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI, const CMeasurementPrefix &multiplier, qint32 displayDigits, double epsilon):
m_name(name), m_unitName(unitName), m_type(type), m_isSIUnit(isSIUnit), m_isSIBaseUnit(isSIBaseUnit),m_displayDigits(displayDigits),m_conversionFactorToSIConversionUnit(conversionFactorToSI),
m_epsilon(epsilon), m_multiplier(multiplier)
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSIUnit, bool isSIBaseUnit,
double conversionFactorToSI, const CMeasurementPrefix &multiplier, qint32 displayDigits, double epsilon,
UnitConverter toSiConverter, UnitConverter fromSiConverter):
m_name(name), m_unitName(unitName), m_type(type), m_isSiUnit(isSIUnit), m_isSiBaseUnit(isSIBaseUnit), m_displayDigits(displayDigits),
m_conversionFactorToSIConversionUnit(conversionFactorToSI),
m_epsilon(epsilon), m_multiplier(multiplier), m_fromSiConverter(fromSiConverter), m_toSiConverter(toSiConverter)
{
// void
}
@@ -105,9 +108,9 @@ CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName,
* Copy constructor
*/
CMeasurementUnit::CMeasurementUnit(const CMeasurementUnit &otherUnit):
m_name(otherUnit.m_name), m_unitName(otherUnit.m_unitName), m_type(otherUnit.m_type), m_isSIUnit(otherUnit.m_isSIUnit),
m_isSIBaseUnit(otherUnit.m_isSIBaseUnit), m_displayDigits(otherUnit.m_displayDigits),m_conversionFactorToSIConversionUnit(otherUnit.m_conversionFactorToSIConversionUnit),
m_epsilon(otherUnit.m_epsilon), m_multiplier(otherUnit.m_multiplier)
m_name(otherUnit.m_name), m_unitName(otherUnit.m_unitName), m_type(otherUnit.m_type), m_isSiUnit(otherUnit.m_isSiUnit),
m_isSiBaseUnit(otherUnit.m_isSiBaseUnit), m_displayDigits(otherUnit.m_displayDigits),m_conversionFactorToSIConversionUnit(otherUnit.m_conversionFactorToSIConversionUnit),
m_epsilon(otherUnit.m_epsilon), m_multiplier(otherUnit.m_multiplier), m_fromSiConverter(otherUnit.m_fromSiConverter), m_toSiConverter(otherUnit.m_toSiConverter)
{
// void
}
@@ -121,12 +124,14 @@ CMeasurementUnit &CMeasurementUnit::operator =(const CMeasurementUnit &otherUnit
this->m_name = otherUnit.m_name;
this->m_unitName =otherUnit.m_unitName;
this->m_type=otherUnit.m_type;
this->m_isSIUnit =otherUnit.m_isSIUnit;
this->m_isSIBaseUnit =otherUnit.m_isSIBaseUnit;
this->m_isSiUnit =otherUnit.m_isSiUnit;
this->m_isSiBaseUnit =otherUnit.m_isSiBaseUnit;
this->m_conversionFactorToSIConversionUnit=otherUnit.m_conversionFactorToSIConversionUnit;
this->m_multiplier = otherUnit.m_multiplier;
this->m_displayDigits=otherUnit.m_displayDigits;
this->m_epsilon= otherUnit.m_epsilon;
this->m_fromSiConverter = otherUnit.m_fromSiConverter;
this->m_toSiConverter = otherUnit.m_toSiConverter;
return *this;
}
@@ -138,7 +143,7 @@ bool CMeasurementUnit::operator ==(const CMeasurementUnit &otherUnit) const
if ( this == &otherUnit ) return true;
if ( this->m_type != otherUnit.m_type) return false;
return this->m_multiplier == otherUnit.m_multiplier && this->m_name == otherUnit.m_name
&& this->m_isSIUnit==otherUnit.m_isSIUnit;
&& this->m_isSiUnit==otherUnit.m_isSiUnit;
}
/**

View File

@@ -162,6 +162,7 @@ public:
* Base class for all units, such as meter, hertz.
*/
class CMeasurementUnit {
/*!
* \brief Stream << overload to be used in debugging messages
* \param d
@@ -179,18 +180,27 @@ class CMeasurementUnit {
*/
friend CLogMessage operator<<(CLogMessage log, const CMeasurementUnit &unit);
protected:
/*!
* Points to a individual converter method
*/
typedef double(*UnitConverter)(const CMeasurementUnit&, double);
private:
QString m_name; //!< name, e.g. "meter"
QString m_unitName; //!< unit name, e.g. "m"
QString m_type; //!< type,such as distance. Somehow redundant, but simplifies unit comparisons
bool m_isSIUnit; //!< is this a SI unit?
bool m_isSIBaseUnit; //!< SI base unit?
bool m_isSiUnit; //!< is this a SI unit?
bool m_isSiBaseUnit; //!< SI base unit?
double m_conversionFactorToSIConversionUnit; //!< factor to convert to SI, set to 0 if not applicable (rare cases, e.g. temperature)
double m_epsilon; //!< values with differences below epsilon are the equal
qint32 m_displayDigits; //!< standard rounding for string conversions
CMeasurementPrefix m_multiplier; //!< multiplier (kilo, Mega)
UnitConverter m_toSiConverter;
UnitConverter m_fromSiConverter;
protected:
/*!
* Constructor by parameter
* \param name
@@ -202,7 +212,9 @@ protected:
* \param displayDigits
* \param epsilon
*/
CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSiUnit, bool isSiBaseUnit, double conversionFactorToSI = 1, const CMeasurementPrefix &multiplier = CMeasurementPrefix::None(), qint32 displayDigits = 2, double epsilon = 1E-10);
CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSiUnit, bool isSiBaseUnit, double conversionFactorToSI = 1,
const CMeasurementPrefix &multiplier = CMeasurementPrefix::None(), qint32 displayDigits = 2,
double epsilon = 1E-10, UnitConverter toSiConverter = nullptr, UnitConverter fromSiConverter = nullptr);
/*!
* \brief Copy constructor
* \param otherUnit
@@ -220,6 +232,20 @@ protected:
* \return
*/
double getConversionFactorToSI() const { return this->m_conversionFactorToSIConversionUnit; }
/*!
* Given value to conversion SI conversion unit (e.g. meter, hertz).
* Standard implementaion is simply factor based.
* \param value
* \return
*/
virtual double conversionToSiConversionUnit(double value) const { return value * this->m_conversionFactorToSIConversionUnit; }
/*!
* \brief Value from SI conversion unit to this unit.
* Standard implementaion is simply factor based.
* \param value
* \return
*/
virtual double conversionFromSiConversionUnit(double value) const { return value / this->m_conversionFactorToSIConversionUnit; }
public:
/*!
@@ -238,17 +264,17 @@ public:
* \brief Representing an SI unit? Examples: kilometer, meter, hertz
* \return
*/
bool isSiUnit() const { return this->m_isSIUnit;}
bool isSiUnit() const { return this->m_isSiUnit;}
/*!
* \brief Representing an base SI unit? Examples: second, meter
* \return
*/
bool isSiBaseUnit() const { return this->m_isSIUnit;}
bool isSiBaseUnit() const { return this->m_isSiUnit;}
/*!
* \brief Representing an SI base unit? Example: meter
* \return
*/
bool isUnprefixedSiUnit() const { return this->m_isSIUnit && this->m_multiplier.getFactor() == 1; }
bool isUnprefixedSiUnit() const { return this->m_isSiUnit && this->m_multiplier.getFactor() == 1; }
/*!
* \brief Name such as "meter"
* \return
@@ -264,20 +290,21 @@ public:
* \return
*/
QString getType() const { return this->m_type; }
/*!
* Given value to conversion SI conversion unit (e.g. meter, hertz).
* Standard implementaion is simply factor based.
* Standard implementation is simply factor based.
* \param value
* \return
*/
virtual double convertToSiConversionUnit(double value) const { return value * this->m_conversionFactorToSIConversionUnit; }
double convertToSiConversionUnit(double value) const { return (this->m_toSiConverter) ? this->m_toSiConverter((*this), value) : this->conversionToSiConversionUnit(value); }
/*!
* \brief Value from SI conversion unit to this unit.
* Standard implementaion is simply factor based.
* Value from SI conversion unit to this unit.
* Standard implementation is simply factor based.
* \param value
* \return
*/
virtual double convertFromSiConversionUnit(double value) const { return value / this->m_conversionFactorToSIConversionUnit; }
double convertFromSiConversionUnit(double value) const { return (this->m_fromSiConverter) ? this->m_fromSiConverter((*this), value) : this->conversionFromSiConversionUnit(value); }
/*!
* Rounded string utility method, virtual so units can have
* specialized formatting

View File

@@ -39,6 +39,21 @@ public:
* \return
*/
static const CLength& Length0ft() { static CLength l(0, CLengthUnit::ft()); return l;}
/*!
* \brief Unicom frequency
* \return
*/
static const CFrequency& FrequencyUnicom() { static CFrequency f(122.8, CFrequencyUnit::MHz()); return f;}
/*!
* \brief Civil aircraft emergency frequency
* \return
*/
static const CFrequency& FrequencyInternationalAirDistress() { static CFrequency f(121.5, CFrequencyUnit::MHz()); return f;}
/*!
* \brief Military aircraft emergency frequency
* \return
*/
static const CFrequency& FrequencyMilitaryAirDistress() { static CFrequency f(243.0, CFrequencyUnit::MHz()); return f;}
};
} // namespace
#endif // PQCONSTANTS_H

View File

@@ -364,7 +364,7 @@ template <class MU, class PQ> double CPhysicalQuantity<MU,PQ>::convertedSiValueT
}
// see here for the reason of this forward instants
// see here for the reason of thess forward instantiations
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
template class CPhysicalQuantity<CLengthUnit, CLength>;
template class CPhysicalQuantity<CPressureUnit, CPressure>;

View File

@@ -5,7 +5,7 @@ namespace BlackMisc {
/**
* Convert to SI
*/
double CTemperatureUnit::convertToSiConversionUnit(double value) const
double CTemperatureUnit::conversionToSiConversionUnit(double value) const
{
double v = value + this->m_conversionOffsetToSi;
v *= this->getConversionFactorToSI();
@@ -15,7 +15,7 @@ double CTemperatureUnit::convertToSiConversionUnit(double value) const
/**
* Convert from SI
*/
double CTemperatureUnit::convertFromSiConversionUnit(double value) const
double CTemperatureUnit::conversionFromSiConversionUnit(double value) const
{
double v = value / this->getConversionFactorToSI();
v -= this->m_conversionOffsetToSi;
@@ -25,49 +25,34 @@ double CTemperatureUnit::convertFromSiConversionUnit(double value) const
/**
* Convert from SI
*/
double CAngleUnit::convertFromSiConversionUnit(double value) const
double CAngleUnit::conversionSexagesimalFromSi(const CMeasurementUnit &angleUnit, double value)
{
double v;
// still a design flaw since I have to distinguish as per type
// but an own converter per object was really too much
if ((*this) == CAngleUnit::sexagesimalDeg()) {
// using rounding here, since fractions can lead to ugly sexagesimal conversion
// e.g. 185.499999 gives 185 29' 59.9999"
value = this->epsilonRounding(value * 180 / M_PI); // degree
v = floor(value);
double c = value - v;
double mr = c * 60.0;
double m = floor(mr); // minutes
double s = (mr-m) * 60; // seconds + rest fraction
v = (v + (m/100) + (s/10000));
} else {
v = CMeasurementUnit::convertFromSiConversionUnit(value);
}
// using rounding here, since fractions can lead to ugly sexagesimal conversion
// e.g. 185.499999 gives 185 29' 59.9999"
value = angleUnit.epsilonRounding(value * 180 / M_PI); // degree
double v = floor(value);
double c = value - v;
double mr = c * 60.0;
double m = floor(mr); // minutes
double s = (mr-m) * 60; // seconds + rest fraction
v = (v + (m/100) + (s/10000));
return v;
}
/**
* Convert to SI
*/
double CAngleUnit::convertToSiConversionUnit(double value) const
double CAngleUnit::conversionSexagesimalToSi(const CMeasurementUnit &, double value)
{
// still a design flaw since I have to distinguish as per type
// but an own converter per object was really too much
double v;
if ((*this) == CAngleUnit::sexagesimalDeg()) {
double v = floor(value); // degrees
double c = value - v;
c = c * 100.0;
double m = floor(c);
c = c - m;
m /= 60.0; // minutes back to decimals
double s = c / 36.0; // seconds back to decimals
v = v + m + s;
return v / 180.0 * M_PI;
} else {
v = CMeasurementUnit::convertToSiConversionUnit(value);
}
return v;
double v = floor(value); // degrees
double c = value - v;
c = c * 100.0;
double m = floor(c);
c = c - m;
m /= 60.0; // minutes back to decimals
double s = c / 36.0; // seconds back to decimals
v = v + m + s;
return v / 180.0 * M_PI;
}
/**
@@ -90,4 +75,4 @@ QString CAngleUnit::toQStringRounded(double value, int digits) const
return s;
}
}
} // namespace

View File

@@ -65,7 +65,7 @@ public:
/*!
* Specialized class for angles (degrees, radian).
* \author KWB
* \author KWB, MS
*/
class CAngleUnit : public CMeasurementUnit {
private:
@@ -79,29 +79,33 @@ private:
* \param displayDigits
* \param epsilon
*/
CAngleUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) :
CMeasurementUnit(name, unitName, "angle", isSIUnit, false, conversionFactorToSI, mulitplier, displayDigits, epsilon)
CAngleUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0,
const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2,
double epsilon = 1E-9, UnitConverter converterToSi = nullptr, UnitConverter converterFromSi= nullptr) :
CMeasurementUnit(name, unitName, "angle", isSIUnit, false, conversionFactorToSI,
mulitplier, displayDigits, epsilon, converterToSi, converterFromSi)
{
// void
}
/*!
* \brief Special conversion for sexagesimal degrees
* \param value
* \return
*/
static double conversionSexagesimalToSi(const CMeasurementUnit &angleUnit, double value);
/*!
* \brief Special conversion for sexagesimal degrees
* \param value
* \return
*/
static double conversionSexagesimalFromSi(const CMeasurementUnit &angleUnit, double value);
public:
/*!
* \brief Copy constructor
* \param otherUnit
*/
CAngleUnit(const CAngleUnit &otherUnit) : CMeasurementUnit(otherUnit) { }
/*!
* \brief Convert to SI conversion unit, specific for angle
* \param value
* \return
*/
virtual double CAngleUnit::convertToSiConversionUnit(double value) const;
/*!
* \brief Convert from SI conversion unit, specific for angle
* \param value
* \return
*/
virtual double CAngleUnit::convertFromSiConversionUnit(double value) const;
/*!
* \brief Special conversion to QString for sexagesimal degrees.
* \param value
@@ -123,12 +127,13 @@ public:
* \brief Sexagesimal degree (degree, minute, seconds)
* \return
*/
static const CAngleUnit& sexagesimalDeg() { static CAngleUnit deg("segadecimal degree", "°", false, M_PI/180); return deg;}
static const CAngleUnit& sexagesimalDeg() { static CAngleUnit deg("segadecimal degree", "°", false, M_PI/180,
CMeasurementPrefix::One(),0, 1E-9, CAngleUnit::conversionSexagesimalToSi, CAngleUnit::conversionSexagesimalFromSi); return deg;}
};
/*!
* Specialized class for frequency (hertz, mega hertz, kilo hertz).
* \author KWB
* \author KWB, MS
*/
class CFrequencyUnit : public CMeasurementUnit {
private:
@@ -159,22 +164,22 @@ public:
* \brief Kilohertz
* \return
*/
static const CFrequencyUnit& kHz() { static CFrequencyUnit kHz("kilohertz", "kHz", true, CMeasurementPrefix::k().getFactor(), CMeasurementPrefix::k(), 0);return kHz;}
static const CFrequencyUnit& kHz() { static CFrequencyUnit kHz("kilohertz", "kHz", true, CMeasurementPrefix::k().getFactor(), CMeasurementPrefix::k(), 1);return kHz;}
/*!
* \brief Megahertz
* \return
*/
static const CFrequencyUnit& MHz() { static CFrequencyUnit MHz("megahertz", "MHz", false, CMeasurementPrefix::M().getFactor(), CMeasurementPrefix::M(), 0); return MHz;}
static const CFrequencyUnit& MHz() { static CFrequencyUnit MHz("megahertz", "MHz", false, CMeasurementPrefix::M().getFactor(), CMeasurementPrefix::M(), 2); return MHz;}
/*!
* \brief Gigahertz
* \return
*/
static const CFrequencyUnit& GHz() { static CFrequencyUnit GHz("gigahertz", "GHz", true, CMeasurementPrefix::G().getFactor(), CMeasurementPrefix::G(), 0);return GHz;}
static const CFrequencyUnit& GHz() { static CFrequencyUnit GHz("gigahertz", "GHz", true, CMeasurementPrefix::G().getFactor(), CMeasurementPrefix::G(), 2);return GHz;}
};
/*!
* Specialized class for mass units (kg, lbs).
* \author KWB
* \author KWB, MS
*/
class CMassUnit : public CMeasurementUnit {
private:
@@ -220,7 +225,7 @@ public:
/*!
* Specialized class for pressure (psi, hPa, bar).
* \author KWB
* \author KWB, MS
*/
class CPressureUnit : public CMeasurementUnit {
private:
@@ -238,6 +243,10 @@ private:
CPressureUnit(const QString &name, const QString &unitName, bool isSIUnit, double conversionFactorToSI = 1.0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) :
CMeasurementUnit(name, unitName, "frequency", isSIUnit, false, conversionFactorToSI, mulitplier, displayDigits, epsilon) {}
public:
/*!
* \brief Copy constructor
* \param otherUnit
*/
CPressureUnit(const CPressureUnit &otherUnit) : CMeasurementUnit(otherUnit)
{
// void
@@ -301,6 +310,19 @@ private:
*/
CTemperatureUnit(const QString &name, const QString &unitName, bool isSIUnit, bool isSIBaseUnit, double conversionFactorToSI = 1.0, double temperatureOffsetToSI=0, const CMeasurementPrefix &mulitplier = CMeasurementPrefix::One(), qint32 displayDigits = 2, double epsilon = 1E-9) :
CMeasurementUnit(name, unitName, "temperature", isSIUnit, isSIBaseUnit, conversionFactorToSI, mulitplier, displayDigits, epsilon), m_conversionOffsetToSi(temperatureOffsetToSI) {}
protected:
/*!
* \brief Convert to SI conversion unit, specific for temperature
* \param value
* \return
*/
virtual double CTemperatureUnit::conversionToSiConversionUnit(double value) const;
/*!
* \brief Convert from SI conversion unit, specific for temperature
* \param value
* \return
*/
virtual double CTemperatureUnit::conversionFromSiConversionUnit(double value) const;
public:
/*!
* \brief Copy constructor
@@ -317,18 +339,6 @@ public:
this->m_conversionOffsetToSi = otherUnit.m_conversionOffsetToSi;
return (*this);
}
/*!
* \brief Convert to SI conversion unit, specific for temperature
* \param value
* \return
*/
virtual double CTemperatureUnit::convertToSiConversionUnit(double value) const;
/*!
* \brief Convert from SI conversion unit, specific for temperature
* \param value
* \return
*/
virtual double CTemperatureUnit::convertFromSiConversionUnit(double value) const;
/*!
* \brief Kelvin
* \return
@@ -344,7 +354,6 @@ public:
* \return
*/
static const CTemperatureUnit& F() { static CTemperatureUnit F("Fahrenheit", "°F", false, false, 5.0/9.0, 459.67);return F;}
};
/*!