diff --git a/src/blackcore/airspacemonitor.cpp b/src/blackcore/airspacemonitor.cpp index 7548c8346..57a546871 100644 --- a/src/blackcore/airspacemonitor.cpp +++ b/src/blackcore/airspacemonitor.cpp @@ -1387,9 +1387,10 @@ namespace BlackCore if (!canLikelySkipNearGround) { + const CLength dpt = correctedSituation.getDistancePerTime(100, CElevationPlane::singlePointRadius()); const CAircraftSituationList situationsBeforeStoring = this->remoteAircraftSituations(callsign); - const CAircraftSituation situationWithElvBeforeStoring = situationsBeforeStoring.findClosestElevationWithinRange(correctedSituation, correctedSituation.getDistancePerTime(100, CElevationPlane::singlePointRadius())); - if (!situationWithElvBeforeStoring.getGroundElevation().isNull()) + const CAircraftSituation situationWithElvBeforeStoring = situationsBeforeStoring.findClosestElevationWithinRange(correctedSituation, dpt); + if (situationWithElvBeforeStoring.transferGroundElevationFromMe(correctedSituation, dpt)) { // from nearby situations of own aircraft, data was transferred above // we use transfer first as it is slightly faster as cache @@ -1433,7 +1434,8 @@ namespace BlackCore if (!averagePlane.isNull()) { correctedSituation.setGroundElevation(averagePlane, CAircraftSituation::Average); - if (fromNonMoving) { m_foundInNonMovingAircraft++; } else { m_foundInElevationsOnGnd++; } + if (fromNonMoving) { m_foundInNonMovingAircraft++; } + else { m_foundInElevationsOnGnd++; } } else { diff --git a/src/blackmisc/aviation/aircraftsituation.cpp b/src/blackmisc/aviation/aircraftsituation.cpp index ed12862bb..aaa8b8161 100644 --- a/src/blackmisc/aviation/aircraftsituation.cpp +++ b/src/blackmisc/aviation/aircraftsituation.cpp @@ -219,7 +219,7 @@ namespace BlackMisc { // same positions, we can use existing elevation // means we were not moving between old an new - situationToPreset.transferGroundElevation(oldSituation); + situationToPreset.transferGroundElevationToMe(oldSituation, true); break; } } @@ -230,7 +230,7 @@ namespace BlackMisc if (oldSituation.hasGroundElevation()) { // almost same positions, we can use existing elevation - situationToPreset.transferGroundElevation(oldSituation); + situationToPreset.transferGroundElevationToMe(oldSituation, true); break; } } @@ -297,23 +297,23 @@ namespace BlackMisc } } - bool CAircraftSituation::extrapolateElevation(CAircraftSituation &newSituation, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange) + bool CAircraftSituation::extrapolateElevation(CAircraftSituation &situationToBeUpdated, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange) { - if (newSituation.hasGroundElevation()) { return false; } + if (situationToBeUpdated.hasGroundElevation()) { return false; } // if acceptable transfer - if (oldSituation.transferGroundElevationFromThis(newSituation)) { return true; } + if (oldSituation.transferGroundElevationFromMe(situationToBeUpdated)) { return true; } if (oldSituation.isNull() || olderSituation.isNull()) { return false; } if (oldChange.isNull()) { return false; } if (oldChange.isConstOnGround() && oldChange.hasAltitudeDevWithinAllowedRange() && oldChange.hasElevationDevWithinAllowedRange()) { // we have almost const altitudes and elevations - const double deltaAltFt = qAbs(newSituation.getAltitude().value(CLengthUnit::ft()) - olderSituation.getAltitude().value(CLengthUnit::ft())); + const double deltaAltFt = qAbs(situationToBeUpdated.getAltitude().value(CLengthUnit::ft()) - olderSituation.getAltitude().value(CLengthUnit::ft())); if (deltaAltFt <= CAircraftSituationChange::allowedAltitudeDeviation().value(CLengthUnit::ft())) { // the current alt is also not much different - newSituation.setGroundElevation(oldSituation.getGroundElevation(), Extrapolated); + situationToBeUpdated.setGroundElevation(oldSituation.getGroundElevation(), Extrapolated); return true; } } @@ -712,6 +712,12 @@ namespace BlackMisc return this->onGroundAsString() % u' ' % this->getOnGroundDetailsAsString(); } + CLength CAircraftSituation::getGroundElevationDistance() const + { + // returns NULL if elevation is N/A + return this->getGroundElevationPlane().calculateGreatCircleDistance(*this); + } + CAircraftSituation::GndElevationInfo CAircraftSituation::getGroundElevationInfo() const { if (!this->hasGroundElevation()) { return NoElevationInfo; } @@ -741,25 +747,28 @@ namespace BlackMisc // 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; } + if (this->getGroundElevationInfo() != CAircraftSituation::FromProvider && transferToSituation.getGroundElevationInfo() == CAircraftSituation::FromCache) { return false; } // distance - const CLength distance = this->getGroundElevationPlane().calculateGreatCircleDistance(transferToSituation); + const CLength distance = this->getGroundElevationPlane().calculateGreatCircleDistance(transferToSituation); const bool transferable = (distance <= radius); return transferable; } - bool CAircraftSituation::transferGroundElevationFromThis(CAircraftSituation &transferToSituation, const CLength &radius) const + bool CAircraftSituation::transferGroundElevationFromMe(CAircraftSituation &transferToSituation, const CLength &radius) const { - if (!this->canTransferGroundElevation(transferToSituation, radius)) { return false; } - transferToSituation.transferGroundElevation(*this); - Q_ASSERT_X(!transferToSituation.getGroundElevationRadius().isNull(), Q_FUNC_INFO, "null radius"); - return true; + return transferToSituation.transferGroundElevationToMe(*this, radius, true); } - void CAircraftSituation::transferGroundElevation(const CAircraftSituation &fromSituation) + bool CAircraftSituation::transferGroundElevationToMe(const CAircraftSituation &fromSituation, const CLength &radius, bool transferred) { - this->setGroundElevation(fromSituation.getGroundElevation(), fromSituation.getGroundElevationInfo(), true); + if (!fromSituation.canTransferGroundElevation(*this, radius)) { return false; } + return this->setGroundElevation(fromSituation.getGroundElevationPlane(), fromSituation.getGroundElevationInfo(), transferred); + } + + bool CAircraftSituation::transferGroundElevationToMe(const CAircraftSituation &fromSituation, bool transferred) + { + return this->setGroundElevation(fromSituation.getGroundElevationPlane(), fromSituation.getGroundElevationInfo(), transferred); } bool CAircraftSituation::presetGroundElevation(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change) @@ -811,8 +820,9 @@ namespace BlackMisc return this->getOnGroundDetails() == CAircraftSituation::InFromParts || this->getOnGroundDetails() == CAircraftSituation::InFromNetwork; } - void CAircraftSituation::setGroundElevation(const CAltitude &altitude, GndElevationInfo info, bool transferred) + bool CAircraftSituation::setGroundElevation(const CAltitude &altitude, GndElevationInfo info, bool transferred) { + bool set = false; if (altitude.isNull()) { m_groundElevationPlane = CElevationPlane::null(); @@ -826,11 +836,14 @@ namespace BlackMisc m_isElvInfoTransferred = transferred; m_groundElevationPlane.setGeodeticHeight(altitude.switchedUnit(this->getAltitudeUnit())); this->setGroundElevationInfo(info); + set = true; } + return set; } - void CAircraftSituation::setGroundElevation(const CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred) + bool CAircraftSituation::setGroundElevation(const CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred) { + bool set = false; if (elevationPlane.isNull()) { m_groundElevationPlane = CElevationPlane::null(); @@ -845,7 +858,9 @@ namespace BlackMisc 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 + set = true; } + return set; } bool CAircraftSituation::setGroundElevationChecked(const CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred) diff --git a/src/blackmisc/aviation/aircraftsituation.h b/src/blackmisc/aviation/aircraftsituation.h index c3281f838..a48073e6e 100644 --- a/src/blackmisc/aviation/aircraftsituation.h +++ b/src/blackmisc/aviation/aircraftsituation.h @@ -280,6 +280,9 @@ namespace BlackMisc //! Elevation of the ground directly beneath const Geo::CElevationPlane &getGroundElevationPlane() const { return m_groundElevationPlane; } + //! Distance of coordinates of situation to coordinates of elevation plane + PhysicalQuantities::CLength getGroundElevationDistance() const; + //! How did we get gnd.elevation? GndElevationInfo getGroundElevationInfo() const; @@ -302,10 +305,13 @@ namespace BlackMisc //! \remark "transfer" can be used, if the positions are known, "preset" if they are still unknown //! \sa CAircraftSituation::interpolateGroundElevation //! \sa CAircraftSituation::interpolateElevation - bool transferGroundElevationFromThis(CAircraftSituation &transferToSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const; + bool transferGroundElevationFromMe(CAircraftSituation &transferToSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const; - //! Transfer ground elevation from given situation - void transferGroundElevation(const CAircraftSituation &fromSituation); + //! Transfer ground elevation from given situation (to me) + bool transferGroundElevationToMe(const CAircraftSituation &fromSituation, const PhysicalQuantities::CLength &radius, bool transferred); + + //! Transfer ground elevation from given situation (to me) + bool transferGroundElevationToMe(const CAircraftSituation &fromSituation, bool transferred); //! Preset "this" elevation from the two adjacent positions //! \remark it is not required that the position of "this" is already known @@ -314,8 +320,8 @@ namespace BlackMisc //! \sa CAircraftSituation::interpolateElevation bool presetGroundElevation(const Aviation::CAircraftSituation &oldSituation, const Aviation::CAircraftSituation &newSituation, const CAircraftSituationChange &change); - //! Set "this" elevation from older situations. - //! \remark this is a future value + //! Set "my" elevation from older situations. + //! \remark this object normally is a future value //! \sa CAircraftSituation::transferGroundElevation //! \sa CAircraftSituation::interpolateElevation bool extrapolateElevation(const Aviation::CAircraftSituation &oldSituation, const Aviation::CAircraftSituation &olderSituation, const CAircraftSituationChange &change); @@ -339,10 +345,10 @@ namespace BlackMisc bool hasInboundGroundDetails() const; //! Elevation of the ground directly beneath at the given situation - void setGroundElevation(const Aviation::CAltitude &altitude, GndElevationInfo info, bool transferred = false); + bool setGroundElevation(const Aviation::CAltitude &altitude, GndElevationInfo info, bool transferred = false); //! Elevation of the ground directly beneath - void setGroundElevation(const Geo::CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred = false); + bool setGroundElevation(const Geo::CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred = false); //! Set elevation of the ground directly beneath, but checked //! \remark override if better @@ -542,7 +548,7 @@ namespace BlackMisc } //! @} - //! Preset the ground elevation based on info we already have + //! Preset the ground elevation based on info we already have, either by transfer or elevation //! \remark either sets a gnd. elevation or sets it to null //! \remark situationToPreset position is unknown //! \remark situationToPreset needs to be between oldSituation and newSituation @@ -550,9 +556,9 @@ namespace BlackMisc static bool presetGroundElevation(CAircraftSituation &situationToPreset, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change); //! Extrapolated between the 2 situations for situation - //! \remark situation is not between oldSituation and olderSituation - //! \remark NULL if there are no two elevations - static bool extrapolateElevation(CAircraftSituation &newSituation, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange); + //! \remark normally used if situationToBeUpdated is not between oldSituation and olderSituation (that would be interpolation) + //! \return false if there are no two elevations, there is already an elevation, or no extrapolation is possible (too much deviation) + static bool extrapolateElevation(CAircraftSituation &situationToBeUpdated, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange); //! Interpolate between the 2 situations for situation //! \remark NULL if there are no two elevations or threshold MaxDeltaElevationFt is exceeded diff --git a/src/blackmisc/aviation/aircraftsituationlist.cpp b/src/blackmisc/aviation/aircraftsituationlist.cpp index 83f392503..482abc3c6 100644 --- a/src/blackmisc/aviation/aircraftsituationlist.cpp +++ b/src/blackmisc/aviation/aircraftsituationlist.cpp @@ -400,14 +400,19 @@ namespace BlackMisc CAircraftSituation CAircraftSituationList::findClosestElevationWithinRange(const ICoordinateGeodetic &coordinate, const CLength &range) const { - CLength r = range.isNull() || range < CElevationPlane::singlePointRadius() ? CElevationPlane::singlePointRadius() : range; + const CLength r = range.isNull() || range < CElevationPlane::singlePointRadius() ? CElevationPlane::singlePointRadius() : range; CAircraftSituation situationWithElevation = CAircraftSituation::null(); CLength bestDistance = CLength::null(); for (const CAircraftSituation &s : *this) { if (!s.hasGroundElevation()) { continue; } - const CLength distance = s.calculateGreatCircleDistance(coordinate); + + // we need to calculate distance to coordinates of the plane + // not the situation using the coordinate + // const CLength distance = s.calculateGreatCircleDistance(coordinate); + const CLength distance = s.getGroundElevationPlane().calculateGreatCircleDistance(coordinate); + if (distance > r) { continue; } if (bestDistance.isNull() || bestDistance > distance) { @@ -601,7 +606,7 @@ namespace BlackMisc { const CAircraftSituation &oldSituation = (*this)[i]; CAircraftSituation &newSituation = (*this)[i - 1]; - if (oldSituation.transferGroundElevationFromThis(newSituation, radius)) { c++; } + if (oldSituation.transferGroundElevationFromMe(newSituation, radius)) { c++; } } return c; } diff --git a/src/blackmisc/simulation/interpolator.cpp b/src/blackmisc/simulation/interpolator.cpp index 844228e85..238392608 100644 --- a/src/blackmisc/simulation/interpolator.cpp +++ b/src/blackmisc/simulation/interpolator.cpp @@ -233,7 +233,7 @@ namespace BlackMisc { // we still have no elevation const CLength radius = currentSituation.getDistancePerTime250ms(CElevationPlane::singlePointRadius()); - if (!m_lastSituation.transferGroundElevationFromThis(currentSituation, radius)) + if (!m_lastSituation.transferGroundElevationFromMe(currentSituation, radius)) { if (currentSituation.canLikelySkipNearGroundInterpolation()) {