Q: How can I fix the GPS altitude display?

Q: How can I fix the GPS altitude display?

Problem is, that the displayed altitude of GPSInfo and OSM Scout is 57 meters too high (the same value at both apps). I tested on the shore (abt 1 or 2 m ASL) and also at 2 locations, where I exactly know the real altitude ASL.
The error is a summand (57m) and not a factor or percentage. Always the same number of meters at all altitudes.

Trying to fix this, I analyzed the GPS Info’s .qml files. There I found, that altitude is a display of a variable named
‘providers.position.position.coordinate.altitude’.

Where does this variable come from? What is the chain from the GPS device’s data output until it comes to the value of this variable? Who knows?

Thanks for any help!

Isn’t that a variable difference related to the geographic latitude, caused by the fact that the earth is no exact sphere? IIRC the difference is about 42 m in my location.
To solve the issue, you would have to calculate the difference from the current latitude using some formula…

Yes I can imagine that SFOS simply displays the raw data from GPS receiver while some licenced and expensive other systems have a table of WGS84 reference ellipsoid to correct altitude data for different places on earth.

Now I made it quick and dirty:
I changed code in the .qml files of GPSIInfo.

/usr/share/harbour-gpsinfo/qml/pages/CoverPage.qml

line 63
change
return locationFormatter.roundToDecimal(providers.position.position.coordinate.altitude, 2) + " m"
to
return locationFormatter.roundToDecimal(providers.position.position.coordinate.altitude - settings.altitudeOffset, 2) + " m"

/usr/share/harbour-gpsinfo/qml/pages/FirstPage.qml

Line 95, the same as above.
Works for this location (La Palma Island). Hope that altitude offset is the same on the whole island and will again check with an official geographic survey point and on the shore and will report here soon.

edit:
This is the tweak for the display in feet if units is set to imperial in settings:

return locationFormatter.roundToDecimal((providers.position.position.coordinate.altitude - settings.altitudeOffset) * 3.2808399, 2) + " ft"

(Replace 57 with your individual display offset.)
edit: settings.altitudeOffset is the variable from the new slider, see below.

(I will try to copy and modify the code from the Update Interval slider for altitude calibration)

In /usr/share/harbour-gpsinfo/qml/pages/ I could now make a second slider, copying and modifying the one for Update Interval. Starting from line 137:

            Label {
                anchors.left: parent.left
                anchors.leftMargin: Theme.paddingMedium * 2
                text: qsTr("Update interval")
            }

            Slider {
                minimumValue: 1
                maximumValue: 120
                stepSize: 1
                value: settings.updateInterval
                valueText: value + "s"
                width: parent.width
                onReleased: settings.updateInterval = value
            }

            Label {
                anchors.left: parent.left
                anchors.leftMargin: Theme.paddingMedium * 2
                text: qsTr("Altitude Offset")
            }

            Slider {
                minimumValue: -100
                maximumValue: 100
                stepSize: 1
                value: settings.altitudeOffset
                valueText: value + "m"
                width: parent.width
                onReleased: settings.altitudeOffset = value
            }

This works, now the slider occurs in the settings page between the Update Interval slider and the Magnetic Declination input field. The lines in my post #3 looks now this way:

