Understanding GPS Elevation and Geoidal Separation

Thursday, 3 July 2025

I like climbing hills and mountains, particularly in the Lake District, and whenever I go there with my wife and dogs, we try to go somewhere new. A decent map is valuable, and so I've been using the Ordnance Survey OS Maps app. A monthly subscription gives access to high-quality maps with detailed information about the terrain, ideal for hiking. These maps can be downloaded for offline use, essential when there is no mobile signal. The app also allows route planning and tracking. I usually subscribe for a month when I need it, and then unsubscribe after the holiday.

Crag Hill summit with dogs
At the trig point on top of Crag Hill, altitude 839 metres.

However, I found a problem. When following a route, the app does not properly report the elevation. For example, the following screenshot was taken at around the same time as the picture shown above. I have climbed Crag Hill (Eel Crag) and I am standing at the summit. The elevation written on the map is 839 metres. However, the elevation reported by the app is 889 metres.

app screenshot Crag Hill
Crag Hill summit. Altitude 839 metres, but the app reports 889 metres.

Here's a similar result on Knott Rigg. The elevation is 556 metres on the map but 615 metres in the app.

app screenshot Knott Rigg
Knott Rigg summit. Altitude 556 metres, but the app reports 615 metres.

This difference is not very helpful. It can be difficult to tell how much more climbing is needed to reach the summit! At first, I thought it must be a random error. But I found that it always seemed to be 50 metres, all the time, on every mountain we climbed. As the error seemed to be so predictable, I tried to trace the cause.

Initially, I didn't find much helpful information online. The effect has been noticed by others, but GPS inaccuracy is normally blamed on poor-quality engineering, cheap GPS receivers, the inherent limitations of GPS, or more conspiratorial effects such as deliberate jamming. Some phones can apparently determine elevation using air pressure sensors, and this has also been blamed for inaccuracy.

The breakthrough was setting up a GPS receiver alongside my phone and connecting it to a laptop via a serial cable. The GPS receiver sends time and position data to the laptop in the NMEA 0183 format which has become a universal standard for GPS data. Part of the output contained the following string:

$GNGGA,183130.00,5436.03999,N,00307.99222,W,1,09,4.04,89.2,M,49.6,M,,*61

This contains the time, latitude and longitude, but the two fields that really caught my attention were these:

$GNGGA,183130.00,5436.03999,N,00307.99222,W,1,09,4.04,89.2,M,49.6,M,,*61

The first of these was the same as the elevation shown on the map, in this case 89.2m (I was staying in Keswick). When the second value 49.6m is added to the first value, the result is the elevation shown in the OS app: 89.2 + 49.6 = 139m.

According to this useful NMEA 0183 guide, these fields are:

  • Antenna Altitude above/below mean-sea-level (geoid) (in meters)
  • Geoidal separation, the difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid

This was the explanation I'd been looking for. The app's reported elevation is from GPS, not the map, and the GPS elevation in the app is the distance from the WGS-84 ellipsoid. This led me to find out the following, from here and here amongst other places.

  • The ellipsoid is a perfectly smooth, mathematically-defined 3D shape, approximately the same shape as the Earth. The centre of the ellipsoid is Earth's centre of mass.
  • The geoid is a model of Earth assuming that there are no surface features such as mountains and hills. Like Waterworld (1995). The geoid isn't exactly the same as the ellipsoid because Earth has uneven gravity.

In every location, there is some offset between the ellipsoid and the geoid. In the Lake District, this offset is about 50m.

Some GPS receivers are aware of this offset, which varies by location. My second GPS receiver has the feature, and so does my wife's iPhone, but my Android phone does not. I tested the Android API call to getMslAltitudeMeters() but it does not work on my phone: the information is not available. Hence, the OS Maps app has fallen back to using the ellipsoid altitude, and because the geoidal separation is not zero, this doesn't correspond to the elevation on the map.

I wrote to Ordnance Survey to ask if the app could compensate for this error in some way. For example, it could use the map data to determine the elevation, or use an internal model of the geoid to add the offset. Aside from displaying contours, the app is aware of the height of each point on the map (and is able to render the map in 3D) so the data does exist. It would be nice if the app could at least warn about a discrepancy (e.g. if hasMslAltitude() returns false). They noted the suggestion.

In the meantime, if you are wondering why your phone's report of elevation doesn't correspond to the map when you are standing on the ground, then "geoidal separation" could be the answer. Geoidal separation does not change significantly within the distance that someone could walk in a day, so if you determine the local separation at the beginning of your walk, it should stay the same throughout the day.