Changed order of samples directory, started with aviation classes.

This commit is contained in:
Klaus Basan
2013-04-01 21:53:35 +02:00
parent f77258343d
commit 943872ff67
34 changed files with 911 additions and 147 deletions

View File

@@ -47,7 +47,7 @@ equals(WITH_SAMPLES, ON) {
SUBDIRS += samples/geodetic2ecef/sample_geodetic2ecef.pro
SUBDIRS += samples/interpolator/sample_interpolator.pro
SUBDIRS += samples/logging/sample_logging.pro
SUBDIRS += samples/physicalquantities/sample_physicalquantities.pro
SUBDIRS += samples/blackmiscquantities/sample_blackmisc_quantities.pro
}
equals(WITH_UNITTESTS, ON) {

View File

@@ -0,0 +1,19 @@
#include <QCoreApplication>
#include "samplesphysicalquantities.h"
#include "samplesaviation.h"
using namespace BlackMisc;
using namespace BlackMiscTest;
/*!
* Sample tests
*/
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// CSamplesPhysicalQuantities::samples();
CSamplesAviation::samples();
return a.exec();
}

View File

@@ -9,7 +9,9 @@ CONFIG -= app_bundle
DEPENDPATH += . ../../src
INCLUDEPATH += . ../../src
SOURCES += main.cpp
SOURCES += main.cpp \
samplesphysicalquantities.cpp \
samplesaviation.cpp
win32-msvc* {
PRE_TARGETDEPS += ../../lib/blackmisc.lib
@@ -22,3 +24,7 @@ win32-msvc* {
}
DESTDIR = ../../bin
HEADERS += \
samplesphysicalquantities.h \
samplesaviation.h

View File

@@ -0,0 +1,23 @@
#include "samplesaviation.h"
namespace BlackMiscTest {
/**
* Samples
*/
int CSamplesAviation::samples()
{
// CSpeed s1(10, CSpeedUnit::kts());
CHeading h1(180, true, CAngleUnit::deg());
CHeading h2(180, false, CAngleUnit::deg());
qDebug() << h1 << h2 << (h1 == h2) << (h1 != h2) << (h1 == h1);
CAviationVerticalPositions vp1 = CAviationVerticalPositions::fromAltitudeAndElevationInFt(10000.0, 1111.0);
CAviationVerticalPositions vp2 = vp1;
qDebug() << vp1 << (vp1 == vp2) << (vp1 != vp2);
// bye
return 0;
}
} // namespace

View File

@@ -0,0 +1,26 @@
#ifndef SAMPLESAVIATION_H
#define SAMPLESAVIATION_H
#include <QDebug>
#include "blackmisc/avheading.h"
#include "blackmisc/avverticalpositions.h"
#include "blackmisc/pqconstants.h"
using namespace BlackMisc;
namespace BlackMiscTest {
/*!
* \brief Samples for physical quantities
*/
class CSamplesAviation
{
public:
/*!
* \brief Run the samples
*/
static int samples();
};
}
#endif

View File

@@ -1,20 +1,11 @@
#include <QCoreApplication>
#include <QDebug>
#include "blackmisc/pqconstants.h"
#include "blackmisc/debug.h"
#include "samplesphysicalquantities.h"
using namespace BlackMisc;
namespace BlackMiscTest {
/*!
* Sample tests
* \brief main
* \param argc
* \param argv
* \return
/**
* Running the quantities
*/
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int CSamplesPhysicalQuantities::samples() {
// cases which must not work
// CMeasurementUnit mu; //must not work
@@ -100,5 +91,7 @@ int main(int argc, char *argv[])
qDebug() << ti1 << ti2;
// bye
return a.exec();
return 0;
}
} // namespace

View File

@@ -0,0 +1,25 @@
#ifndef SAMPLESPHYSICALQUANTITIES_H
#define SAMPLESPHYSICALQUANTITIES_H
#include <QDebug>
#include "blackmisc/pqconstants.h"
#include "blackmisc/debug.h"
using namespace BlackMisc;
namespace BlackMiscTest {
/*!
* \brief Samples for physical quantities
*/
class CSamplesPhysicalQuantities
{
public:
/*!
* \brief Run the samples
*/
static int samples();
};
}
#endif // SAMPLESPHYSICALQUANTITIES_H

View File

@@ -0,0 +1,42 @@
#include "avaltitude.h"
namespace BlackMisc {
/**
* Own implementation for streaming
*/
QString CAltitude::stringForStreamingOperator() const
{
QString s = CLength::stringForStreamingOperator();
return s.append(this->m_msl ? " MSL" : " AGL");
}
/**
* Assigment
*/
CAltitude& CAltitude::operator =(const CAltitude &otherAltitude)
{
// Check for self-assignment!
if (this == &otherAltitude) return *this;
CLength::operator = (otherAltitude);
this->m_msl = otherAltitude.m_msl;
return (*this);
}
/**
* Equal?
*/
bool CAltitude::operator ==(const CAltitude &otherAltitude)
{
return otherAltitude.m_msl == this->m_msl && CLength::operator ==(otherAltitude);
}
/**
* Unequal?
*/
bool CAltitude::operator !=(const CAltitude &otherAltitude)
{
return !((*this) == otherAltitude);
}
} // namespace

View File

@@ -0,0 +1,88 @@
#ifndef AVALTITUDE_H
#define AVALTITUDE_H
#include "blackmisc/pqlength.h"
namespace BlackMisc {
/*!
* \brief Altitude as used in aviation, can be AGL or MSL Altitude
* \remarks Intentionally allowing +/- CLength , and >= / <= CLength.
*/
class CAltitude : public CLength
{
private:
bool m_msl; //!< MSL or AGL?
protected:
/*!
* \brief Specific stream operation for Altitude
* \return
*/
virtual QString stringForStreamingOperator() const;
public:
/*!
* \brief Default constructor: 0 Altitude true
*/
CAltitude() : CLength(0, CLengthUnit::m()), m_msl(true) {}
/*!
* \brief Constructor
* \param value
* \param msl MSL or AGL?
* \param unit
*/
CAltitude(double value, bool msl, const CLengthUnit &unit) : CLength(value, unit), m_msl(msl) {}
/*!
* \brief Constructor
* \param value
* \param msl MSL or AGL?
* \param unit
*/
CAltitude(int value, bool msl, const CLengthUnit &unit) : CLength(value, unit), m_msl(msl) {}
/*!
* \brief Constructor by CLength
* \param Altitude
* \param msl
*/
CAltitude(CLength altitude, bool msl) : CLength(), m_msl(msl) {
CLength::operator =(altitude);
}
/*!
* \brief Copy constructor
* \param otherAltitude
*/
CAltitude(const CAltitude &otherAltitude) : CLength(otherAltitude), m_msl(otherAltitude.m_msl) {}
/*!
* \brief Assignment operator =
* \param otherQuantity
* @return
*/
CAltitude &operator =(const CAltitude &otherAltitude);
/*!
* \brief Equal operator ==
* \param otherQuantity
* @return
*/
bool operator ==(const CAltitude &otherAltitude);
/*!
* \brief Unequal operator ==
* \param otherQuantity
* @return
*/
bool operator !=(const CAltitude &otherAltitude);
/*!
* \brief AGL Above ground level?
* \return
*/
bool isAboveGroundLevel() const { return !this->m_msl; }
/*!
* \brief MSL Mean sea level?
* \return
*/
bool isMeanSeaLevel() const { return this->m_msl; }
};
} // namespace
#endif // AVALTITUDE_H

View File

@@ -0,0 +1,42 @@
#include "avheading.h"
namespace BlackMisc {
/**
* Own implementation for streaming
*/
QString CHeading::stringForStreamingOperator() const
{
QString s = CAngle::stringForStreamingOperator();
return s.append(this->m_magnetic ? " magnetic" : " true");
}
/**
* Assigment
*/
CHeading& CHeading::operator =(const CHeading &otherHeading)
{
// Check for self-assignment!
if (this == &otherHeading) return *this;
CAngle::operator = (otherHeading);
this->m_magnetic = otherHeading.m_magnetic;
return (*this);
}
/**
* Equal?
*/
bool CHeading::operator ==(const CHeading &otherHeading)
{
return otherHeading.m_magnetic == this->m_magnetic && CAngle::operator ==(otherHeading);
}
/**
* Unequal?
*/
bool CHeading::operator !=(const CHeading &otherHeading)
{
return !((*this) == otherHeading);
}
} // namespace

86
src/blackmisc/avheading.h Normal file
View File

@@ -0,0 +1,86 @@
#ifndef AVHEADING_H
#define AVHEADING_H
#include "blackmisc/pqangle.h"
namespace BlackMisc {
/*!
* \brief Heading as used in aviation, can be true or magnetic heading
* \remarks Intentionally allowing +/- CAngle , and >= / <= CAngle.
*/
class CHeading : public CAngle
{
private:
bool m_magnetic; //!< magnetic or true heading?
protected:
/*!
* \brief Specific stream operation for heading
* \return
*/
virtual QString stringForStreamingOperator() const;
public:
/*!
* \brief Default constructor: 0 heading true
*/
CHeading() : CAngle(0, CAngleUnit::rad()), m_magnetic(true) {}
/*!
* \brief Constructor
* \param value
* \param magnetic
* \param unit
*/
CHeading(double value, bool magnetic, const CAngleUnit &unit) : CAngle(value, unit), m_magnetic(magnetic) {}
/*!
* \brief Constructor
* \param value
* \param magnetic
* \param unit
*/
CHeading(int value, bool magnetic, const CAngleUnit &unit) : CAngle(value, unit), m_magnetic(magnetic) {}
/*!
* \brief Constructor by CAngle
* \param heading
* \param magnetic
*/
CHeading(CAngle heading, bool magnetic) : CAngle(), m_magnetic(magnetic) {
CAngle::operator =(heading);
}
/*!
* \brief Copy constructor
* \param otherHeading
*/
CHeading(const CHeading &otherHeading) : CAngle(otherHeading), m_magnetic(otherHeading.m_magnetic) {}
/*!
* \brief Assignment operator =
* \param otherQuantity
* @return
*/
CHeading &operator =(const CHeading &otherHeading);
/*!
* \brief Equal operator ==
* \param otherQuantity
* @return
*/
bool operator ==(const CHeading &otherHeading);
/*!
* \brief Unequal operator ==
* \param otherQuantity
* @return
*/
bool operator !=(const CHeading &otherHeading);
/*!
* \brief Magnetic heading?
* \return
*/
bool isMagneticHeading() const { return this->m_magnetic; }
/*!
* \brief True heading?
* \return
*/
bool isTrueHeading() const { return !this->m_magnetic; }
};
} // namespace
#endif // AVHEADING_H

42
src/blackmisc/avtrack.cpp Normal file
View File

@@ -0,0 +1,42 @@
#include "avtrack.h"
namespace BlackMisc {
/**
* Own implementation for streaming
*/
QString CTrack::stringForStreamingOperator() const
{
QString s = CAngle::stringForStreamingOperator();
return s.append(this->m_magnetic ? " magnetic" : " true");
}
/**
* Assigment
*/
CTrack& CTrack::operator =(const CTrack &otherTrack)
{
// Check for self-assignment!
if (this == &otherTrack) return *this;
CAngle::operator = (otherTrack);
this->m_magnetic = otherTrack.m_magnetic;
return (*this);
}
/**
* Equal?
*/
bool CTrack::operator ==(const CTrack &otherTrack)
{
return otherTrack.m_magnetic == this->m_magnetic && CAngle::operator ==(otherTrack);
}
/**
* Unequal?
*/
bool CTrack::operator !=(const CTrack &otherTrack)
{
return !((*this) == otherTrack);
}
} // namespace

87
src/blackmisc/avtrack.h Normal file
View File

@@ -0,0 +1,87 @@
#ifndef AVTRACK_H
#define AVTRACK_H
#include "blackmisc/pqangle.h"
namespace BlackMisc {
/*!
* \brief Track as used in aviation, can be true or magnetic Track
* \remarks Intentionally allowing +/- CAngle , and >= / <= CAngle.
*/
class CTrack : public CAngle
{
private:
bool m_magnetic; //!< magnetic or true Track?
protected:
/*!
* \brief Specific stream operation for Track
* \return
*/
virtual QString stringForStreamingOperator() const;
public:
/*!
* \brief Default constructor: 0 Track true
*/
CTrack() : CAngle(0, CAngleUnit::rad()), m_magnetic(true) {}
/*!
* \brief Constructor
* \param value
* \param magnetic
* \param unit
*/
CTrack(double value, bool magnetic, const CAngleUnit &unit) : CAngle(value, unit), m_magnetic(magnetic) {}
/*!
* \brief Constructor
* \param value
* \param magnetic
* \param unit
*/
CTrack(int value, bool magnetic, const CAngleUnit &unit) : CAngle(value, unit), m_magnetic(magnetic) {}
/*!
* \brief Constructor by CAngle
* \param Track
* \param magnetic
*/
CTrack(CAngle track, bool magnetic) : CAngle(), m_magnetic(magnetic) {
CAngle::operator =(track);
}
/*!
* \brief Copy constructor
* \param otherTrack
*/
CTrack(const CTrack &otherTrack) : CAngle(otherTrack), m_magnetic(otherTrack.m_magnetic) {}
/*!
* \brief Assignment operator =
* \param otherQuantity
* @return
*/
CTrack &operator =(const CTrack &otherTrack);
/*!
* \brief Equal operator ==
* \param otherQuantity
* @return
*/
bool operator ==(const CTrack &otherTrack);
/*!
* \brief Unequal operator ==
* \param otherQuantity
* @return
*/
bool operator !=(const CTrack &otherTrack);
/*!
* \brief Magnetic Track?
* \return
*/
bool isMagneticTrack() const { return this->m_magnetic; }
/*!
* \brief True Track?
* \return
*/
bool isTrueTrack() const { return !this->m_magnetic; }
};
} // namespace
#endif // AVTRACK_H

View File

@@ -1,20 +0,0 @@
#include "avverticalposition.h"
namespace BlackMisc {
/**
* @brief Default constructor
*/
CAviationVerticalPosition::CAviationVerticalPosition() :m_elevation(CAviationVerticalPosition::valueNotSet()), m_height(CAviationVerticalPosition::valueNotSet()), m_altitude(CAviationVerticalPosition::valueNotSet())
{
// void
}
/**
* Constructor
*/
CAviationVerticalPosition::CAviationVerticalPosition(const CLength &height, const CLength &elevation, const CLength &altitude) : m_height(height), m_elevation(elevation), m_altitude(altitude)
{
// void
}
}

View File

@@ -1,56 +0,0 @@
#ifndef AVLATERALPOSITION_H
#define AVLATERALPOSITION_H
#include "blackmisc/pqlength.h"
namespace BlackMisc {
/*!
* \brief Vertical (Z) position of an aircraft
*/
class CAviationVerticalPosition
{
private:
CLength m_height; //!< height
CLength m_elevation; //!< elevation
CLength m_altitude; //!< altitude
public:
/*!
* \brief Default constructor
*/
CAviationVerticalPosition();
/*!
* \brief Constructor
* \param height
* \param elevation
* \param altitude
*/
CAviationVerticalPosition(const CLength &height, const CLength &elevation, const CLength &altitude);
/*!
* \brief Value isnot set
* \return
*/
static const CLength& valueNotSet() { static CLength notSet(-1, CLengthUnit::m()); return notSet;}
/*!
* \brief Factory method for convenience if only one component is available
* \param initValue
* \return
*/
static CAviationVerticalPosition getHeight(const CLength &initValue) { return CAviationVerticalPosition(initValue, CAviationVerticalPosition::valueNotSet(), CAviationVerticalPosition::valueNotSet());}
/*!
* \brief Factory method for convenience if only one component is available
* \param initValue
* \return
*/
static CAviationVerticalPosition getElevation(const CLength &initValue) { return CAviationVerticalPosition(CAviationVerticalPosition::valueNotSet(), initValue, CAviationVerticalPosition::valueNotSet());}
/*!
* \brief Factory method for convenience if only one component is available
* \param initValue
* \return
*/
static CAviationVerticalPosition getAltitude(const CLength &initValue) { return CAviationVerticalPosition(CAviationVerticalPosition::valueNotSet(), CAviationVerticalPosition::valueNotSet(), initValue);}
};
} // namespace
#endif // AVLATERALPOSITION_H

View File

@@ -0,0 +1,118 @@
#include "avverticalpositions.h"
namespace BlackMisc {
/**
* Constructor
*/
CAviationVerticalPositions::CAviationVerticalPositions() :
m_altitude(CAltitude(0, true, CLengthUnit::ft())),
m_height(CPhysicalQuantitiesConstants::Length0ft()),
m_elevation(CPhysicalQuantitiesConstants::Length0ft())
{
// void
}
/**
* Constructor
*/
CAviationVerticalPositions::CAviationVerticalPositions(const CAltitude &altitude, const CLength &elevation, const CLength &height) :
m_altitude(altitude), m_elevation(elevation), m_height(height)
{
// void
}
/**
* Copy constructor
*/
CAviationVerticalPositions::CAviationVerticalPositions(const CAviationVerticalPositions &otherPosition) :
m_altitude(otherPosition.m_altitude), m_elevation(otherPosition.m_elevation), m_height(otherPosition.m_height)
{
// void
}
/**
* Assigment
*/
CAviationVerticalPositions &CAviationVerticalPositions::operator =(const CAviationVerticalPositions &otherPositions)
{
if (this == &otherPositions) return *this; // Same object?
this->m_altitude = otherPositions.m_altitude;
this->m_elevation = otherPositions.m_elevation;
this->m_height= otherPositions.m_height;
return *this;
}
/**
* Equal operator
*/
bool CAviationVerticalPositions::operator ==(const CAviationVerticalPositions &otherPositions)
{
return this->m_altitude == otherPositions.m_altitude &&
this->m_elevation == otherPositions.m_elevation &&
this->m_height == otherPositions.m_height;
}
/**
* Unequal operator
*/
bool CAviationVerticalPositions::operator !=(const CAviationVerticalPositions &otherPositions)
{
return !(*this == otherPositions);
}
/**
* String representation for streaming
*/
QString CAviationVerticalPositions::stringForStreamingOperator() const
{
QString s = QString("Altitude: ").
append(this->m_altitude.unitValueRoundedWithUnit()).
append(" Elevation: ").
append(this->m_elevation.unitValueRoundedWithUnit()).
append(" Height: ").
append(this->m_height.unitValueRoundedWithUnit());
return s;
}
/**
* Factory by elevation and altitude
*/
CAviationVerticalPositions CAviationVerticalPositions::fromAltitudeAndElevationInFt(double altitudeMslFt, double elevationFt)
{
CAltitude a(altitudeMslFt, true, CLengthUnit::ft());
CLength e(elevationFt, CLengthUnit::ft());
CLength h(altitudeMslFt-elevationFt,CLengthUnit::ft());
return CAviationVerticalPositions(a, e, h);
}
/**
* Factory by elevation and altitude
*/
CAviationVerticalPositions CAviationVerticalPositions::fromAltitudeAndElevationInM(double altitudeMslM, double elevationM)
{
CAltitude a(altitudeMslM, true, CLengthUnit::m());
CLength e(elevationM, CLengthUnit::m());
CLength h(altitudeMslM-elevationM,CLengthUnit::m());
return CAviationVerticalPositions(a, e, h);
}
/**
* Stream for log message
*/
CLogMessage operator <<(CLogMessage log, const CAviationVerticalPositions &positions)
{
log << positions.stringForStreamingOperator();
return log;
}
/**
* Stream for qDebug
*/
QDebug operator <<(QDebug d, const CAviationVerticalPositions &positions)
{
d << positions.stringForStreamingOperator();
return d;
}
}

View File

@@ -0,0 +1,110 @@
#ifndef AVLATERALPOSITION_H
#define AVLATERALPOSITION_H
#include "blackmisc/avaltitude.h"
#include "blackmisc/pqconstants.h"
namespace BlackMisc {
/*!
* \brief Vertical (Z) positions of an aircraft
*/
class CAviationVerticalPositions
{
/*!
* \brief Stream << overload to be used in debugging messages
* \param d
* \param unit
* \return
*/
friend QDebug operator<<(QDebug d, const CAviationVerticalPositions &positions);
/*!
* Stream operator for log messages
* \brief operator <<
* \param log
* \param unit
* \return
*/
friend CLogMessage operator<<(CLogMessage log, const CAviationVerticalPositions &positions);
private:
CLength m_height; //!< height
CLength m_elevation; //!< elevation
CAltitude m_altitude; //!< altitude
protected:
/*!
* \brief Specific stream operation for heading
* \return
*/
virtual QString stringForStreamingOperator() const;
public:
/*!
* \brief Default constructor
*/
CAviationVerticalPositions();
/*!
* \brief Constructor
* \param altitude
* \param elevation
* \param height
*/
CAviationVerticalPositions(const CAltitude &altitude, const CLength &elevation, const CLength &height);
/*!
* \brief Copy constructor
* \param otherPosition
*/
CAviationVerticalPositions(const CAviationVerticalPositions &otherPosition);
/*!
* \brief Assignment operator =
* \param otherQuantity
* @return
*/
CAviationVerticalPositions &operator =(const CAviationVerticalPositions &otherPositions);
/*!
* \brief Equal operator ==
* \param otherQuantity
* @return
*/
bool operator ==(const CAviationVerticalPositions &otherPositions);
/*!
* \brief Unequal operator ==
* \param otherQuantity
* @return
*/
bool operator !=(const CAviationVerticalPositions &otherPositions);
/*!
* \brief Height
* \return
*/
CLength getHeight() const { return this->m_height;}
/*!
* \brief Elevation
* \return
*/
CLength getElevation() const { return this->m_elevation;}
/*!
* \brief Altitude
* \return
*/
CAltitude getAltitude()const { return this->m_altitude; }
/*!
* \brief Factory getting tupel frome levation and altitude values in ft
* \param altitudeMslFt
* \param elevationFt
* \return
*/
static CAviationVerticalPositions fromAltitudeAndElevationInFt(double altitudeMslFt, double elevationFt);
/*!
* \brief Factory getting tupel frome levation and altitude values in meters
* \param altitudeMslM
* \param elevationM
* \return
*/
static CAviationVerticalPositions fromAltitudeAndElevationInM(double altitudeMslM, double elevationM);
};
} // namespace
#endif // AVLATERALPOSITION_H

View File

@@ -45,11 +45,14 @@ HEADERS += \
pqpressure.h \
pqtemperature.h \
pqconstants.h \
avverticalposition.h \
pqunits.h \
pqallquantities.h \
pqlength.h \
pqtime.h
pqtime.h \
avheading.h \
avtrack.h \
avaltitude.h \
avverticalpositions.h
SOURCES += \
logmessage.cpp \
@@ -73,6 +76,9 @@ SOURCES += \
pqphysicalquantity.cpp \
pqbase.cpp \
pqunits.cpp \
avverticalposition.cpp
avheading.cpp \
avtrack.cpp \
avaltitude.cpp \
avverticalpositions.cpp
DESTDIR = ../../lib

View File

@@ -215,4 +215,15 @@ double CMeasurementUnit::round(double value, int digits) {
return rv;
}
/*!
* Epsilon rounding
*/
double CMeasurementUnit::epsilonRounding(double value) const
{
// does notwork reliable with qRound for some reason
double v = floor((value + this->m_epsilon) / this->m_epsilon);
v *=this->m_epsilon;
return v;
}
} // namespace

