From 33b1e26460f2561d4d56976946c75278cc40615b Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Tue, 18 Feb 2020 00:45:47 +0100 Subject: [PATCH] Ref T773, cache ground elevations for "on ground" planes separately Rational: * Those values represent taxiways and runways * we cache those longer and keep more It is much more likely we need/can use these values --- src/blackcore/context/contextnetworkimpl.cpp | 4 +- src/blackcore/context/contextnetworkimpl.h | 2 +- src/blackmisc/geo/coordinategeodeticlist.cpp | 29 ++++++++ src/blackmisc/geo/coordinategeodeticlist.h | 5 ++ .../simulation/remoteaircraftprovider.cpp | 11 +-- .../simulation/remoteaircraftprovider.h | 11 +-- .../simulationenvironmentprovider.cpp | 69 ++++++++++++------- .../simulationenvironmentprovider.h | 25 ++++--- 8 files changed, 113 insertions(+), 43 deletions(-) diff --git a/src/blackcore/context/contextnetworkimpl.cpp b/src/blackcore/context/contextnetworkimpl.cpp index 464141a66..875dd7760 100644 --- a/src/blackcore/context/contextnetworkimpl.cpp +++ b/src/blackcore/context/contextnetworkimpl.cpp @@ -1140,9 +1140,9 @@ namespace BlackCore return c; } - int CContextNetwork::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info) + int CContextNetwork::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition) { - return m_airspace->updateAircraftGroundElevation(callsign, elevation, info); + return m_airspace->updateAircraftGroundElevation(callsign, elevation, info, setForOnGroundPosition); } void CContextNetwork::updateMarkAllAsNotRendered() diff --git a/src/blackcore/context/contextnetworkimpl.h b/src/blackcore/context/contextnetworkimpl.h index 8de81ac47..389772e84 100644 --- a/src/blackcore/context/contextnetworkimpl.h +++ b/src/blackcore/context/contextnetworkimpl.h @@ -112,7 +112,7 @@ namespace BlackCore virtual bool updateAircraftRendered(const BlackMisc::Aviation::CCallsign &callsign, bool rendered) override; virtual int updateMultipleAircraftRendered(const BlackMisc::Aviation::CCallsignSet &callsigns, bool rendered) override; virtual int updateMultipleAircraftEnabled(const BlackMisc::Aviation::CCallsignSet &callsigns, bool enabled) override; - virtual int updateAircraftGroundElevation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Geo::CElevationPlane &elevation, BlackMisc::Aviation::CAircraftSituation::GndElevationInfo info) override; + virtual int updateAircraftGroundElevation(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Geo::CElevationPlane &elevation, BlackMisc::Aviation::CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition) override; virtual void updateMarkAllAsNotRendered() override; virtual BlackMisc::PhysicalQuantities::CLength getCGFromDB(const BlackMisc::Aviation::CCallsign &callsign) const override; virtual BlackMisc::PhysicalQuantities::CLength getCGFromDB(const QString &modelString) const override; diff --git a/src/blackmisc/geo/coordinategeodeticlist.cpp b/src/blackmisc/geo/coordinategeodeticlist.cpp index 7f42fc69c..00c903e38 100644 --- a/src/blackmisc/geo/coordinategeodeticlist.cpp +++ b/src/blackmisc/geo/coordinategeodeticlist.cpp @@ -7,11 +7,15 @@ */ #include "coordinategeodeticlist.h" +#include "math/mathutils.h" #include #include #include +using namespace BlackMisc::Math; +using namespace BlackMisc::PhysicalQuantities; + namespace BlackMisc { namespace Geo @@ -22,5 +26,30 @@ namespace BlackMisc CCoordinateGeodeticList::CCoordinateGeodeticList(const CSequence &other) : CSequence(other) { } + + CElevationPlane CCoordinateGeodeticList::averageGeodeticHeight(const CCoordinateGeodetic &reference, const CLength &range, const CLength &maxDeviation, int minValues) const + { + if (this->size() < minValues) { return CElevationPlane::null(); } // no change to succeed + + QList valuesInFt; + int count = 0; + for (const CCoordinateGeodetic &coordinate : *this) + { + if (!coordinate.hasMSLGeodeticHeight()) { continue; } + if (!coordinate.isWithinRange(reference, range)) { continue; } + const double elvFt = coordinate.geodeticHeight().value(CLengthUnit::ft()); + valuesInFt.push_back(elvFt); + count++; + if (count > 5 && valuesInFt.size() > 3 * minValues) { break; } + } + + if (count < minValues) { return CElevationPlane::null(); } + + const double MaxDevFt = maxDeviation.value(CLengthUnit::ft()); + const QPair elvStdDevMean = CMathUtils::standardDeviationAndMean(valuesInFt); + if (elvStdDevMean.first > MaxDevFt) { return CElevationPlane::null(); } + return CElevationPlane(reference, elvStdDevMean.second, CElevationPlane::singlePointRadius()); + } + } // namespace } // namespace diff --git a/src/blackmisc/geo/coordinategeodeticlist.h b/src/blackmisc/geo/coordinategeodeticlist.h index 78a114bab..af320d296 100644 --- a/src/blackmisc/geo/coordinategeodeticlist.h +++ b/src/blackmisc/geo/coordinategeodeticlist.h @@ -11,8 +11,10 @@ #ifndef BLACKMISC_GEO_COORDINATEGEODETICLIST_H #define BLACKMISC_GEO_COORDINATEGEODETICLIST_H +#include "elevationplane.h" #include "coordinategeodetic.h" #include "geoobjectlist.h" + #include "blackmisc/blackmiscexport.h" #include "blackmisc/collection.h" #include "blackmisc/json.h" @@ -43,6 +45,9 @@ namespace BlackMisc //! Construct from a base class object. CCoordinateGeodeticList(const CSequence &other); + + //! Average height within range and having an height + CElevationPlane averageGeodeticHeight(const CCoordinateGeodetic &reference, const PhysicalQuantities::CLength &range, const PhysicalQuantities::CLength &maxDeviation = PhysicalQuantities::CLength(1.0, PhysicalQuantities::CLengthUnit::m()), int minValues = 3) const; }; } //namespace } // namespace diff --git a/src/blackmisc/simulation/remoteaircraftprovider.cpp b/src/blackmisc/simulation/remoteaircraftprovider.cpp index 7bc6b053f..b27a6c6be 100644 --- a/src/blackmisc/simulation/remoteaircraftprovider.cpp +++ b/src/blackmisc/simulation/remoteaircraftprovider.cpp @@ -551,7 +551,7 @@ namespace BlackMisc return c; } - int CRemoteAircraftProvider::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info) + int CRemoteAircraftProvider::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition) { if (!this->isAircraftInRange(callsign)) { return 0; } @@ -559,12 +559,14 @@ namespace BlackMisc const qint64 now = QDateTime::currentMSecsSinceEpoch(); const CAircraftModel model = this->getAircraftInRangeModelForCallsign(callsign); CAircraftSituationChange change; + bool setForOnGndPosition = false; + int updated = 0; { QWriteLocker l(&m_lockSituations); CAircraftSituationList &situations = m_situationsByCallsign[callsign]; if (situations.isEmpty()) { return 0; } - updated = situations.setGroundElevationCheckedAndGuessGround(elevation, info, model, &change); + updated = situations.setGroundElevationCheckedAndGuessGround(elevation, info, model, &change, &setForOnGndPosition); if (updated < 1) { return 0; } m_situationsLastModified[callsign] = now; const CAircraftSituation latestSituation = situations.front(); @@ -587,6 +589,7 @@ namespace BlackMisc m_aircraftInRange[callsign].setGroundElevationChecked(elevation, info); } + if (setForOnGroundPosition) { *setForOnGroundPosition = setForOnGndPosition; } return updated; // updated situations } @@ -981,10 +984,10 @@ namespace BlackMisc return this->provider()->updateMultipleAircraftRendered(callsigns, rendered); } - int CRemoteAircraftAware::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info) + int CRemoteAircraftAware::updateAircraftGroundElevation(const CCallsign &callsign, const CElevationPlane &elevation, CAircraftSituation::GndElevationInfo info, bool *updatedAircraftGroundElevation) { Q_ASSERT_X(this->provider(), Q_FUNC_INFO, "No object available"); - return this->provider()->updateAircraftGroundElevation(callsign, elevation, info); + return this->provider()->updateAircraftGroundElevation(callsign, elevation, info, updatedAircraftGroundElevation); } bool CRemoteAircraftAware::updateCG(const CCallsign &callsign, const CLength &cg) diff --git a/src/blackmisc/simulation/remoteaircraftprovider.h b/src/blackmisc/simulation/remoteaircraftprovider.h index e7ec76a56..7da923395 100644 --- a/src/blackmisc/simulation/remoteaircraftprovider.h +++ b/src/blackmisc/simulation/remoteaircraftprovider.h @@ -190,7 +190,7 @@ namespace BlackMisc //! Update the ground elevation //! \threadsafe - virtual int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info) = 0; + virtual int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info, bool *updateAircraftGroundElevation) = 0; //! Update the CG //! \threadsafe @@ -248,7 +248,8 @@ namespace BlackMisc //! \threadsafe virtual qint64 partsLastModified(const Aviation::CCallsign &callsign) const = 0; - //! \copydoc BlackMisc::Aviation::CAircraftSituationList::averageElevationOfNonMovingAircraft + //! Average elevation of aircraft in given range, which are NOT moving + //! \remark can be used to anticipate field elevation //! \threadsafe virtual Geo::CElevationPlane averageElevationOfNonMovingAircraft(const Aviation::CAircraftSituation &reference, const PhysicalQuantities::CLength &range, int minValues = 1) const = 0; @@ -328,7 +329,7 @@ namespace BlackMisc virtual bool updateFastPositionEnabled(const Aviation::CCallsign &callsign, bool enableFastPositonUpdates) override; virtual bool updateAircraftRendered(const Aviation::CCallsign &callsign, bool rendered) override; virtual int updateMultipleAircraftRendered(const Aviation::CCallsignSet &callsigns, bool rendered) override; - virtual int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info) override; + virtual int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info, bool *setForOnGroundPosition) override; virtual bool updateCG(const Aviation::CCallsign &callsign, const PhysicalQuantities::CLength &cg) override; virtual bool updateCGAndModelString(const Aviation::CCallsign &callsign, const PhysicalQuantities::CLength &cg, const QString &modelString) override; virtual PhysicalQuantities::CLength getCGFromDB(const Aviation::CCallsign &callsign) const override; @@ -474,7 +475,7 @@ namespace BlackMisc Aviation::CAircraftSituationListPerCallsign m_situationsByCallsign; //!< situations, for performance reasons per callsign, thread safe access required Aviation::CAircraftSituationPerCallsign m_latestSituationByCallsign; //!< latest situations, for performance reasons per callsign, thread safe access required - Aviation::CAircraftSituationPerCallsign m_latestOnGroundProviderElevation; //!< situation on ground with elevation from provider + Aviation::CAircraftSituationPerCallsign m_latestOnGroundProviderElevation; //!< situations on ground with elevation from provider Aviation::CAircraftPartsListPerCallsign m_partsByCallsign; //!< parts, for performance reasons per callsign, thread safe access required Aviation::CAircraftSituationChangeListPerCallsign m_changesByCallsign; //!< changes, for performance reasons per callsign, thread safe access required (same timestamps as corresponding situations) Aviation::CCallsignSet m_aircraftWithParts; //!< aircraft supporting parts, thread safe access required @@ -588,7 +589,7 @@ namespace BlackMisc bool updateMultipleAircraftRendered(const Aviation::CCallsignSet &callsigns, bool rendered); //! \copydoc IRemoteAircraftProvider::updateAircraftGroundElevation - int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info); + int updateAircraftGroundElevation(const Aviation::CCallsign &callsign, const Geo::CElevationPlane &elevation, Aviation::CAircraftSituation::GndElevationInfo info, bool *updateAircraftGroundElevation); //! \copydoc IRemoteAircraftProvider::updateCG bool updateCG(const Aviation::CCallsign &callsign, const PhysicalQuantities::CLength &cg); diff --git a/src/blackmisc/simulation/simulationenvironmentprovider.cpp b/src/blackmisc/simulation/simulationenvironmentprovider.cpp index 019957284..474ebe1ab 100644 --- a/src/blackmisc/simulation/simulationenvironmentprovider.cpp +++ b/src/blackmisc/simulation/simulationenvironmentprovider.cpp @@ -19,7 +19,7 @@ namespace BlackMisc { namespace Simulation { - bool ISimulationEnvironmentProvider::rememberGroundElevation(const CCallsign &requestedForCallsign, const ICoordinateGeodetic &elevationCoordinate, const CLength &epsilon) + bool ISimulationEnvironmentProvider::rememberGroundElevation(const CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const ICoordinateGeodetic &elevationCoordinate, const CLength &epsilon) { if (!elevationCoordinate.hasMSLGeodeticHeight()) { @@ -27,11 +27,14 @@ namespace BlackMisc return false; } + const CLength minRange = ISimulationEnvironmentProvider::minRange(epsilon); { - // no 2nd elevation nearby? QReadLocker l(&m_lockElvCoordinates); if (!m_enableElevation) { return false; } - if (m_elvCoordinates.containsObjectInRange(elevationCoordinate, minRange(epsilon))) { return false; } + + // check if we have already an elevation within range + if (m_elvCoordinatesGnd.containsObjectInRange(elevationCoordinate, minRange)) { return false; } + if (m_elvCoordinates.containsObjectInRange(elevationCoordinate, minRange)) { return false; } } { @@ -39,13 +42,24 @@ namespace BlackMisc // * we assume we find them faster // * and need them more frequently (the recent ones) const qint64 now = QDateTime::currentMSecsSinceEpoch(); + QWriteLocker l(&m_lockElvCoordinates); - if (m_elvCoordinates.size() > m_maxElevations) { m_elvCoordinates.pop_back(); } - m_elvCoordinates.push_front(elevationCoordinate); + if (likelyOnGroundElevation) + { + if (m_elvCoordinatesGnd.size() > m_maxElevationsGnd) { m_elvCoordinatesGnd.pop_back(); } + m_elvCoordinatesGnd.push_front(elevationCoordinate); + } + else + { + if (m_elvCoordinates.size() > m_maxElevations) { m_elvCoordinates.pop_back(); } + m_elvCoordinates.push_front(elevationCoordinate); + } + + // statistics if (m_pendingElevationRequests.contains(requestedForCallsign)) { const qint64 startedMs = m_pendingElevationRequests.value(requestedForCallsign); - const qint64 deltaMs = now - startedMs; + const qint64 deltaMs = now - startedMs; m_pendingElevationRequests.remove(requestedForCallsign); m_statsCurrentElevRequestTimeMs = deltaMs; if (m_statsMaxElevRequestTimeMs < deltaMs) { m_statsMaxElevRequestTimeMs = deltaMs; } @@ -54,14 +68,14 @@ namespace BlackMisc return true; } - bool ISimulationEnvironmentProvider::rememberGroundElevation(const CCallsign &requestedForCallsign, const CElevationPlane &elevationPlane) + bool ISimulationEnvironmentProvider::rememberGroundElevation(const CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const CElevationPlane &elevationPlane) { if (!elevationPlane.hasMSLGeodeticHeight()) { BLACK_AUDIT_X(false, Q_FUNC_INFO, "Elevation plane needs to be MSL NON NULL"); return false; } - return this->rememberGroundElevation(requestedForCallsign, elevationPlane, elevationPlane.getRadius()); + return this->rememberGroundElevation(requestedForCallsign, likelyOnGroundElevation, elevationPlane, elevationPlane.getRadius()); } bool ISimulationEnvironmentProvider::insertCG(const CLength &cg, const CCallsign &cs) @@ -69,15 +83,10 @@ namespace BlackMisc if (cs.isEmpty()) { return false; } const bool remove = cg.isNull(); - if (remove) { QWriteLocker l(&m_lockCG); - m_cgsPerCallsign.remove(cs); - } - else - { - QWriteLocker l(&m_lockCG); - m_cgsPerCallsign[cs] = cg; + if (remove) { m_cgsPerCallsign.remove(cs); } + else { m_cgsPerCallsign[cs] = cg; } } return true; } @@ -86,7 +95,7 @@ namespace BlackMisc { bool ok = false; QWriteLocker l(&m_lockCG); - if (!m_enableCG) { return false; } + if (!m_enableCG) { return false; } if (!cs.isEmpty()) { m_cgsPerCallsign[cs] = cg; ok = true; } if (!modelString.isEmpty()) { m_cgsPerModel[modelString.toUpper()] = cg; ok = true; } return ok; @@ -95,6 +104,7 @@ namespace BlackMisc bool ISimulationEnvironmentProvider::insertCGForModelString(const CLength &cg, const QString &modelString) { if (modelString.isEmpty()) { return false; } + QWriteLocker l(&m_lockCG); if (!m_enableCG) { return false; } if (cg.isNull()) @@ -141,23 +151,33 @@ namespace BlackMisc range; } - CCoordinateGeodeticList ISimulationEnvironmentProvider::getElevationCoordinates() const + CCoordinateGeodeticList ISimulationEnvironmentProvider::getAllElevationCoordinates() const { QReadLocker l(&m_lockElvCoordinates); - return m_elvCoordinates; + CCoordinateGeodeticList cl(m_elvCoordinatesGnd); + cl.push_back(m_elvCoordinates); + return cl; } - CCoordinateGeodeticList ISimulationEnvironmentProvider::getElevationCoordinates(int &maxRemembered) const + CCoordinateGeodeticList ISimulationEnvironmentProvider::getElevationCoordinatesOnGround() const + { + QReadLocker l(&m_lockElvCoordinates); + return m_elvCoordinatesGnd; + } + + CCoordinateGeodeticList ISimulationEnvironmentProvider::getAllElevationCoordinates(int &maxRemembered) const { QReadLocker l(&m_lockElvCoordinates); maxRemembered = m_maxElevations; - return m_elvCoordinates; + CCoordinateGeodeticList cl(m_elvCoordinatesGnd); + cl.push_back(m_elvCoordinates); + return cl; } int ISimulationEnvironmentProvider::cleanUpElevations(const ICoordinateGeodetic &referenceCoordinate, int maxNumber) { int currentMax; - CCoordinateGeodeticList coordinates(this->getElevationCoordinates(currentMax)); + CCoordinateGeodeticList coordinates(this->getAllElevationCoordinates(currentMax)); if (maxNumber < 0) { maxNumber = currentMax; } const int size = coordinates.size(); if (size <= maxNumber) { return 0; } @@ -177,10 +197,12 @@ namespace BlackMisc // for single point we use a slightly optimized version const bool singlePoint = (&range == &CElevationPlane::singlePointRadius() || range.isNull() || range <= CElevationPlane::singlePointRadius()); + const CCoordinateGeodeticList elevations = this->getAllElevationCoordinates(); const CCoordinateGeodetic coordinate = singlePoint ? - this->getElevationCoordinates().findFirstWithinRangeOrDefault(reference, CElevationPlane::singlePointRadius()) : - this->getElevationCoordinates().findClosestWithinRange(reference, range); + elevations.findFirstWithinRangeOrDefault(reference, CElevationPlane::singlePointRadius()) : + elevations.findClosestWithinRange(reference, range); const bool found = !coordinate.isNull(); + { QWriteLocker l{&m_lockElvCoordinates }; if (found) @@ -455,6 +477,7 @@ namespace BlackMisc { QWriteLocker l(&m_lockElvCoordinates); m_elvCoordinates.clear(); + m_elvCoordinatesGnd.clear(); m_pendingElevationRequests.clear(); m_statsCurrentElevRequestTimeMs = -1; m_statsMaxElevRequestTimeMs = -1; diff --git a/src/blackmisc/simulation/simulationenvironmentprovider.h b/src/blackmisc/simulation/simulationenvironmentprovider.h index 8d6ead0dd..5c82768e2 100644 --- a/src/blackmisc/simulation/simulationenvironmentprovider.h +++ b/src/blackmisc/simulation/simulationenvironmentprovider.h @@ -34,9 +34,13 @@ namespace BlackMisc class BLACKMISC_EXPORT ISimulationEnvironmentProvider : public IProvider { public: - //! All remembered coordiantes + //! All remembered coordinates //! \threadsafe - Geo::CCoordinateGeodeticList getElevationCoordinates() const; + Geo::CCoordinateGeodeticList getAllElevationCoordinates() const; + + //! All remembered coordinates + //! \threadsafe + Geo::CCoordinateGeodeticList getElevationCoordinatesOnGround() const; //! Find closest elevation (or return NULL) //! \threadsafe @@ -141,7 +145,7 @@ namespace BlackMisc //! All remembered coordiantes plus max.remembered situations //! \threadsafe - Geo::CCoordinateGeodeticList getElevationCoordinates(int &maxRemembered) const; + Geo::CCoordinateGeodeticList getAllElevationCoordinates(int &maxRemembered) const; //! New plugin info and default model //! \remark normally only used by emulated driver @@ -196,11 +200,11 @@ namespace BlackMisc //! Remember a given elevation //! \threadsafe - bool rememberGroundElevation(const Aviation::CCallsign &requestedForCallsign, const Geo::ICoordinateGeodetic &elevationCoordinate, const PhysicalQuantities::CLength &epsilon = Geo::CElevationPlane::singlePointRadius()); + bool rememberGroundElevation(const Aviation::CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const Geo::ICoordinateGeodetic &elevationCoordinate, const PhysicalQuantities::CLength &epsilon = Geo::CElevationPlane::singlePointRadius()); //! Remember a given elevation //! \threadsafe - bool rememberGroundElevation(const Aviation::CCallsign &requestedForCallsign, const Geo::CElevationPlane &elevationPlane) ; + bool rememberGroundElevation(const Aviation::CCallsign &requestedForCallsign, bool likelyOnGroundElevation, const Geo::CElevationPlane &elevationPlane); //! Insert or replace a CG //! \remark passing a NULL value will remove the CG @@ -240,8 +244,13 @@ namespace BlackMisc QString m_simulatorDetails; //!< describes version etc. QString m_simulatorVersion; //!< simulator version CAircraftModel m_defaultModel; //!< default model - int m_maxElevations = 100; //!< How many elevations we keep - Geo::CCoordinateGeodeticList m_elvCoordinates; //!< elevation cache + + // idea: the elevations on gnd are likely taxiways and runways, so we keep those + int m_maxElevations = 100; //!< How many elevations we keep + int m_maxElevationsGnd = 400; //!< How many elevations we keep for elevations on gnd. + Geo::CCoordinateGeodeticList m_elvCoordinates; //!< elevation cache + Geo::CCoordinateGeodeticList m_elvCoordinatesGnd; //!< elevation cache for on ground situations + Aviation::CTimestampPerCallsign m_pendingElevationRequests; //!< pending elevation requests for aircraft callsign Aviation::CLengthPerCallsign m_cgsPerCallsign; //!< CGs per callsign QHash m_cgsPerModel; //!< CGs per model string @@ -250,7 +259,7 @@ namespace BlackMisc qint64 m_statsCurrentElevRequestTimeMs = -1; bool m_enableElevation = true; - bool m_enableCG = true; + bool m_enableCG = true; mutable int m_elvFound = 0; //!< statistics only mutable int m_elvMissed = 0; //!< statistics only