diff --git a/src/blackmisc/aviation/altitude.cpp b/src/blackmisc/aviation/altitude.cpp index f564d9eaa..a4a72834f 100644 --- a/src/blackmisc/aviation/altitude.cpp +++ b/src/blackmisc/aviation/altitude.cpp @@ -106,5 +106,11 @@ namespace BlackMisc return BlackMisc::CIcon::iconByIndex(CIcons::GeoPosition); } + const CAltitude &CAltitude::null() + { + static const CAltitude null(0, CAltitude::MeanSeaLevel, CLengthUnit::nullUnit()); + return null; + } + } // namespace } // namespace diff --git a/src/blackmisc/aviation/altitude.h b/src/blackmisc/aviation/altitude.h index 9c1228455..d11ded89f 100644 --- a/src/blackmisc/aviation/altitude.h +++ b/src/blackmisc/aviation/altitude.h @@ -63,7 +63,7 @@ namespace BlackMisc /*! * Enum type to distinguish between MSL and AGL */ - enum ReferenceDatum : uint + enum ReferenceDatum { MeanSeaLevel = 0, //!< MSL AboveGround, //!< AGL @@ -115,6 +115,9 @@ namespace BlackMisc //! \copydoc BlackMisc::Mixin::Icon::toIcon BlackMisc::CIcon toIcon() const; + //! Null altitude (MSL) + static const CAltitude &null(); + private: ReferenceDatum m_datum; //!< MSL or AGL? diff --git a/src/blackmisc/simulation/interpolationhints.cpp b/src/blackmisc/simulation/interpolationhints.cpp index ad11f3363..77c9d3a44 100644 --- a/src/blackmisc/simulation/interpolationhints.cpp +++ b/src/blackmisc/simulation/interpolationhints.cpp @@ -10,6 +10,7 @@ #include "interpolationhints.h" #include "blackmisc/aviation/aircraftsituation.h" +using namespace BlackMisc::Aviation; using namespace BlackMisc::Geo; using namespace BlackMisc::PhysicalQuantities; @@ -22,6 +23,13 @@ namespace BlackMisc CInterpolationHints::CInterpolationHints(bool isVtolAircraft) : m_isVtol(isVtolAircraft) { } + CAltitude CInterpolationHints::getGroundElevation(const Aviation::CAircraftSituation &situation) const + { + if (m_elevationProvider) { return m_elevationProvider(situation); } + if (m_elevation.isNull() || !m_elevation.isWithinRange(situation)) { return CAltitude::null(); } + return m_elevation.geodeticHeight(); + } + void CInterpolationHints::resetElevation() { m_elevation = CElevationPlane(); @@ -33,6 +41,12 @@ namespace BlackMisc return m_elevation.isWithinRange(coordinate); } + void CInterpolationHints::setAircraftParts(const CAircraftParts &parts, bool hasParts) + { + m_hasParts = hasParts; + m_aircraftParts = parts; + } + CVariant CInterpolationHints::propertyByIndex(const CPropertyIndex &index) const { if (index.isMyself()) { return CVariant::from(*this); } diff --git a/src/blackmisc/simulation/interpolationhints.h b/src/blackmisc/simulation/interpolationhints.h index 51eb6cc36..23713bab3 100644 --- a/src/blackmisc/simulation/interpolationhints.h +++ b/src/blackmisc/simulation/interpolationhints.h @@ -20,7 +20,6 @@ namespace BlackMisc { namespace Aviation { class CAircraftSituation; } - namespace Simulation { //! Hints for interpolator such as ground elevation @@ -45,6 +44,9 @@ namespace BlackMisc //! Get elevation const BlackMisc::Geo::CElevationPlane &getElevation() const { return m_elevation;} + //! Get elevation from CInterpolationHints::getElevationProvider or CInterpolationHints::getElevation + Aviation::CAltitude getGroundElevation(const BlackMisc::Aviation::CAircraftSituation &situation) const; + //! Set elevation void setElevation(const BlackMisc::Geo::CElevationPlane &elevation) { m_elevation = elevation; } @@ -69,16 +71,18 @@ namespace BlackMisc //! Has valid aircraft parts? bool hasAircraftParts() const { return m_hasParts; } - //! Aircraft parts + //! Aircraft parts required for interpolation BlackMisc::Aviation::CAircraftParts getAircraftParts() const { return m_aircraftParts; } - //! Set aircraft parts - void setAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts) { m_hasParts = true; m_aircraftParts = parts; } + //! Set aircraft parts required for interpolation if any + //! \remark when used to reset value (default object) use hasParts false. Needed as there is no null parts object + void setAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts, bool hasParts = true); //! Function object that can obtain ground elevation - using ElevationProvider = std::function; + using ElevationProvider = std::function; //! Function object that can obtain ground elevation + //! \remark either a provider or a value set can be used const ElevationProvider &getElevationProvider() const { return m_elevationProvider; } //! Set function object that can obtain ground elevation @@ -97,12 +101,12 @@ namespace BlackMisc QString debugInfo(const BlackMisc::Geo::CElevationPlane &deltaElevation) const; private: - bool m_isVtol = false; //!< VTOL aircraft? - BlackMisc::Geo::CElevationPlane m_elevation; //!< aircraft's elevation if available - BlackMisc::PhysicalQuantities::CLength m_cgAboveGround { 0, nullptr }; //!< center of gravity above ground + bool m_isVtol = false; //!< VTOL aircraft? bool m_hasParts = false; //!< Has valid aircraft parts? BlackMisc::Aviation::CAircraftParts m_aircraftParts; //!< Aircraft parts - ElevationProvider m_elevationProvider; //!< Provider of ground elevation (lazy computation) + BlackMisc::Geo::CElevationPlane m_elevation; //!< aircraft's elevation if available + ElevationProvider m_elevationProvider; //!< Provider of ground elevation (lazy computation) + BlackMisc::PhysicalQuantities::CLength m_cgAboveGround { 0, nullptr }; //!< center of gravity above ground BLACK_METACLASS( CInterpolationHints, diff --git a/src/plugins/simulator/fs9/fs9client.cpp b/src/plugins/simulator/fs9/fs9client.cpp index 48624a451..c8d23f0e3 100644 --- a/src/plugins/simulator/fs9/fs9client.cpp +++ b/src/plugins/simulator/fs9/fs9client.cpp @@ -170,7 +170,7 @@ namespace BlackSimPlugin if (m_clientStatus == Disconnected) { return; } IInterpolator::InterpolationStatus status; - const CInterpolationHints hints; + const CInterpolationHints hints; // \fixme 201701 #865 KB if there is an elevation provider for FS9 add it here or set elevation const CAircraftSituation situation = this->m_interpolator->getInterpolatedSituation(m_callsign, -1, hints, status); // Test only for successful interpolation. FS9 requires constant positions diff --git a/src/xbus/traffic.cpp b/src/xbus/traffic.cpp index a2fe5507d..72251fc8a 100644 --- a/src/xbus/traffic.cpp +++ b/src/xbus/traffic.cpp @@ -50,12 +50,14 @@ namespace XBus hints.setElevationProvider([this](const auto &situation) { using namespace BlackMisc::PhysicalQuantities; - const auto meters = terrainProbe.getElevation(situation.latitude().value(CAngleUnit::deg()), - situation.longitude().value(CAngleUnit::deg()), - situation.getAltitude().value(CLengthUnit::m())); - if (std::isnan(meters)) { return CLength(0, nullptr); } + using namespace BlackMisc::Aviation; + const auto meters = terrainProbe.getElevation( + situation.latitude().value(CAngleUnit::deg()), + situation.longitude().value(CAngleUnit::deg()), + situation.getAltitude().value(CLengthUnit::m())); + if (std::isnan(meters)) { return CAltitude::null(); } constexpr decltype(meters) fudgeFactor = 3.0; //! \fixme Value should be different for each plane, derived from the CSL model geometry - return CLength(meters + fudgeFactor, CLengthUnit::m()); + return CAltitude(CLength(meters + fudgeFactor, CLengthUnit::m()), CAltitude::MeanSeaLevel); }); return hints; }