View File

@@ -187,7 +187,7 @@ private:
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 dor string conversions
qint32 m_displayDigits; //!< standard rounding for string conversions
CMeasurementPrefix m_multiplier; //!< multiplier (kilo, Mega)
protected:
@@ -333,6 +333,15 @@ public:
* \return
*/
static double round(double value, int digits);
/*!
* Epsilon rounding. In some conversion rouding is required to avoid
* periodical numbers.
* \param value
* \return
*/
double epsilonRounding(double value) const;
/*!
* \brief Unit is not specified
* \return

View File

@@ -29,6 +29,16 @@ public:
* \return
*/
static const CPressure& InternationalStandardSeaLevelPressure() { static CPressure p(1013.25, CPressureUnit::hPa()); return p;}
/*!
* \brief 0m
* \return
*/
static const CLength& Length0m() { static CLength l(0, CLengthUnit::m()); return l;}
/*!
* \brief 0ft
* \return
*/
static const CLength& Length0ft() { static CLength l(0, CLengthUnit::ft()); return l;}
};
} // namespace
#endif // PQCONSTANTS_H

View File

@@ -1,6 +1,6 @@
#ifndef PQMASS_H
#define PQMASS_H
#include "pqphysicalquantity.h"
#include "blackmisc/pqphysicalquantity.h"
namespace BlackMisc {

View File

@@ -79,7 +79,7 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU,PQ>::operator !=(const C
template <class MU, class PQ> CPhysicalQuantity<MU,PQ>& CPhysicalQuantity<MU,PQ>::operator=(const CPhysicalQuantity<MU,PQ> &otherQuantity) {
// Check for self-assignment!
if (this == &otherQuantity) return *this; // Same object? Yes, so skip assignment, and just return *this
if (this == &otherQuantity) return *this; // Same object?
this->m_unitValueI = otherQuantity.m_unitValueI;
this->m_unitValueD = otherQuantity.m_unitValueD;
@@ -280,7 +280,8 @@ template <class MU, class PQ> void CPhysicalQuantity<MU,PQ>::setUnitValue(double
* Set SI value
*/
template <class MU, class PQ> void CPhysicalQuantity<MU,PQ>::setConversionSiUnitValue() {
this->m_convertedSiUnitValueD = this->m_unit.convertToSiConversionUnit(this->m_unitValueD);
double si = this->m_unit.convertToSiConversionUnit(this->m_unitValueD);
this->m_convertedSiUnitValueD = si;
}
/**

View File

@@ -1,7 +1,6 @@
#ifndef PQPHYSICALQUANTITY_H
#define PQPHYSICALQUANTITY_H
#include <QtGlobal>
#include <QString>
#include <QLocale>
@@ -11,20 +10,12 @@
namespace BlackMisc {
class CAngle;
/*!
* \brief A physical quantity such as "5m", "20s", "1500ft/s"
* \author KWB
*/
template <class MU, class PQ> class CPhysicalQuantity
{
/*!
* Our converter function, should be implemented as static method of the quantity
* classes for clarity
*/
typedef double (*CPhysicalQuantityUnitConverter)(const PQ *quantity, const MU &unit);
/*!
* Stream operator for debugging
* \brief operator <<
@@ -34,7 +25,7 @@ template <class MU, class PQ> class CPhysicalQuantity
* \remarks Has to be in the header files to avoid template link errors
*/
friend QDebug operator<<(QDebug debug, const CPhysicalQuantity &quantity) {
QString v = quantity.unitValueRoundedWithUnit(-1);
QString v = quantity.stringForStreamingOperator();
debug << v;
return debug;
}
@@ -45,10 +36,10 @@ template <class MU, class PQ> class CPhysicalQuantity
* \param log
* \param quantity
* \return
* \remarks Has to be in the header files toavoid templatelink errors
* \remarks Has to be in the header files to avoid template link errors
*/
friend CLogMessage operator<<(CLogMessage log, const CPhysicalQuantity &quantity) {
QString v = quantity.unitValueRoundedWithUnit(-1);
QString v = quantity.stringForStreamingOperator();
log << v;
return log;
}
@@ -62,6 +53,11 @@ private:
protected:
MU m_unit; //!< unit
MU m_conversionSiUnit; //!< corresponding SI base unit
/*!
* \brief String for streaming operators
* \return
*/
virtual QString stringForStreamingOperator() const { return this->unitValueRoundedWithUnit(-1); }
/*!
* \brief Constructor with int
@@ -232,10 +228,6 @@ public:
* \param value
*/
void substractUnitValue(double value);
/*!
* \brief Cast as double
*/
operator double() const { return this->m_convertedSiUnitValueD; }
/*!
* \brief Cast as QString
*/
@@ -334,6 +326,6 @@ public:
};
} // namespace BlackCore
} // namespace
#endif // PQPHYSICALQUANTITY_H

View File

@@ -31,7 +31,9 @@ double CAngleUnit::convertFromSiConversionUnit(double value) const
// 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()) {
value = value * 180 / M_PI; // degree
// 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;
@@ -75,6 +77,7 @@ QString CAngleUnit::toQStringRounded(double value, int digits) const
{
QString s;
if ((*this) == CAngleUnit::sexagesimalDeg()) {
// special formatting for sexagesimal degrees
double de = floor(value);
double mi = floor((value-de)*100.0);
double se = floor((value-de-mi/100.0)*1000000) / 100.0;

View File

@@ -377,9 +377,14 @@ public:
* \brief Meter/second m/s
* \return
*/
static const CSpeedUnit& m_s() { static CSpeedUnit ms("meter/second", "m/s", true, false); return ms;}
static const CSpeedUnit& m_s() { static CSpeedUnit ms("meters/second", "m/s", true, false); return ms;}
/*!
* \brief Nautical miles per hour NM/h
* \brief Knots
* \return
*/
static const CSpeedUnit& kts() { static CSpeedUnit kts("knot", "kts", false, false, 1852.0/3600.0, CMeasurementPrefix::One(), 1);return kts;}
/*!
* \brief Nautical miles per hour NM/h (same as kts)
* \return
*/
static const CSpeedUnit& NM_h() { static CSpeedUnit NMh("nautical miles/hour", "NM/h", false, false, 1852.0/3600.0, CMeasurementPrefix::One(), 1);return NMh;}
@@ -397,7 +402,7 @@ public:
* \brief Kilometer/hour km/h
* \return
*/
static const CSpeedUnit& km_h() { static CSpeedUnit kmh("kilometer/hour", "km/h", false, false, 1.0/3.6, CMeasurementPrefix::One(), 1);return kmh;}
static const CSpeedUnit& km_h() { static CSpeedUnit kmh("kilometers/hour", "km/h", false, false, 1.0/3.6, CMeasurementPrefix::One(), 1);return kmh;}
};
/*!

View File

@@ -14,7 +14,7 @@ using namespace BlackMiscTest;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
TestMain::unitMain(argc, argv);
CTestMain::unitMain(argc, argv);
// bye
return a.exec();

View File

@@ -9,9 +9,14 @@ CONFIG -= app_bundle
DEPENDPATH += . ../../src
INCLUDEPATH += . ../../src
SOURCES += main.cpp testmain.cpp testphysicalquantitiesbase.cpp
HEADERS += testmain.h testphysicalquantitiesbase.h \
blackmisctest.h
SOURCES += main.cpp testmain.cpp \
testphysicalquantitiesbase.cpp \
testaviationbase.cpp
HEADERS += testmain.h \
testphysicalquantitiesbase.h \
blackmisctest.h \
testaviationbase.h
win32-msvc* {
PRE_TARGETDEPS += ../../lib/blackmisc.lib

View File

@@ -0,0 +1,47 @@
#include "testaviationbase.h"
namespace BlackMiscTest {
/**
* Constructor
*/
CTestAviationBase::CTestAviationBase(QObject *parent): QObject(parent)
{
// void
}
/**
* Basic tests
*/
void CTestAviationBase::headingBasics()
{
CHeading h1(180, true, CAngleUnit::deg());
CHeading h2(180, false, CAngleUnit::deg());
CHeading h3(181, true, CAngleUnit::deg());
CAngle a1(200,CAngleUnit::deg());
CHeading h4;
h4 = h1;
QVERIFY2(h1 != h2, "Magnetic and true heading are not the same");
QVERIFY2(h1 < h3, "180deg are less than 181deg");
QVERIFY2(a1 > h3, "200deg are more than 200deg");
QVERIFY2(h4 == h1, "Values shall be equal");
h1 -= h1;
QVERIFY2(h1.unitValueToDouble() == 0, "Value shall be 0");
// h4 = h1 + h2; does not work, because misleading
h2 += h2; // add just angle
QVERIFY2(h2.unitValueToDouble() == 360, "Value shall be 360");
}
/**
* Vertical positions
*/
void CTestAviationBase::verticalPosition()
{
CAviationVerticalPositions vp1 = CAviationVerticalPositions::fromAltitudeAndElevationInFt(10000.0, 3000.0);
CAviationVerticalPositions vp2 = vp1;
QVERIFY2(vp1== vp2, "Values shall be equal");
}
} // namespace

View File

@@ -0,0 +1,41 @@
#ifndef TESTAVIATIONBASE_H
#define TESTAVIATIONBASE_H
#include <QtTest/QtTest>
#include "blackmisc/pqconstants.h"
#include "blackmisc/avheading.h"
#include "blackmisc/avverticalpositions.h"
using namespace BlackMisc;
namespace BlackMiscTest {
/*!
* \brief Aviation classes basic tests
*/
class CTestAviationBase : public QObject
{
Q_OBJECT
public:
/*!
* \brief Standard test case constructor
* \param parent
*/
explicit CTestAviationBase(QObject *parent = 0);
private slots:
/*!
* \brief Basic unit tests for physical units
*/
void headingBasics();
/*!
* \brief Vertical positions
*/
void verticalPosition();
};
} // namespace
#endif // TESTAVIATIONBASE_H

View File

@@ -7,12 +7,14 @@ namespace BlackMiscTest {
\param argv
\sa http://stackoverflow.com/questions/12194256/qt-how-to-organize-unit-test-with-more-than-one-class
*/
int TestMain::unitMain(int argc, char *argv[])
int CTestMain::unitMain(int argc, char *argv[])
{
int status = 0;
{
TestPhysicalQuantitiesBase pqBaseTests ;
CTestPhysicalQuantitiesBase pqBaseTests ;
CTestAviationBase avBaseTests;
status |= QTest::qExec(&pqBaseTests, argc, argv);
status |= QTest::qExec(&avBaseTests, argc, argv);
}
return status;
}

View File

@@ -3,6 +3,7 @@
#include <QtTest/QtTest>
#include "testphysicalquantitiesbase.h"
#include "testaviationbase.h"
namespace BlackMiscTest{
@@ -11,7 +12,7 @@ namespace BlackMiscTest{
* Avoids clashes with other main(..) functions and allows to fire the test cases
* simply from any other main.
*/
class TestMain
class CTestMain
{
public:
static int unitMain(int argc, char *argv[]);

View File

@@ -3,10 +3,9 @@
namespace BlackMiscTest {
/*!
* \brief Constructor
* \param parent
* Constructor
*/
TestPhysicalQuantitiesBase::TestPhysicalQuantitiesBase(QObject *parent) : QObject(parent)
CTestPhysicalQuantitiesBase::CTestPhysicalQuantitiesBase(QObject *parent) : QObject(parent)
{
// void
}
@@ -14,7 +13,7 @@ TestPhysicalQuantitiesBase::TestPhysicalQuantitiesBase(QObject *parent) : QObjec
/*!
* Basic unit tests for physical units
*/
void TestPhysicalQuantitiesBase::unitsBasics()
void CTestPhysicalQuantitiesBase::unitsBasics()
{
QVERIFY(CMeasurementPrefix::k() > CMeasurementPrefix::h());
@@ -35,7 +34,7 @@ void TestPhysicalQuantitiesBase::unitsBasics()
/*!
* Distance tests
*/
void TestPhysicalQuantitiesBase::lengthBasics()
void CTestPhysicalQuantitiesBase::lengthBasics()
{
CLength d1(1,CLengthUnit::m()); // 1m
CLength d2(100, CLengthUnit::cm());
@@ -66,7 +65,7 @@ void TestPhysicalQuantitiesBase::lengthBasics()
/**
* Unit tests for speed
*/
void TestPhysicalQuantitiesBase::speedBasics()
void CTestPhysicalQuantitiesBase::speedBasics()
{
CSpeed s1(100, CSpeedUnit::km_h());
CSpeed s2(1000, CSpeedUnit::ft_min());
@@ -77,11 +76,12 @@ void TestPhysicalQuantitiesBase::speedBasics()
/**
* Frequency unit tests
*/
void TestPhysicalQuantitiesBase::frequencyTests()
void CTestPhysicalQuantitiesBase::frequencyTests()
{
CFrequency f1(1, CFrequencyUnit::MHz());
QVERIFY2(f1.valueRounded(CFrequencyUnit::kHz(),2) == 1000, "Mega is 1000kHz");
QVERIFY2(f1 == 1000000 , "MHz is 1E6 Hz");
QVERIFY2(f1.unitValueToDouble() == 1 , "1MHz");
QVERIFY2(f1.siBaseUnitValueToDouble() == 1000000 , "1E6 Hz");
CFrequency f2(CMeasurementPrefix::M(),CFrequencyUnit::Hz()) ; // 1 Megahertz
QVERIFY2(f1 == f2 , "MHz is 1E6 Hz");
}
@@ -89,7 +89,7 @@ void TestPhysicalQuantitiesBase::frequencyTests()
/**
* Angle tests
*/
void TestPhysicalQuantitiesBase::angleTests()
void CTestPhysicalQuantitiesBase::angleTests()
{
CAngle a1(180, CAngleUnit::deg());
CAngle a2(1.5 * CAngle::pi(), CAngleUnit::rad());
@@ -103,10 +103,10 @@ void TestPhysicalQuantitiesBase::angleTests()
/**
* Weight tests
*/
void TestPhysicalQuantitiesBase::massTests()
void CTestPhysicalQuantitiesBase::massTests()
{
CMass w1(1000, CMassUnit::kg());
CMass w2(w1, CMassUnit::kg());
CMass w2(w1.unitValueToInteger(), CMassUnit::kg());
w2.switchUnit(CMassUnit::t());
QVERIFY2(w2.unitValueToInteger() == 1, "1tonne shall be 1000kg");
w2.switchUnit(CMassUnit::lb());
@@ -117,7 +117,7 @@ void TestPhysicalQuantitiesBase::massTests()
/**
* Pressure tests
*/
void TestPhysicalQuantitiesBase::pressureTests()
void CTestPhysicalQuantitiesBase::pressureTests()
{
CPressure p1(1013.25, CPressureUnit::hPa());
CPressure p2(29.92,CPressureUnit::inHg());
@@ -134,7 +134,7 @@ void TestPhysicalQuantitiesBase::pressureTests()
/**
* Temperature tests
*/
void TestPhysicalQuantitiesBase::temperatureTests()
void CTestPhysicalQuantitiesBase::temperatureTests()
{
CTemperature t1(0, CTemperatureUnit::C()); // 0C
CTemperature t2(1, CTemperatureUnit::F()); // 1F
@@ -149,7 +149,7 @@ void TestPhysicalQuantitiesBase::temperatureTests()
/**
* Temperature tests
*/
void TestPhysicalQuantitiesBase::timeTests()
void CTestPhysicalQuantitiesBase::timeTests()
{
CTime t1(1, CTimeUnit::h());
QVERIFY2(t1.siBaseUnitValueToInteger() == 3600, "1hour shall be 3600s");
@@ -158,7 +158,7 @@ void TestPhysicalQuantitiesBase::timeTests()
/**
* Just testing obvious memory create / destruct flaws
*/
void TestPhysicalQuantitiesBase::memoryTests()
void CTestPhysicalQuantitiesBase::memoryTests()
{
CLength* c = new CLength(100, CLengthUnit::m());
c->switchUnit(CLengthUnit::NM());
@@ -176,7 +176,7 @@ void TestPhysicalQuantitiesBase::memoryTests()
/**
* @brief Just testing obvious memory create / destruct flaws
*/
void TestPhysicalQuantitiesBase::basicArithmetic()
void CTestPhysicalQuantitiesBase::basicArithmetic()
{
CPressure p1 = CPhysicalQuantitiesConstants::InternationalStandardSeaLevelPressure();
CPressure p2(p1);

View File

@@ -10,7 +10,7 @@ namespace BlackMiscTest {
/*!
* \brief Physical quantities,basic tests
*/
class TestPhysicalQuantitiesBase : public QObject
class CTestPhysicalQuantitiesBase : public QObject
{
Q_OBJECT
public:
@@ -18,7 +18,7 @@ public:
* \brief Standard test case constructor
* \param parent
*/
explicit TestPhysicalQuantitiesBase(QObject *parent = 0);
explicit CTestPhysicalQuantitiesBase(QObject *parent = 0);
private slots:
/*!
* \brief Basic unit tests for physical units
@@ -67,6 +67,6 @@ private slots:
};
}
} // namespace
#endif // TESTPHYSICALQUANTITIESBASE_H