Ref T268, aircraft situation improvements

* Transfer gnd. elevation
* find closest elevation
This commit is contained in:
Klaus Basan
2018-07-09 22:13:53 +02:00
parent f06482b554
commit 62f9beae89
4 changed files with 148 additions and 58 deletions

View File

@@ -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) 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_position(position), m_groundElevationPlane(groundElevation),
m_bank(bank), m_groundSpeed(gs), 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())); 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) 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_correspondingCallsign(correspondingCallsign),
m_position(position), m_heading(heading), m_pitch(pitch), m_position(position), m_groundElevationPlane(groundElevation),
m_bank(bank), m_groundSpeed(gs), m_groundElevationPlane(groundElevation) m_heading(heading), m_pitch(pitch), m_bank(bank),
m_groundSpeed(gs)
{ {
m_correspondingCallsign.setTypeHint(CCallsign::Aircraft); m_correspondingCallsign.setTypeHint(CCallsign::Aircraft);
m_pressureAltitude = position.geodeticHeight().toPressureAltitude(CPressure(1013.25, CPressureUnit::mbar())); 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 noDetails("no details");
static const QString unknown("unknown"); static const QString unknown("unknown");
static const QString transferred("transferred");
static const QString provider("provider"); static const QString provider("provider");
static const QString change("situation change"); static const QString change("situation change");
static const QString cache("cached"); static const QString cache("cached");
@@ -147,12 +148,13 @@ namespace BlackMisc
static const QString interpolated("interpolated"); static const QString interpolated("interpolated");
static const QString extrapolated("extrapolated"); static const QString extrapolated("extrapolated");
static const QString avg("average"); static const QString avg("average");
static const QString otherSituations("other situations");
switch (details) switch (details)
{ {
case NoElevationInfo: return noDetails; case NoElevationInfo: return noDetails;
case TransferredElevation: return transferred;
case FromProvider: return provider; case FromProvider: return provider;
case FromOtherSituations: return otherSituations;
case SituationChange: return change; case SituationChange: return change;
case FromCache: return cache; case FromCache: return cache;
case Test: return test; case Test: return test;
@@ -184,7 +186,7 @@ namespace BlackMisc
bool CAircraftSituation::presetGroundElevation(CAircraftSituation &situationToPreset, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change) 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(); situationToPreset.resetGroundElevation();
do do
{ {
@@ -194,18 +196,18 @@ namespace BlackMisc
{ {
// same positions, we can use existing elevation // same positions, we can use existing elevation
// means we were not moving between old an new // means we were not moving between old an new
situationToPreset.setGroundElevation(oldSituation.getGroundElevationPlane(), CAircraftSituation::TransferredElevation); situationToPreset.transferGroundElevation(oldSituation);
break; break;
} }
} }
const CLength distance = newSituation.calculateGreatCircleDistance(oldSituation); const CLength distance = newSituation.calculateGreatCircleDistance(oldSituation);
if (distance < newSituation.getDistancePerTime250ms()) if (distance < newSituation.getDistancePerTime250ms(CElevationPlane::singlePointRadius()))
{ {
if (oldSituation.hasGroundElevation()) if (oldSituation.hasGroundElevation())
{ {
// almost same positions, we can use existing elevation // almost same positions, we can use existing elevation
situationToPreset.setGroundElevation(oldSituation.getGroundElevationPlane(), CAircraftSituation::TransferredElevation); situationToPreset.transferGroundElevation(oldSituation);
break; break;
} }
} }
@@ -267,7 +269,7 @@ namespace BlackMisc
bool CAircraftSituation::extrapolateElevation(CAircraftSituation &newSituation, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange) bool CAircraftSituation::extrapolateElevation(CAircraftSituation &newSituation, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange)
{ {
if (newSituation.hasGroundElevation()) { return false; } 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 (oldSituation.isNull() || olderSituation.isNull()) { return false; }
if (oldChange.isNull()) { return false; } if (oldChange.isNull()) { return false; }
@@ -309,8 +311,9 @@ namespace BlackMisc
case IndexIsOnGround: return CVariant::fromValue(m_onGround); case IndexIsOnGround: return CVariant::fromValue(m_onGround);
case IndexIsOnGroundString: return CVariant::fromValue(this->onGroundAsString()); case IndexIsOnGroundString: return CVariant::fromValue(this->onGroundAsString());
case IndexOnGroundReliability: return CVariant::fromValue(m_onGroundDetails); 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 IndexGroundElevationInfo: return CVariant::fromValue(this->getGroundElevationInfo());
case IndexGroundElevationInfoTransferred: return CVariant::fromValue(this->isGroundElevationInfoTransferred());
case IndexGroundElevationInfoString: return CVariant::fromValue(this->getGroundElevationInfoAsString()); case IndexGroundElevationInfoString: return CVariant::fromValue(this->getGroundElevationInfoAsString());
case IndexGroundElevationPlusInfo: return CVariant::fromValue(this->getGroundElevationAndInfo()); case IndexGroundElevationPlusInfo: return CVariant::fromValue(this->getGroundElevationAndInfo());
case IndexCanLikelySkipNearGroundInterpolation: return CVariant::fromValue(this->canLikelySkipNearGroundInterpolation()); case IndexCanLikelySkipNearGroundInterpolation: return CVariant::fromValue(this->canLikelySkipNearGroundInterpolation());
@@ -336,6 +339,7 @@ namespace BlackMisc
case IndexIsOnGround: m_onGround = variant.toInt(); break; case IndexIsOnGround: m_onGround = variant.toInt(); break;
case IndexOnGroundReliability: m_onGroundDetails = variant.toInt(); break; case IndexOnGroundReliability: m_onGroundDetails = variant.toInt(); break;
case IndexGroundElevationInfo: m_elvInfo = variant.toInt(); break; case IndexGroundElevationInfo: m_elvInfo = variant.toInt(); break;
case IndexGroundElevationInfoTransferred: m_isElvInfoTransferred = variant.toBool(); break;
case IndexGroundElevationPlusInfo: break; case IndexGroundElevationPlusInfo: break;
case IndexCanLikelySkipNearGroundInterpolation: break; case IndexCanLikelySkipNearGroundInterpolation: break;
default: CValueObject::setPropertyByIndex(index, variant); break; default: CValueObject::setPropertyByIndex(index, variant); break;
@@ -371,7 +375,12 @@ namespace BlackMisc
return Compare::compare(m_onGroundDetails, compareValue.m_onGroundDetails); return Compare::compare(m_onGroundDetails, compareValue.m_onGroundDetails);
case IndexGroundElevationInfo: case IndexGroundElevationInfo:
case IndexGroundElevationInfoString: 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()); case IndexCanLikelySkipNearGroundInterpolation: return Compare::compare(this->canLikelySkipNearGroundInterpolation(), compareValue.canLikelySkipNearGroundInterpolation());
default: break; default: break;
} }
@@ -385,11 +394,14 @@ namespace BlackMisc
return this->isPositionNull(); 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; } if (info == NoElevationInfo || info == Test) { return false; }
const int i = static_cast<int>(info); const int i = static_cast<int>(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 bool CAircraftSituation::equalPbh(const CAircraftSituation &other) const
@@ -402,6 +414,13 @@ namespace BlackMisc
return this->equalNormalVectorDouble(other.normalVectorDouble()) && this->equalPbh(other); 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() void CAircraftSituation::setNull()
{ {
m_position.setNull(); m_position.setNull();
@@ -413,6 +432,7 @@ namespace BlackMisc
m_groundSpeed.setNull(); m_groundSpeed.setNull();
m_onGroundDetails = CAircraftSituation::NotSetGroundDetails; m_onGroundDetails = CAircraftSituation::NotSetGroundDetails;
m_elvInfo = NoElevationInfo; m_elvInfo = NoElevationInfo;
m_isElvInfoTransferred = false;
} }
bool CAircraftSituation::isOnGroundFromParts() const bool CAircraftSituation::isOnGroundFromParts() const
@@ -605,7 +625,7 @@ namespace BlackMisc
return this->getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails; return this->getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails;
} }
const QString &CAircraftSituation::getOnDetailsAsString() const const QString CAircraftSituation::getOnGroundDetailsAsString() const
{ {
return CAircraftSituation::onGroundDetailsToString(this->getOnGroundDetails()); return CAircraftSituation::onGroundDetailsToString(this->getOnGroundDetails());
} }
@@ -646,7 +666,7 @@ namespace BlackMisc
QString CAircraftSituation::getOnGroundInfo() const QString CAircraftSituation::getOnGroundInfo() const
{ {
return this->onGroundAsString() % QLatin1Char(' ') % this->getOnDetailsAsString(); return this->onGroundAsString() % QLatin1Char(' ') % this->getOnGroundDetailsAsString();
} }
CAircraftSituation::GndElevationInfo CAircraftSituation::getGroundElevationInfo() const CAircraftSituation::GndElevationInfo CAircraftSituation::getGroundElevationInfo() const
@@ -655,6 +675,13 @@ namespace BlackMisc
return static_cast<GndElevationInfo>(m_elvInfo); return static_cast<GndElevationInfo>(m_elvInfo);
} }
QString CAircraftSituation::getGroundElevationInfoAsString() const
{
return m_isElvInfoTransferred ?
gndElevationInfoToString(this->getGroundElevationInfo()) % QStringLiteral(" - tx") :
gndElevationInfoToString(this->getGroundElevationInfo());
}
QString CAircraftSituation::getGroundElevationAndInfo() const QString CAircraftSituation::getGroundElevationAndInfo() const
{ {
static const QString n("null"); static const QString n("null");
@@ -664,22 +691,34 @@ namespace BlackMisc
QStringLiteral(" [") % this->getGroundElevationInfoAsString() % QStringLiteral("]"); 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; } 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); const bool transferable = (distance <= radius);
return transferable; 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; } 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"); Q_ASSERT_X(!transferToSituation.getGroundElevationRadius().isNull(), Q_FUNC_INFO, "null radius");
return true; 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) bool CAircraftSituation::presetGroundElevation(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change)
{ {
return CAircraftSituation::presetGroundElevation(*this, oldSituation, newSituation, change); return CAircraftSituation::presetGroundElevation(*this, oldSituation, newSituation, change);
@@ -729,47 +768,53 @@ namespace BlackMisc
return this->getOnGroundDetails() == CAircraftSituation::InFromParts || this->getOnGroundDetails() == CAircraftSituation::InFromNetwork; 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()) if (altitude.isNull())
{ {
m_groundElevationPlane = CElevationPlane::null(); m_groundElevationPlane = CElevationPlane::null();
m_isElvInfoTransferred = false;
this->setGroundElevationInfo(NoElevationInfo); this->setGroundElevationInfo(NoElevationInfo);
} }
else else
{ {
m_groundElevationPlane = CElevationPlane(*this); m_groundElevationPlane = CElevationPlane(*this);
m_groundElevationPlane.setSinglePointRadius(); m_groundElevationPlane.setSinglePointRadius();
m_isElvInfoTransferred = transferred;
m_groundElevationPlane.setGeodeticHeight(altitude.switchedUnit(this->getAltitudeUnit())); m_groundElevationPlane.setGeodeticHeight(altitude.switchedUnit(this->getAltitudeUnit()));
this->setGroundElevationInfo(info); 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()) if (elevationPlane.isNull())
{ {
m_groundElevationPlane = CElevationPlane::null();
m_isElvInfoTransferred = false;
this->setGroundElevationInfo(NoElevationInfo); this->setGroundElevationInfo(NoElevationInfo);
} }
else else
{ {
m_groundElevationPlane = elevationPlane;
m_groundElevationPlane.fixRadius();
m_isElvInfoTransferred = transferred;
this->setGroundElevationInfo(info); this->setGroundElevationInfo(info);
Q_ASSERT_X(!m_groundElevationPlane.getRadius().isNull(), Q_FUNC_INFO, "Null radius"); 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 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; } if (elevationPlane.isNull()) { return false; }
const CLength distance = this->calculateGreatCircleDistance(elevationPlane); const CLength distance = this->calculateGreatCircleDistance(elevationPlane);
if (distance > elevationPlane.getRadius()) { return false; } if (distance > elevationPlane.getRadiusOrMinimumRadius()) { return false; }
if (m_groundElevationPlane.isNull() || this->isBetterInfo(info)) if (m_groundElevationPlane.isNull() || this->isBetterInfo(info, transferred))
{ {
// better values // better values
this->setGroundElevation(elevationPlane, info); this->setGroundElevation(elevationPlane, info, transferred);
m_groundElevationPlane.setRadiusOrMinimum(distance); m_groundElevationPlane.setRadiusOrMinimumRadius(distance);
return true; return true;
} }
return false; return false;
@@ -931,25 +976,34 @@ namespace BlackMisc
return false; 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()); 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 seconds = milliseconds / 1000;
const double gsMeterSecond = this->getGroundSpeed().value(CSpeedUnit::m_s()); const double gsMeterSecond = this->getGroundSpeed().value(CSpeedUnit::m_s());
const CLength d(seconds * gsMeterSecond, CLengthUnit::m()); const CLength d(seconds * gsMeterSecond, CLengthUnit::m());
if (!min.isNull() && d < min) { return min; }
return d; 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) void CAircraftSituation::setCallsign(const CCallsign &callsign)

View File

@@ -68,6 +68,7 @@ namespace BlackMisc
IndexGroundSpeed, IndexGroundSpeed,
IndexGroundElevationPlane, IndexGroundElevationPlane,
IndexGroundElevationInfo, IndexGroundElevationInfo,
IndexGroundElevationInfoTransferred,
IndexGroundElevationInfoString, IndexGroundElevationInfoString,
IndexGroundElevationPlusInfo, IndexGroundElevationPlusInfo,
IndexCallsign, IndexCallsign,
@@ -116,14 +117,14 @@ namespace BlackMisc
{ {
// best info (most accurate) last // best info (most accurate) last
NoElevationInfo, NoElevationInfo,
Test, //!< unit test Test, //!< unit test
SituationChange, //!< from BlackMisc::Aviation::CAircraftSituationChange SituationChange, //!< from BlackMisc::Aviation::CAircraftSituationChange
Extrapolated, //!< extrapolated ("guessing") Extrapolated, //!< extrapolated ("guessing")
Average, //!< average value of "nearby" situation CAircraftSituationList::averageElevationOfNonMovingAircraft FromOtherSituations, //!< transferred from other situations ("sibling situations" same callsign)
Interpolated, //!< interpolated between 2 elevations Average, //!< average value of "nearby" situation CAircraftSituationList::averageElevationOfNonMovingAircraft
TransferredElevation, //!< transferred from nearby situation Interpolated, //!< interpolated between 2 elevations
FromCache, //!< from cache FromCache, //!< from cache
FromProvider //!< from BlackMisc::Simulation::ISimulationEnvironmentProvider FromProvider //!< from BlackMisc::Simulation::ISimulationEnvironmentProvider
}; };
//! Default constructor. //! Default constructor.
@@ -174,7 +175,7 @@ namespace BlackMisc
virtual bool isNull() const override; virtual bool isNull() const override;
//! Is better info (more accurate)? //! Is better info (more accurate)?
bool isBetterInfo(GndElevationInfo info) const; bool isBetterInfo(GndElevationInfo info, bool transferred) const;
//! Equal pitch, bank heading //! Equal pitch, bank heading
//! \sa Geo::ICoordinateGeodetic::equalNormalVectorDouble //! \sa Geo::ICoordinateGeodetic::equalNormalVectorDouble
@@ -184,6 +185,10 @@ namespace BlackMisc
//! \sa Geo::ICoordinateGeodetic::equalNormalVectorDouble //! \sa Geo::ICoordinateGeodetic::equalNormalVectorDouble
bool equalPbhAndVector(const CAircraftSituation &other) const; bool equalPbhAndVector(const CAircraftSituation &other) const;
//! Equal PBH and vector
//! \sa Geo::ICoordinateGeodetic::equalNormalVectorDouble
bool equalPbhVectorAltitude(const CAircraftSituation &other) const;
//! Set to null //! Set to null
void setNull(); void setNull();
@@ -245,7 +250,7 @@ namespace BlackMisc
bool hasGroundDetailsForGndInterpolation() const; bool hasGroundDetailsForGndInterpolation() const;
//! On ground reliability as string //! On ground reliability as string
const QString &getOnDetailsAsString() const; const QString getOnGroundDetailsAsString() const;
//! On ground details //! On ground details
bool setOnGroundDetails(CAircraftSituation::OnGroundDetails details); bool setOnGroundDetails(CAircraftSituation::OnGroundDetails details);
@@ -278,22 +283,28 @@ namespace BlackMisc
GndElevationInfo getGroundElevationInfo() const; GndElevationInfo getGroundElevationInfo() const;
//! How did we get gnd.elevation? //! How did we get gnd.elevation?
const QString &getGroundElevationInfoAsString() const { return gndElevationInfoToString(this->getGroundElevationInfo()); } QString getGroundElevationInfoAsString() const;
//! Ground elevation plus info //! Ground elevation plus info
QString getGroundElevationAndInfo() const; QString getGroundElevationAndInfo() const;
//! Is the elv.info transferred?
bool isGroundElevationInfoTransferred() const { return m_isElvInfoTransferred; }
//! How we did get gnd.elevation //! How we did get gnd.elevation
void setGroundElevationInfo(GndElevationInfo details) { m_elvInfo = static_cast<int>(details); } void setGroundElevationInfo(GndElevationInfo details) { m_elvInfo = static_cast<int>(details); }
//! Can the elevation be transferred to another situation? //! 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 //! Transfer from "this" situation to \c otherSituation
//! \remark "transfer" can be used, if the positions are known, "preset" if they are still unknown //! \remark "transfer" can be used, if the positions are known, "preset" if they are still unknown
//! \sa CAircraftSituation::interpolateGroundElevation //! \sa CAircraftSituation::interpolateGroundElevation
//! \sa CAircraftSituation::interpolateElevation //! \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 //! Preset "this" elevation from the two adjacent positions
//! \remark it is not required that the position of "this" is already known //! \remark it is not required that the position of "this" is already known
@@ -327,14 +338,14 @@ namespace BlackMisc
bool hasInboundGroundDetails() const; bool hasInboundGroundDetails() const;
//! Elevation of the ground directly beneath at the given situation //! 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 //! 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 //! Set elevation of the ground directly beneath, but checked
//! \remark override if better //! \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 //! Reset ground elevation
void resetGroundElevation(); void resetGroundElevation();
@@ -410,13 +421,13 @@ namespace BlackMisc
bool canLikelySkipNearGroundInterpolation() const; bool canLikelySkipNearGroundInterpolation() const;
//! Distance per time //! 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 //! 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) //! Distance per milliseconds (250ms)
PhysicalQuantities::CLength getDistancePerTime250ms() const; PhysicalQuantities::CLength getDistancePerTime250ms(const PhysicalQuantities::CLength &min = PhysicalQuantities::CLength::null()) const;
//! Corresponding callsign //! Corresponding callsign
const CCallsign &getCallsign() const { return m_correspondingCallsign; } const CCallsign &getCallsign() const { return m_correspondingCallsign; }
@@ -522,14 +533,15 @@ namespace BlackMisc
private: private:
CCallsign m_correspondingCallsign; CCallsign m_correspondingCallsign;
Geo::CCoordinateGeodetic m_position; //!< NULL position as default Geo::CCoordinateGeodetic m_position; //!< NULL position as default
Geo::CElevationPlane m_groundElevationPlane; //!< NULL elevation as default
Aviation::CAltitude m_pressureAltitude { 0, nullptr }; Aviation::CAltitude m_pressureAltitude { 0, nullptr };
CHeading m_heading { 0, nullptr }; CHeading m_heading { 0, nullptr };
PhysicalQuantities::CAngle m_pitch { 0, nullptr }; PhysicalQuantities::CAngle m_pitch { 0, nullptr };
PhysicalQuantities::CAngle m_bank { 0, nullptr }; PhysicalQuantities::CAngle m_bank { 0, nullptr };
PhysicalQuantities::CSpeed m_groundSpeed { 0, nullptr }; PhysicalQuantities::CSpeed m_groundSpeed { 0, nullptr };
PhysicalQuantities::CLength m_cg { 0, nullptr }; PhysicalQuantities::CLength m_cg { 0, nullptr };
Geo::CElevationPlane m_groundElevationPlane; //!< NULL elevation as default bool m_isInterim = false; //!< interim situation?
bool m_isInterim = false; bool m_isElvInfoTransferred = false; //!< the gnd.elevation has been transferred
int m_onGround = static_cast<int>(CAircraftSituation::OnGroundSituationUnknown); int m_onGround = static_cast<int>(CAircraftSituation::OnGroundSituationUnknown);
int m_onGroundDetails = static_cast<int>(CAircraftSituation::NotSetGroundDetails); int m_onGroundDetails = static_cast<int>(CAircraftSituation::NotSetGroundDetails);
int m_elvInfo = static_cast<int>(CAircraftSituation::NoElevationInfo); //!< where did we gnd.elevation from? int m_elvInfo = static_cast<int>(CAircraftSituation::NoElevationInfo); //!< where did we gnd.elevation from?
@@ -556,6 +568,7 @@ namespace BlackMisc
BLACK_METAMEMBER(onGround), BLACK_METAMEMBER(onGround),
BLACK_METAMEMBER(onGroundDetails), BLACK_METAMEMBER(onGroundDetails),
BLACK_METAMEMBER(elvInfo), BLACK_METAMEMBER(elvInfo),
BLACK_METAMEMBER(isElvInfoTransferred),
BLACK_METAMEMBER(onGroundFactor), BLACK_METAMEMBER(onGroundFactor),
BLACK_METAMEMBER(timestampMSecsSinceEpoch), BLACK_METAMEMBER(timestampMSecsSinceEpoch),
BLACK_METAMEMBER(timeOffsetMs), BLACK_METAMEMBER(timeOffsetMs),

View File

@@ -347,6 +347,26 @@ namespace BlackMisc
return found; 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 CAircraftSituationList::setOnGround(CAircraftSituation::IsOnGround og)
{ {
int c = 0; int c = 0;
@@ -530,7 +550,7 @@ namespace BlackMisc
{ {
const CAircraftSituation &oldSituation = (*this)[i]; const CAircraftSituation &oldSituation = (*this)[i];
CAircraftSituation &newSituation = (*this)[i - 1]; CAircraftSituation &newSituation = (*this)[i - 1];
if (oldSituation.transferGroundElevation(newSituation, radius)) { c++; } if (oldSituation.transferGroundElevationFromThis(newSituation, radius)) { c++; }
} }
return c; return c;
} }

View File

@@ -135,6 +135,9 @@ namespace BlackMisc
//! Situations with CAircraftSituation::IsOnGround and elevation //! Situations with CAircraftSituation::IsOnGround and elevation
CAircraftSituationList findOnGroundWithElevation(CAircraftSituation::IsOnGround og) const; 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 //! Set on ground
int setOnGround(CAircraftSituation::IsOnGround og); int setOnGround(CAircraftSituation::IsOnGround og);