diff --git a/src/blackmisc/geo/geoobjectlist.cpp b/src/blackmisc/geo/geoobjectlist.cpp index b8c3d00e2..ceae36ecc 100644 --- a/src/blackmisc/geo/geoobjectlist.cpp +++ b/src/blackmisc/geo/geoobjectlist.cpp @@ -133,6 +133,20 @@ namespace BlackMisc return stats; } + template + CAltitude IGeoObjectList::findMaxHeight() const + { + if (this->container().isEmpty()) { return CAltitude::null(); } + CAltitude max = CAltitude::null(); + for (const OBJ &obj : this->container()) + { + if (!obj.hasMSLGeodeticHeight()) { continue; } + const CAltitude alt = obj.geodeticHeight(); + if (max.isNull() || alt > max) { max = alt; } + } + return max; + } + template int IGeoObjectList::removeOutsideRange(const ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &range) { diff --git a/src/blackmisc/geo/geoobjectlist.h b/src/blackmisc/geo/geoobjectlist.h index ce0e2419e..5cbab4024 100644 --- a/src/blackmisc/geo/geoobjectlist.h +++ b/src/blackmisc/geo/geoobjectlist.h @@ -83,6 +83,9 @@ namespace BlackMisc //! Find min/max/average height MinMaxAverageHeight findMinMaxAverageHeight() const; + //! Find min/max/average height + Aviation::CAltitude findMaxHeight() const; + //! Remove outside range int removeOutsideRange(const ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &range); diff --git a/src/blackmisc/simulation/simulationenvironmentprovider.cpp b/src/blackmisc/simulation/simulationenvironmentprovider.cpp index a58131b53..716705109 100644 --- a/src/blackmisc/simulation/simulationenvironmentprovider.cpp +++ b/src/blackmisc/simulation/simulationenvironmentprovider.cpp @@ -173,6 +173,13 @@ namespace BlackMisc return coordinates.averageGeodeticHeight(reference, range, CAircraftSituationChange::allowedAltitudeDeviation(), minValues); } + CAltitude ISimulationEnvironmentProvider::highestElevation() const + { + const CCoordinateGeodeticList coordinates = this->getElevationCoordinatesOnGround(); + if (coordinates.isEmpty()) { return CAltitude::null(); } + return coordinates.findMaxHeight(); + } + CCoordinateGeodeticList ISimulationEnvironmentProvider::getAllElevationCoordinates(int &maxRemembered) const { QReadLocker l(&m_lockElvCoordinates); @@ -392,6 +399,60 @@ namespace BlackMisc m_elvFound = m_elvMissed = 0; } + bool ISimulationEnvironmentProvider::cleanElevationValues(const CAircraftSituation &reference, const CLength &range, bool forced) + { + if (reference.isNull() || range.isNull()) { return false; } + const CLength r = minRange(range); + + CCoordinateGeodeticList elvs; + CCoordinateGeodeticList cleanedElvs; + bool maxReached = false; + bool cleaned = false; + + { + QReadLocker l(&m_lockElvCoordinates); + elvs = m_elvCoordinates; + maxReached = m_elvCoordinates.size() >= m_maxElevations; + } + if (!elvs.isEmpty() && (forced || maxReached)) + { + for (const CAircraftSituation &s : elvs) + { + if (s.isWithinRange(reference, r)) { cleanedElvs.push_back(s); } + } + + if (cleanedElvs.size() < elvs.size()) + { + cleaned = true; + QWriteLocker l(&m_lockElvCoordinates); + m_elvCoordinates = cleanedElvs; + } + } + + cleanedElvs.clear(); + { + QReadLocker l(&m_lockElvCoordinates); + elvs = m_elvCoordinatesGnd; + maxReached = m_elvCoordinatesGnd.size() >= m_maxElevationsGnd; + } + if (!elvs.isEmpty() && (forced || maxReached)) + { + for (const CAircraftSituation &s : elvs) + { + if (s.isWithinRange(reference, r)) { cleanedElvs.push_back(s); } + } + + if (cleanedElvs.size() < elvs.size()) + { + cleaned = true; + QWriteLocker l(&m_lockElvCoordinates); + m_elvCoordinatesGnd = cleanedElvs; + } + } + + return cleaned; + } + ISimulationEnvironmentProvider::ISimulationEnvironmentProvider(const CSimulatorPluginInfo &pluginInfo) : m_simulatorPluginInfo(pluginInfo) { } @@ -529,6 +590,12 @@ namespace BlackMisc return this->provider()->averageElevationOfOnGroundAircraft(reference, range, minValues); } + CAltitude CSimulationEnvironmentAware::highestElevation() const + { + if (!this->hasProvider()) { return CAltitude::null(); } + return this->provider()->highestElevation(); + } + bool CSimulationEnvironmentAware::requestElevation(const ICoordinateGeodetic &reference, const CCallsign &callsign) { if (!this->hasProvider()) { return false; } @@ -605,5 +672,11 @@ namespace BlackMisc if (!this->hasProvider()) { return false; } return this->provider()->hasSimulatorCG(callsign); } + + bool CSimulationEnvironmentAware::cleanElevationValues(const CAircraftSituation &reference, const CLength &range, bool forced) + { + if (!this->hasProvider()) { return false; } + return this->provider()->cleanElevationValues(reference, range, forced); + } } // namespace } // namespace diff --git a/src/blackmisc/simulation/simulationenvironmentprovider.h b/src/blackmisc/simulation/simulationenvironmentprovider.h index 65b3ce068..0906cdb03 100644 --- a/src/blackmisc/simulation/simulationenvironmentprovider.h +++ b/src/blackmisc/simulation/simulationenvironmentprovider.h @@ -134,6 +134,10 @@ namespace BlackMisc //! \threadsafe void resetSimulationEnvironmentStatistics(); + //! Average elevation of "on ground" cached values + //! \threadsafe + bool cleanElevationValues(const Aviation::CAircraftSituation &reference, const PhysicalQuantities::CLength &range, bool forced = false); + protected: //! Ctor ISimulationEnvironmentProvider(const CSimulatorPluginInfo &pluginInfo); @@ -296,6 +300,9 @@ namespace BlackMisc //! \copydoc ISimulationEnvironmentProvider::averageElevationOfOnGroundAircraft Geo::CElevationPlane averageElevationOfOnGroundAircraft(const Aviation::CAircraftSituation &reference, const PhysicalQuantities::CLength &range, int minValues) const; + //! \copydoc ISimulationEnvironmentProvider::highestElevation + Aviation::CAltitude highestElevation() const; + //! \copydoc ISimulationEnvironmentProvider::requestElevation bool requestElevation(const Geo::ICoordinateGeodetic &reference, const Aviation::CCallsign &callsign); @@ -335,6 +342,9 @@ namespace BlackMisc //! \copydoc ISimulationEnvironmentProvider::hasSimulatorCG bool hasSimulatorCG(const Aviation::CCallsign &callsign) const; + //! \copydoc ISimulationEnvironmentProvider::cleanElevationValues + bool cleanElevationValues(const Aviation::CAircraftSituation &reference, const PhysicalQuantities::CLength &range, bool forced = false); + protected: //! Default constructor CSimulationEnvironmentAware() {}