diff --git a/src/blackmisc/aviation/aircraftsituation.cpp b/src/blackmisc/aviation/aircraftsituation.cpp index fa3e087d2..e2feae4d1 100644 --- a/src/blackmisc/aviation/aircraftsituation.cpp +++ b/src/blackmisc/aviation/aircraftsituation.cpp @@ -510,10 +510,16 @@ namespace BlackMisc { m_groundElevationPlane = CElevationPlane(*this); 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) { if (elevationPlane.isNull()) { return false; } @@ -522,7 +528,7 @@ namespace BlackMisc if (m_groundElevationPlane.isNull() || distance < m_groundElevationPlane.getRadius()) { // better values - m_groundElevationPlane = elevationPlane; + this->setGroundElevation(elevationPlane); m_groundElevationPlane.setRadius(distance); return true; } @@ -548,6 +554,12 @@ namespace BlackMisc 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 { return this->getCorrectedAltitude(m_cg, enableDragToGround, correction); @@ -571,7 +583,7 @@ namespace BlackMisc } else { - const CAltitude groundPlusCG = this->getGroundElevation().withOffset(centerOfGravity); + const CAltitude groundPlusCG = this->getGroundElevation().withOffset(centerOfGravity).switchedUnit(this->getAltitudeOrDefaultUnit()); if (groundPlusCG.isNull()) { if (correction) { *correction = NoElevation; } @@ -615,6 +627,11 @@ namespace BlackMisc return altCor; } + void CAircraftSituation::setAltitude(const CAltitude &altitude) + { + m_position.setGeodeticHeight(altitude.switchedUnit(CAltitude::defaultUnit())); + } + CAltitude CAircraftSituation::addAltitudeOffset(const CLength &offset) { if (offset.isNull()) { return this->getAltitude(); } @@ -675,6 +692,11 @@ namespace BlackMisc 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) { Q_ASSERT_X(timeDeviationFactor >= 0 && timeDeviationFactor <= 1.0, Q_FUNC_INFO, "Expect 0..1"); diff --git a/src/blackmisc/aviation/aircraftsituation.h b/src/blackmisc/aviation/aircraftsituation.h index bd154de0d..defaeb683 100644 --- a/src/blackmisc/aviation/aircraftsituation.h +++ b/src/blackmisc/aviation/aircraftsituation.h @@ -253,7 +253,7 @@ namespace BlackMisc void setGroundElevation(const Aviation::CAltitude &altitude); //! 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 //! \remark override if better @@ -277,6 +277,9 @@ namespace BlackMisc //! Get altitude unit 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 //! \remark with dragToGround it will also compensate overflows, otherwise only underflow //! @{ @@ -291,7 +294,7 @@ namespace BlackMisc //! @} //! Set altitude - void setAltitude(const CAltitude &altitude) { m_position.setGeodeticHeight(altitude); } + void setAltitude(const CAltitude &altitude); //! Add offset to altitude CAltitude addAltitudeOffset(const PhysicalQuantities::CLength &offset); @@ -342,7 +345,7 @@ namespace BlackMisc const PhysicalQuantities::CLength &getCG() const { return m_cg; } //! Set CG - void setCG(const PhysicalQuantities::CLength &cg) { m_cg = cg; } + void setCG(const PhysicalQuantities::CLength &cg); //! Has CG set? bool hasCG() const { return !m_cg.isNull(); } diff --git a/src/blackmisc/aviation/altitude.cpp b/src/blackmisc/aviation/altitude.cpp index 39501d12d..42ee415e7 100644 --- a/src/blackmisc/aviation/altitude.cpp +++ b/src/blackmisc/aviation/altitude.cpp @@ -16,6 +16,7 @@ #include #include +#include using namespace BlackMisc::PhysicalQuantities; @@ -34,7 +35,7 @@ namespace BlackMisc CAltitude copy(*this); if (!offset.isNull() && !offset.isZeroEpsilonConsidered()) { - copy += offset; + copy += offset.switchedUnit(this->getUnit()); } return copy; } @@ -44,6 +45,21 @@ namespace BlackMisc *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 { if (this->m_datum == FlightLevel) @@ -324,6 +340,11 @@ namespace BlackMisc return null; } + const CLengthUnit &CAltitude::defaultUnit() + { + return CLengthUnit::ft(); + } + const CPressure &CAltitude::standardISASeaLevelPressure() { // Average sea-level pressure is 1013.25mbar or 1013.25hPa diff --git a/src/blackmisc/aviation/altitude.h b/src/blackmisc/aviation/altitude.h index 987c9476c..42891b964 100644 --- a/src/blackmisc/aviation/altitude.h +++ b/src/blackmisc/aviation/altitude.h @@ -108,6 +108,12 @@ namespace BlackMisc //! Add offset value 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? bool isAboveGroundLevel() const { return AboveGround == this->m_datum; } @@ -176,6 +182,10 @@ namespace BlackMisc //! Null altitude (MSL) 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 static const PhysicalQuantities::CPressure &standardISASeaLevelPressure(); diff --git a/src/blackmisc/geo/elevationplane.cpp b/src/blackmisc/geo/elevationplane.cpp index d7be56d41..714885dc2 100644 --- a/src/blackmisc/geo/elevationplane.cpp +++ b/src/blackmisc/geo/elevationplane.cpp @@ -45,6 +45,13 @@ namespace BlackMisc 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 { return (isWithinRange(coordinate)) ? geodeticHeight() : CAltitude::null(); diff --git a/src/blackmisc/geo/elevationplane.h b/src/blackmisc/geo/elevationplane.h index bfbf9d323..ba0e32a04 100644 --- a/src/blackmisc/geo/elevationplane.h +++ b/src/blackmisc/geo/elevationplane.h @@ -51,12 +51,18 @@ namespace BlackMisc //! Add offset to altitude void addAltitudeOffset(const PhysicalQuantities::CLength &offset); + //! Switch altitude unit + void switchAltitudeUnit(const PhysicalQuantities::CLengthUnit &unit); + //! Altitude when within radius, else null const Aviation::CAltitude &getAltitudeIfWithinRadius(const ICoordinateGeodetic &coordinate) const; //! Altitude (synonym for geodetic height) 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) Aviation::CAltitude getAltitudeInUnit(const PhysicalQuantities::CLengthUnit &unit) const; diff --git a/src/blackmisc/pq/physicalquantity.cpp b/src/blackmisc/pq/physicalquantity.cpp index 0740214f8..436d06b87 100644 --- a/src/blackmisc/pq/physicalquantity.cpp +++ b/src/blackmisc/pq/physicalquantity.cpp @@ -247,16 +247,23 @@ namespace BlackMisc } template - PQ &CPhysicalQuantity::switchUnit(MU newUnit) + PQ &CPhysicalQuantity::switchUnit(const MU &newUnit) { - if (m_unit != newUnit) - { - m_value = newUnit.convertFrom(m_value, m_unit); - m_unit = newUnit; - } + if (m_unit == newUnit || this->isNull()) { return *derived(); } + m_value = newUnit.convertFrom(m_value, m_unit); + m_unit = newUnit; return *derived(); } + template + PQ CPhysicalQuantity::switchedUnit(const MU &newUnit) const + { + if (m_unit == newUnit || this->isNull()) { return *derived(); } + PQ copy(*derived()); + copy.switchUnit(newUnit); + return copy; + } + template bool CPhysicalQuantity::isNull() const { @@ -293,7 +300,7 @@ namespace BlackMisc } template - QString CPhysicalQuantity::valueRoundedWithUnit(MU unit, int digits, bool i18n) const + QString CPhysicalQuantity::valueRoundedWithUnit(const MU &unit, int digits, bool i18n) const { Q_ASSERT_X(!unit.isNull(), Q_FUNC_INFO, "Cannot convert to null"); if (this->isNull()) { return this->convertToQString(i18n); } diff --git a/src/blackmisc/pq/physicalquantity.h b/src/blackmisc/pq/physicalquantity.h index 6614ddab0..8ed95af18 100644 --- a/src/blackmisc/pq/physicalquantity.h +++ b/src/blackmisc/pq/physicalquantity.h @@ -74,7 +74,7 @@ namespace BlackMisc //! Simply set unit, do no calclulate conversion //! \sa switchUnit - void setUnit(MU unit) { m_unit = unit; } + void setUnit(const MU &unit) { m_unit = unit; } //! Set unit by string void setUnitBySymbol(const QString &unitName); @@ -83,7 +83,10 @@ namespace BlackMisc QString getUnitSymbol() const; //! 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? bool isNull() const; @@ -119,7 +122,7 @@ namespace BlackMisc //! Value to QString with the given unit, e.g. "5.00m" //! \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" //! \note default digits is CMeasurementUnit::getDisplayDigits @@ -219,24 +222,24 @@ namespace BlackMisc //! \copydoc BlackMisc::Mixin::JsonByMetaClass::convertFromJson 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 void parseFromString(const QString &value, CPqString::SeparatorMode mode); //! Parse value from string 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 int comparePropertyByIndex(const CPropertyIndex &index, const PQ &pq) const; - //! \copydoc BlackMisc::Mixin::String::toQString - QString convertToQString(bool i18n = false) const; - //! Maximum of 2 quantities static const PQ &maxValue(const PQ &pq1, const PQ &pq2); @@ -281,8 +284,7 @@ namespace BlackMisc extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CPhysicalQuantity; extern template class BLACKMISC_EXPORT_DECLARE_TEMPLATE CPhysicalQuantity; //! \endcond - - } -} + } // ns +} // ns #endif // guard