@Override
public void onNmeaReceived(final long timestamp, final String nmea) {
final Pattern pattern = Pattern.compile("\\$..GGA,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([+-]?\\d+(.\\d+)?),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$");
final Matcher matcher = pattern.matcher(nmea);
if (matcher.find()) {
final float altitude = Float.parseFloat(matcher.group(1));
// ...enjoy the altitude!
}
}
8条答案
按热度按时间5cnsuln71#
使用智能手机/平板电脑GPS的高度存在两个问题:
1.海拔高度是指WGS 84参考椭球体上方的海拔高度。它不是地平面或海平面以上的海拔高度。以下是更多细节:http://www.gpspassion.com/forumsen/topic.asp?TOPIC_ID=10915。此错误可以更正;下面是如何手动执行此操作说明:http://www.unavco.org/edu_outreach/tutorial/geoidcorr.html.该网络文章链接到计算器以获得用于校正的大地水准面高度;我不知道是否也有一个Web服务可用于此计算。
1.对于相对便宜的GPS接收器来说,GPS高度非常不准确。这里有一篇文章:http://gpsinformation.net/main/altitude.htm。科普这种不准确性的一种方法是过滤高度数据。我使用了一个圆形阵列数据结构来记住最后几个(我使用了4个)高度读数并计算平均值。这足以为我的应用程序获得相对准确的垂直速度读数。
kmb7vmvb2#
另一种方法是解析NMEA字符串。$GPGGA语句已经包含了海平面以上的校正高度数据。
因此,只需为您的LocationManager创建一个NMEA字符串的侦听器并解析消息:
您可以替换通过位置侦听器接收到的最后一个Location对象的高度,也可以通过NMEA解析整个新位置。
kzmpq1sx3#
另一种方法是从气压计测量高度。
通过使用压力,你可以计算用户的高度。我不确定这个的精度水平,以及它是否比其他答案的方法更准确。
通过使用hypsometric formula,您可以计算高度:
变量定义:
你可以从environment sensors中获得Android中的压力
pgky5nke4#
如果设备有一个气压计,那么使用它可以提高相对精度。我不是说使用气压计来计算相对于海平面的高度,因为这在很大程度上取决于天气条件。
你要做的是,当你知道设备有一个很好的定位时,以高精度值获得GPS高度。在这一点上,你获取气压并将该压力设置为参考。
当气压增加约12百帕时,您将知道您的高度降低约100米(https://en.wikipedia.org/wiki/Atmospheric_pressure“* 在海平面以上的低海拔地区,气压每100米降低约1.2千帕(12百帕)。
不要把这个值当作一个精确的值,但是由于树木覆盖视线和其他因素,GPS确定的高度变化很大,而气压计在这些条件下仍然非常精确。
下图是一次大约1小时20分钟的自行车骑行。起点和终点都在海拔477米左右,通过GPS确定。测量的压力为1015.223 hPa。
最低点是377米,测得的压力为1025.119百帕。因此,在这种情况下,100米的差异为10百帕。
最高点为550米,测得的压力为1007.765百帕。
终点是相同的高度,和完全相同的压力作为起始条件(压力可能会因天气条件而变化,但它没有)。温度下降约1°C,所以这一切都是相当恒定的。
包含许多变化的黑线是通过GPS测量的高度,镜像,但干净的线,是气压。它的变化很小,只是因为压力没有像GPS质量那样变化。这是一个非常平滑,非常精确的曲线。这不是由于滞后。这是用博世BME 280传感器测量的,它能够检测门的关闭。楼层检测,电梯方向,无人机的变化,噪音为0.2 Pa,相当于1.7 cm,高度变化400 m时误差为1 m。这些类型的传感器集成在一些智能手机中。例如,Pixel 3包含Bosch BMP 380。
如果你镜像压力图,如图中的黑色虚线所示,你会看到它与GPS高度非常接近。它比GPS精确得多,但唯一的问题是你不能把它当作一个绝对值。
GPS和压力的样本都是以1秒的间隔采集的,因此没有来自d3库的曲线平滑,导致一些错误的印象。
因此,也许重新调整压力约每10-30分钟,而你有一个全球定位系统良好的修复将给予你一个很好的基础,执行您的高度测量的压力之间。
ttp71kqs5#
还有其他方法来获得海拔比GPS.您可以使用气压计,但由于没有那么多的设备与气压传感器尚未(只有新的).我会建议使用Web服务来获取所需的数据.
这里有一个问题,应该可以帮助你通过:Get altitude by longitude and latitude in Android
hsgswve46#
对于新手,我做了一个库,将LocationManager Package 到rxjava observables中,并添加一些observable helper来从Nmea/GPGGA mre info here获取海平面高度
nhn9ugyo7#
有一些库,比如开源的CS-Map,它提供了一个API,可以在大型表格中进行这些查找。您指定坐标,它会告诉您需要应用到该位置的椭球高度以获得“真实世界”的正高的高度偏移。
注意:之前使用过CS-Map,将其插入并不是一件简单的5分钟工作。提前警告您,这比使用一组lat-long坐标调用单个API并返回高度要复杂得多。我不再在我们做这种工作的公司工作,所以不幸的是无法查找代码来确切地说明要调用哪个API。
现在(2019年)在谷歌上搜索它,似乎CS-Map已经合并到OSGeo的MetaCRS中,即“Open Source Geospatial Foundation”项目。同样的搜索使我找到了this old CS-Map wiki和the PROJ GitHub page,其中PROJ似乎与CS-Map类似。
4uqofj5v8#
我建议使用NmeaListener,就像sladstaetter在his answer中建议的那样。然而,根据NMEA文档,“$GPGGA”不是唯一可以得到的句子。您应该寻找任何“GGA”句子($--GGA)。
正则表达式非常适合于此,例如: