diff --git a/src/AndroidManifest.xml.in b/src/AndroidManifest.xml.in
index 0da0b3d7f..74dc46a19 100644
--- a/src/AndroidManifest.xml.in
+++ b/src/AndroidManifest.xml.in
@@ -156,7 +156,7 @@
-
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d7cd24063..eee8b9fd6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -544,6 +544,8 @@ qt_add_qml_module(${PROJECT_NAME}
URI akaflieg_freiburg.enroute
VERSION 1.0
NO_RESOURCE_TARGET_PATH
+ DEPENDENCIES
+ QtQuick
QML_FILES
qml/main.qml
qml/dialogs/AddBTDeviceDialog.qml
@@ -624,7 +626,6 @@ qt_add_qml_module(${PROJECT_NAME}
traffic/TrafficDataProvider_BluetoothLowEnergy.cpp
)
-
#
# Translations
#
diff --git a/src/GlobalSettings.cpp b/src/GlobalSettings.cpp
index 7a7361183..b90ace337 100644
--- a/src/GlobalSettings.cpp
+++ b/src/GlobalSettings.cpp
@@ -35,17 +35,20 @@ GlobalSettings::GlobalSettings(QObject *parent)
QCoreApplication::processEvents();
// Save some values
- settings.setValue(QStringLiteral("lastVersion"), ENROUTE_VERSION_STRING);
+ m_settings.setValue(QStringLiteral("lastVersion"), ENROUTE_VERSION_STRING);
+
+ // Read values
+ m_positioningByTrafficDataReceiver = m_settings.value(QStringLiteral("positioningByTrafficDataReceiver"), false).toBool();
// Convert old setting to new system
- if (settings.contains(QStringLiteral("Map/hideUpperAirspaces"))) {
- auto hide = settings.value(QStringLiteral("Map/hideUpperAirspaces"), false).toBool();
+ if (m_settings.contains(QStringLiteral("Map/hideUpperAirspaces"))) {
+ auto hide = m_settings.value(QStringLiteral("Map/hideUpperAirspaces"), false).toBool();
if (hide) {
setAirspaceAltitudeLimit( Units::Distance::fromFT(10000) );
} else {
setAirspaceAltitudeLimit( Units::Distance::fromFT(qInf()) );
}
- settings.remove(QStringLiteral("Map/hideUpperAirspaces"));
+ m_settings.remove(QStringLiteral("Map/hideUpperAirspaces"));
}
}
@@ -56,7 +59,7 @@ GlobalSettings::GlobalSettings(QObject *parent)
auto GlobalSettings::airspaceAltitudeLimit() const -> Units::Distance
{
- auto aspAlttLimit = Units::Distance::fromFT( settings.value(QStringLiteral("Map/airspaceAltitudeLimit_ft"), qQNaN()).toDouble() );
+ auto aspAlttLimit = Units::Distance::fromFT( m_settings.value(QStringLiteral("Map/airspaceAltitudeLimit_ft"), qQNaN()).toDouble() );
if (aspAlttLimit < airspaceAltitudeLimit_min) {
aspAlttLimit = airspaceAltitudeLimit_min;
}
@@ -69,21 +72,21 @@ auto GlobalSettings::airspaceAltitudeLimit() const -> Units::Distance
auto GlobalSettings::fontSize() const -> int
{
- auto fontSize = settings.value(QStringLiteral("fontSize"), 14).toInt();
+ auto fontSize = m_settings.value(QStringLiteral("fontSize"), 14).toInt();
return qBound(14, fontSize, 20);
}
auto GlobalSettings::lastValidAirspaceAltitudeLimit() const -> Units::Distance
{
- auto result = Units::Distance::fromFT(settings.value(QStringLiteral("Map/lastValidAirspaceAltitudeLimit_ft"), 99999).toInt() );
+ auto result = Units::Distance::fromFT(m_settings.value(QStringLiteral("Map/lastValidAirspaceAltitudeLimit_ft"), 99999).toInt() );
return qBound(airspaceAltitudeLimit_min, result, airspaceAltitudeLimit_max);
}
auto GlobalSettings::mapBearingPolicy() const -> GlobalSettings::MapBearingPolicy
{
- auto intVal = settings.value(QStringLiteral("Map/bearingPolicy"), 0).toInt();
+ auto intVal = m_settings.value(QStringLiteral("Map/bearingPolicy"), 0).toInt();
if (intVal == 0) {
return NUp;
}
@@ -103,7 +106,7 @@ void GlobalSettings::setAcceptedTerms(int terms)
if (terms == acceptedTerms()) {
return;
}
- settings.setValue(QStringLiteral("acceptedTerms"), terms);
+ m_settings.setValue(QStringLiteral("acceptedTerms"), terms);
emit acceptedTermsChanged();
}
@@ -113,7 +116,7 @@ void GlobalSettings::setAlwaysOpenExternalWebsites(bool alwaysOpen)
if (alwaysOpen == alwaysOpenExternalWebsites()) {
return;
}
- settings.setValue(QStringLiteral("alwaysOpenExternalWebsites"), alwaysOpen);
+ m_settings.setValue(QStringLiteral("alwaysOpenExternalWebsites"), alwaysOpen);
emit alwaysOpenExternalWebsitesChanged();
}
@@ -128,13 +131,13 @@ void GlobalSettings::setAirspaceAltitudeLimit(Units::Distance newAirspaceAltitud
}
if (newAirspaceAltitudeLimit != airspaceAltitudeLimit()) {
- settings.setValue(QStringLiteral("Map/airspaceAltitudeLimit_ft"), newAirspaceAltitudeLimit.toFeet());
+ m_settings.setValue(QStringLiteral("Map/airspaceAltitudeLimit_ft"), newAirspaceAltitudeLimit.toFeet());
emit airspaceAltitudeLimitChanged();
}
if (newAirspaceAltitudeLimit.isFinite() &&
(newAirspaceAltitudeLimit != lastValidAirspaceAltitudeLimit())) {
- settings.setValue(QStringLiteral("Map/lastValidAirspaceAltitudeLimit_ft"), newAirspaceAltitudeLimit.toFeet());
+ m_settings.setValue(QStringLiteral("Map/lastValidAirspaceAltitudeLimit_ft"), newAirspaceAltitudeLimit.toFeet());
emit lastValidAirspaceAltitudeLimitChanged();
}
}
@@ -146,7 +149,7 @@ void GlobalSettings::setExpandNotamAbbreviations(bool newExpandNotamAbbreviation
{
return;
}
- settings.setValue(QStringLiteral("expandNotamAbbreviations"), newExpandNotamAbbreviations);
+ m_settings.setValue(QStringLiteral("expandNotamAbbreviations"), newExpandNotamAbbreviations);
emit expandNotamAbbreviationsChanged();
}
@@ -160,7 +163,7 @@ void GlobalSettings::setFontSize(int newFontSize)
{
return;
}
- settings.setValue(QStringLiteral("fontSize"), newFontSize);
+ m_settings.setValue(QStringLiteral("fontSize"), newFontSize);
emit fontSizeChanged();
}
@@ -171,7 +174,7 @@ void GlobalSettings::setHideGlidingSectors(bool hide)
{
return;
}
- settings.setValue(QStringLiteral("Map/hideGlidingSectors"), hide);
+ m_settings.setValue(QStringLiteral("Map/hideGlidingSectors"), hide);
emit hideGlidingSectorsChanged();
}
@@ -182,7 +185,7 @@ void GlobalSettings::setIgnoreSSLProblems(bool ignore)
{
return;
}
- settings.setValue(QStringLiteral("ignoreSSLProblems"), ignore);
+ m_settings.setValue(QStringLiteral("ignoreSSLProblems"), ignore);
emit ignoreSSLProblemsChanged();
}
@@ -193,7 +196,7 @@ void GlobalSettings::setLastWhatsNewHash(Units::ByteSize lwnh)
{
return;
}
- settings.setValue(QStringLiteral("lastWhatsNewHash"), QVariant::fromValue((size_t)lwnh));
+ m_settings.setValue(QStringLiteral("lastWhatsNewHash"), QVariant::fromValue((size_t)lwnh));
emit lastWhatsNewHashChanged();
}
@@ -204,7 +207,7 @@ void GlobalSettings::setLastWhatsNewInMapsHash(Units::ByteSize lwnh)
{
return;
}
- settings.setValue(QStringLiteral("lastWhatsNewInMapsHash"), QVariant::fromValue((size_t)lwnh));
+ m_settings.setValue(QStringLiteral("lastWhatsNewInMapsHash"), QVariant::fromValue((size_t)lwnh));
emit lastWhatsNewInMapsHashChanged();
}
@@ -215,7 +218,7 @@ void GlobalSettings::setPrivacyHash(Units::ByteSize newHash)
{
return;
}
- settings.setValue(QStringLiteral("privacyHash"), QVariant::fromValue((size_t)newHash));
+ m_settings.setValue(QStringLiteral("privacyHash"), QVariant::fromValue((size_t)newHash));
emit privacyHashChanged();
}
@@ -229,13 +232,13 @@ void GlobalSettings::setMapBearingPolicy(MapBearingPolicy policy)
switch(policy){
case NUp:
- settings.setValue(QStringLiteral("Map/bearingPolicy"), 0);
+ m_settings.setValue(QStringLiteral("Map/bearingPolicy"), 0);
break;
case TTUp:
- settings.setValue(QStringLiteral("Map/bearingPolicy"), 1);
+ m_settings.setValue(QStringLiteral("Map/bearingPolicy"), 1);
break;
default:
- settings.setValue(QStringLiteral("Map/bearingPolicy"), 2);
+ m_settings.setValue(QStringLiteral("Map/bearingPolicy"), 2);
break;
}
emit mapBearingPolicyChanged();
@@ -249,20 +252,15 @@ void GlobalSettings::setNightMode(bool newNightMode)
return;
}
- settings.setValue(QStringLiteral("Map/nightMode"), newNightMode);
+ m_settings.setValue(QStringLiteral("Map/nightMode"), newNightMode);
emit nightModeChanged();
}
void GlobalSettings::setPositioningByTrafficDataReceiver(bool newPositioningByTrafficDataReceiver)
{
- if (newPositioningByTrafficDataReceiver == positioningByTrafficDataReceiver())
- {
- return;
- }
-
- settings.setValue(QStringLiteral("positioningByTrafficDataReceiver"), newPositioningByTrafficDataReceiver);
- emit positioningByTrafficDataReceiverChanged();
+ m_settings.setValue(QStringLiteral("positioningByTrafficDataReceiver"), newPositioningByTrafficDataReceiver);
+ m_positioningByTrafficDataReceiver = newPositioningByTrafficDataReceiver;
}
@@ -272,7 +270,7 @@ void GlobalSettings::setShowAltitudeAGL(bool newShowAltitudeAGL)
{
return;
}
- settings.setValue(QStringLiteral("showAltitudeAGL"), newShowAltitudeAGL);
+ m_settings.setValue(QStringLiteral("showAltitudeAGL"), newShowAltitudeAGL);
emit showAltitudeAGLChanged();
}
@@ -283,6 +281,6 @@ void GlobalSettings::setVoiceNotifications(uint newVoiceNotifications)
{
return;
}
- settings.setValue(QStringLiteral("voiceNotifications"), newVoiceNotifications);
+ m_settings.setValue(QStringLiteral("voiceNotifications"), newVoiceNotifications);
emit voiceNotificationsChanged();
}
diff --git a/src/GlobalSettings.h b/src/GlobalSettings.h
index e55264b98..5ce5acc0c 100644
--- a/src/GlobalSettings.h
+++ b/src/GlobalSettings.h
@@ -20,6 +20,7 @@
#pragma once
+#include
#include
#include
@@ -155,6 +156,9 @@ class GlobalSettings : public QObject
/*! \brief Night mode */
Q_PROPERTY(bool nightMode READ nightMode WRITE setNightMode NOTIFY nightModeChanged)
+ /*! \brief Use traffic data receiver for positioning */
+ Q_PROPERTY(bool positioningByTrafficDataReceiver READ positioningByTrafficDataReceiver WRITE setPositioningByTrafficDataReceiver BINDABLE bindablePositioningByTrafficDataReceiver)
+
/*! \brief Hash of the last "privacy" message that was accepted by the user
*
* This property is used in the app to determine if the message has been
@@ -165,9 +169,6 @@ class GlobalSettings : public QObject
/*! \brief Show Altitude AGL */
Q_PROPERTY(bool showAltitudeAGL READ showAltitudeAGL WRITE setShowAltitudeAGL NOTIFY showAltitudeAGLChanged)
- /*! \brief Use traffic data receiver for positioning */
- Q_PROPERTY(bool positioningByTrafficDataReceiver READ positioningByTrafficDataReceiver WRITE setPositioningByTrafficDataReceiver NOTIFY positioningByTrafficDataReceiverChanged)
-
/*! \brief Voice notifications that should be played
*
* This property is an "or" of the entries of Notifications::Notification::Importance. It determines
@@ -184,13 +185,13 @@ class GlobalSettings : public QObject
*
* @returns Property acceptedTerms
*/
- [[nodiscard]] auto acceptedTerms() const -> int { return settings.value(QStringLiteral("acceptedTerms"), 0).toInt(); }
+ [[nodiscard]] auto acceptedTerms() const -> int { return m_settings.value(QStringLiteral("acceptedTerms"), 0).toInt(); }
/*! \brief Getter function for property of the same name
*
* @returns Property alwaysOpenExternalWebsites
*/
- [[nodiscard]] bool alwaysOpenExternalWebsites() const { return settings.value(QStringLiteral("alwaysOpenExternalWebsites"), false).toBool(); }
+ [[nodiscard]] bool alwaysOpenExternalWebsites() const { return m_settings.value(QStringLiteral("alwaysOpenExternalWebsites"), false).toBool(); }
/*! \brief Getter function for property of the same name
*
@@ -202,7 +203,7 @@ class GlobalSettings : public QObject
*
* @returns Property expandNotamAbbreviations
*/
- [[nodiscard]] bool expandNotamAbbreviations() const { return settings.value(QStringLiteral("expandNotamAbbreviations"), false).toBool(); }
+ [[nodiscard]] bool expandNotamAbbreviations() const { return m_settings.value(QStringLiteral("expandNotamAbbreviations"), false).toBool(); }
/*! \brief Getter function for property with the same name
*
@@ -214,13 +215,13 @@ class GlobalSettings : public QObject
*
* @returns Property hideGlidingSectors
*/
- [[nodiscard]] auto hideGlidingSectors() const -> bool { return settings.value(QStringLiteral("Map/hideGlidingSectors"), true).toBool(); }
+ [[nodiscard]] auto hideGlidingSectors() const -> bool { return m_settings.value(QStringLiteral("Map/hideGlidingSectors"), true).toBool(); }
/*! \brief Getter function for property of the same name
*
* @returns Property ignoreSSLProblems
*/
- [[nodiscard]] auto ignoreSSLProblems() const -> bool { return settings.value(QStringLiteral("ignoreSSLProblems"), false).toBool(); }
+ [[nodiscard]] auto ignoreSSLProblems() const -> bool { return m_settings.value(QStringLiteral("ignoreSSLProblems"), false).toBool(); }
/*! \brief Getter function for property with the same name
*
@@ -234,7 +235,7 @@ class GlobalSettings : public QObject
*/
[[nodiscard]] auto lastWhatsNewHash() const -> Units::ByteSize
{
- return settings.value(QStringLiteral("lastWhatsNewHash"), 0).value();
+ return m_settings.value(QStringLiteral("lastWhatsNewHash"), 0).value();
}
/*! \brief Getter function for property of the same name
@@ -243,7 +244,7 @@ class GlobalSettings : public QObject
*/
[[nodiscard]] auto lastWhatsNewInMapsHash() const -> Units::ByteSize
{
- return settings.value(QStringLiteral("lastWhatsNewInMapsHash"), 0).value();
+ return m_settings.value(QStringLiteral("lastWhatsNewInMapsHash"), 0).value();
}
/*! \brief Getter function for property of the same name
@@ -256,25 +257,31 @@ class GlobalSettings : public QObject
*
* @returns Property night mode
*/
- [[nodiscard]] auto nightMode() const -> bool { return settings.value(QStringLiteral("Map/nightMode"), false).toBool(); }
+ [[nodiscard]] auto nightMode() const -> bool { return m_settings.value(QStringLiteral("Map/nightMode"), false).toBool(); }
+
+ /*! \brief Getter function for property of the same name
+ *
+ * @returns Property positioningByTrafficDataReceiver
+ */
+ [[nodiscard]] bool positioningByTrafficDataReceiver() const { return m_positioningByTrafficDataReceiver.value(); }
/*! \brief Getter function for property of the same name
*
* @returns Property positioningByTrafficDataReceiver
*/
- [[nodiscard]] auto positioningByTrafficDataReceiver() const -> bool { return settings.value(QStringLiteral("positioningByTrafficDataReceiver"), false).toBool(); }
+ [[nodiscard]] QBindable bindablePositioningByTrafficDataReceiver() const { return &m_positioningByTrafficDataReceiver; }
/*! \brief Getter function for property of the same name
*
* @returns Property privacyHash
*/
- [[nodiscard]] auto privacyHash() const -> Units::ByteSize { return settings.value(QStringLiteral("privacyHash"), 0).value(); }
+ [[nodiscard]] auto privacyHash() const -> Units::ByteSize { return m_settings.value(QStringLiteral("privacyHash"), 0).value(); }
/*! \brief Getter function for property of the same name
*
* @returns Property positioningByTrafficDataReceiver
*/
- [[nodiscard]] auto showAltitudeAGL() const -> bool { return settings.value(QStringLiteral("showAltitudeAGL"), false).toBool(); }
+ [[nodiscard]] auto showAltitudeAGL() const -> bool { return m_settings.value(QStringLiteral("showAltitudeAGL"), false).toBool(); }
/*! \brief Getter function for property of the same name
*
@@ -282,7 +289,7 @@ class GlobalSettings : public QObject
*/
[[nodiscard]] auto voiceNotifications() const -> uint
{
- return settings.value(QStringLiteral("voiceNotifications"),
+ return m_settings.value(QStringLiteral("voiceNotifications"),
Notifications::Notification::Info_Navigation |
Notifications::Notification::Warning |
Notifications::Notification::Warning_Navigation |
@@ -439,9 +446,6 @@ class GlobalSettings : public QObject
/*! \brief Notifier signal */
void nightModeChanged();
- /*! \brief Notifier signal */
- void positioningByTrafficDataReceiverChanged();
-
/*! \brief Notifier signal */
void privacyHashChanged();
@@ -454,5 +458,7 @@ class GlobalSettings : public QObject
private:
Q_DISABLE_COPY_MOVE(GlobalSettings)
- QSettings settings;
+ QSettings m_settings;
+
+ QProperty m_positioningByTrafficDataReceiver;
};
diff --git a/src/fileFormats/GeoTIFF.cpp b/src/fileFormats/GeoTIFF.cpp
index 85053028b..113076f6e 100644
--- a/src/fileFormats/GeoTIFF.cpp
+++ b/src/fileFormats/GeoTIFF.cpp
@@ -62,7 +62,7 @@ QList FileFormats::GeoTIFF::getTransformation(const QMap int
qRegisterMetaType();
qRegisterMetaType();
- qmlRegisterUncreatableType("enroute", 1, 0, "DemoRunner", QStringLiteral("DemoRunner objects cannot be created in QML"));
- qmlRegisterUncreatableType("enroute", 1, 0, "SSLErrorHandler", QStringLiteral("SSLErrorHandler objects cannot be created in QML"));
- qmlRegisterUncreatableType("enroute", 1, 0, "GeoMapProvider", QStringLiteral("GeoMapProvider objects cannot be created in QML"));
- qmlRegisterUncreatableType("enroute", 1, 0, "WaypointLibrary", QStringLiteral("WaypointLibrary objects cannot be created in QML"));
- qmlRegisterUncreatableType("enroute", 1, 0, "DataManager", QStringLiteral("DataManager objects cannot be created in QML"));
- qmlRegisterUncreatableType("enroute", 1, 0, "TrafficDataProvider", QStringLiteral("TrafficDataProvider objects cannot be created in QML"));
- qmlRegisterUncreatableType("enroute", 1, 0, "TrafficFactor_WithPosition", QStringLiteral("TrafficFactor_WithPosition objects cannot be created in QML"));
-
-
// Required by the maplibre plugin to QtLocation
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
diff --git a/src/navigation/Navigator.cpp b/src/navigation/Navigator.cpp
index d1eb30fa5..1f249487d 100644
--- a/src/navigation/Navigator.cpp
+++ b/src/navigation/Navigator.cpp
@@ -43,9 +43,12 @@ Navigation::Navigator::Navigator(QObject *parent) : GlobalObject(parent)
// Restore aircraft
QFile file(m_aircraftFileName);
- if (file.open(QIODevice::ReadOnly)) {
+ if (file.open(QIODevice::ReadOnly))
+ {
(void)m_aircraft.loadFromJSON(file.readAll());
- } else {
+ }
+ else
+ {
auto cruiseSpeed = Units::Speed::fromKN(settings.value(QStringLiteral("Aircraft/cruiseSpeedInKTS"), 0.0).toDouble());
auto descentSpeed = Units::Speed::fromKN(settings.value(QStringLiteral("Aircraft/descentSpeedInKTS"), 0.0).toDouble());
auto fuelConsumption = Units::VolumeFlow::fromLPH(settings.value(QStringLiteral("Aircraft/fuelConsumptionInLPH"), 0.0).toDouble());
@@ -73,7 +76,8 @@ void Navigation::Navigator::deferredInitialization()
auto Navigation::Navigator::flightRoute() -> FlightRoute*
{
- if (m_flightRoute.isNull()) {
+ if (m_flightRoute.isNull())
+ {
m_flightRoute = new FlightRoute(this);
m_flightRoute->load(m_flightRouteFileName);
connect(m_flightRoute, &Navigation::FlightRoute::waypointsChanged, this, [this]() {if (m_flightRoute != nullptr) {(void)m_flightRoute->save(m_flightRouteFileName);}});
@@ -89,7 +93,8 @@ auto Navigation::Navigator::flightRoute() -> FlightRoute*
void Navigation::Navigator::setAircraft(const Navigation::Aircraft& newAircraft)
{
- if (newAircraft == m_aircraft) {
+ if (newAircraft == m_aircraft)
+ {
return;
}
@@ -106,7 +111,8 @@ void Navigation::Navigator::setAircraft(const Navigation::Aircraft& newAircraft)
void Navigation::Navigator::setFlightStatus(FlightStatus newFlightStatus)
{
- if (m_flightStatus == newFlightStatus) {
+ if (m_flightStatus == newFlightStatus)
+ {
return;
}
@@ -117,7 +123,8 @@ void Navigation::Navigator::setFlightStatus(FlightStatus newFlightStatus)
void Navigation::Navigator::setWind(Weather::Wind newWind)
{
- if (newWind == m_wind) {
+ if (newWind == m_wind)
+ {
return;
}
@@ -139,16 +146,17 @@ void Navigation::Navigator::setWind(Weather::Wind newWind)
void Navigation::Navigator::updateAltitudeLimit()
{
auto info = GlobalObject::positionProvider()->positionInfo();
- if (!info.isValid()) {
+ if (!info.isValid())
+ {
return;
}
auto altLimit = GlobalObject::globalSettings()->airspaceAltitudeLimit();
auto trueAltitude = info.trueAltitudeAMSL();
if (altLimit.isFinite() &&
- trueAltitude.isFinite() &&
- (trueAltitude + Units::Distance::fromFT(1000) > altLimit)) {
-
+ trueAltitude.isFinite() &&
+ (trueAltitude + Units::Distance::fromFT(1000) > altLimit))
+ {
// Round trueAltitude+1000ft up to nearest 500ft and set that as a new limit
auto newAltLimit = Units::Distance::fromFT(500.0*qCeil(trueAltitude.toFeet()/500.0+2.0));
GlobalObject::globalSettings()->setAirspaceAltitudeLimit(newAltLimit);
@@ -160,7 +168,8 @@ void Navigation::Navigator::updateAltitudeLimit()
void Navigation::Navigator::updateFlightStatus()
{
auto info = GlobalObject::positionProvider()->positionInfo();
- if (!info.isValid()) {
+ if (!info.isValid())
+ {
setFlightStatus(Unknown);
return;
}
@@ -168,22 +177,26 @@ void Navigation::Navigator::updateFlightStatus()
// Get ground speed and aircraft minimum speed
auto GS = info.groundSpeed();
auto aircraftMinSpeed = m_aircraft.minimumSpeed();
- if (!GS.isFinite() || !aircraftMinSpeed.isFinite()) {
+ if (!GS.isFinite() || !aircraftMinSpeed.isFinite())
+ {
setFlightStatus(Unknown);
return;
}
// Go to ground mode if ground speed is less then aircraftMinSpeed-flightSpeedHysteresis
- if (m_flightStatus == Flight) {
+ if (m_flightStatus == Flight)
+ {
// If we are in flight at present, go back to ground mode only if the ground speed is less than minFlightSpeedInKT-flightSpeedHysteresis
- if ( GS < aircraftMinSpeed-flightSpeedHysteresis) {
+ if ( GS < aircraftMinSpeed-flightSpeedHysteresis)
+ {
setFlightStatus(Ground);
}
return;
}
// Go to flight mode if ground speed is more than aircraftMinSpeed
- if ( GS > aircraftMinSpeed ) {
+ if ( GS > aircraftMinSpeed )
+ {
setFlightStatus(Flight);
}
}
@@ -223,7 +236,7 @@ void Navigation::Navigator::updateRemainingRouteInfo()
}
// If we are closer than 3 nm from endpoint, then we do not give a remaining route info
- auto finalCoordinate = geoPath[geoPath.size()-1];
+ const auto &finalCoordinate = geoPath[geoPath.size() - 1];
if (Units::Distance::fromM(finalCoordinate.distanceTo(info.coordinate())) < Leg::nearThreshold)
{
RemainingRouteInfo rrInfo;
diff --git a/src/positioning/PositionInfo.cpp b/src/positioning/PositionInfo.cpp
index 55d8a2829..28c2bd19d 100644
--- a/src/positioning/PositionInfo.cpp
+++ b/src/positioning/PositionInfo.cpp
@@ -22,8 +22,8 @@
#include "geomaps/GeoMapProvider.h"
#include "positioning/PositionInfo.h"
-Positioning::PositionInfo::PositionInfo(const QGeoPositionInfo &info)
- : m_positionInfo(info)
+Positioning::PositionInfo::PositionInfo(const QGeoPositionInfo& info, const QString& source)
+ : m_positionInfo(info), m_source(source)
{}
auto Positioning::PositionInfo::groundSpeed() const -> Units::Speed
@@ -38,7 +38,6 @@ auto Positioning::PositionInfo::groundSpeed() const -> Units::Speed
return Units::Speed::fromMPS(m_positionInfo.attribute(QGeoPositionInfo::GroundSpeed));
}
-
auto Positioning::PositionInfo::isValid() const -> bool
{
if (!m_positionInfo.isValid()) {
@@ -49,7 +48,6 @@ auto Positioning::PositionInfo::isValid() const -> bool
return expiry >= QDateTime::currentDateTime();
}
-
auto Positioning::PositionInfo::positionErrorEstimate() const -> Units::Distance
{
if (!m_positionInfo.isValid()) {
@@ -62,7 +60,6 @@ auto Positioning::PositionInfo::positionErrorEstimate() const -> Units::Distance
return Units::Distance::fromM(m_positionInfo.attribute(QGeoPositionInfo::HorizontalAccuracy));
}
-
auto Positioning::PositionInfo::terrainElevationAMSL() -> Units::Distance
{
if (m_terrainAMSL.isFinite())
@@ -74,7 +71,6 @@ auto Positioning::PositionInfo::terrainElevationAMSL() -> Units::Distance
return m_terrainAMSL;
}
-
auto Positioning::PositionInfo::trueAltitudeAMSL() const -> Units::Distance
{
if (!m_positionInfo.isValid()) {
@@ -127,7 +123,6 @@ auto Positioning::PositionInfo::trueAltitudeErrorEstimate() const -> Units::Dist
return Units::Distance::fromM(m_positionInfo.attribute(QGeoPositionInfo::VerticalAccuracy));
}
-
auto Positioning::PositionInfo::trueTrack() const -> Units::Angle
{
if (!m_positionInfo.isValid())
@@ -150,7 +145,6 @@ auto Positioning::PositionInfo::trueTrack() const -> Units::Angle
return Units::Angle::fromDEG(m_positionInfo.attribute(QGeoPositionInfo::Direction));
}
-
auto Positioning::PositionInfo::trueTrackErrorEstimate() const -> Units::Angle
{
if (!trueTrack().isFinite())
@@ -165,7 +159,6 @@ auto Positioning::PositionInfo::trueTrackErrorEstimate() const -> Units::Angle
return Units::Angle::fromDEG(m_positionInfo.attribute(QGeoPositionInfo::DirectionAccuracy));
}
-
auto Positioning::PositionInfo::variation() const -> Units::Angle
{
if (!m_positionInfo.isValid()) {
@@ -178,7 +171,6 @@ auto Positioning::PositionInfo::variation() const -> Units::Angle
return Units::Angle::fromDEG(m_positionInfo.attribute(QGeoPositionInfo::MagneticVariation));
}
-
auto Positioning::PositionInfo::verticalSpeed() const -> Units::Speed
{
if (!m_positionInfo.isValid()) {
diff --git a/src/positioning/PositionInfo.h b/src/positioning/PositionInfo.h
index 2fcf03e90..8bf56817a 100644
--- a/src/positioning/PositionInfo.h
+++ b/src/positioning/PositionInfo.h
@@ -22,7 +22,7 @@
#include
#include
-#include
+//#include
#include "units/Angle.h"
#include "units/Distance.h"
@@ -53,8 +53,10 @@ class PositionInfo
/*! \brief Constructor
*
* @param info QGeoPositionInfo this is copied into this class
+ *
+ * @param source Name of the source that generated with instance
*/
- explicit PositionInfo(const QGeoPositionInfo &info);
+ explicit PositionInfo(const QGeoPositionInfo& info, const QString& source);
/*! \brief Coordinate
*
@@ -87,6 +89,12 @@ class PositionInfo
*/
[[nodiscard]] Q_INVOKABLE Units::Distance positionErrorEstimate() const;
+ /*! \brief Name of source, as set in the constructor
+ *
+ * @returns Name of source
+ */
+ [[nodiscard]] Q_INVOKABLE QString source() const {return m_source;}
+
/*! \brief Elevation of terrain at a given coordinate, above sea level
*
* @returns Elevation of the terrain at position, or
@@ -187,8 +195,9 @@ class PositionInfo
private:
QGeoPositionInfo m_positionInfo;
- Units::Distance m_terrainAMSL{};
- Units::Distance m_trueAltitudeAGL {};
+ QString m_source;
+ Units::Distance m_terrainAMSL;
+ Units::Distance m_trueAltitudeAGL;
};
} // namespace Positioning
diff --git a/src/positioning/PositionInfoSource_Abstract.cpp b/src/positioning/PositionInfoSource_Abstract.cpp
index a1085bfd1..e38cfd04f 100644
--- a/src/positioning/PositionInfoSource_Abstract.cpp
+++ b/src/positioning/PositionInfoSource_Abstract.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2021-2023 by Stefan Kebekus *
+ * Copyright (C) 2021-2024 by Stefan Kebekus *
* stefan.kebekus@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -21,85 +21,24 @@
#include "positioning/PositionInfoSource_Abstract.h"
-Positioning::PositionInfoSource_Abstract::PositionInfoSource_Abstract(QObject *parent) : QObject(parent)
+Positioning::PositionInfoSource_Abstract::PositionInfoSource_Abstract(QObject* parent) : QObject(parent)
{
// Setup timer
m_positionInfoTimer.setInterval( PositionInfo::lifetime );
m_positionInfoTimer.setSingleShot(true);
- connect(&m_positionInfoTimer, &QTimer::timeout, this, &Positioning::PositionInfoSource_Abstract::resetPositionInfo);
-
- // Setup timer
- m_pressureAltitudeTimer.setInterval( PositionInfo::lifetime );
- m_pressureAltitudeTimer.setSingleShot(true);
- connect(&m_pressureAltitudeTimer, &QTimer::timeout, this, &Positioning::PositionInfoSource_Abstract::resetPressureAltitude);
+ connect(&m_positionInfoTimer, &QTimer::timeout, this, [this]() {setPositionInfo({});});
}
-void Positioning::PositionInfoSource_Abstract::setPositionInfo(const Positioning::PositionInfo &info)
+void Positioning::PositionInfoSource_Abstract::setPositionInfo(const Positioning::PositionInfo& info)
{
- if (info.isValid()) {
+ if (info.isValid())
+ {
m_positionInfoTimer.start();
}
- if (info == m_positionInfo) {
- return;
- }
+ Qt::beginPropertyUpdateGroup();
m_positionInfo = info;
- emit positionInfoChanged();
-
- auto newReceiving = m_positionInfo.isValid();
- if (_receivingPositionInfo == newReceiving) {
- return;
- }
-
- _receivingPositionInfo = newReceiving;
- emit receivingPositionInfoChanged();
-}
-
-
-void Positioning::PositionInfoSource_Abstract::setSourceName(const QString &name)
-{
- if (m_sourceName == name) {
- return;
- }
-
- m_sourceName = name;
- emit sourceNameChanged(m_sourceName);
-}
-
-
-void Positioning::PositionInfoSource_Abstract::setStatusString(const QString &status)
-{
- if (m_statusString == status) {
- return;
- }
-
- m_statusString = status;
- emit statusStringChanged(m_statusString);
-}
-
-
-void Positioning::PositionInfoSource_Abstract::setPressureAltitude(Units::Distance newPressureAltitude)
-{
- if (newPressureAltitude.isFinite()) {
- m_pressureAltitudeTimer.start();
- }
- if (newPressureAltitude == m_pressureAltitude) {
- return;
- }
-
- m_pressureAltitude = newPressureAltitude;
- emit pressureAltitudeChanged();
-}
-
-
-void Positioning::PositionInfoSource_Abstract::resetPressureAltitude()
-{
- setPressureAltitude( {} );
-}
-
-
-void Positioning::PositionInfoSource_Abstract::resetPositionInfo()
-{
- setPositionInfo( {} );
+ m_receivingPositionInfo = info.isValid();
+ Qt::endPropertyUpdateGroup();
}
diff --git a/src/positioning/PositionInfoSource_Abstract.h b/src/positioning/PositionInfoSource_Abstract.h
index 11492092f..8bc442701 100644
--- a/src/positioning/PositionInfoSource_Abstract.h
+++ b/src/positioning/PositionInfoSource_Abstract.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2021-2023 by Stefan Kebekus *
+ * Copyright (C) 2021-2024 by Stefan Kebekus *
* stefan.kebekus@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -21,22 +21,19 @@
#pragma once
#include
+#include
#include
#include "positioning/PositionInfo.h"
-#include "units/Distance.h"
namespace Positioning {
-/*! \brief Abstract base class for all classes that provide geographic position information
+/*! \brief Abstract base class for all classes that provide geographic position
+ * information
*
* This is the base class for all classes that provide geographic position
- * information. The information is exposed via two properties, positionInfo
- * and pressureAltitude.
- *
- * The property statusString gives more information about the status of the
- * source
+ * information.
*/
@@ -51,7 +48,6 @@ class PositionInfoSource_Abstract : public QObject {
explicit PositionInfoSource_Abstract(QObject *parent = nullptr);
-
//
// Properties
//
@@ -62,140 +58,122 @@ class PositionInfoSource_Abstract : public QObject {
* that the data is up-to-date, the position information will be set to an
* invalid positionInfo when no data has arrived for more than the time
* specified in PositionInfo::lifetime.
+ */
+ Q_PROPERTY(Positioning::PositionInfo positionInfo READ positionInfo BINDABLE bindablePositionInfo)
+
+ /*! \brief Indicator that position information is being received
*
- * Consumers of the class can use positionInfo().isValid() property to
- * check if position data is continually arriving.
+ * This is a shortcut for positionInfo().isValid. This property exists
+ * because it does not change so often, and can thus be more efficient to
+ * use.
*/
- Q_PROPERTY(Positioning::PositionInfo positionInfo READ positionInfo NOTIFY positionInfoChanged)
+ Q_PROPERTY(bool receivingPositionInfo READ receivingPositionInfo BINDABLE bindableReceivingPositionInfo)
- /*! \brief Getter method for property with the same name
+ /*! \brief Source name
*
- * @returns Property positionInfo
+ * This property holds a translated, human-readable string that describes
+ * the source. This could typically be a string of the form "Traffic
+ * Receiver" or "Built-in satellite receiver".
*/
- [[nodiscard]] auto positionInfo() const -> Positioning::PositionInfo
- {
- return m_positionInfo;
- }
+ Q_PROPERTY(QString sourceName READ sourceName BINDABLE bindableSourceName)
- /*! \brief Pressure altitude
+ /*! \brief Source status
*
- * This property holds information about the pressure altitude, that is,
- * the altitude that you would read off your altimeter if the altimeter is
- * set to 1013.2 hPa. To ensure that the data is up-to-date, the position
- * information will be set to "invalid" when no data has arrived for more
- * than the time specified in PositionInfo::lifetime.
+ * This property holds a translated, human-readable string that describes
+ * the status of the positionInfo source. This could typically be a string
+ * of the form "OK" or "Insufficient permission to access position info"
*/
- Q_PROPERTY(Units::Distance pressureAltitude READ pressureAltitude NOTIFY pressureAltitudeChanged)
+ Q_PROPERTY(QString statusString READ statusString BINDABLE bindableStatusString)
+
+
+ //
+ // Getter Methods
+ //
/*! \brief Getter method for property with the same name
*
- * @returns Property pressureAltitude
+ * @returns Property positionInfo
*/
- [[nodiscard]] auto pressureAltitude() const -> Units::Distance
+ [[nodiscard]] Positioning::PositionInfo positionInfo() const
{
- return m_pressureAltitude;
+ return m_positionInfo.value();
}
- /*! \brief Indicator that position information is being received
+ /*! \brief Getter method for property with the same name
*
- * Use this property to tell if position information is being received.
+ * @returns Property positionInfo
*/
- Q_PROPERTY(bool receivingPositionInfo READ receivingPositionInfo NOTIFY receivingPositionInfoChanged)
+ [[nodiscard]] QBindable bindablePositionInfo() const
+ {
+ return &m_positionInfo;
+ }
/*! \brief Getter method for property with the same name
*
* @returns Property receivingPositionInfo
*/
- [[nodiscard]] auto receivingPositionInfo() const -> bool
- {
- return _receivingPositionInfo;
- }
+ [[nodiscard]] bool receivingPositionInfo() const {return m_receivingPositionInfo.value();}
- /*! \brief Source name
+ /*! \brief Getter method for property with the same name
*
- * This property holds a translated, human-readable string that describes
- * the source. This could typically be a string of the form "Traffic
- * Receiver" or "Built-in satellite receiver".
+ * @returns Property receivingPositionInfo
*/
- Q_PROPERTY(QString sourceName READ sourceName NOTIFY sourceNameChanged)
+ [[nodiscard]] QBindable bindableReceivingPositionInfo() {return &m_receivingPositionInfo;}
/*! \brief Getter method for property with the same name
*
* @returns Property sourceName
*/
- [[nodiscard]] auto sourceName() const -> QString
+ [[nodiscard]] QString sourceName() const
{
- return m_sourceName;
+ return m_sourceName.value();
}
- /*! \brief Source status
+ /*! \brief Getter method for property with the same name
*
- * This property holds a translated, human-readable string that describes
- * the status of the positionInfo source. This could typically be a string
- * of the form "OK" or "Insufficient permission to access position info"
+ * @returns Property sourceName
*/
- Q_PROPERTY(QString statusString READ statusString NOTIFY statusStringChanged)
+ [[nodiscard]] QBindable bindableSourceName() const
+ {
+ return &m_sourceName;
+ }
/*! \brief Getter method for property with the same name
*
* @returns Property statusString
*/
- [[nodiscard]] auto statusString() const -> QString
+ [[nodiscard]] QString statusString() const
{
- return m_statusString;
+ return m_statusString.value();
}
-signals:
- /*! \brief Notifier signal */
- void positionInfoChanged();
-
- /*! \brief Notifier signal */
- void pressureAltitudeChanged();
-
- /*! \brief Notifier signal */
- void receivingPositionInfoChanged();
-
- /*! \brief Notifier signal */
- void sourceNameChanged(const QString &name);
-
- /*! \brief Notifier signal */
- void statusStringChanged(const QString &status);
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property statusString
+ */
+ [[nodiscard]] QBindable bindableStatusString() const
+ {
+ return &m_statusString;
+ }
protected:
// This method must be used by child classes to update the position info.
// The class uses a timer internally to reset the position info to "invalid"
// after the time specified in PositionInfo::lifetime seconds. It also
// updates the property receivingPositionInfo.
- void setPositionInfo(const Positioning::PositionInfo &info);
-
- // This method must be used by child classes to update the pressure altitude
- // The class uses a timer internally to reset the position info to "invalid"
- // after the time specified in PositionInfo::lifetime seconds.
- void setPressureAltitude(Units::Distance newPressureAltitude);
+ void setPositionInfo(const Positioning::PositionInfo& info);
// This method must be used by child classes to update the source name
- void setSourceName(const QString &name);
+ void setSourceName(const QString& name) {m_sourceName = name;}
- // This method must be used by child classes to update the status string
- void setStatusString(const QString &status);
+ QProperty m_statusString;
private:
- // Resets the position info to "invalid"
- void resetPositionInfo();
-
- // Resets the pressure altitude to "invalid"
- void resetPressureAltitude();
-
- Units::Distance m_pressureAltitude {};
- QTimer m_pressureAltitudeTimer;
-
- Positioning::PositionInfo m_positionInfo;
+ QProperty m_positionInfo;
QTimer m_positionInfoTimer;
- QString m_sourceName;
- QString m_statusString;
-
- bool _receivingPositionInfo{false};
+ QProperty m_receivingPositionInfo {false};
+ QProperty m_sourceName;
};
} // namespace Positioning
diff --git a/src/positioning/PositionInfoSource_Satellite.cpp b/src/positioning/PositionInfoSource_Satellite.cpp
index 3a75157f9..21e11ed02 100644
--- a/src/positioning/PositionInfoSource_Satellite.cpp
+++ b/src/positioning/PositionInfoSource_Satellite.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2021 by Stefan Kebekus *
+ * Copyright (C) 2021-2024 by Stefan Kebekus *
* stefan.kebekus@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -54,29 +54,33 @@ void Positioning::PositionInfoSource_Satellite::startUpdates()
void Positioning::PositionInfoSource_Satellite::updateStatusString()
{
- if (source == nullptr) {
- setStatusString( tr("Not installed or access denied") );
+ if (source == nullptr)
+ {
+ m_statusString = tr("Not installed or access denied");
return;
}
auto sourceStatus = source->error();
- if (sourceStatus == QGeoPositionInfoSource::AccessError) {
- setStatusString( tr("Access denied") );
+ if (sourceStatus == QGeoPositionInfoSource::AccessError)
+ {
+ m_statusString = tr("Access denied");
return;
}
- if (sourceStatus == QGeoPositionInfoSource::ClosedError) {
- setStatusString( tr("Connection to satellite system lost") );
+ if (sourceStatus == QGeoPositionInfoSource::ClosedError)
+ {
+ m_statusString = tr("Connection to satellite system lost");
return;
}
- if (!receivingPositionInfo()) {
- setStatusString( tr("Waiting for signal") );
+ if (!receivingPositionInfo())
+ {
+ m_statusString = tr("Waiting for signal");
return;
}
- setStatusString( tr("Receiving data") );
+ m_statusString = tr("Receiving data");
}
@@ -99,6 +103,6 @@ void Positioning::PositionInfoSource_Satellite::onPositionUpdated(const QGeoPosi
// Therefore, set the current time as a timestamp.
correctedInfo.setTimestamp( QDateTime::currentDateTimeUtc() );
- setPositionInfo( Positioning::PositionInfo(correctedInfo) );
+ setPositionInfo( Positioning::PositionInfo(correctedInfo, sourceName()) );
updateStatusString();
}
diff --git a/src/positioning/PositionProvider.cpp b/src/positioning/PositionProvider.cpp
index f438e379b..856d95b12 100644
--- a/src/positioning/PositionProvider.cpp
+++ b/src/positioning/PositionProvider.cpp
@@ -25,12 +25,15 @@
#include "GlobalSettings.h"
#include "positioning/PositionProvider.h"
#include "traffic/TrafficDataProvider.h"
-#include "units/Units.h"
+#include "Units.h"
+
using namespace Qt::Literals::StringLiterals;
-Positioning::PositionProvider::PositionProvider(QObject *parent) : PositionInfoSource_Abstract(parent)
+Positioning::PositionProvider::PositionProvider(QObject* parent)
+ : QObject(parent),
+ m_receivingPositionInfo(false)
{
// Restore the last valid coordiante and track
QSettings const settings;
@@ -42,16 +45,9 @@ Positioning::PositionProvider::PositionProvider(QObject *parent) : PositionInfoS
m_lastValidCoordinate = tmp;
}
m_lastValidTT = Units::Angle::fromDEG( qBound(0, settings.value(QStringLiteral("PositionProvider/lastValidTrack"), 0).toInt(), 359) );
+ m_approximateLastValidCoordinate = m_lastValidCoordinate.value();
- // Wire up satellite source
- connect(&satelliteSource, &Positioning::PositionInfoSource_Satellite::positionInfoChanged, this, &PositionProvider::onPositionUpdated);
- connect(&satelliteSource, &Positioning::PositionInfoSource_Satellite::pressureAltitudeChanged, this, &PositionProvider::onPressureAltitudeUpdated);
-
- // Binding for updateStatusString
- connect(this, &Positioning::PositionProvider::receivingPositionInfoChanged, this, &Positioning::PositionProvider::updateStatusString);
- connect(&satelliteSource, &Positioning::PositionInfoSource_Satellite::statusStringChanged, this, &Positioning::PositionProvider::updateStatusString);
-
- // Wire up traffic data provider source
+ // Start deferred initialization
QTimer::singleShot(0, this, &Positioning::PositionProvider::deferredInitialization);
// Save position at regular intervals
@@ -61,90 +57,35 @@ Positioning::PositionProvider::PositionProvider(QObject *parent) : PositionInfoS
connect(saveTimer, &QTimer::timeout, this, &Positioning::PositionProvider::savePositionAndTrack);
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &Positioning::PositionProvider::savePositionAndTrack);
saveTimer->start();
-
- // Update properties
- updateStatusString();
- m_approximateLastValidCoordinate = m_lastValidCoordinate.value();
- connect(this, &Positioning::PositionProvider::lastValidCoordinateChanged, this, [this]() {
- if (m_approximateLastValidCoordinate.value().isValid()
- && (m_approximateLastValidCoordinate.value().distanceTo(m_lastValidCoordinate) < 10000))
- {
- return;
- }
- m_approximateLastValidCoordinate = m_lastValidCoordinate.value();
- });
}
-
-
-void Positioning::PositionProvider::deferredInitialization() const
+void Positioning::PositionProvider::deferredInitialization()
{
- connect(GlobalObject::trafficDataProvider(), &Traffic::TrafficDataProvider::positionInfoChanged, this, &PositionProvider::onPositionUpdated);
- connect(GlobalObject::trafficDataProvider(), &Traffic::TrafficDataProvider::pressureAltitudeChanged, this, &PositionProvider::onPressureAltitudeUpdated);
+ // Binding for updateStatusString
+ m_statusString.setBinding([this]() {return computeStatusString();});
+ m_incomingPositionInfo.setBinding([this]() {return computeIncomingPositionInfo();});
+ m_incomingPositionInfoNotifier = m_incomingPositionInfo.addNotifier([this]() {return onIncomingPositionInfoUpdated();});
+ onIncomingPositionInfoUpdated();
}
-
-void Positioning::PositionProvider::onPositionUpdated()
+void Positioning::PositionProvider::onIncomingPositionInfoUpdated()
{
- // This method is called if one of our providers has a new position info.
- // We go through the list of providers in order of preference, to find the first one
- // that has a valid position info available for us.
- PositionInfo newInfo;
- QString source;
-
-
- if (GlobalObject::globalSettings()->positioningByTrafficDataReceiver())
- {
-
- // Priority #1: Traffic data provider
- auto* trafficDataProvider = GlobalObject::trafficDataProvider();
- if (trafficDataProvider != nullptr)
- {
- newInfo = trafficDataProvider->positionInfo();
- source = trafficDataProvider->sourceName();
- }
-
- // Priority #2: Built-in sat receiver
- if (!newInfo.isValid())
- {
- newInfo = satelliteSource.positionInfo();
- source = satelliteSource.sourceName();
- }
-
- }
- else
+ auto newInfo = m_incomingPositionInfo.value();
+ if (!newInfo.isValid())
{
-
- // Priority #1: Built-in sat receiver
- newInfo = satelliteSource.positionInfo();
- source = satelliteSource.sourceName();
-
- // Priority #2: Traffic data provider
- if (!newInfo.isValid())
- {
- auto* trafficDataProvider = GlobalObject::trafficDataProvider();
- if (trafficDataProvider != nullptr)
- {
- newInfo = trafficDataProvider->positionInfo();
- source = trafficDataProvider->sourceName();
- }
-
- }
-
+ m_receivingPositionInfo = false;
+ m_positionInfo = newInfo;
+ return;
}
+ // If no vertical speed has been provided by the system, we compute our own.
auto oldInfo = positionInfo();
auto oldTimeStamp = oldInfo.timestamp();
auto newTimeStamp = newInfo.timestamp();
- if (newTimeStamp == oldTimeStamp)
- {
- return;
- }
-
- // If no vertical speed has been provided by the system, we compute our own.
if (!newInfo.verticalSpeed().isFinite()
- && newInfo.trueAltitudeAMSL().isFinite()
- && oldInfo.trueAltitudeAMSL().isFinite())
+ && newInfo.trueAltitudeAMSL().isFinite()
+ && oldInfo.trueAltitudeAMSL().isFinite()
+ && (newTimeStamp != oldTimeStamp))
{
auto deltaV = (newInfo.trueAltitudeAMSL() - oldInfo.trueAltitudeAMSL());
auto deltaT = Units::Timespan::fromMS( static_cast(oldTimeStamp.msecsTo(newTimeStamp)) );
@@ -153,47 +94,36 @@ void Positioning::PositionProvider::onPositionUpdated()
{
if (oldInfo.verticalSpeed().isFinite())
{
- vSpeed = 0.8*vSpeed + 0.2*positionInfo().verticalSpeed();
+ vSpeed = 0.8*vSpeed + 0.2*oldInfo.verticalSpeed();
}
QGeoPositionInfo tmp = newInfo;
+ QString const src = newInfo.source();
tmp.setAttribute(QGeoPositionInfo::VerticalSpeed, vSpeed.toMPS());
- newInfo = PositionInfo(tmp);
+ newInfo = PositionInfo(tmp, src);
}
}
// Set new info
- setPositionInfo(newInfo);
- setLastValidCoordinate(newInfo.coordinate());
- setLastValidTT(newInfo.trueTrack());
- setSourceName(source);
- updateStatusString();
-}
-
-
-void Positioning::PositionProvider::onPressureAltitudeUpdated()
-{
- // This method is called if one of our providers has a new pressure altitude.
- // We go through the list of providers in order of preference, to find the first one
- // that has valid data for us.
- Units::Distance pAlt;
+ m_positionInfo = newInfo;
+ m_receivingPositionInfo = true;
- // Priority #1: Traffic data provider
- auto* trafficDataProvider = GlobalObject::trafficDataProvider();
- if (trafficDataProvider != nullptr) {
- pAlt = trafficDataProvider->pressureAltitude();
+ m_lastValidCoordinate = newInfo.coordinate();
+ auto TT = newInfo.trueTrack();
+ if (TT.isFinite())
+ {
+ m_lastValidTT = TT;
}
-
- // Priority #2: Built-in sat receiver
- if (!pAlt.isFinite()) {
- pAlt = satelliteSource.pressureAltitude();
+ if (!m_approximateLastValidCoordinate.value().isValid())
+ {
+ m_approximateLastValidCoordinate = m_lastValidCoordinate.value();
+ }
+ if (m_approximateLastValidCoordinate.value().isValid()
+ && (m_approximateLastValidCoordinate.value().distanceTo(m_lastValidCoordinate) > 10000))
+ {
+ m_approximateLastValidCoordinate = m_lastValidCoordinate.value();
}
-
- // Set new info
- setPressureAltitude(pAlt);
-
}
-
void Positioning::PositionProvider::savePositionAndTrack()
{
// Save the last valid coordinate
@@ -203,37 +133,10 @@ void Positioning::PositionProvider::savePositionAndTrack()
settings.setValue(QStringLiteral("PositionProvider/lastValidAltitude"), m_lastValidCoordinate.value().altitude());
// Save the last valid track
- settings.setValue(QStringLiteral("PositionProvider/lastValidTrack"), m_lastValidTT.toDEG());
-}
-
-
-void Positioning::PositionProvider::setLastValidCoordinate(const QGeoCoordinate &newCoordinate)
-{
- if (!newCoordinate.isValid()) {
- return;
- }
- if (newCoordinate == m_lastValidCoordinate) {
- return;
- }
- m_lastValidCoordinate = newCoordinate;
- emit lastValidCoordinateChanged(m_lastValidCoordinate);
-}
-
-
-void Positioning::PositionProvider::setLastValidTT(Units::Angle newTT)
-{
- if (!newTT.isFinite()) {
- return;
- }
- if (newTT == m_lastValidTT) {
- return;
- }
- m_lastValidTT = newTT;
- emit lastValidTTChanged(m_lastValidTT);
+ settings.setValue(QStringLiteral("PositionProvider/lastValidTrack"), m_lastValidTT.value().toDEG());
}
-
-auto Positioning::PositionProvider::lastValidCoordinate() -> QGeoCoordinate
+QGeoCoordinate Positioning::PositionProvider::lastValidCoordinate()
{
auto *positionProvider = GlobalObject::positionProvider();
if (positionProvider == nullptr) {
@@ -242,31 +145,74 @@ auto Positioning::PositionProvider::lastValidCoordinate() -> QGeoCoordinate
return positionProvider->m_lastValidCoordinate.value();
}
-
-auto Positioning::PositionProvider::lastValidTT() -> Units::Angle
+Units::Angle Positioning::PositionProvider::lastValidTT()
{
auto *positionProvider = GlobalObject::positionProvider();
if (positionProvider == nullptr) {
return {};
}
- return positionProvider->m_lastValidTT;
+ return positionProvider->m_lastValidTT.value();
}
-void Positioning::PositionProvider::updateStatusString()
+//
+// Computing Functions/Bindings
+//
+
+QString Positioning::PositionProvider::computeStatusString()
{
- if (receivingPositionInfo()) {
+ if (m_positionInfo.value().isValid())
+ {
QString result = QStringLiteral("");
- result += QStringLiteral("- %1: %2
").arg(tr("Source"), sourceName());
+ result += QStringLiteral("- %1: %2
").arg(tr("Source"), m_positionInfo.value().source());
result += QStringLiteral("- %1
").arg(tr("Receiving position information"));
result += u"
"_s;
- setStatusString(result);
- return;
+ return result;
}
QString result = QStringLiteral("%1
").arg(tr("Not receiving position information"));
result += QStringLiteral("- %1: %2
").arg( satelliteSource.sourceName(), satelliteSource.statusString());
result += QStringLiteral("- %1: %2
").arg( tr("Traffic receiver"), tr("Not receiving position information"));
result += u"
"_s;
- setStatusString(result);
+ return result;
+}
+
+Positioning::PositionInfo Positioning::PositionProvider::computeIncomingPositionInfo()
+{
+ // This method is called if one of our providers has a new position info.
+ // We go through the list of providers in order of preference, to find the first one
+ // that has a valid position info available for us.
+ PositionInfo newInfo;
+
+ if (GlobalObject::globalSettings()->positioningByTrafficDataReceiver())
+ {
+ // Priority #1: Traffic data provider
+ auto* trafficDataProvider = GlobalObject::trafficDataProvider();
+ if (trafficDataProvider != nullptr)
+ {
+ newInfo = trafficDataProvider->positionInfo();
+ }
+
+ // Priority #2: Built-in sat receiver
+ if (!newInfo.isValid())
+ {
+ newInfo = satelliteSource.positionInfo();
+ }
+ }
+ else
+ {
+ // Priority #1: Built-in sat receiver
+ newInfo = satelliteSource.positionInfo();
+
+ // Priority #2: Traffic data provider
+ if (!newInfo.isValid())
+ {
+ auto* trafficDataProvider = GlobalObject::trafficDataProvider();
+ if (trafficDataProvider != nullptr)
+ {
+ newInfo = trafficDataProvider->positionInfo();
+ }
+ }
+ }
+ return newInfo;
}
diff --git a/src/positioning/PositionProvider.h b/src/positioning/PositionProvider.h
index 3cf72d4dc..d38eee409 100644
--- a/src/positioning/PositionProvider.h
+++ b/src/positioning/PositionProvider.h
@@ -24,7 +24,6 @@
#include
#include "GlobalObject.h"
-#include "positioning/PositionInfoSource_Abstract.h"
#include "positioning/PositionInfoSource_Satellite.h"
@@ -46,17 +45,12 @@ namespace Positioning {
* The methods in this class are reentrant, but not thread safe.
*/
-class PositionProvider : public PositionInfoSource_Abstract
+class PositionProvider : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
- // Repeat properties from PositionInfoSource_Abstract so qmllint knows about them
- Q_PROPERTY(Positioning::PositionInfo positionInfo READ positionInfo NOTIFY positionInfoChanged)
- Q_PROPERTY(Units::Distance pressureAltitude READ pressureAltitude NOTIFY pressureAltitudeChanged)
- Q_PROPERTY(bool receivingPositionInfo READ receivingPositionInfo NOTIFY receivingPositionInfoChanged)
-
public:
/*! \brief Standard constructor
@@ -97,7 +91,7 @@ class PositionProvider : public PositionInfoSource_Abstract
* value is stored in a QSetting at destruction, and restored in the
* construction.
*/
- Q_PROPERTY(QGeoCoordinate lastValidCoordinate READ lastValidCoordinate NOTIFY lastValidCoordinateChanged)
+ Q_PROPERTY(QGeoCoordinate lastValidCoordinate READ lastValidCoordinate BINDABLE bindableLastValidCoordinate)
/*! \brief Last valid true track
*
@@ -105,7 +99,32 @@ class PositionProvider : public PositionInfoSource_Abstract
* start, this property is set to 0°. The value is stored in a QSetting at
* destruction, and restored in the construction.
*/
- Q_PROPERTY(Units::Angle lastValidTT READ lastValidTT NOTIFY lastValidTTChanged)
+ Q_PROPERTY(Units::Angle lastValidTT READ lastValidTT BINDABLE bindableLastValidTT)
+
+ /*! \brief Position information
+ *
+ * This property holds information about the device position. To ensure
+ * that the data is up-to-date, the position information will be set to an
+ * invalid positionInfo when no data has arrived for more than the time
+ * specified in PositionInfo::lifetime.
+ */
+ Q_PROPERTY(Positioning::PositionInfo positionInfo READ positionInfo BINDABLE bindablePositionInfo NOTIFY positionInfoChanged)
+
+ /*! \brief Indicator that position information is being received
+ *
+ * This is a shortcut for positionInfo().isValid. This property exists
+ * because it does not change so often, and can thus be more efficient to
+ * use.
+ */
+ Q_PROPERTY(bool receivingPositionInfo READ receivingPositionInfo BINDABLE bindableReceivingPositionInfo)
+
+ /*! \brief Source status
+ *
+ * This property holds a translated, human-readable string that describes
+ * the status of the positionInfo source. This could typically be a string
+ * of the form "OK" or "Insufficient permission to access position info"
+ */
+ Q_PROPERTY(QString statusString READ statusString BINDABLE bindableStatusString)
//
@@ -116,20 +135,80 @@ class PositionProvider : public PositionInfoSource_Abstract
*
* @returns Property approximateLastValidCoordinate
*/
- Q_REQUIRED_RESULT QGeoCoordinate approximateLastValidCoordinate() const {return {m_approximateLastValidCoordinate};}
- Q_REQUIRED_RESULT QBindable bindableApproximateLastValidCoordinate() const {return &m_approximateLastValidCoordinate;}
+ [[nodiscard]] QGeoCoordinate approximateLastValidCoordinate() const {return m_approximateLastValidCoordinate.value();}
+
+ /*! \brief Getter function for the property with the same name
+ *
+ * @returns Property approximateLastValidCoordinate
+ */
+ [[nodiscard]] QBindable bindableApproximateLastValidCoordinate() const {return &m_approximateLastValidCoordinate;}
/*! \brief Getter function for the property with the same name
*
* @returns Property lastValidCoordinate
*/
- static QGeoCoordinate lastValidCoordinate();
+ [[nodiscard]] static QGeoCoordinate lastValidCoordinate();
+
+ /*! \brief Getter function for the property with the same name
+ *
+ * @returns Property lastValidCoordinate
+ */
+ [[nodiscard]] QBindable bindableLastValidCoordinate() {return &m_lastValidCoordinate;}
+
+ /*! \brief Getter function for the property with the same name
+ *
+ * @returns Property lastValidTrack
+ */
+ [[nodiscard]] static Units::Angle lastValidTT();
/*! \brief Getter function for the property with the same name
*
* @returns Property lastValidTrack
*/
- static Units::Angle lastValidTT();
+ [[nodiscard]] QBindable bindableLastValidTT() {return &m_lastValidTT;}
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property positionInfo
+ */
+ [[nodiscard]] Positioning::PositionInfo positionInfo() const {return m_positionInfo.value();}
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property positionInfo
+ */
+ [[nodiscard]] QBindable bindablePositionInfo() const {return &m_positionInfo;}
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property receivingPositionInfo
+ */
+ [[nodiscard]] bool receivingPositionInfo() const {return m_receivingPositionInfo.value();}
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property receivingPositionInfo
+ */
+ [[nodiscard]] QBindable bindableReceivingPositionInfo() {return &m_receivingPositionInfo;}
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property statusString
+ */
+ [[nodiscard]] QString statusString() const
+ {
+ return m_statusString.value();
+ }
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property statusString
+ */
+ [[nodiscard]] QBindable bindableStatusString() const
+ {
+ return &m_statusString;
+ }
+
//
@@ -145,41 +224,29 @@ class PositionProvider : public PositionInfoSource_Abstract
Q_INVOKABLE void startUpdates() { satelliteSource.startUpdates(); }
signals:
- /*! \brief Notifier signal */
+ // Notifier signal
void approximateLastValidCoordinateChanged();
- /*! \brief Notifier signal */
- void lastValidTTChanged(Units::Angle);
+ // Notifier signal
+ void positionInfoChanged();
- /*! \brief Notifier signal */
- void lastValidCoordinateChanged(QGeoCoordinate);
+ // Notifier signal
+ void receivingPositionInfoChanged();
private slots:
// Intializations that are moved out of the constructor, in order to avoid
// nested uses of constructors in Global.
- void deferredInitialization() const;
-
- // Connected to sources, in order to receive new data
- void onPositionUpdated();
-
- // Connected to sources, in order to receive new data
- void onPressureAltitudeUpdated();
+ void deferredInitialization();
// Saves last valid position and track
void savePositionAndTrack();
- // Setter method for property with the same name
- void setLastValidCoordinate(const QGeoCoordinate &newCoordinate);
-
- // Setter method for property with the same name
- void setLastValidTT(Units::Angle newTT);
-
- // Setter method for property with the same name
- void updateStatusString();
-
private:
Q_DISABLE_COPY_MOVE(PositionProvider)
+ // Computation method for property with the same name
+ QString computeStatusString();
+
// Aircraft is considered flying if speed is at least this high
static constexpr double minFlightSpeedInKT = 30.0;
// Hysteresis for flight speed
@@ -192,9 +259,24 @@ private slots:
PositionInfoSource_Satellite satelliteSource;
- Q_OBJECT_BINDABLE_PROPERTY(PositionProvider, QGeoCoordinate, m_approximateLastValidCoordinate, &Positioning::PositionProvider::approximateLastValidCoordinateChanged)
+ // The incoming position info is set by a binding that monitors
+ // the satelliteSource and the TrafficDataSource
+ QProperty m_incomingPositionInfo;
+ Positioning::PositionInfo computeIncomingPositionInfo();
+
+ // This method updates m_approximateLastValidCoordinate, m_lastValidCoordinate and m_lastValidTT
+ // whenever m_incomingPositionInfo changes.
+ void onIncomingPositionInfoUpdated();
+ QPropertyNotifier m_incomingPositionInfoNotifier;
+
+ Q_OBJECT_BINDABLE_PROPERTY(Positioning::PositionProvider, Positioning::PositionInfo, m_positionInfo, &Positioning::PositionProvider::positionInfoChanged);
+ Q_OBJECT_BINDABLE_PROPERTY(Positioning::PositionProvider, QGeoCoordinate, m_approximateLastValidCoordinate, &Positioning::PositionProvider::approximateLastValidCoordinateChanged);
QProperty m_lastValidCoordinate {QGeoCoordinate(EDTF_lat, EDTF_lon, EDTF_ele)};
- Units::Angle m_lastValidTT {};
+ QProperty m_lastValidTT;
+
+ Q_OBJECT_BINDABLE_PROPERTY(Positioning::PositionProvider, bool, m_receivingPositionInfo, &Positioning::PositionProvider::receivingPositionInfoChanged);
+ QProperty m_statusString;
+
};
} // namespace Positioning
diff --git a/src/qml/items/MFM.qml b/src/qml/items/MFM.qml
index 09b742dce..42bd19096 100644
--- a/src/qml/items/MFM.qml
+++ b/src/qml/items/MFM.qml
@@ -27,11 +27,8 @@ import QtQuick.Controls
import QtQuick.Layouts
import akaflieg_freiburg.enroute
-import enroute 1.0
-
import "."
-import ".."
import "../dialogs"
Item {
diff --git a/src/qml/items/NavBar.qml b/src/qml/items/NavBar.qml
index 1620d9d76..a85a14397 100644
--- a/src/qml/items/NavBar.qml
+++ b/src/qml/items/NavBar.qml
@@ -119,7 +119,7 @@ Rectangle {
Layout.alignment: Qt.AlignHCenter
- text: PositionProvider.pressureAltitude.isFinite() ? "FL" + ("000" + Math.round(PositionProvider.pressureAltitude.toFeet()/100.0)).slice(-3) : "-"
+ text: TrafficDataProvider.pressureAltitude.isFinite() ? "FL" + ("000" + Math.round(TrafficDataProvider.pressureAltitude.toFeet()/100.0)).slice(-3) : "-"
font.weight: Font.Bold
font.pixelSize: dummy.font.pixelSize*1.3
color: "white"
diff --git a/src/qml/main.qml b/src/qml/main.qml
index 22fd280d2..ebf022e16 100644
--- a/src/qml/main.qml
+++ b/src/qml/main.qml
@@ -346,7 +346,7 @@ AppWindow {
ItemDelegate { // PressureAltitude
text: qsTr("Barometric Data")
+`
`
- + (PositionProvider.pressureAltitude.isFinite() ? qsTr("Receiving pressure altitude.") : qsTr("Not receiving pressure altitude."))
+ + (TrafficDataProvider.pressureAltitude.isFinite() ? qsTr("Receiving pressure altitude.") : qsTr("Not receiving pressure altitude."))
+ ``
icon.source: "/icons/material/ic_speed.svg"
Layout.fillWidth: true
@@ -359,7 +359,7 @@ AppWindow {
}
background: Rectangle {
anchors.fill: parent
- color: PositionProvider.pressureAltitude.isFinite() ? "green" : "red"
+ color: TrafficDataProvider.pressureAltitude.isFinite() ? "green" : "red"
opacity: 0.2
}
}
diff --git a/src/qml/pages/PressureAltitude.qml b/src/qml/pages/PressureAltitude.qml
index 82d875497..123309af3 100644
--- a/src/qml/pages/PressureAltitude.qml
+++ b/src/qml/pages/PressureAltitude.qml
@@ -68,7 +68,7 @@ Page {
Layout.rightMargin: 4
Layout.columnSpan: 3
- text: PositionProvider.pressureAltitude.isFinite() ? qsTr("Receiving static pressure data from traffic receiver") : qsTr("Not connected to a traffic receiver that provides static pressure data")
+ text: TrafficDataProvider.pressureAltitude.isFinite() ? qsTr("Receiving static pressure data from traffic receiver") : qsTr("Not connected to a traffic receiver that provides static pressure data")
wrapMode: Text.WordWrap
textFormat: Text.RichText
@@ -83,7 +83,7 @@ Page {
background: Rectangle {
border.color: "black"
- color: PositionProvider.pressureAltitude.isFinite() ? "green" : "red"
+ color: TrafficDataProvider.pressureAltitude.isFinite() ? "green" : "red"
opacity: 0.2
radius: 4
}
@@ -140,7 +140,7 @@ Page {
text: qsTr("Pressure Altitude") }
Label {
Layout.fillWidth: true
- text: PositionProvider.pressureAltitude.isFinite() ? "FL" + ("000" + Math.round(PositionProvider.pressureAltitude.toFeet()/100.0)).slice(-3) : "-"
+ text: TrafficDataProvider.pressureAltitude.isFinite() ? "FL" + ("000" + Math.round(TrafficDataProvider.pressureAltitude.toFeet()/100.0)).slice(-3) : "-"
wrapMode: Text.Wrap
}
Item { }
@@ -149,7 +149,7 @@ Page {
Label {
Layout.fillWidth: true
text: {
- var pAlt = PositionProvider.pressureAltitude
+ var pAlt = TrafficDataProvider.pressureAltitude
if (!pAlt.isFinite())
return "-"
var qnhpAlt = WeatherDataProvider.QNHPressureAltitude
diff --git a/src/traffic/TrafficDataProvider.cpp b/src/traffic/TrafficDataProvider.cpp
index 1726e1d5e..e6e7fc52d 100644
--- a/src/traffic/TrafficDataProvider.cpp
+++ b/src/traffic/TrafficDataProvider.cpp
@@ -33,7 +33,9 @@
using namespace Qt::Literals::StringLiterals;
-Traffic::TrafficDataProvider::TrafficDataProvider(QObject *parent) : Positioning::PositionInfoSource_Abstract(parent)
+Traffic::TrafficDataProvider::TrafficDataProvider(QObject *parent)
+ : Positioning::PositionInfoSource_Abstract(parent),
+ m_receivingHeartbeat(false)
{
// Create traffic objects
const int numTrafficObjects = 20;
@@ -68,14 +70,15 @@ Traffic::TrafficDataProvider::TrafficDataProvider(QObject *parent) : Positioning
addDataSource( new Traffic::TrafficDataSource_Udp(true, 4000, this) );
addDataSource( new Traffic::TrafficDataSource_Udp(true, 49002, this));
+ // Setup Bindings
+ m_pressureAltitude.setBinding([this]() {return computePressureAltitude();});
+
// Bindings for saving
loadConnectionInfos();
connect(this, &Traffic::TrafficDataProvider::dataSourcesChanged, this, &Traffic::TrafficDataProvider::saveConnectionInfos);
// Bindings for status string
- connect(this, &Traffic::TrafficDataProvider::positionInfoChanged, this, &Traffic::TrafficDataProvider::updateStatusString);
- connect(this, &Traffic::TrafficDataProvider::pressureAltitudeChanged, this, &Traffic::TrafficDataProvider::updateStatusString);
- connect(this, &Traffic::TrafficDataProvider::receivingHeartbeatChanged, this, &Traffic::TrafficDataProvider::updateStatusString);
+ m_statusString.setBinding([this]() {return computeStatusString();});
// Connect timer. Try to (re)connect after 2s, and then again every five minutes.
QTimer::singleShot(2s, this, &Traffic::TrafficDataProvider::connectToTrafficReceiver);
@@ -103,18 +106,22 @@ void Traffic::TrafficDataProvider::addDataSource(Traffic::TrafficDataSource_Abst
source->setParent(this);
QQmlEngine::setObjectOwnership(source, QQmlEngine::CppOwnership);
- m_dataSources << source;
- connect(source, &Traffic::TrafficDataSource_Abstract::connectivityStatusChanged, this, &Traffic::TrafficDataProvider::updateStatusString);
- connect(source, &Traffic::TrafficDataSource_Abstract::errorStringChanged, this, &Traffic::TrafficDataProvider::updateStatusString);
connect(source, &Traffic::TrafficDataSource_Abstract::passwordRequest, this, &Traffic::TrafficDataProvider::passwordRequest);
connect(source, &Traffic::TrafficDataSource_Abstract::passwordStorageRequest, this, &Traffic::TrafficDataProvider::passwordStorageRequest);
- connect(source, &Traffic::TrafficDataSource_Abstract::receivingHeartbeatChanged, this, &Traffic::TrafficDataProvider::updateStatusString);
connect(source, &Traffic::TrafficDataSource_Abstract::receivingHeartbeatChanged, this, &Traffic::TrafficDataProvider::onSourceHeartbeatChanged);
connect(source, &Traffic::TrafficDataSource_Abstract::trafficReceiverRuntimeErrorChanged, this, &Traffic::TrafficDataProvider::onTrafficReceiverRuntimeError);
connect(source, &Traffic::TrafficDataSource_Abstract::trafficReceiverSelfTestErrorChanged, this, &Traffic::TrafficDataProvider::onTrafficReceiverSelfTestError);
+ auto tmp = m_dataSources.value();
+ tmp.append(source);
+ tmp.removeAll(nullptr);
+ std::sort(tmp.begin(),
+ tmp.end(),
+ [](const Traffic::TrafficDataSource_Abstract* first, const Traffic::TrafficDataSource_Abstract* second)
+ { return first->sourceName() < second->sourceName(); });
+ m_dataSources = tmp;
+
emit dataSourcesChanged();
- updateStatusString();
}
QString Traffic::TrafficDataProvider::addDataSource(const Traffic::ConnectionInfo &connectionInfo)
@@ -140,7 +147,7 @@ QString Traffic::TrafficDataProvider::addDataSource(const Traffic::ConnectionInf
QString Traffic::TrafficDataProvider::addDataSource_UDP(quint16 port)
{
// Ignore new device if data source already exists.
- foreach(auto _dataSource, m_dataSources)
+ foreach(auto _dataSource, m_dataSources.value())
{
auto* dataSourceUDP = qobject_cast(_dataSource);
if (dataSourceUDP != nullptr)
@@ -162,7 +169,7 @@ QString Traffic::TrafficDataProvider::addDataSource_SerialPort(const QString& po
{
#if __has_include()
// Ignore new device if data source already exists.
- foreach(auto _dataSource, m_dataSources)
+ foreach(auto _dataSource, m_dataSources.value())
{
auto* dataSourceSerialPort = qobject_cast(_dataSource);
if (dataSourceSerialPort != nullptr)
@@ -186,7 +193,7 @@ QString Traffic::TrafficDataProvider::addDataSource_SerialPort(const QString& po
QString Traffic::TrafficDataProvider::addDataSource_TCP(const QString& host, quint16 port)
{
// Ignore new device if data source already exists.
- foreach(auto _dataSource, m_dataSources)
+ foreach(auto _dataSource, m_dataSources.value())
{
auto* dataSourceTCP = qobject_cast(_dataSource);
if (dataSourceTCP != nullptr)
@@ -206,11 +213,11 @@ QString Traffic::TrafficDataProvider::addDataSource_TCP(const QString& host, qui
void Traffic::TrafficDataProvider::clearDataSources()
{
- if (m_dataSources.isEmpty())
+ if (m_dataSources.value().isEmpty())
{
return;
}
- foreach(auto dataSource, m_dataSources)
+ foreach(auto dataSource, m_dataSources.value())
{
if (dataSource.isNull())
{
@@ -219,12 +226,15 @@ void Traffic::TrafficDataProvider::clearDataSources()
dataSource->disconnect();
delete dataSource;
}
- m_dataSources.clear();
+
+ auto tmp = m_dataSources.value();
+ tmp.clear();
+ m_dataSources = tmp;
}
void Traffic::TrafficDataProvider::connectToTrafficReceiver()
{
- foreach(auto dataSource, m_dataSources)
+ foreach(auto dataSource, m_dataSources.value())
{
if (dataSource.isNull())
{
@@ -232,14 +242,12 @@ void Traffic::TrafficDataProvider::connectToTrafficReceiver()
}
dataSource->connectToTrafficReceiver();
}
-
- updateStatusString();
}
QList Traffic::TrafficDataProvider::dataSources() const
{
QList result;
- foreach(auto dataSource, m_dataSources)
+ foreach(auto dataSource, m_dataSources.value())
{
if (dataSource == nullptr)
{
@@ -264,7 +272,7 @@ void Traffic::TrafficDataProvider::deferredInitialization() const
void Traffic::TrafficDataProvider::disconnectFromTrafficReceiver()
{
- foreach(auto dataSource, m_dataSources)
+ foreach(auto dataSource, m_dataSources.value())
{
if (dataSource.isNull())
{
@@ -298,16 +306,16 @@ void Traffic::TrafficDataProvider::loadConnectionInfos()
void Traffic::TrafficDataProvider::onSourceHeartbeatChanged()
{
// If we have a current source, if the current source has a heartbeat and if the current source is a TCP source, then we simply stick with it.
- if ((qobject_cast(m_currentSource) != nullptr)
+ if ((qobject_cast(m_currentSource.value()) != nullptr)
&& m_currentSource->receivingHeartbeat() )
{
- setReceivingHeartbeat(true);
+ m_receivingHeartbeat = true;
return;
}
// Among the m_dataSources, find the first (=most preferred) source that is receiving heartbeat messages.
Traffic::TrafficDataSource_Abstract *heartbeatDataSource = nullptr;
- foreach(auto source, m_dataSources)
+ foreach(auto source, m_dataSources.value())
{
if (source.isNull())
{
@@ -326,31 +334,29 @@ void Traffic::TrafficDataProvider::onSourceHeartbeatChanged()
// Disconnect old m_currentSource
- if (!m_currentSource.isNull())
+ if (!m_currentSource.value().isNull())
{
- disconnect(m_currentSource, &Traffic::TrafficDataSource_Abstract::pressureAltitudeUpdated, this, &Traffic::TrafficDataProvider::setPressureAltitude);
- disconnect(m_currentSource, &Traffic::TrafficDataSource_Abstract::factorWithoutPosition, this, &Traffic::TrafficDataProvider::onTrafficFactorWithoutPosition);
- disconnect(m_currentSource, &Traffic::TrafficDataSource_Abstract::factorWithPosition, this, &Traffic::TrafficDataProvider::onTrafficFactorWithPosition);
- disconnect(m_currentSource, &Traffic::TrafficDataSource_Abstract::positionUpdated, this, &Traffic::TrafficDataProvider::setPositionInfo);
- disconnect(m_currentSource, &Traffic::TrafficDataSource_Abstract::warning, this, &Traffic::TrafficDataProvider::setWarning);
+ disconnect(m_currentSource.value(), &Traffic::TrafficDataSource_Abstract::factorWithoutPosition, this, &Traffic::TrafficDataProvider::onTrafficFactorWithoutPosition);
+ disconnect(m_currentSource.value(), &Traffic::TrafficDataSource_Abstract::factorWithPosition, this, &Traffic::TrafficDataProvider::onTrafficFactorWithPosition);
+ disconnect(m_currentSource.value(), &Traffic::TrafficDataSource_Abstract::positionUpdated, this, &Traffic::TrafficDataProvider::setPositionInfo);
+ disconnect(m_currentSource.value(), &Traffic::TrafficDataSource_Abstract::warning, this, &Traffic::TrafficDataProvider::setWarning);
}
// Update m_currentsource
m_currentSource = heartbeatDataSource;
- if (!m_currentSource.isNull())
+ if (!m_currentSource.value().isNull())
{
// If there is a new m_currentSource, then setup Qt connections and
// disconnect all sources of lower priority from the traffic receivers.
- connect(m_currentSource, &Traffic::TrafficDataSource_Abstract::pressureAltitudeUpdated, this, &Traffic::TrafficDataProvider::setPressureAltitude);
- connect(m_currentSource, &Traffic::TrafficDataSource_Abstract::factorWithoutPosition, this, &Traffic::TrafficDataProvider::onTrafficFactorWithoutPosition);
- connect(m_currentSource, &Traffic::TrafficDataSource_Abstract::factorWithPosition, this, &Traffic::TrafficDataProvider::onTrafficFactorWithPosition);
- connect(m_currentSource, &Traffic::TrafficDataSource_Abstract::positionUpdated, this, &Traffic::TrafficDataProvider::setPositionInfo);
- connect(m_currentSource, &Traffic::TrafficDataSource_Abstract::warning, this, &Traffic::TrafficDataProvider::setWarning);
+ connect(m_currentSource.value(), &Traffic::TrafficDataSource_Abstract::factorWithoutPosition, this, &Traffic::TrafficDataProvider::onTrafficFactorWithoutPosition);
+ connect(m_currentSource.value(), &Traffic::TrafficDataSource_Abstract::factorWithPosition, this, &Traffic::TrafficDataProvider::onTrafficFactorWithPosition);
+ connect(m_currentSource.value(), &Traffic::TrafficDataSource_Abstract::positionUpdated, this, &Traffic::TrafficDataProvider::setPositionInfo);
+ connect(m_currentSource.value(), &Traffic::TrafficDataSource_Abstract::warning, this, &Traffic::TrafficDataProvider::setWarning);
// Disconnect from traffic receiver
bool doDisconnect = false;
- foreach(auto source, m_dataSources)
+ foreach(auto source, m_dataSources.value())
{
if ( source.isNull() )
{
@@ -376,13 +382,13 @@ void Traffic::TrafficDataProvider::onSourceHeartbeatChanged()
}
// Update heartbeat status
- if (m_currentSource.isNull())
+ if (m_currentSource.value().isNull())
{
- setReceivingHeartbeat(false);
+ m_receivingHeartbeat = false;
}
else
{
- setReceivingHeartbeat(m_currentSource->receivingHeartbeat());
+ m_receivingHeartbeat = m_currentSource->receivingHeartbeat();
}
}
@@ -466,7 +472,7 @@ void Traffic::TrafficDataProvider::onTrafficFactorWithPosition(const Traffic::Tr
void Traffic::TrafficDataProvider::onTrafficReceiverRuntimeError()
{
QString result;
- foreach(auto dataSource, m_dataSources)
+ foreach(auto dataSource, m_dataSources.value())
{
if (dataSource.isNull())
{
@@ -490,7 +496,7 @@ void Traffic::TrafficDataProvider::onTrafficReceiverRuntimeError()
void Traffic::TrafficDataProvider::onTrafficReceiverSelfTestError()
{
QString result;
- foreach(auto dataSource, m_dataSources)
+ foreach(auto dataSource, m_dataSources.value())
{
if (dataSource.isNull())
{
@@ -521,7 +527,10 @@ void Traffic::TrafficDataProvider::removeDataSource(Traffic::TrafficDataSource_A
return;
}
- m_dataSources.removeAll(source);
+ auto tmp = m_dataSources.value();
+ tmp.removeAll(source);
+ m_dataSources = tmp;
+
emit dataSourcesChanged();
source->deleteLater();
}
@@ -534,7 +543,7 @@ void Traffic::TrafficDataProvider::resetWarning()
void Traffic::TrafficDataProvider::saveConnectionInfos()
{
QList connectionInfos;
- foreach (auto dataSource, m_dataSources)
+ foreach (auto dataSource, m_dataSources.value())
{
if (dataSource == nullptr)
{
@@ -564,7 +573,7 @@ void Traffic::TrafficDataProvider::saveConnectionInfos()
void Traffic::TrafficDataProvider::setPassword(const QString& SSID, const QString &password)
{
- foreach(auto dataSource, m_dataSources)
+ foreach(auto dataSource, m_dataSources.value())
{
if (dataSource.isNull())
{
@@ -574,16 +583,6 @@ void Traffic::TrafficDataProvider::setPassword(const QString& SSID, const QStrin
}
}
-void Traffic::TrafficDataProvider::setReceivingHeartbeat(bool newReceivingHeartbeat)
-{
- if (m_receivingHeartbeat == newReceivingHeartbeat)
- {
- return;
- }
- m_receivingHeartbeat = newReceivingHeartbeat;
- emit receivingHeartbeatChanged(m_receivingHeartbeat);
-}
-
void Traffic::TrafficDataProvider::setWarning(const Traffic::Warning& warning)
{
if (warning.alarmLevel() > -1)
@@ -600,12 +599,33 @@ void Traffic::TrafficDataProvider::setWarning(const Traffic::Warning& warning)
emit warningChanged(m_Warning);
}
-void Traffic::TrafficDataProvider::updateStatusString()
+
+//
+// Private Methods
+//
+
+Units::Distance Traffic::TrafficDataProvider::computePressureAltitude()
+{
+ for (const auto &dataSource : m_dataSources.value()) {
+ if (dataSource.isNull())
+ {
+ continue;
+ }
+ auto pAlt = dataSource->pressureAltitude();
+ if (pAlt.isFinite())
+ {
+ return pAlt;
+ }
+ }
+ return {};
+}
+
+QString Traffic::TrafficDataProvider::computeStatusString()
{
if (receivingHeartbeat())
{
QString result;
- if (!m_currentSource.isNull())
+ if (!m_currentSource.value().isNull())
{
result += QStringLiteral("%1
").arg(m_currentSource->sourceName());
}
@@ -619,10 +639,8 @@ void Traffic::TrafficDataProvider::updateStatusString()
result += QStringLiteral("- %1
").arg(tr("Receiving barometric altitude info."));
}
result += u"
"_s;
- setStatusString(result);
- return;
+ return result;
}
- const QString result = tr("Not receiving traffic receiver heartbeat through any of the configured data connections.");
- setStatusString(result);
+ return tr("Not receiving traffic receiver heartbeat through any of the configured data connections.");
}
diff --git a/src/traffic/TrafficDataProvider.h b/src/traffic/TrafficDataProvider.h
index 0adc3b3ef..ed322addd 100644
--- a/src/traffic/TrafficDataProvider.h
+++ b/src/traffic/TrafficDataProvider.h
@@ -84,6 +84,16 @@ class TrafficDataProvider : public Positioning::PositionInfoSource_Abstract {
*/
Q_PROPERTY(QList dataSources READ dataSources NOTIFY dataSourcesChanged)
+ /*! \brief Pressure altitude
+ *
+ * This property holds information about the pressure altitude, that is,
+ * the altitude that you would read off your altimeter if the altimeter is
+ * set to 1013.2 hPa. To ensure that the data is up-to-date, the position
+ * information will be set to "invalid" when no data has arrived for more
+ * than the time specified in PositionInfo::lifetime.
+ */
+ Q_PROPERTY(Units::Distance pressureAltitude READ pressureAltitude BINDABLE bindablePressureAltitude)
+
/*! \brief Heartbeat indicator
*
* When active, traffic receivers send regular heartbeat messages. These
@@ -91,7 +101,7 @@ class TrafficDataProvider : public Positioning::PositionInfoSource_Abstract {
* times when no traffic is reported. This property indicates if the class
* receives heartbeat messages from at least one of the known receivers.
*/
- Q_PROPERTY(bool receivingHeartbeat READ receivingHeartbeat WRITE setReceivingHeartbeat NOTIFY receivingHeartbeatChanged)
+ Q_PROPERTY(bool receivingHeartbeat READ receivingHeartbeat BINDABLE bindableReceivingHeartbeat NOTIFY receivingHeartbeatChanged)
/*! \brief Traffic objects whose position is known
*
@@ -149,13 +159,34 @@ class TrafficDataProvider : public Positioning::PositionInfoSource_Abstract {
*/
[[nodiscard]] QList dataSources() const;
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property pressureAltitude
+ */
+ [[nodiscard]] Units::Distance pressureAltitude() const {return m_pressureAltitude.value();}
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property pressureAltitude
+ */
+ [[nodiscard]] QBindable bindablePressureAltitude() const {return &m_pressureAltitude;}
+
/*! \brief Getter method for property with the same name
*
* @returns Property receiving
*/
[[nodiscard]] bool receivingHeartbeat() const
{
- return m_receivingHeartbeat;
+ return m_receivingHeartbeat.value();
+ }
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property receiving
+ */
+ [[nodiscard]] QBindable bindableReceivingHeartbeat() const
+ {
+ return &m_receivingHeartbeat;
}
/*! \brief Getter method for property with the same name
@@ -292,6 +323,7 @@ class TrafficDataProvider : public Positioning::PositionInfoSource_Abstract {
*/
static constexpr Units::Distance maxHorizontalDistance = Units::Distance::fromNM(20.0);
+
signals:
/*! \brief Notifier signal */
void dataSourcesChanged();
@@ -314,7 +346,7 @@ class TrafficDataProvider : public Positioning::PositionInfoSource_Abstract {
void passwordStorageRequest(const QString& SSID, const QString& password);
/*! \brief Notifier signal */
- void receivingHeartbeatChanged(bool);
+ void receivingHeartbeatChanged();
/*! \brief Notifier signal */
void trafficReceiverRuntimeErrorChanged();
@@ -395,17 +427,16 @@ private slots:
// Save connection infos to file
void saveConnectionInfos();
- // Setter method
- void setReceivingHeartbeat(bool newReceivingHeartbeat);
-
// Setter method
void setWarning(const Traffic::Warning& warning);
- // Updates the property statusString that is inherited from
- // Positioning::PositionInfoSource_Abstract
- void updateStatusString();
-
private:
+ //
+ // Compute Methods
+ //
+
+ QString computeStatusString();
+
// UDP Socket for ForeFlight Broadcast messages.
// See https://www.foreflight.com/connect/spec/
QNetworkDatagram foreFlightBroadcastDatagram {R"({"App":"Enroute Flight Navigation","GDL90":{"port":4000}})", QHostAddress::Broadcast, 63093};
@@ -417,8 +448,8 @@ private slots:
QPointer m_trafficObjectWithoutPosition;
// TrafficData Sources
- QList> m_dataSources;
- QPointer m_currentSource;
+ QProperty>> m_dataSources;
+ QProperty> m_currentSource;
// Property cache
Traffic::Warning m_Warning;
@@ -426,11 +457,13 @@ private slots:
QString m_trafficReceiverRuntimeError;
QString m_trafficReceiverSelfTestError;
+ QProperty m_pressureAltitude;
+ Units::Distance computePressureAltitude();
+
// Reconnect
QTimer reconnectionTimer;
- // Property Cache
- bool m_receivingHeartbeat {false};
+ Q_OBJECT_BINDABLE_PROPERTY(Traffic::TrafficDataProvider, bool, m_receivingHeartbeat, &Traffic::TrafficDataProvider::receivingHeartbeatChanged);
// Standard file name for saveConnectionInfos()
QString stdFileName{QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/connectionInfos.data"};
diff --git a/src/traffic/TrafficDataProvider_BluetoothClassic.cpp b/src/traffic/TrafficDataProvider_BluetoothClassic.cpp
index ea9183e21..397ff2b65 100644
--- a/src/traffic/TrafficDataProvider_BluetoothClassic.cpp
+++ b/src/traffic/TrafficDataProvider_BluetoothClassic.cpp
@@ -36,7 +36,7 @@ QString Traffic::TrafficDataProvider::addDataSource_BluetoothClassic(const Traff
}
// Ignore new device if data source already exists.
- foreach(auto _dataSource, m_dataSources)
+ foreach(auto _dataSource, m_dataSources.value())
{
auto* dataSourceBTClassic = qobject_cast(_dataSource);
if (dataSourceBTClassic != nullptr)
diff --git a/src/traffic/TrafficDataSource_Abstract.cpp b/src/traffic/TrafficDataSource_Abstract.cpp
index 5bd14c14e..ec857890c 100644
--- a/src/traffic/TrafficDataSource_Abstract.cpp
+++ b/src/traffic/TrafficDataSource_Abstract.cpp
@@ -20,6 +20,7 @@
#include
+#include "positioning/PositionInfo.h"
#include "traffic/TrafficDataSource_Abstract.h"
@@ -35,8 +36,12 @@ Traffic::TrafficDataSource_Abstract::TrafficDataSource_Abstract(bool isCanonical
m_heartbeatTimer.setInterval(5s);
connect(&m_heartbeatTimer, &QTimer::timeout, this, &Traffic::TrafficDataSource_Abstract::resetReceivingHeartbeat);
+ // Setup timer for pressure altitude
+ m_pressureAltitudeTimer.setInterval(Positioning::PositionInfo::lifetime);
+ m_pressureAltitudeTimer.setSingleShot(true);
+ connect(&m_pressureAltitudeTimer, &QTimer::timeout, this, [this]() {m_pressureAltitude = Units::Distance();});
+
// Setup other times
- m_pressureAltitudeTimer.setInterval(5s);
m_pressureAltitudeTimer.setSingleShot(true);
m_trueAltitudeTimer.setInterval(5s);
m_trueAltitudeTimer.setSingleShot(true);
@@ -64,6 +69,11 @@ void Traffic::TrafficDataSource_Abstract::setErrorString(const QString& newError
emit errorStringChanged(m_errorString);
}
+void Traffic::TrafficDataSource_Abstract::setPressureAltitude(Units::Distance newPressureAltitude)
+{
+ m_pressureAltitudeTimer.start();
+ m_pressureAltitude = newPressureAltitude;
+}
void Traffic::TrafficDataSource_Abstract::setReceivingHeartbeat(bool newReceivingHeartbeat)
{
diff --git a/src/traffic/TrafficDataSource_Abstract.h b/src/traffic/TrafficDataSource_Abstract.h
index f165b485e..4ef4d0589 100644
--- a/src/traffic/TrafficDataSource_Abstract.h
+++ b/src/traffic/TrafficDataSource_Abstract.h
@@ -20,6 +20,8 @@
#pragma once
+#include
+
#include "positioning/PositionInfo.h"
#include "traffic/ConnectionInfo.h"
#include "traffic/TrafficFactor_DistanceOnly.h"
@@ -102,6 +104,16 @@ class TrafficDataSource_Abstract : public QObject {
/*! \brief Icon that can be used to represent the connection in a GUI */
Q_PROPERTY(QString icon READ icon CONSTANT)
+ /*! \brief Pressure altitude
+ *
+ * This property holds information about the pressure altitude, that is,
+ * the altitude that you would read off your altimeter if the altimeter is
+ * set to 1013.2 hPa. To ensure that the data is up-to-date, the position
+ * information will be set to "invalid" when no data has arrived for more
+ * than the time specified in PositionInfo::lifetime.
+ */
+ Q_PROPERTY(Units::Distance pressureAltitude READ pressureAltitude BINDABLE bindablePressureAltitude)
+
/*! \brief Heartbeat indicator
*
* When active, traffic receivers send regular heartbeat messages. These
@@ -191,6 +203,18 @@ class TrafficDataSource_Abstract : public QObject {
*/
[[nodiscard]] virtual QString icon() const = 0;
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property pressureAltitude
+ */
+ [[nodiscard]] Units::Distance pressureAltitude() const {return m_pressureAltitude.value();}
+
+ /*! \brief Getter method for property with the same name
+ *
+ * @returns Property pressureAltitude
+ */
+ [[nodiscard]] QBindable bindablePressureAltitude() const {return &m_pressureAltitude;}
+
/*! \brief Getter function for the property with the same name
*
* @returns Property receivingHeartbeat
@@ -224,6 +248,7 @@ class TrafficDataSource_Abstract : public QObject {
return m_trafficReceiverSelfTestError;
}
+
signals:
/*! \brief Notifier signal */
void connectivityStatusChanged(QString newStatus);
@@ -267,15 +292,6 @@ class TrafficDataSource_Abstract : public QObject {
*/
void passwordStorageRequest(const QString& SSID, const QString& password);
- /*! \brief Pressure altitude
- *
- * If this class received pressure altitude information from a connected
- * traffic receiver, this information is emitted here. Pressure altitude is
- * the altitude shown by your altimeter if the altimeter is set to 1013.2
- * hPa.
- */
- void pressureAltitudeUpdated(Units::Distance);
-
/*! \brief Position info
*
* If this class received position information from a connected traffic
@@ -414,6 +430,16 @@ public slots:
*/
void setErrorString(const QString& newErrorString = QString());
+ /*! \brief Setter function for the property with the same name
+ *
+ * This method must be used by child classes to update the pressure altitude
+ * The class uses a timer internally to reset the position info to "invalid"
+ * after the time specified in PositionInfo::lifetime seconds.
+ *
+ * @param newPressureAltitude Pressure Altitude
+ */
+ void setPressureAltitude(Units::Distance newPressureAltitude);
+
/*! \brief Setter method for the property with the same name
*
* When set to 'true' a timer is stated that will automatically reset the
@@ -473,9 +499,9 @@ public slots:
Units::Distance m_trueAltitudeFOM; // Fig. of Merit
QTimer m_trueAltitudeTimer;
- // Pressure altitude of own aircraft. See the member m_trueAltitude for a
- // description how the timer should be used.
- Units::Distance m_pressureAltitude;
+ // Pressure altitude of own aircraft. The timer will reset the pressureAltitude
+ // to an invalid value if no data is received for a while.
+ QProperty m_pressureAltitude;
QTimer m_pressureAltitudeTimer;
// Heartbeat timer
diff --git a/src/traffic/TrafficDataSource_Abstract_FLARM.cpp b/src/traffic/TrafficDataSource_Abstract_FLARM.cpp
index fdad07666..99073cc6a 100644
--- a/src/traffic/TrafficDataSource_Abstract_FLARM.cpp
+++ b/src/traffic/TrafficDataSource_Abstract_FLARM.cpp
@@ -328,7 +328,7 @@ void Traffic::TrafficDataSource_Abstract::processFLARMMessageGPRMC(const QString
pInfo.setAttribute(QGeoPositionInfo::Direction, TT );
}
- emit positionUpdated( Positioning::PositionInfo(pInfo));
+ emit positionUpdated( Positioning::PositionInfo(pInfo, sourceName()) );
}
@@ -523,7 +523,7 @@ void Traffic::TrafficDataSource_Abstract::processFLARMMessagePFLAA(const QString
m_factor.setCallSign( GlobalObject::flarmnetDB()->getRegistration(targetID) );
m_factor.setHDist(hDist);
m_factor.setID(targetID);
- m_factor.setPositionInfo( Positioning::PositionInfo(pInfo) );
+ m_factor.setPositionInfo( Positioning::PositionInfo(pInfo, sourceName()) );
m_factor.setType(type);
m_factor.setVDist(vDist);
m_factor.startLiveTime();
@@ -818,5 +818,5 @@ void Traffic::TrafficDataSource_Abstract::processFLARMMessagePGRMZ(const QString
{
return;
}
- emit pressureAltitudeUpdated(barometricAlt);
+ setPressureAltitude(barometricAlt);
}
diff --git a/src/traffic/TrafficDataSource_Abstract_GDL90.cpp b/src/traffic/TrafficDataSource_Abstract_GDL90.cpp
index 58b8288e0..dacfecf74 100644
--- a/src/traffic/TrafficDataSource_Abstract_GDL90.cpp
+++ b/src/traffic/TrafficDataSource_Abstract_GDL90.cpp
@@ -289,10 +289,10 @@ void Traffic::TrafficDataSource_Abstract::processGDLMessage(const QByteArray& ra
m_pressureAltitude = Units::Distance::fromM( qQNaN() );
m_pressureAltitudeTimer.stop();
}
- emit pressureAltitudeUpdated(m_pressureAltitude);
+ setPressureAltitude(m_pressureAltitude);
// Update position information and continue
- emit positionUpdated( Positioning::PositionInfo(pInfo) );
+ emit positionUpdated( Positioning::PositionInfo(pInfo, sourceName()) );
return;
}
@@ -427,7 +427,7 @@ void Traffic::TrafficDataSource_Abstract::processGDLMessage(const QByteArray& ra
m_factor.setCallSign(callSign);
m_factor.setHDist(hDist);
m_factor.setID(id);
- m_factor.setPositionInfo( Positioning::PositionInfo(pInfo) );
+ m_factor.setPositionInfo( Positioning::PositionInfo(pInfo, sourceName()) );
m_factor.setType(type);
m_factor.setVDist(vDist);
m_factor.startLiveTime();
diff --git a/src/traffic/TrafficDataSource_Abstract_XGPS.cpp b/src/traffic/TrafficDataSource_Abstract_XGPS.cpp
index 007d6dc03..5aa3c3610 100644
--- a/src/traffic/TrafficDataSource_Abstract_XGPS.cpp
+++ b/src/traffic/TrafficDataSource_Abstract_XGPS.cpp
@@ -68,7 +68,7 @@ void Traffic::TrafficDataSource_Abstract::processXGPSString(const QByteArray& da
// Update position information and continue
if (_geoPos.isValid()) {
- emit positionUpdated( Positioning::PositionInfo(_geoPos) );
+ emit positionUpdated( Positioning::PositionInfo(_geoPos, sourceName()) );
setReceivingHeartbeat(true);
}
@@ -85,7 +85,7 @@ void Traffic::TrafficDataSource_Abstract::processXGPSString(const QByteArray& da
}
bool ok = false;
- QString const targetID = list[1];
+ QString const &targetID = list[1];
double const lat = list[2].toDouble(&ok);
if (!ok) {
return;
@@ -141,7 +141,7 @@ void Traffic::TrafficDataSource_Abstract::processXGPSString(const QByteArray& da
m_factor.setCallSign(callsign);
m_factor.setHDist(hDist);
m_factor.setID(targetID);
- m_factor.setPositionInfo( Positioning::PositionInfo(geoPositionInfo) );
+ m_factor.setPositionInfo( Positioning::PositionInfo(geoPositionInfo, sourceName()) );
m_factor.setType(Traffic::TrafficFactor_Abstract::unknown);
m_factor.setVDist(vDist);
m_factor.startLiveTime();
diff --git a/src/traffic/TrafficDataSource_Simulate.cpp b/src/traffic/TrafficDataSource_Simulate.cpp
index 738411e0e..ba860cb7d 100644
--- a/src/traffic/TrafficDataSource_Simulate.cpp
+++ b/src/traffic/TrafficDataSource_Simulate.cpp
@@ -61,7 +61,7 @@ void Traffic::TrafficDataSource_Simulate::sendSimulatorData()
geoInfo.setTimestamp( QDateTime::currentDateTimeUtc() );
if (geoInfo.isValid()) {
- emit positionUpdated( Positioning::PositionInfo(geoInfo) );
+ emit positionUpdated( Positioning::PositionInfo(geoInfo, sourceName()) );
setReceivingHeartbeat(true);
} else {
setReceivingHeartbeat(false);
@@ -82,5 +82,5 @@ void Traffic::TrafficDataSource_Simulate::sendSimulatorData()
emit factorWithoutPosition(*trafficFactor_DistanceOnly);
}
- emit pressureAltitudeUpdated(barometricHeight);
+ setPressureAltitude(barometricHeight);
}
diff --git a/src/traffic/TrafficFactor_DistanceOnly.h b/src/traffic/TrafficFactor_DistanceOnly.h
index 99dc68b90..a88c478b8 100644
--- a/src/traffic/TrafficFactor_DistanceOnly.h
+++ b/src/traffic/TrafficFactor_DistanceOnly.h
@@ -38,6 +38,7 @@ namespace Traffic {
class TrafficFactor_DistanceOnly : public Traffic::TrafficFactor_Abstract {
Q_OBJECT
+ QML_ELEMENT
public:
/*! \brief Default constructor
diff --git a/src/traffic/TrafficFactor_WithPosition.cpp b/src/traffic/TrafficFactor_WithPosition.cpp
index 4431e6c0f..03a94198d 100644
--- a/src/traffic/TrafficFactor_WithPosition.cpp
+++ b/src/traffic/TrafficFactor_WithPosition.cpp
@@ -19,10 +19,8 @@
***************************************************************************/
#include "GlobalObject.h"
-#include "GlobalSettings.h"
#include "navigation/Aircraft.h"
#include "navigation/Navigator.h"
-#include "positioning/PositionProvider.h"
#include "traffic/TrafficFactor_WithPosition.h"
@@ -110,7 +108,7 @@ void Traffic::TrafficFactor_WithPosition::updateDescription()
if (vDist().isFinite()) {
QString result = GlobalObject::navigator()->aircraft().verticalDistanceToString(vDist(), true);
- auto climbRateMPS = m_positionInfo.attribute(QGeoPositionInfo::VerticalSpeed);
+ auto climbRateMPS = m_positionInfo.verticalSpeed().toMPS();
if ( qIsFinite(climbRateMPS) ) {
if (climbRateMPS < -1.0) {
result += QStringLiteral(" ↘");
@@ -132,7 +130,6 @@ void Traffic::TrafficFactor_WithPosition::updateDescription()
}
m_description = newDescription;
emit descriptionChanged();
-
}
@@ -140,9 +137,11 @@ void Traffic::TrafficFactor_WithPosition::updateIcon()
{
// BaseType
QString baseType = QStringLiteral("noDirection");
- if (m_positionInfo.hasAttribute(QGeoPositionInfo::GroundSpeed) && m_positionInfo.hasAttribute(QGeoPositionInfo::Direction)) {
- auto GS = Units::Speed::fromMPS( m_positionInfo.attribute(QGeoPositionInfo::GroundSpeed) );
- if (GS.isFinite() && (GS.toKN() > 4)) {
+ if (m_positionInfo.groundSpeed().isFinite() && m_positionInfo.trueTrack().isFinite())
+ {
+ auto GS = m_positionInfo.groundSpeed();
+ if (GS.isFinite() && (GS.toKN() > 4))
+ {
baseType = QStringLiteral("withDirection");
}
}
@@ -168,5 +167,4 @@ void Traffic::TrafficFactor_WithPosition::updateValid()
}
TrafficFactor_Abstract::updateValid();
-
}
diff --git a/src/traffic/TrafficFactor_WithPosition.h b/src/traffic/TrafficFactor_WithPosition.h
index 67b0224a8..d05ef59f0 100644
--- a/src/traffic/TrafficFactor_WithPosition.h
+++ b/src/traffic/TrafficFactor_WithPosition.h
@@ -98,7 +98,7 @@ class TrafficFactor_WithPosition : public TrafficFactor_Abstract {
*/
[[nodiscard]] auto positionInfo() const -> Positioning::PositionInfo
{
- return Positioning::PositionInfo(m_positionInfo);
+ return m_positionInfo;
}
/*! \brief Setter function for property with the same name
@@ -136,7 +136,7 @@ class TrafficFactor_WithPosition : public TrafficFactor_Abstract {
// Property values
//
QString m_icon;
- QGeoPositionInfo m_positionInfo;
+ Positioning::PositionInfo m_positionInfo;
Units::Distance m_vDist;
Units::Distance m_hDist;
diff --git a/src/units/Speed.cpp b/src/units/Speed.cpp
index a396f9eae..309052a76 100644
--- a/src/units/Speed.cpp
+++ b/src/units/Speed.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2019-2021 by Stefan Kebekus *
+ * Copyright (C) 2019-2024 by Stefan Kebekus *
* stefan.kebekus@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -18,7 +18,6 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-#include "GlobalSettings.h"
#include "units/Speed.h"
diff --git a/src/units/Timespan.h b/src/units/Timespan.h
index 52f32f914..f469ba883 100644
--- a/src/units/Timespan.h
+++ b/src/units/Timespan.h
@@ -1,5 +1,5 @@
/***************************************************************************
- * Copyright (C) 2019-2023 by Stefan Kebekus *
+ * Copyright (C) 2019-2024 by Stefan Kebekus *
* stefan.kebekus@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
@@ -55,9 +55,10 @@ class Timespan {
*
* @returns time
*/
- static auto fromMS(double timeInMS) -> Timespan {
+ static Timespan fromMS(double timeInMS)
+ {
Timespan result;
- result.m_timeInS = qRound(timeInMS/1000.0);
+ result.m_timeInS = timeInMS/1000.0;
return result;
}