From 8b2edc48018a939b93018e2d063f7e332e830a82 Mon Sep 17 00:00:00 2001 From: Tomas Mizera Date: Wed, 19 Nov 2025 13:09:43 +0100 Subject: [PATCH 1/3] Geoid separation support for external providers (#4176) --- app/position/positionkit.cpp | 12 ++++++++++++ app/position/positionkit.h | 4 ++++ app/qml/gps/MMGpsDataDrawer.qml | 14 ++++++++++++++ app/variablesmanager.cpp | 1 + 4 files changed, 31 insertions(+) diff --git a/app/position/positionkit.cpp b/app/position/positionkit.cpp index f2b65c224..92e3ddae0 100644 --- a/app/position/positionkit.cpp +++ b/app/position/positionkit.cpp @@ -212,6 +212,13 @@ void PositionKit::parsePositionUpdate( const GeoPosition &newPosition ) hasAnythingChanged = true; } + if ( !qgsDoubleNear( newPosition.elevation_diff, mPosition.elevation_diff ) ) + { + mPosition.elevation_diff = newPosition.elevation_diff; + emit geoidSeparationChanged( mPosition.elevation_diff ); + hasAnythingChanged = true; + } + if ( newPosition.hasValidPosition() != mHasPosition ) { mHasPosition = newPosition.hasValidPosition(); @@ -349,6 +356,11 @@ double PositionKit::altitude() const return mPosition.elevation; } +double PositionKit::geoidSeparation() const +{ + return mPosition.elevation_diff; +} + QgsPoint PositionKit::positionCoordinate() const { if ( mPosition.hasValidPosition() ) diff --git a/app/position/positionkit.h b/app/position/positionkit.h index 374ca497a..b8a6859de 100644 --- a/app/position/positionkit.h +++ b/app/position/positionkit.h @@ -30,7 +30,9 @@ class PositionKit : public QObject Q_PROPERTY( double latitude READ latitude NOTIFY latitudeChanged ) Q_PROPERTY( double longitude READ longitude NOTIFY longitudeChanged ) + Q_PROPERTY( double altitude READ altitude NOTIFY altitudeChanged ) + Q_PROPERTY( double geoidSeparation READ geoidSeparation NOTIFY geoidSeparationChanged ) // auxiliary property providing QgsPoint for lat/long/alt instead of separate properties Q_PROPERTY( QgsPoint positionCoordinate READ positionCoordinate NOTIFY positionCoordinateChanged ) @@ -84,6 +86,7 @@ class PositionKit : public QObject double latitude() const; double longitude() const; double altitude() const; + double geoidSeparation() const; QgsPoint positionCoordinate() const; bool hasPosition() const; @@ -127,6 +130,7 @@ class PositionKit : public QObject void latitudeChanged( double ); void longitudeChanged( double ); void altitudeChanged( double ); + void geoidSeparationChanged( double ); void positionCoordinateChanged( QgsPoint ); void hasPositionChanged( bool ); diff --git a/app/qml/gps/MMGpsDataDrawer.qml b/app/qml/gps/MMGpsDataDrawer.qml index d7b2f7597..f7b4d6f8f 100644 --- a/app/qml/gps/MMGpsDataDrawer.qml +++ b/app/qml/gps/MMGpsDataDrawer.qml @@ -316,6 +316,20 @@ MMComponents.MMDrawer { alignmentRight: Positioner.index % 2 === 1 } + + MMGpsComponents.MMGpsDataText { + width: parent.width / 2 + + title: qsTr( "Geoid separation" ) + value: { + if ( !__positionKit.hasPosition || Number.isNaN( __positionKit.geoidSeparation ) ) { + return qsTr( "N/A" ) + } + __inputUtils.formatNumber( __positionKit.geoidSeparation, 2 ) + " m" + } + + alignmentRight: Positioner.index % 2 === 1 + } } } diff --git a/app/variablesmanager.cpp b/app/variablesmanager.cpp index 375204f0a..16fdf184a 100644 --- a/app/variablesmanager.cpp +++ b/app/variablesmanager.cpp @@ -72,6 +72,7 @@ QgsExpressionContextScope *VariablesManager::positionScope() addPositionVariable( scope, QStringLiteral( "longitude" ), position.longitude ); addPositionVariable( scope, QStringLiteral( "latitude" ), position.latitude ); addPositionVariable( scope, QStringLiteral( "altitude" ), position.elevation ); + addPositionVariable( scope, QStringLiteral( "geoid_separation" ), position.elevation_diff ); addPositionVariable( scope, QStringLiteral( "horizontal_accuracy" ), getGeoPositionAttribute( position.hacc ) ); addPositionVariable( scope, QStringLiteral( "vertical_accuracy" ), getGeoPositionAttribute( position.vacc ) ); addPositionVariable( scope, QStringLiteral( "ground_speed" ), getGeoPositionAttribute( position.speed ) ); From b0fb84287e379d36d236f190c974ccc533283580 Mon Sep 17 00:00:00 2001 From: Matej Bagar Date: Fri, 12 Dec 2025 19:05:24 +0100 Subject: [PATCH 2/3] Cherry pick android 15 altitude fix --- .../android15_altitude_fix.patch | 68 +++++++++++++++++++ vcpkg/ports/qtpositioning/portfile.cmake | 3 +- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 vcpkg/ports/qtpositioning/android15_altitude_fix.patch diff --git a/vcpkg/ports/qtpositioning/android15_altitude_fix.patch b/vcpkg/ports/qtpositioning/android15_altitude_fix.patch new file mode 100644 index 000000000..453b830a2 --- /dev/null +++ b/vcpkg/ports/qtpositioning/android15_altitude_fix.patch @@ -0,0 +1,68 @@ +diff --git a/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java b/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java +index e4163b09..afb2889e 100644 +--- a/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java ++++ b/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java +@@ -112,6 +112,8 @@ class QtPositioning implements LocationListener + static private void addMslAltitude(Location location) + { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { ++ if (location.hasMslAltitude()) // Nothing to be done ++ return; + if (altitudeConverter == null) + altitudeConverter = new AltitudeConverter(); + try { +diff --git a/src/plugins/position/android/src/jnipositioning.cpp b/src/plugins/position/android/src/jnipositioning.cpp +index 2b2919fa..0abc2cad 100644 +--- a/src/plugins/position/android/src/jnipositioning.cpp ++++ b/src/plugins/position/android/src/jnipositioning.cpp +@@ -220,7 +220,7 @@ namespace AndroidPositioning { + return ret; + } + +- QGeoPositionInfo positionInfoFromJavaLocation(const jobject &location) ++ QGeoPositionInfo positionInfoFromJavaLocation(const jobject &location, bool useAltConverter) + { + QGeoPositionInfo info; + +@@ -241,8 +241,11 @@ namespace AndroidPositioning { + coordinate.setAltitude(value); + } + // MSL altitude, available in API Level 34+. +- // It will be available only if we requested it when starting updates. +- if (QNativeInterface::QAndroidApplication::sdkVersion() >= 34) { ++ // In API Level 34 it was available only if we manually added it. ++ // In API Level 35 (and potentially later), it's automatically added ++ // to the location object, so we need to use it *only* when the user ++ // set the relevant plugin parameter. ++ if (useAltConverter && QNativeInterface::QAndroidApplication::sdkVersion() >= 34) { + attributeExists = jniObject.callMethod("hasMslAltitude"); + if (attributeExists) { + const jdouble value = jniObject.callMethod("getMslAltitudeMeters"); +@@ -451,7 +454,7 @@ namespace AndroidPositioning { + if (location == nullptr) + return QGeoPositionInfo(); + +- const QGeoPositionInfo info = positionInfoFromJavaLocation(location); ++ const QGeoPositionInfo info = positionInfoFromJavaLocation(location, useAltitudeConverter); + + return info; + } +@@ -615,7 +618,6 @@ static void positionUpdated(JNIEnv *env, jobject thiz, QtJniTypes::Location loca + { + Q_UNUSED(env); + Q_UNUSED(thiz); +- QGeoPositionInfo info = AndroidPositioning::positionInfoFromJavaLocation(location.object()); + + QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); + if (!source) { +@@ -623,6 +625,10 @@ static void positionUpdated(JNIEnv *env, jobject thiz, QtJniTypes::Location loca + return; + } + ++ const bool useAltitudeConverter = source->useAltitudeConverter(); ++ QGeoPositionInfo info = ++ AndroidPositioning::positionInfoFromJavaLocation(location.object(), useAltitudeConverter); ++ + //we need to invoke indirectly as the Looper thread is likely to be not the same thread + if (!isSingleUpdate) + QMetaObject::invokeMethod(source, "processPositionUpdate", Qt::AutoConnection, diff --git a/vcpkg/ports/qtpositioning/portfile.cmake b/vcpkg/ports/qtpositioning/portfile.cmake index a5b211b1f..f4f3231b6 100644 --- a/vcpkg/ports/qtpositioning/portfile.cmake +++ b/vcpkg/ports/qtpositioning/portfile.cmake @@ -3,7 +3,8 @@ include("${SCRIPT_PATH}/qt_install_submodule.cmake") set(${PORT}_PATCHES devendor-poly2tri.patch - foregroundservice.patch) + foregroundservice.patch + android15_altitude_fix.patch) vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS FEATURES From 23b9d487408ff20272ab965afbed6c65bba69866 Mon Sep 17 00:00:00 2001 From: Matej Bagar Date: Mon, 15 Dec 2025 11:42:00 +0100 Subject: [PATCH 3/3] Hide geoid separation values for non external providers --- app/qml/gps/MMGpsDataDrawer.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/qml/gps/MMGpsDataDrawer.qml b/app/qml/gps/MMGpsDataDrawer.qml index f7b4d6f8f..b9b600c39 100644 --- a/app/qml/gps/MMGpsDataDrawer.qml +++ b/app/qml/gps/MMGpsDataDrawer.qml @@ -327,6 +327,7 @@ MMComponents.MMDrawer { } __inputUtils.formatNumber( __positionKit.geoidSeparation, 2 ) + " m" } + visible: __positionKit.positionProvider && __positionKit.positionProvider.type() === "external" alignmentRight: Positioner.index % 2 === 1 }