Android:如何获取准确的高度?
我需要仅使用 GPS 来准确测量高度。
我尝试了 Location.getAltitude()
,但这非常不准确。 有什么建议吗?
I need to get an accurate measurement of altitude using GPS only.
I tried Location.getAltitude()
, but that is terribly inaccurate.
Any advice?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
使用智能手机/平板电脑 GPS 的高度有两个问题:
There are two issues with using altitude of a smartphone / tablet GPS:
另一种方法是解析 NMEA 字符串。 $GPGGA 语句 已包含修正后的海拔高度数据。
因此,只需为 LocationManager 创建一个 NMEA 字符串侦听器并解析消息:
您可以替换通过位置侦听器接收到的最后一个 Location 对象的海拔高度,或者通过 NMEA 解析整个新位置。
Another way would be parsing NMEA strings. The $GPGGA sentence already contains the corrected altitude data above sea level.
So, simply create a listener to NMEA-strings for your LocationManager and parse the messages:
You can either replace the altitude of the last Location object received through a location listener, or parse the whole new location through NMEA.
另一种方法是通过气压计测量高度。
通过使用压力,您可以计算用户的海拔高度。我不确定它的精度水平以及它是否比其他答案的方法更准确。
通过使用测压公式,您可以计算海拔高度:
变量定义:
您可以从环境传感器获取android中的压力
Another approach is to measure the altitude from the barometer.
By using the pressure you can calculate the user's altitude. I'm uncertain of the precision level of this and whether it is more accurate than the other answer's approach.
By using the hypsometric formula you can calculate the altitude:
Variable definition:
You can get the pressure in android from the environment sensors
如果设备有气压计,那么使用它可以提高相对精度。我并不是想使用气压计来计算相对于海平面的高度,这可以在几个公式中找到,因为这高度依赖于天气条件。
当您知道设备具有良好的定位且具有高精度值时,您想要做的是获取 GPS 高度。此时,您获取气压并将该压力设置为参考。
当气压增加约 12 hPa 时,您会知道您的海拔高度降低了约 100 m ( https:// en.wikipedia.org/wiki/Atmospheric_Pressure “在海拔较低的地方,每升高 100 度,气压就会降低约 1.2 kPa (12 hPa)米。”)。
不要将该值视为精确值,但由于树木遮挡视线和其他因素,GPS 确定的高度变化很大,而气压计在这些条件下将保持非常精确。
下图是骑行时间约为 1 小时 20 分钟的情况。起点和终点相同,均在海拔 477 m 左右,由 GPS 确定。测得的压力为 1015.223 hPA。
最低点为377 m,实测气压为1025.119 hPa。因此,在这种情况下,100 m 会产生 10 hPa 的差异。
最高点550 m,实测气压1007.765 hPa。
终点与起始条件具有相同的高度和完全相同的压力(压力可能会因天气条件而变化,但事实并非如此)。温度下降了 1°C 左右,所以一切都相当稳定。
包含许多变化的黑线是通过 GPS 测量的高度,镜像但干净的线是气压。它的变化非常小,只是因为压力的变化不像 GPS 质量那样剧烈。这是一条非常平滑、非常精确的曲线。这不是由于滞后。这是用博世BME280传感器测量的,该传感器能够检测门的关闭、楼层检测、电梯方向、无人机,噪音为0.2 Pa(相当于1.7厘米),400m高度变化时误差为1m 。一些智能手机中集成了此类传感器。例如,Pixel 3 包含 Bosch BMP380。
如果镜像压力图(如黑色虚线所示),您会发现它与 GPS 高度非常匹配。它比 GPS 精确得多,但唯一的问题是你不能将其视为绝对值。
GPS 和压力的样本都是以 1 秒的间隔采集的,因此 d3 库没有进行曲线平滑,从而导致一些错误的印象。
,当您的 GPS 定位良好时,也许每 10-30 分钟重新调整一次压力将为您提供一个良好的基础,以便通过其间的压力进行高度测量。
If the device has a barometer, then using it can improve the relative accuracy. I don't mean to use the barometer to compute the height in relation to the sea level, as can be found in several formulas, as this is highly dependent of the weather conditions.
What you want to do is to get the GPS-altitude when you know that the device has a good fix, with high accuracy values. At that point you fetch the barometric pressure and set that pressure as a reference.
When the pressure increases around 12 hPa, you will know that your altitude decreased by around 100 m ( https://en.wikipedia.org/wiki/Atmospheric_pressure "At low altitudes above sea level, the pressure decreases by about 1.2 kPa (12 hPa) for every 100 metres." ).
Don't take that value as an exact, but variations in the altitude determined by GPS vary a lot due to trees covering the line of sight and other factors, while the barometer will remain very precise under those conditions.
The following graph is a bike ride of around one hour and 20 minutes in duration. Starting point and end point are the same at around 477 m above sea level, determined via GPS. The measured pressure is 1015.223 hPA.
The lowest point is 377 m, with a measured pressure of 1025.119 hPa. So in that case, 100 m make a difference of 10 hPa.
The highest point is 550 m, with a measured pressure of 1007.765 hPa.
Ending point is the same height, and the exact same pressure as the starting conditions (the pressure could have varied due to the weather conditions, but it didn't). The temperature dropped around 1°C, so it was all pretty constant.
The black line containing the many variations is the altitude measured via GPS, the mirrored, but clean line, is the barometric pressure. It has very little variation in it simply because the pressure doesn't vary as wild as the GPS-quality. It is a very smooth, very precise curve. This is not due to lag. This is measured with a Bosch BME280 sensor, which is capable of detecting the closing of a door, change of floor detection, elevator direction, drones, with a noise of 0.2 Pa which equals 1.7 cm and an error of 1m at 400m of height change. These kind of sensors are integrated in some Smartphones. For example, the Pixel 3 contains a Bosch BMP380.
If you mirror the pressure graph, as is shown with the dotted black line, you will see that it very closely matches the GPS altitude. It is much more precise than GPS, but the only problem is that you can't take it as an absolute value.
The samples of GPS and pressure were both taken in 1 second intervals, so there is no curve smoothing from the d3 library causing some false impressions.
So maybe readjusting the pressure around every 10-30 minutes while you have a GPS good fix will give you a good base to perform your altitude measurements by pressure in between.
除了 GPS 之外,还有其他方法可以获得高度。您可以使用气压计,但目前还没有那么多带有气压传感器的设备(只有新设备)。我建议使用网络服务来获取所需的数据。
这是一个应该可以帮助您解决的问题: 在 Android 中通过经度和纬度获取高度
There are other ways to get the altitude than by GPS. You can use the barometer but as there isn't that many devices with a barometric sensors yet (only the new ones). I will recommend to use a web service to acquire the desired data.
Here is a question which should help you through: Get altitude by longitude and latitude in Android
对于新手,我制作了一个库,将 LocationManager 包装到 rxjava observables 中,并添加一些可观察的帮助程序,以从 Nmea/GPGGA mre 信息获取海平面高度
For newcomers I made a library that wrap LocationManager into rxjava observables and add some observable helpers to get sea level altitutde from Nmea/GPGGA mre info here
有一些库(例如开源 CS-Map)提供了在大型表中执行这些查找的 API。您指定坐标,它会告诉您需要应用于该位置的椭球体高度以获得“真实世界”的正交高度的高度偏移。
注意:之前使用过 CS-Map,将其插入并不是完全简单的 5 分钟工作。提前警告您,它比使用一组经纬度坐标调用单个 API 并获取更复杂退了一个高度。 我不再在我们从事此类工作的公司工作,因此遗憾的是无法查找代码来准确说明要调用哪个 API。
现在(2019 年)在 google 上搜索它,看来 CS-Map 已合并到 OSGeo 中的 MetaCRS,即“开源地理空间基金会”项目。同样的搜索让我找到了这个旧的 CS-Map wiki 以及 PROJ GitHub 页面,其中 PROJ 似乎是与 CS-Map 类似的项目。
There are libraries, such as the open-source CS-Map which provide an API that do these lookups in large tables. You specify the coordinates, and it will tell you the height offset that needs to be applied to the ellipsoidal height at that location to get the "real-world" orthometric height.
Note: Having used CS-Map before, it isn't exactly straight-forward 5-minute job to plug it in. Warning you in advance that it is more complicated than calling a single API with a set of lat-long coordinates and getting back a height. I no longer work at the company where we were doing this kind of work, so unfortunately cannot look up the code to say exactly which API to call.
Doing a google search for it right now (2019), it seems CS-Map has been merged into MetaCRS in OSGeo, the "Open Source Geospatial Foundation" project. That same search led me to this old CS-Map wiki as well as the PROJ GitHub page, where PROJ seems to be similar project to CS-Map.
我建议使用 NmeaListener,如 sladstaetter
他的回答中建议。然而,根据 NMEA 文档,“$GPGGA”并不是您可以获得的唯一句子。您应该查找任何“GGA”句子 ($--GGA)。
正则表达式非常适合这一点,例如:
I would recommend using NmeaListener, as sladstaetter
suggested in his answer. However, according to NMEA documentation, "$GPGGA" is not the only sentence you can get. You should look for any "GGA" sentence ($--GGA).
Regular expressions are great for that, e.g.: