-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support altitude conversion between mean sea level (MSL) and WGS84 #704
Comments
This issue has been automatically marked as stale because it has not had recent activity. Please comment here if it is still valid so that we can reprioritize. Thank you! |
Still valid |
This issue has been automatically marked as stale because it has not had recent activity. Please comment here if it is still valid so that we can reprioritize. Thank you! |
This issue has been automatically marked as stale because it has not had recent activity. Please comment here if it is still valid so that we can reprioritize. Thank you! |
Related to this issue (and further justifying the need for a canonical source of altitude MSL) - there seems to be a bug impacting NMEA sentences which results in the wrong MSL altitude being returned: I've observed this on two devices (Pixel 5 and Samsung Galaxy S21+), but based on anecdotal evidence from others it seems to be more widespread. The error seems to be larger on some devices than others - see also barbeau/gpstest#503. |
I started looking into what it would take for apps (or AMU) to bundle their own geoid model to be able to calculate the altitude MSL value (H) themselves. In short, to bundle the latest EGM2008 model adds around 16-17MB to the app APK size. OpenTracks is one open-source app that has already done this:
They bundle the geographiclib EGM2008 model: The resulting OpenTracks APK size is 21MB. More notes are here. I believe the impact on AMU would be the same additional 16-17MB to add this feature (it's currently about 217KB). @arriolac Given what appear to be widespread issues with altitude MSL quality in NMEA streams, and the sizeable impact of adding the geoid model to an app or library to be able to calculate the geoid offset ourselves, it really seems like the best place for this functionality to live is within the Android Location API, especially if the device already has this knowledge somewhere. I added a comment to this effect on the above AOSP issue at: |
EGM96 is around only 2MB and it seems good enough for me. |
@sudokai That's true, although the EGM96 2MB file is also at a lesser grid resolution (15 vs 5 minutes) than the smallest EGM2008 model. I think "good enough" certainly depends on your use case. Here's the full table of the different models and their resolution (grid) and size from GeographicLib for reference:
|
I've opened a feature request issue for a reliable first-class Android API to get the H and N values directly from the platform (vs parsing NMEA sentences or bundling your own geoid model) on the main Android issue tracker here: Please star it if you'd like to see a solution directly in Android! If implemented this would solve the problem presumably for Android T and higher, although we still need a solution for Android S and lower, so this ticket is still relevant. |
This issue has been automatically marked as stale because it has not had recent activity. Please comment here if it is still valid so that we can reprioritize. Thank you! |
This issue has been automatically marked as stale because it has not had recent activity. Please comment here if it is still valid so that we can reprioritize. Thank you! |
Hi, this is a great thread! What's the progress on this? I was investigating exactly the same issue on the Qt platform for Android, the bug report is here: https://bugreports.qt.io/browse/QTBUG-106049 |
@junwoo091400 I would suggest starring this feature request for Android to directly support a dedicated API for this info - https://google.com/issues/195660815. You can also "thumbs up" this GitHub issue to vote for it. |
Looks like this has been quietly added in AOSP, in
|
@rockgecko-development You're right! Support for this feature is live in Android U DP1, so I'm going to close this issue. You can also use this API to get the geoid offset at a lat/lon by passing in a location with a lat/lon and with WGS84 altitude 0 - you will get the negative geoid offset back via So something like: location.setLatitude(...);
location.setLongitude(...);
location.setAltitude(0);
altitudeConverter.addMslAltitudeToLocation(context, location);
double geoidOffset = -LocationCompat.getMslAltitudeMeters(location); Note that it shouldn't be run on the main thread because it potentially does I/O. Thanks to everyone that worked on this in the Android team, it will be a very helpful utility! And thanks to everyone who upvoted the Google issue to express their interest in the feature. |
Is your feature request related to a problem? Please describe.
Altitude is commonly represented using two different units: meters above mean sea level (MSL), and meters above the WGS84 ellipsoid. This is a good article describing the difference between the two representations:
https://www.esri.com/news/arcuser/0703/geoid1of3.html
On Android, the Location API provides location altitude in WGS84:
https://developer.android.com/reference/android/location/Location.html#getAltitude()
However, this is problematic if you want to display this altitude to end users, who are more commonly familiar with MSL altitude. In fact, if you display WGS84 altitude to users, many of them will report this as an error in altitude. Additionally, if you want to allow users to enter altitude into an app, users again want to enter this as MSL. Here are some examples of user preferences:
Therefore, a method to convert between MSL and WGS84 altitude is needed. However, this conversion isn't trivial because the difference between MSL and WGS84 altitudes changes based on where you are located on the surface of Earth.
Describe the solution you'd like
Provide a utility method to convert between WGS84 and MSL altitude values.
We would need to bundle a lookup table to find the offset between WGS84 and MSL altitudes at a given latitude and longitude.
See https://github.com/barbeau/earth-gravitational-model for a project I started working on to port some of the GeoTools library to Android to do this operation. The plain text version of the lookup table (egm180.nor) is 700KB uncompressed outside the app. Additional tests would need to be done to determine the size of the lookup table when bundled with the library, and if additional compression would be helpful (e.g., storing in protocol buffer format instead of plain text).
GeoTools is licensed under L-GPL, so we couldn't adopt that code directly, but the GeoTools implementation of EarthGravitationalModel has this header:
So the original Fortran implementation and the egm180.nor file are public domain. There may be other OSS implementations I'm not aware of too that could be used as building blocks.
Describe alternatives you've considered
Location.getAltitudeMsl()
). However, it's not clear if all GNSS receiver chipsets provide MSL altitude that could be passed through the Android framework and if AOSP would support this change, although in my experience this data is readily available from many handsets via NMEA (see below). This solution doesn't help if you want to do MSL<->WGS84 conversion from a source other than the Location API.$GPGGA
sentences. Android allows GNSS chipset OEMs to provide NMEA sentences via the Android Location OnNmeaMessageListener API. However, there is no guarantee that a particular device will support MSL altitude via NMEA - it's not required by Android. And similar to above, this only helps with locations from the Location API.Location.getWgs84MslOffset(lat, lon)
) - This is a generalized solution that would work for converting any altitude but is more involved that the above Location API-based solution as it would imply native layer implementing/exposing the lookup database. Unclear if this would be supported by OEMs and/or AOSP.Additional context
The text was updated successfully, but these errors were encountered: