diff --git a/src/blackmisc/aviation/aircraftsituation.cpp b/src/blackmisc/aviation/aircraftsituation.cpp index 501f29728..01b1affe6 100644 --- a/src/blackmisc/aviation/aircraftsituation.cpp +++ b/src/blackmisc/aviation/aircraftsituation.cpp @@ -38,16 +38,18 @@ namespace BlackMisc {} CAircraftSituation::CAircraftSituation(const CCoordinateGeodetic &position, const CHeading &heading, const CAngle &pitch, const CAngle &bank, const CSpeed &gs, const CElevationPlane &groundElevation) - : m_position(position), m_heading(heading), m_pitch(pitch), - m_bank(bank), m_groundSpeed(gs), m_groundElevationPlane(groundElevation) + : m_position(position), m_groundElevationPlane(groundElevation), + m_heading(heading), m_pitch(pitch), m_bank(bank), + m_groundSpeed(gs) { m_pressureAltitude = position.geodeticHeight().toPressureAltitude(CPressure(1013.25, CPressureUnit::mbar())); } CAircraftSituation::CAircraftSituation(const CCallsign &correspondingCallsign, const CCoordinateGeodetic &position, const CHeading &heading, const CAngle &pitch, const CAngle &bank, const CSpeed &gs, const CElevationPlane &groundElevation) : m_correspondingCallsign(correspondingCallsign), - m_position(position), m_heading(heading), m_pitch(pitch), - m_bank(bank), m_groundSpeed(gs), m_groundElevationPlane(groundElevation) + m_position(position), m_groundElevationPlane(groundElevation), + m_heading(heading), m_pitch(pitch), m_bank(bank), + m_groundSpeed(gs) { m_correspondingCallsign.setTypeHint(CCallsign::Aircraft); m_pressureAltitude = position.geodeticHeight().toPressureAltitude(CPressure(1013.25, CPressureUnit::mbar())); @@ -139,7 +141,6 @@ namespace BlackMisc { static const QString noDetails("no details"); static const QString unknown("unknown"); - static const QString transferred("transferred"); static const QString provider("provider"); static const QString change("situation change"); static const QString cache("cached"); @@ -147,12 +148,13 @@ namespace BlackMisc static const QString interpolated("interpolated"); static const QString extrapolated("extrapolated"); static const QString avg("average"); + static const QString otherSituations("other situations"); switch (details) { case NoElevationInfo: return noDetails; - case TransferredElevation: return transferred; case FromProvider: return provider; + case FromOtherSituations: return otherSituations; case SituationChange: return change; case FromCache: return cache; case Test: return test; @@ -184,7 +186,7 @@ namespace BlackMisc bool CAircraftSituation::presetGroundElevation(CAircraftSituation &situationToPreset, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change) { - // IMPORTANT: we do not know what the situation will be interpolated to, so we cannot transfer + // IMPORTANT: we do not know what the situation will be (interpolated to), so we cannot transfer situationToPreset.resetGroundElevation(); do { @@ -194,18 +196,18 @@ namespace BlackMisc { // same positions, we can use existing elevation // means we were not moving between old an new - situationToPreset.setGroundElevation(oldSituation.getGroundElevationPlane(), CAircraftSituation::TransferredElevation); + situationToPreset.transferGroundElevation(oldSituation); break; } } const CLength distance = newSituation.calculateGreatCircleDistance(oldSituation); - if (distance < newSituation.getDistancePerTime250ms()) + if (distance < newSituation.getDistancePerTime250ms(CElevationPlane::singlePointRadius())) { if (oldSituation.hasGroundElevation()) { // almost same positions, we can use existing elevation - situationToPreset.setGroundElevation(oldSituation.getGroundElevationPlane(), CAircraftSituation::TransferredElevation); + situationToPreset.transferGroundElevation(oldSituation); break; } } @@ -267,7 +269,7 @@ namespace BlackMisc bool CAircraftSituation::extrapolateElevation(CAircraftSituation &newSituation, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange) { if (newSituation.hasGroundElevation()) { return false; } - if (oldSituation.transferGroundElevation(newSituation)) { return true; } + if (oldSituation.transferGroundElevationFromThis(newSituation)) { return true; } if (oldSituation.isNull() || olderSituation.isNull()) { return false; } if (oldChange.isNull()) { return false; } @@ -309,8 +311,9 @@ namespace BlackMisc case IndexIsOnGround: return CVariant::fromValue(m_onGround); case IndexIsOnGroundString: return CVariant::fromValue(this->onGroundAsString()); case IndexOnGroundReliability: return CVariant::fromValue(m_onGroundDetails); - case IndexOnGroundReliabilityString: return CVariant::fromValue(this->getOnDetailsAsString()); + case IndexOnGroundReliabilityString: return CVariant::fromValue(this->getOnGroundDetailsAsString()); case IndexGroundElevationInfo: return CVariant::fromValue(this->getGroundElevationInfo()); + case IndexGroundElevationInfoTransferred: return CVariant::fromValue(this->isGroundElevationInfoTransferred()); case IndexGroundElevationInfoString: return CVariant::fromValue(this->getGroundElevationInfoAsString()); case IndexGroundElevationPlusInfo: return CVariant::fromValue(this->getGroundElevationAndInfo()); case IndexCanLikelySkipNearGroundInterpolation: return CVariant::fromValue(this->canLikelySkipNearGroundInterpolation()); @@ -336,6 +339,7 @@ namespace BlackMisc case IndexIsOnGround: m_onGround = variant.toInt(); break; case IndexOnGroundReliability: m_onGroundDetails = variant.toInt(); break; case IndexGroundElevationInfo: m_elvInfo = variant.toInt(); break; + case IndexGroundElevationInfoTransferred: m_isElvInfoTransferred = variant.toBool(); break; case IndexGroundElevationPlusInfo: break; case IndexCanLikelySkipNearGroundInterpolation: break; default: CValueObject::setPropertyByIndex(index, variant); break; @@ -371,7 +375,12 @@ namespace BlackMisc return Compare::compare(m_onGroundDetails, compareValue.m_onGroundDetails); case IndexGroundElevationInfo: case IndexGroundElevationInfoString: - return Compare::compare(this->getGroundElevationInfo(), compareValue.getGroundElevationInfo()); + { + const int c = Compare::compare(this->getGroundElevationInfo(), compareValue.getGroundElevationInfo()); + if (c != 0) { return c; } + // fall thrue, compare flag + } + case IndexGroundElevationInfoTransferred: return Compare::compare(m_isElvInfoTransferred, compareValue.m_isElvInfoTransferred); case IndexCanLikelySkipNearGroundInterpolation: return Compare::compare(this->canLikelySkipNearGroundInterpolation(), compareValue.canLikelySkipNearGroundInterpolation()); default: break; } @@ -385,11 +394,14 @@ namespace BlackMisc return this->isPositionNull(); } - bool CAircraftSituation::isBetterInfo(CAircraftSituation::GndElevationInfo info) const + bool CAircraftSituation::isBetterInfo(CAircraftSituation::GndElevationInfo info, bool transferred) const { + if (!transferred && info == FromProvider) { return true; } // always override with latest value from provider if (info == NoElevationInfo || info == Test) { return false; } const int i = static_cast(info); - return i > m_onGroundDetails; + if (i > m_onGroundDetails) { return true; } + if (i == m_onGroundDetails) { return !transferred; } // transferred elevations are not better + return false; } bool CAircraftSituation::equalPbh(const CAircraftSituation &other) const @@ -402,6 +414,13 @@ namespace BlackMisc return this->equalNormalVectorDouble(other.normalVectorDouble()) && this->equalPbh(other); } + bool CAircraftSituation::equalPbhVectorAltitude(const CAircraftSituation &other) const + { + if (!this->equalPbhAndVector(other)) { return false; } + const int c = this->getAltitude().compare(other.getAltitude()); + return c == 0; + } + void CAircraftSituation::setNull() { m_position.setNull(); @@ -413,6 +432,7 @@ namespace BlackMisc m_groundSpeed.setNull(); m_onGroundDetails = CAircraftSituation::NotSetGroundDetails; m_elvInfo = NoElevationInfo; + m_isElvInfoTransferred = false; } bool CAircraftSituation::isOnGroundFromParts() const @@ -605,7 +625,7 @@ namespace BlackMisc return this->getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails; } - const QString &CAircraftSituation::getOnDetailsAsString() const + const QString CAircraftSituation::getOnGroundDetailsAsString() const { return CAircraftSituation::onGroundDetailsToString(this->getOnGroundDetails()); } @@ -646,7 +666,7 @@ namespace BlackMisc QString CAircraftSituation::getOnGroundInfo() const { - return this->onGroundAsString() % QLatin1Char(' ') % this->getOnDetailsAsString(); + return this->onGroundAsString() % QLatin1Char(' ') % this->getOnGroundDetailsAsString(); } CAircraftSituation::GndElevationInfo CAircraftSituation::getGroundElevationInfo() const @@ -655,6 +675,13 @@ namespace BlackMisc return static_cast(m_elvInfo); } + QString CAircraftSituation::getGroundElevationInfoAsString() const + { + return m_isElvInfoTransferred ? + gndElevationInfoToString(this->getGroundElevationInfo()) % QStringLiteral(" - tx") : + gndElevationInfoToString(this->getGroundElevationInfo()); + } + QString CAircraftSituation::getGroundElevationAndInfo() const { static const QString n("null"); @@ -664,22 +691,34 @@ namespace BlackMisc QStringLiteral(" [") % this->getGroundElevationInfoAsString() % QStringLiteral("]"); } - bool CAircraftSituation::canTransferGroundElevation(const CAircraftSituation &otherSituation, const CLength &radius) const + bool CAircraftSituation::canTransferGroundElevation(const CAircraftSituation &transferToSituation, const CLength &radius) const { if (!this->hasGroundElevation()) { return false; } - const CLength distance = this->getGroundElevationPlane().calculateGreatCircleDistance(otherSituation); + + // decide if transfer makes sense + // always transfer from provider, but do not override provider + if (transferToSituation.getGroundElevationInfo() == CAircraftSituation::FromProvider) { return false; } + if (this->getGroundElevationInfo() != CAircraftSituation::FromProvider && transferToSituation.getGroundElevationInfo() == CAircraftSituation::FromCache) { return false; } + + // distance + const CLength distance = this->getGroundElevationPlane().calculateGreatCircleDistance(transferToSituation); const bool transferable = (distance <= radius); return transferable; } - bool CAircraftSituation::transferGroundElevation(CAircraftSituation &transferToSituation, const CLength &radius) const + bool CAircraftSituation::transferGroundElevationFromThis(CAircraftSituation &transferToSituation, const CLength &radius) const { if (!this->canTransferGroundElevation(transferToSituation, radius)) { return false; } - transferToSituation.setGroundElevation(this->getGroundElevationPlane(), TransferredElevation); + transferToSituation.transferGroundElevation(*this); Q_ASSERT_X(!transferToSituation.getGroundElevationRadius().isNull(), Q_FUNC_INFO, "null radius"); return true; } + void CAircraftSituation::transferGroundElevation(const CAircraftSituation &fromSituation) + { + this->setGroundElevation(fromSituation.getGroundElevation(), fromSituation.getGroundElevationInfo(), true); + } + bool CAircraftSituation::presetGroundElevation(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change) { return CAircraftSituation::presetGroundElevation(*this, oldSituation, newSituation, change); @@ -729,47 +768,53 @@ namespace BlackMisc return this->getOnGroundDetails() == CAircraftSituation::InFromParts || this->getOnGroundDetails() == CAircraftSituation::InFromNetwork; } - void CAircraftSituation::setGroundElevation(const CAltitude &altitude, GndElevationInfo info) + void CAircraftSituation::setGroundElevation(const CAltitude &altitude, GndElevationInfo info, bool transferred) { if (altitude.isNull()) { m_groundElevationPlane = CElevationPlane::null(); + m_isElvInfoTransferred = false; this->setGroundElevationInfo(NoElevationInfo); } else { m_groundElevationPlane = CElevationPlane(*this); m_groundElevationPlane.setSinglePointRadius(); + m_isElvInfoTransferred = transferred; m_groundElevationPlane.setGeodeticHeight(altitude.switchedUnit(this->getAltitudeUnit())); this->setGroundElevationInfo(info); } } - void CAircraftSituation::setGroundElevation(const CElevationPlane &elevationPlane, GndElevationInfo info) + void CAircraftSituation::setGroundElevation(const CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred) { - m_groundElevationPlane = elevationPlane; if (elevationPlane.isNull()) { + m_groundElevationPlane = CElevationPlane::null(); + m_isElvInfoTransferred = false; this->setGroundElevationInfo(NoElevationInfo); } else { + m_groundElevationPlane = elevationPlane; + m_groundElevationPlane.fixRadius(); + m_isElvInfoTransferred = transferred; this->setGroundElevationInfo(info); Q_ASSERT_X(!m_groundElevationPlane.getRadius().isNull(), Q_FUNC_INFO, "Null radius"); m_groundElevationPlane.switchUnit(this->getAltitudeOrDefaultUnit()); // we use ft as internal unit, no "must" but simplification } } - bool CAircraftSituation::setGroundElevationChecked(const CElevationPlane &elevationPlane, GndElevationInfo info) + bool CAircraftSituation::setGroundElevationChecked(const CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred) { if (elevationPlane.isNull()) { return false; } const CLength distance = this->calculateGreatCircleDistance(elevationPlane); - if (distance > elevationPlane.getRadius()) { return false; } - if (m_groundElevationPlane.isNull() || this->isBetterInfo(info)) + if (distance > elevationPlane.getRadiusOrMinimumRadius()) { return false; } + if (m_groundElevationPlane.isNull() || this->isBetterInfo(info, transferred)) { // better values - this->setGroundElevation(elevationPlane, info); - m_groundElevationPlane.setRadiusOrMinimum(distance); + this->setGroundElevation(elevationPlane, info, transferred); + m_groundElevationPlane.setRadiusOrMinimumRadius(distance); return true; } return false; @@ -931,25 +976,34 @@ namespace BlackMisc return false; } - CLength CAircraftSituation::getDistancePerTime(const CTime &time) const + CLength CAircraftSituation::getDistancePerTime(const CTime &time, const CLength &min) const { - if (this->getGroundSpeed().isNull()) { return CLength(0, CLengthUnit::nullUnit()); } + if (this->getGroundSpeed().isNull()) + { + if (!min.isNull()) { return min; } + return CLength(0, CLengthUnit::nullUnit()); + } const int ms = time.valueInteger(CTimeUnit::ms()); - return this->getDistancePerTime(ms); + return this->getDistancePerTime(ms, min); } - CLength CAircraftSituation::getDistancePerTime(int milliseconds) const + CLength CAircraftSituation::getDistancePerTime(int milliseconds, const CLength &min) const { - if (this->getGroundSpeed().isNull()) { return CLength(0, CLengthUnit::nullUnit()); } + if (this->getGroundSpeed().isNull()) + { + if (!min.isNull()) { return min; } + return CLength(0, CLengthUnit::nullUnit()); + } const double seconds = milliseconds / 1000; const double gsMeterSecond = this->getGroundSpeed().value(CSpeedUnit::m_s()); const CLength d(seconds * gsMeterSecond, CLengthUnit::m()); + if (!min.isNull() && d < min) { return min; } return d; } - CLength CAircraftSituation::getDistancePerTime250ms() const + CLength CAircraftSituation::getDistancePerTime250ms(const CLength &min) const { - return this->getDistancePerTime(250); + return this->getDistancePerTime(250, min); } void CAircraftSituation::setCallsign(const CCallsign &callsign) diff --git a/src/blackmisc/aviation/aircraftsituation.h b/src/blackmisc/aviation/aircraftsituation.h index ad0b3f321..be9c719fd 100644 --- a/src/blackmisc/aviation/aircraftsituation.h +++ b/src/blackmisc/aviation/aircraftsituation.h @@ -68,6 +68,7 @@ namespace BlackMisc IndexGroundSpeed, IndexGroundElevationPlane, IndexGroundElevationInfo, + IndexGroundElevationInfoTransferred, IndexGroundElevationInfoString, IndexGroundElevationPlusInfo, IndexCallsign, @@ -116,14 +117,14 @@ namespace BlackMisc { // best info (most accurate) last NoElevationInfo, - Test, //!< unit test - SituationChange, //!< from BlackMisc::Aviation::CAircraftSituationChange - Extrapolated, //!< extrapolated ("guessing") - Average, //!< average value of "nearby" situation CAircraftSituationList::averageElevationOfNonMovingAircraft - Interpolated, //!< interpolated between 2 elevations - TransferredElevation, //!< transferred from nearby situation - FromCache, //!< from cache - FromProvider //!< from BlackMisc::Simulation::ISimulationEnvironmentProvider + Test, //!< unit test + SituationChange, //!< from BlackMisc::Aviation::CAircraftSituationChange + Extrapolated, //!< extrapolated ("guessing") + FromOtherSituations, //!< transferred from other situations ("sibling situations" same callsign) + Average, //!< average value of "nearby" situation CAircraftSituationList::averageElevationOfNonMovingAircraft + Interpolated, //!< interpolated between 2 elevations + FromCache, //!< from cache + FromProvider //!< from BlackMisc::Simulation::ISimulationEnvironmentProvider }; //! Default constructor. @@ -174,7 +175,7 @@ namespace BlackMisc virtual bool isNull() const override; //! Is better info (more accurate)? - bool isBetterInfo(GndElevationInfo info) const; + bool isBetterInfo(GndElevationInfo info, bool transferred) const; //! Equal pitch, bank heading //! \sa Geo::ICoordinateGeodetic::equalNormalVectorDouble @@ -184,6 +185,10 @@ namespace BlackMisc //! \sa Geo::ICoordinateGeodetic::equalNormalVectorDouble bool equalPbhAndVector(const CAircraftSituation &other) const; + //! Equal PBH and vector + //! \sa Geo::ICoordinateGeodetic::equalNormalVectorDouble + bool equalPbhVectorAltitude(const CAircraftSituation &other) const; + //! Set to null void setNull(); @@ -245,7 +250,7 @@ namespace BlackMisc bool hasGroundDetailsForGndInterpolation() const; //! On ground reliability as string - const QString &getOnDetailsAsString() const; + const QString getOnGroundDetailsAsString() const; //! On ground details bool setOnGroundDetails(CAircraftSituation::OnGroundDetails details); @@ -278,22 +283,28 @@ namespace BlackMisc GndElevationInfo getGroundElevationInfo() const; //! How did we get gnd.elevation? - const QString &getGroundElevationInfoAsString() const { return gndElevationInfoToString(this->getGroundElevationInfo()); } + QString getGroundElevationInfoAsString() const; //! Ground elevation plus info QString getGroundElevationAndInfo() const; + //! Is the elv.info transferred? + bool isGroundElevationInfoTransferred() const { return m_isElvInfoTransferred; } + //! How we did get gnd.elevation void setGroundElevationInfo(GndElevationInfo details) { m_elvInfo = static_cast(details); } //! Can the elevation be transferred to another situation? - bool canTransferGroundElevation(const CAircraftSituation &otherSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const; + bool canTransferGroundElevation(const CAircraftSituation &transferToSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const; //! Transfer from "this" situation to \c otherSituation //! \remark "transfer" can be used, if the positions are known, "preset" if they are still unknown //! \sa CAircraftSituation::interpolateGroundElevation //! \sa CAircraftSituation::interpolateElevation - bool transferGroundElevation(CAircraftSituation &transferToSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const; + bool transferGroundElevationFromThis(CAircraftSituation &transferToSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const; + + //! Transfer ground elevation from given situation + void transferGroundElevation(const CAircraftSituation &fromSituation); //! Preset "this" elevation from the two adjacent positions //! \remark it is not required that the position of "this" is already known @@ -327,14 +338,14 @@ namespace BlackMisc bool hasInboundGroundDetails() const; //! Elevation of the ground directly beneath at the given situation - void setGroundElevation(const Aviation::CAltitude &altitude, GndElevationInfo info); + void setGroundElevation(const Aviation::CAltitude &altitude, GndElevationInfo info, bool transferred = false); //! Elevation of the ground directly beneath - void setGroundElevation(const Geo::CElevationPlane &elevationPlane, GndElevationInfo info); + void setGroundElevation(const Geo::CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred = false); //! Set elevation of the ground directly beneath, but checked //! \remark override if better - bool setGroundElevationChecked(const Geo::CElevationPlane &elevationPlane, GndElevationInfo info); + bool setGroundElevationChecked(const Geo::CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred = false); //! Reset ground elevation void resetGroundElevation(); @@ -410,13 +421,13 @@ namespace BlackMisc bool canLikelySkipNearGroundInterpolation() const; //! Distance per time - PhysicalQuantities::CLength getDistancePerTime(const PhysicalQuantities::CTime &time) const; + PhysicalQuantities::CLength getDistancePerTime(const PhysicalQuantities::CTime &time, const PhysicalQuantities::CLength &min = PhysicalQuantities::CLength::null()) const; //! Distance per milliseconds - PhysicalQuantities::CLength getDistancePerTime(int milliseconds) const; + PhysicalQuantities::CLength getDistancePerTime(int milliseconds, const PhysicalQuantities::CLength &min = PhysicalQuantities::CLength::null()) const; //! Distance per milliseconds (250ms) - PhysicalQuantities::CLength getDistancePerTime250ms() const; + PhysicalQuantities::CLength getDistancePerTime250ms(const PhysicalQuantities::CLength &min = PhysicalQuantities::CLength::null()) const; //! Corresponding callsign const CCallsign &getCallsign() const { return m_correspondingCallsign; } @@ -522,14 +533,15 @@ namespace BlackMisc private: CCallsign m_correspondingCallsign; Geo::CCoordinateGeodetic m_position; //!< NULL position as default + Geo::CElevationPlane m_groundElevationPlane; //!< NULL elevation as default Aviation::CAltitude m_pressureAltitude { 0, nullptr }; CHeading m_heading { 0, nullptr }; PhysicalQuantities::CAngle m_pitch { 0, nullptr }; PhysicalQuantities::CAngle m_bank { 0, nullptr }; PhysicalQuantities::CSpeed m_groundSpeed { 0, nullptr }; PhysicalQuantities::CLength m_cg { 0, nullptr }; - Geo::CElevationPlane m_groundElevationPlane; //!< NULL elevation as default - bool m_isInterim = false; + bool m_isInterim = false; //!< interim situation? + bool m_isElvInfoTransferred = false; //!< the gnd.elevation has been transferred int m_onGround = static_cast(CAircraftSituation::OnGroundSituationUnknown); int m_onGroundDetails = static_cast(CAircraftSituation::NotSetGroundDetails); int m_elvInfo = static_cast(CAircraftSituation::NoElevationInfo); //!< where did we gnd.elevation from? @@ -556,6 +568,7 @@ namespace BlackMisc BLACK_METAMEMBER(onGround), BLACK_METAMEMBER(onGroundDetails), BLACK_METAMEMBER(elvInfo), + BLACK_METAMEMBER(isElvInfoTransferred), BLACK_METAMEMBER(onGroundFactor), BLACK_METAMEMBER(timestampMSecsSinceEpoch), BLACK_METAMEMBER(timeOffsetMs), diff --git a/src/blackmisc/aviation/aircraftsituationlist.cpp b/src/blackmisc/aviation/aircraftsituationlist.cpp index 490a8de18..7c3c01a04 100644 --- a/src/blackmisc/aviation/aircraftsituationlist.cpp +++ b/src/blackmisc/aviation/aircraftsituationlist.cpp @@ -347,6 +347,26 @@ namespace BlackMisc return found; } + CElevationPlane CAircraftSituationList::findCLosestElevationWithinRange(const ICoordinateGeodetic &coordinate, const CLength &range) const + { + CLength r = range.isNull() || range < CElevationPlane::singlePointRadius() ? CElevationPlane::singlePointRadius() : range; + CElevationPlane ep = CElevationPlane::null(); + + CLength bestDistance = CLength::null(); + for (const CAircraftSituation &s : *this) + { + if (!s.hasGroundElevation()) { continue; } + const CLength distance = s.calculateGreatCircleDistance(coordinate); + if (distance > r) { continue; } + if (bestDistance.isNull() || bestDistance > distance) + { + ep = s.getGroundElevationPlane(); + bestDistance = distance; + } + } + return ep; + } + int CAircraftSituationList::setOnGround(CAircraftSituation::IsOnGround og) { int c = 0; @@ -530,7 +550,7 @@ namespace BlackMisc { const CAircraftSituation &oldSituation = (*this)[i]; CAircraftSituation &newSituation = (*this)[i - 1]; - if (oldSituation.transferGroundElevation(newSituation, radius)) { c++; } + if (oldSituation.transferGroundElevationFromThis(newSituation, radius)) { c++; } } return c; } diff --git a/src/blackmisc/aviation/aircraftsituationlist.h b/src/blackmisc/aviation/aircraftsituationlist.h index a37bc8afe..55ea88e01 100644 --- a/src/blackmisc/aviation/aircraftsituationlist.h +++ b/src/blackmisc/aviation/aircraftsituationlist.h @@ -135,6 +135,9 @@ namespace BlackMisc //! Situations with CAircraftSituation::IsOnGround and elevation CAircraftSituationList findOnGroundWithElevation(CAircraftSituation::IsOnGround og) const; + //! CLosest elevation within given range + Geo::CElevationPlane findCLosestElevationWithinRange(const Geo::ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &range = Geo::CElevationPlane::singlePointRadius()) const; + //! Set on ground int setOnGround(CAircraftSituation::IsOnGround og);