Ref T261, unify unit handling in situation altitude related values

* this is an optimization, it would work without that, but there are numerous calculations in interpolation which are faster and easier to debug in the same unit
* PQ switch unit functions use "const &PQUnit"
This commit is contained in:
Klaus Basan
2018-05-07 11:40:59 +02:00
committed by Roland Winklmeier
parent 337f661499
commit 23c54938ea
8 changed files with 107 additions and 29 deletions

View File

@@ -510,10 +510,16 @@ namespace BlackMisc
{ {
m_groundElevationPlane = CElevationPlane(*this); m_groundElevationPlane = CElevationPlane(*this);
m_groundElevationPlane.setSinglePointRadius(); m_groundElevationPlane.setSinglePointRadius();
m_groundElevationPlane.setGeodeticHeight(altitude); m_groundElevationPlane.setGeodeticHeight(altitude.switchedUnit(this->getAltitudeUnit()));
} }
} }
void CAircraftSituation::setGroundElevation(const CElevationPlane &elevationPlane)
{
m_groundElevationPlane = elevationPlane;
m_groundElevationPlane.switchUnit(this->getAltitudeOrDefaultUnit()); // we use ft as internal unit, no "must" but simplification
}
bool CAircraftSituation::setGroundElevationChecked(const CElevationPlane &elevationPlane) bool CAircraftSituation::setGroundElevationChecked(const CElevationPlane &elevationPlane)
{ {
if (elevationPlane.isNull()) { return false; } if (elevationPlane.isNull()) { return false; }
@@ -522,7 +528,7 @@ namespace BlackMisc
if (m_groundElevationPlane.isNull() || distance < m_groundElevationPlane.getRadius()) if (m_groundElevationPlane.isNull() || distance < m_groundElevationPlane.getRadius())
{ {
// better values // better values
m_groundElevationPlane = elevationPlane; this->setGroundElevation(elevationPlane);
m_groundElevationPlane.setRadius(distance); m_groundElevationPlane.setRadius(distance);
return true; return true;
} }
@@ -548,6 +554,12 @@ namespace BlackMisc
return this->getAltitude() - gh; return this->getAltitude() - gh;
} }
const CLengthUnit &CAircraftSituation::getAltitudeOrDefaultUnit() const
{
if (this->getAltitude().isNull()) { return CAltitude::defaultUnit(); }
return m_position.geodeticHeight().getUnit();
}
CAltitude CAircraftSituation::getCorrectedAltitude(bool enableDragToGround, CAircraftSituation::AltitudeCorrection *correction) const CAltitude CAircraftSituation::getCorrectedAltitude(bool enableDragToGround, CAircraftSituation::AltitudeCorrection *correction) const
{ {
return this->getCorrectedAltitude(m_cg, enableDragToGround, correction); return this->getCorrectedAltitude(m_cg, enableDragToGround, correction);
@@ -571,7 +583,7 @@ namespace BlackMisc
} }
else else
{ {
const CAltitude groundPlusCG = this->getGroundElevation().withOffset(centerOfGravity); const CAltitude groundPlusCG = this->getGroundElevation().withOffset(centerOfGravity).switchedUnit(this->getAltitudeOrDefaultUnit());
if (groundPlusCG.isNull()) if (groundPlusCG.isNull())
{ {
if (correction) { *correction = NoElevation; } if (correction) { *correction = NoElevation; }
@@ -615,6 +627,11 @@ namespace BlackMisc
return altCor; return altCor;
} }
void CAircraftSituation::setAltitude(const CAltitude &altitude)
{
m_position.setGeodeticHeight(altitude.switchedUnit(CAltitude::defaultUnit()));
}
CAltitude CAircraftSituation::addAltitudeOffset(const CLength &offset) CAltitude CAircraftSituation::addAltitudeOffset(const CLength &offset)
{ {
if (offset.isNull()) { return this->getAltitude(); } if (offset.isNull()) { return this->getAltitude(); }
@@ -675,6 +692,11 @@ namespace BlackMisc
m_correspondingCallsign.setTypeHint(CCallsign::Aircraft); m_correspondingCallsign.setTypeHint(CCallsign::Aircraft);
} }
void CAircraftSituation::setCG(const CLength &cg)
{
m_cg = cg.switchedUnit(this->getAltitudeOrDefaultUnit());
}
bool CAircraftSituation::adjustGroundFlag(const CAircraftParts &parts, bool alwaysSetDetails, double timeDeviationFactor, qint64 *differenceMs) bool CAircraftSituation::adjustGroundFlag(const CAircraftParts &parts, bool alwaysSetDetails, double timeDeviationFactor, qint64 *differenceMs)
{ {
Q_ASSERT_X(timeDeviationFactor >= 0 && timeDeviationFactor <= 1.0, Q_FUNC_INFO, "Expect 0..1"); Q_ASSERT_X(timeDeviationFactor >= 0 && timeDeviationFactor <= 1.0, Q_FUNC_INFO, "Expect 0..1");

View File

@@ -253,7 +253,7 @@ namespace BlackMisc
void setGroundElevation(const Aviation::CAltitude &altitude); void setGroundElevation(const Aviation::CAltitude &altitude);
//! Elevation of the ground directly beneath //! Elevation of the ground directly beneath
void setGroundElevation(const Geo::CElevationPlane &elevationPlane) { m_groundElevationPlane = elevationPlane; } void setGroundElevation(const Geo::CElevationPlane &elevationPlane);
//! Set elevation of the ground directly beneath, but checked //! Set elevation of the ground directly beneath, but checked
//! \remark override if better //! \remark override if better
@@ -277,6 +277,9 @@ namespace BlackMisc
//! Get altitude unit //! Get altitude unit
const PhysicalQuantities::CLengthUnit &getAltitudeUnit() const { return m_position.geodeticHeight().getUnit(); } const PhysicalQuantities::CLengthUnit &getAltitudeUnit() const { return m_position.geodeticHeight().getUnit(); }
//! Get altitude unit
const PhysicalQuantities::CLengthUnit &getAltitudeOrDefaultUnit() const;
//! Get altitude under consideration of ground elevation and ground flag //! Get altitude under consideration of ground elevation and ground flag
//! \remark with dragToGround it will also compensate overflows, otherwise only underflow //! \remark with dragToGround it will also compensate overflows, otherwise only underflow
//! @{ //! @{
@@ -291,7 +294,7 @@ namespace BlackMisc
//! @} //! @}
//! Set altitude //! Set altitude
void setAltitude(const CAltitude &altitude) { m_position.setGeodeticHeight(altitude); } void setAltitude(const CAltitude &altitude);
//! Add offset to altitude //! Add offset to altitude
CAltitude addAltitudeOffset(const PhysicalQuantities::CLength &offset); CAltitude addAltitudeOffset(const PhysicalQuantities::CLength &offset);
@@ -342,7 +345,7 @@ namespace BlackMisc
const PhysicalQuantities::CLength &getCG() const { return m_cg; } const PhysicalQuantities::CLength &getCG() const { return m_cg; }
//! Set CG //! Set CG
void setCG(const PhysicalQuantities::CLength &cg) { m_cg = cg; } void setCG(const PhysicalQuantities::CLength &cg);
//! Has CG set? //! Has CG set?
bool hasCG() const { return !m_cg.isNull(); } bool hasCG() const { return !m_cg.isNull(); }

View File

@@ -16,6 +16,7 @@
#include <Qt> #include <Qt>
#include <QtGlobal> #include <QtGlobal>
#include <QStringBuilder>
using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::PhysicalQuantities;
@@ -34,7 +35,7 @@ namespace BlackMisc
CAltitude copy(*this); CAltitude copy(*this);
if (!offset.isNull() && !offset.isZeroEpsilonConsidered()) if (!offset.isNull() && !offset.isZeroEpsilonConsidered())
{ {
copy += offset; copy += offset.switchedUnit(this->getUnit());
} }
return copy; return copy;
} }
@@ -44,6 +45,21 @@ namespace BlackMisc
*this = this->withOffset(offset); *this = this->withOffset(offset);
} }
CAltitude &CAltitude::switchUnit(const CLengthUnit &newUnit)
{
if (newUnit.isNull() || this->getUnit().isNull() || this->getUnit() == newUnit) { return *this; }
CLength::switchUnit(newUnit);
return *this;
}
CAltitude CAltitude::switchedUnit(const CLengthUnit &newUnit) const
{
if (newUnit.isNull() || this->getUnit().isNull() || this->getUnit() == newUnit) { return *this; }
CAltitude copy(*this);
copy.switchUnit(newUnit);
return copy;
}
QString CAltitude::convertToQString(bool i18n) const QString CAltitude::convertToQString(bool i18n) const
{ {
if (this->m_datum == FlightLevel) if (this->m_datum == FlightLevel)
@@ -324,6 +340,11 @@ namespace BlackMisc
return null; return null;
} }
const CLengthUnit &CAltitude::defaultUnit()
{
return CLengthUnit::ft();
}
const CPressure &CAltitude::standardISASeaLevelPressure() const CPressure &CAltitude::standardISASeaLevelPressure()
{ {
// Average sea-level pressure is 1013.25mbar or 1013.25hPa // Average sea-level pressure is 1013.25mbar or 1013.25hPa

View File

@@ -108,6 +108,12 @@ namespace BlackMisc
//! Add offset value //! Add offset value
void addOffset(const CLength &offset); void addOffset(const CLength &offset);
//! Value in switched unit
CAltitude &switchUnit(const PhysicalQuantities::CLengthUnit &newUnit);
//! Value in switched unit
CAltitude switchedUnit(const PhysicalQuantities::CLengthUnit &newUnit) const;
//! AGL Above ground level? //! AGL Above ground level?
bool isAboveGroundLevel() const { return AboveGround == this->m_datum; } bool isAboveGroundLevel() const { return AboveGround == this->m_datum; }
@@ -176,6 +182,10 @@ namespace BlackMisc
//! Null altitude (MSL) //! Null altitude (MSL)
static const CAltitude &null(); static const CAltitude &null();
//! Default unit for calculations
//! \remark using this is optional and will simplify debugging and calculations
static const PhysicalQuantities::CLengthUnit &defaultUnit();
//! Standard pressure 1013.25mbar/hPa //! Standard pressure 1013.25mbar/hPa
static const PhysicalQuantities::CPressure &standardISASeaLevelPressure(); static const PhysicalQuantities::CPressure &standardISASeaLevelPressure();

View File

@@ -45,6 +45,13 @@ namespace BlackMisc
this->setGeodeticHeight(newAlt); this->setGeodeticHeight(newAlt);
} }
void CElevationPlane::switchAltitudeUnit(const CLengthUnit &unit)
{
if (unit.isNull() || this->getAltitudeUnit().isNull()) { return; }
if (this->getAltitudeUnit() == unit) { return; }
this->setGeodeticHeight(this->getAltitude().switchedUnit(unit));
}
const CAltitude &CElevationPlane::getAltitudeIfWithinRadius(const ICoordinateGeodetic &coordinate) const const CAltitude &CElevationPlane::getAltitudeIfWithinRadius(const ICoordinateGeodetic &coordinate) const
{ {
return (isWithinRange(coordinate)) ? geodeticHeight() : CAltitude::null(); return (isWithinRange(coordinate)) ? geodeticHeight() : CAltitude::null();

View File

@@ -51,12 +51,18 @@ namespace BlackMisc
//! Add offset to altitude //! Add offset to altitude
void addAltitudeOffset(const PhysicalQuantities::CLength &offset); void addAltitudeOffset(const PhysicalQuantities::CLength &offset);
//! Switch altitude unit
void switchAltitudeUnit(const PhysicalQuantities::CLengthUnit &unit);
//! Altitude when within radius, else null //! Altitude when within radius, else null
const Aviation::CAltitude &getAltitudeIfWithinRadius(const ICoordinateGeodetic &coordinate) const; const Aviation::CAltitude &getAltitudeIfWithinRadius(const ICoordinateGeodetic &coordinate) const;
//! Altitude (synonym for geodetic height) //! Altitude (synonym for geodetic height)
const Aviation::CAltitude &getAltitude() const { return this->geodeticHeight(); } const Aviation::CAltitude &getAltitude() const { return this->geodeticHeight(); }
//! Altitude (synonym for geodetic height) unit
const PhysicalQuantities::CLengthUnit &getAltitudeUnit() const { return this->geodeticHeight().getUnit(); }
//! Altitude (synonym for geodetic height) //! Altitude (synonym for geodetic height)
Aviation::CAltitude getAltitudeInUnit(const PhysicalQuantities::CLengthUnit &unit) const; Aviation::CAltitude getAltitudeInUnit(const PhysicalQuantities::CLengthUnit &unit) const;

View File

@@ -247,16 +247,23 @@ namespace BlackMisc
} }
template <class MU, class PQ> template <class MU, class PQ>
PQ &CPhysicalQuantity<MU, PQ>::switchUnit(MU newUnit) PQ &CPhysicalQuantity<MU, PQ>::switchUnit(const MU &newUnit)
{ {
if (m_unit != newUnit) if (m_unit == newUnit || this->isNull()) { return *derived(); }
{ m_value = newUnit.convertFrom(m_value, m_unit);
m_value = newUnit.convertFrom(m_value, m_unit); m_unit = newUnit;
m_unit = newUnit;
}
return *derived(); return *derived();
} }
template <class MU, class PQ>
PQ CPhysicalQuantity<MU, PQ>::switchedUnit(const MU &newUnit) const
{
if (m_unit == newUnit || this->isNull()) { return *derived(); }
PQ copy(*derived());
copy.switchUnit(newUnit);
return copy;
}
template <class MU, class PQ> template <class MU, class PQ>
bool CPhysicalQuantity<MU, PQ>::isNull() const bool CPhysicalQuantity<MU, PQ>::isNull() const
{ {
@@ -293,7 +300,7 @@ namespace BlackMisc
} }
template <class MU, class PQ> template <class MU, class PQ>
QString CPhysicalQuantity<MU, PQ>::valueRoundedWithUnit(MU unit, int digits, bool i18n) const QString CPhysicalQuantity<MU, PQ>::valueRoundedWithUnit(const MU &unit, int digits, bool i18n) const
{ {
Q_ASSERT_X(!unit.isNull(), Q_FUNC_INFO, "Cannot convert to null"); Q_ASSERT_X(!unit.isNull(), Q_FUNC_INFO, "Cannot convert to null");
if (this->isNull()) { return this->convertToQString(i18n); } if (this->isNull()) { return this->convertToQString(i18n); }

View File

@@ -74,7 +74,7 @@ namespace BlackMisc
//! Simply set unit, do no calclulate conversion //! Simply set unit, do no calclulate conversion
//! \sa switchUnit //! \sa switchUnit
void setUnit(MU unit) { m_unit = unit; } void setUnit(const MU &unit) { m_unit = unit; }
//! Set unit by string //! Set unit by string
void setUnitBySymbol(const QString &unitName); void setUnitBySymbol(const QString &unitName);
@@ -83,7 +83,10 @@ namespace BlackMisc
QString getUnitSymbol() const; QString getUnitSymbol() const;
//! Change unit, and convert value to maintain the same quantity //! Change unit, and convert value to maintain the same quantity
PQ &switchUnit(MU newUnit); PQ &switchUnit(const MU &newUnit);
//! Return copy with switched unit
PQ switchedUnit(const MU &newUnit) const;
//! Is quantity null? //! Is quantity null?
bool isNull() const; bool isNull() const;
@@ -119,7 +122,7 @@ namespace BlackMisc
//! Value to QString with the given unit, e.g. "5.00m" //! Value to QString with the given unit, e.g. "5.00m"
//! \note default digits is CMeasurementUnit::getDisplayDigits //! \note default digits is CMeasurementUnit::getDisplayDigits
QString valueRoundedWithUnit(MU unit, int digits = -1, bool i18n = false) const; QString valueRoundedWithUnit(const MU &unit, int digits = -1, bool i18n = false) const;
//! Value to QString with the current unit, e.g. "5.00m" //! Value to QString with the current unit, e.g. "5.00m"
//! \note default digits is CMeasurementUnit::getDisplayDigits //! \note default digits is CMeasurementUnit::getDisplayDigits
@@ -219,24 +222,24 @@ namespace BlackMisc
//! \copydoc BlackMisc::Mixin::JsonByMetaClass::convertFromJson //! \copydoc BlackMisc::Mixin::JsonByMetaClass::convertFromJson
void convertFromJson(const QJsonObject &json); void convertFromJson(const QJsonObject &json);
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex
CVariant propertyByIndex(const CPropertyIndex &index) const;
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
void setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant);
//! \copydoc BlackMisc::Mixin::String::toQString
QString convertToQString(bool i18n = false) const;
//! Parse to string, with specified separator //! Parse to string, with specified separator
void parseFromString(const QString &value, CPqString::SeparatorMode mode); void parseFromString(const QString &value, CPqString::SeparatorMode mode);
//! Parse value from string //! Parse value from string
void parseFromString(const QString &value); void parseFromString(const QString &value);
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
void setPropertyByIndex(const BlackMisc::CPropertyIndex &index, const CVariant &variant);
//! Compare //! Compare
int comparePropertyByIndex(const CPropertyIndex &index, const PQ &pq) const; int comparePropertyByIndex(const CPropertyIndex &index, const PQ &pq) const;
//! \copydoc BlackMisc::Mixin::String::toQString
QString convertToQString(bool i18n = false) const;
//! Maximum of 2 quantities //! Maximum of 2 quantities
static const PQ &maxValue(const PQ &pq1, const PQ &pq2); static const PQ &maxValue(const PQ &pq1, const PQ &pq2);
@@ -281,8 +284,7 @@ namespace BlackMisc
extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CPhysicalQuantity<CTimeUnit, CTime>; extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CPhysicalQuantity<CTimeUnit, CTime>;
extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CPhysicalQuantity<CAccelerationUnit, CAcceleration>; extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CPhysicalQuantity<CAccelerationUnit, CAcceleration>;
//! \endcond //! \endcond
} // ns
} } // ns
}
#endif // guard #endif // guard