//                            return locationFormatter.roundToDecimal(providers.position.position.coordinate.altitude, 2) + " m"
                            return locationFormatter.roundToDecimal(providers.position.position.coordinate.altitude - settings.altitudeOffset, 2) + " m"
                        } else {
//                            return locationFormatter.roundToDecimal(providers.position.position.coordinate.altitude * 3.2808399, 2) + " ft"
                            return locationFormatter.roundToDecimal((providers.position.position.coordinate.altitude - settings.altitudeOffset) * 3.2808399, 2) + " ft"

It works if a value is set manually after going to the settings page and setting some value, but GPSInfo doesn’t store the setting made here. After each app start it has to be set new. If not, the Altitude shows ‘NaN m’.

What can I do that the app remembers the setting at next app start? What can I do to have a default value of 0 if nothing is set by user?

Thanks for any help!

What exactly is the point of making this a configurable value that only applies in a certain area?
Why not go fishing for data to enable a map app to show this, if they don’t already?

OSM Scout and Pure Maps also display the same wrong altitude.
On my next journey to another part of the world I’ll check if the altitude displays the same 57m wrong or another value. Hence and for fun I made it adjustable.

edit: @attah it’s meant in the same way as the calibration of an altimeter of an airplane at the airport on a location with a well known altitude.

you could instead enter a formula with a correction depending on the longitudinal coordinate. This should have only one parameter if you assume perfect ellipsoidal form, i.e. the excentricity of earth

1 Like

You have to keep in mind 3 important things:

  1. GPS altitude is above the Earth ellipsoid, while sea level is the geoid height. This can lead to discrepancy between GPS height and sea level.
  2. By design, GPS height is much less accurate than GPS coordinates on the Earth surface.
  3. All the world lives happily with GPS reported height.
1 Like

I’ve had the same or similar problems you seem to experience. I’ve included elevation in my speedometer applications, of which I’ve always felt was quite inaccurate, sometimes double what I’m expecting or think I should have. Either other apps have been developed incorrectly, or you’re not getting a reliable reading from comparable sources.

I use whatismyelevation.com. Here you can put your full address or use your device location (GPS), gps is best

As a result of the data from the above website using the devices GPS, I note that one of my speedometer apps, is very close to the reading given by whatsmyelevation.com (warning, this site is awkward to use on sailfish browser, but it does yield eventually).

1 Like

My 2 cents: The height difference between geoid end WGS84 ellipsoid at La Palma is about 44 meters. So that explains most of what @Seven.of.nine is seeing, but not all.

3 Likes

@jameson Thanks for information! I did this small hack more for fun than because I need it urgently.

Yes, of course. Bottom line is that to get accurate height you will be better off with an altimeter. GPS was never designed to be an accurate height reporting system. Height is just a “by-product” of localization.

2 Likes

An altimeter is also not that accurate, because it relies on measurement of air pressure and that also changes with the weather

The last problem is to make GPSInfo remember the ‘settings.altitudeOffset’ permanently, the same way as Update Interval is remembered. At the moment I always have to set the offset value new at every app start. Otherwise ‘NaN’ is displayed in the Altitude field and the setting jumps back to 0 (zero).

What can I do to make GPSInfo remember the setting at next launching time?

You can use nemo.config to recall your value, something like this;

import Nemo.ConfigurationGroup 1.0

Label {
    id: myOffset
    text: Math.max(src.position.coordinate.altitude) ? Math.max(src.position.coordinate.altitude).toFixed(1) : "n/a"
} 

ConfigurationGroup {
    id: settings
    path: "/apps/harbour-myapp"
}
Component.onCompleted: {
    myOffset.text = settings.value("myOffsetText", "0")
}
Component.onDestruction: {
    settings.setValue("myOffsetText", myOffset.text)
}
1 Like

Thank you so much @Edz but this is too complex for me. But I could move the Altitude Offset setting to the FirstPage.qml this way by inserting the slider code between the GPS data display and the Compass display:

            InfoField {
                label: qsTr("Satellites in use / view")
                visible: settings.showSatelliteInfoApp
                value: providers.gps.active ? providers.gps.numberOfUsedSatellites + " / " + providers.gps.numberOfVisibleSatellites : "-"
            }
// begin of insertion
            SectionHeader {                                                                               
                anchors.left: parent.left                                                                
                anchors.leftMargin: Theme.paddingMedium * 2                                  
                text: "Altitude Offset"                                           
            }                                                                          
                                                                                                  
            Slider {                                                                             
                minimumValue: -100                                                              
                maximumValue: 100                                                       
                stepSize: 1                                                            
                value: settings.altitudeOffset
                valueText: value + "m"                                                           
                width: parent.width                                                          
                onReleased: settings.altitudeOffset = value                             
            }                                                                          
// end of insertion
            SectionHeader {
                visible: settings.showCompassDirectionApp
                text: "Compass"
            }

Then I replaced the SettingsPage.qml with the original backup file.

So I have the slider visible on app start, no more need to go into settings, and now I can set the value easy on app start and so the problem is solved.

Thank you all very much for help!! :star_struck: :smile: :star_struck:

2 Likes

It’s not the same every day, there are small differences abt +/- 10 meters. Today the deviation is in fact 44 meters!

But that is just GPS inaccuracy, right? The physical height profile should not change over (short) times

Right. The GPS altitude accuracy is about +/- 23 meters, so I’d say that after adjusting by 44 meters you are within that range.

2 Likes

Yes @vige , real altitude + 44m +/- 23m matches the displayed value good. So everything’s fine, nothing is broken.

Everything’s inside the tolerances @davidrasch , the physical height profile didn’t change significantly since the last volcano eruption in 2021. But seriously, the geologists with their high precision equipment really can measure a movement of the island surface in a range of some decimeters in a time range of days or weeks. But in normal life, it’s quiet now (until the next eruption).