如何从 GPS LocationManager 获取 HDOP 或 VDOP 值?
Posted
技术标签:
【中文标题】如何从 GPS LocationManager 获取 HDOP 或 VDOP 值?【英文标题】:How do I get the HDOP or VDOP values from the GPS LocationManager? 【发布时间】:2011-10-23 00:39:10 【问题描述】:如何从 GPS LocationManager 获取HDOP or VDOP values?
【问题讨论】:
【参考方案1】:GPS_Location:
double lo=gps_loc.getLongitude();
double la=gps_loc.getLatitude();
水平精度:
int horiAcc=(int)(gps_loc.getAccuracy());
HDOP:
int hd= (int) (horiAcc/5);
【讨论】:
能否解释一下最后一个公式。为什么要制作 div 5? div 5 看起来像是某种近似值,osmtracker 使用了值 4:github.com/nguillaumin/osmtracker-android/blob/master/src/me/… 5 是 5 米,这是您使用的 GPS 设备的估计精度。您可以从芯片制造商规范中获得它(如果您知道手机中的芯片)。 4 或 5 米对手机来说是好的 - 如果您知道设备精度,您可以计算 HDOP,或者您可以直接从 NMEA 读取 HDOP,请参阅下面的答案。【参考方案2】:要获取 HDOP、VDOP、PDOP、DGPSID 和 AGEOFDGPSDATA 使用GpsStatus.NmeaListener 并实现onNmeaReceived()
protected String latestHdop;
protected String latestPdop;
protected String latestVdop;
protected String geoIdHeight;
protected String ageOfDgpsData;
protected String dgpsId;
@Override
public void onNmeaReceived(long timestamp, String nmeaSentence)
loggingService.OnNmeaSentence(timestamp, nmeaSentence);
if(Utilities.IsNullOrEmpty(nmeaSentence))
return;
String[] nmeaParts = nmeaSentence.split(",");
if (nmeaParts[0].equalsIgnoreCase("$GPGSA"))
if (nmeaParts.length > 15 && !Utilities.IsNullOrEmpty(nmeaParts[15]))
this.latestPdop = nmeaParts[15];
if (nmeaParts.length > 16 &&!Utilities.IsNullOrEmpty(nmeaParts[16]))
this.latestHdop = nmeaParts[16];
if (nmeaParts.length > 17 &&!Utilities.IsNullOrEmpty(nmeaParts[17]) && !nmeaParts[17].startsWith("*"))
this.latestVdop = nmeaParts[17].split("\\*")[0];
if (nmeaParts[0].equalsIgnoreCase("$GPGGA"))
if (nmeaParts.length > 8 &&!Utilities.IsNullOrEmpty(nmeaParts[8]))
this.latestHdop = nmeaParts[8];
if (nmeaParts.length > 11 &&!Utilities.IsNullOrEmpty(nmeaParts[11]))
this.geoIdHeight = nmeaParts[11];
if (nmeaParts.length > 13 &&!Utilities.IsNullOrEmpty(nmeaParts[13]))
this.ageOfDgpsData = nmeaParts[13];
if (nmeaParts.length > 14 &&!Utilities.IsNullOrEmpty(nmeaParts[14]) && !nmeaParts[14].startsWith("*"))
this.dgpsId = nmeaParts[14].split("\\*")[0];
从Lightweight GPS Logging Application For Android找到实现
【讨论】:
【参考方案3】:您可以从 GpsStatus 对象中的 GpsSatellite 对象中获得 DOP 值的粗略估计(技术上它是原始值)。这使得您无需解析 NMEA 字符串,而且您不仅可以获得 H(水平)、V(垂直)和 P(位置)DOP;您还可以获得 N(orth)、E(ast)、T(ime) 和 G(eometric) DOP。
对于每个 GpsSatellite 对象,您需要获取仰角、方位角、usedInFix 和 snr。 首先过滤掉所有卫星,只保留snr>0和usedInFix==true的卫星。
为每个卫星创建一个矩阵,其中每个卫星代表矩阵中的一行(表示为双精度数组)以创建我们将调用 A 的矩阵:
注意:要使其正常工作,您至少需要 4 颗卫星
el=高度,单位为 弧度
az=方位角,单位为弧度
Sv=GpsSatellite 的集合
A[n]=sin(Sv[n].az)*cos(Sv[n].el), cos(Sv[n].az)*cos(Sv[n].el), sin (Sv[n].el), 1d
有趣的部分来了
DOP矩阵方程如下
At = 转置矩阵 A
(At*A)^-1 = inverse(转置(A).times(A)) =
EDOP^2 x x x x NDOP^2 x x x x VDOP^2 x x x x TDOP^2明显的 DOP:
EDOP = sqrt(EDOP^2)
NDOP = sqrt(NDOP^2)
VDOP = sqrt(VDOP^2)
TDOP = sqrt(TDOP^2)
派生的 DOP:
GDOP = sqrt(EDOP^2+NDOP^2+VDOP^2+TDOP^2)
HDOP = sqrt(EDOP^2+NDOP^2)
PDOP = sqrt(EDOP^2+NDOP^2+VDOP^2)
【讨论】:
对于所有想知道这个数学从何而来的人,它来自books.google.com/…。我使用弧度而不是度数的原因是因为 java 的 Math.sin 和 Math.cos 需要弧度【参考方案4】:Accuracy 通常指位置类中 GPS 的 HDOP。但是,如果您想要两者都需要,您可以尝试 NmeaListener 获取原始 NMEA 字符串并对其进行解析以获取 HDOP 和 VDOP。
【讨论】:
【参考方案5】:您需要注册一个NMEAListener
并尝试解析GSA
语句(包含HDOP、VDOP 和PDOP)或GGA
语句(其中包含用于修复的HDOP)。
有关详细信息,请参阅 NMEA 0183 标准。
【讨论】:
以上是关于如何从 GPS LocationManager 获取 HDOP 或 VDOP 值?的主要内容,如果未能解决你的问题,请参考以下文章
当 gps 关闭时,.isProviderEnabled(LocationManager.NETWORK_PROVIDER) 总是返回 false?
如何不断地将 GPS 数据从 android 发送到服务器,直到应用程序关闭
无法通过 LocationManager.GPS_PROVIDER 获取 GPS 坐标
不适用于 Android Studio-locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this)