Android:正確な高度を取得する方法は?
質問
GPSのみを使用して高度の正確な測定値を取得する必要があります。
私は試した Location.getAltitude()
, 、しかし、それはひどく不正確です。何かアドバイス?
解決
スマートフォン /タブレットGPSの高度を使用することには2つの問題があります。
- 高度は、WGS84参照楕円体の上の高度です。地上レベルや海面上の高度ではありません。それについての詳細が次のとおりです。 http://www.gpspassion.com/forumsen/topic.asp?topic_id=10915. 。このエラーは修正できます。これが手でそれを行う方法の説明です: http://www.unavco.org/edu_outreach/tutorial/geoidcorr.html. 。 Web記事は計算機にリンクして、補正のためにジオイドの高さを取得します。この計算に利用できるWebサービスもあるかどうかはわかりません。
- GPS高度は、比較的安価なGPSレシーバーにとって非常に不正確です。これに関する記事は次のとおりです。 http://gpsinformation.net/main/altitude.htm. 。この種の不正確さに対処する1つの方法は、高度データをフィルタリングすることです。循環配列データ構造を使用して、最後の数個(4)の高度測定値を覚えていて、平均を計算しました。これにより、アプリケーションの垂直速度を比較的正確に読むことができました。
他のヒント
別の方法は、NMEA文字列を解析することです。 $ gpgga文 すでに海面上の修正された高度データが含まれています。
したがって、LocationManagerのNMEAストリングスのリスナーを作成し、メッセージを解析するだけです。
private GpsStatus.NmeaListener mNmeaListener = new GpsStatus.NmeaListener() {
@Override
public void onNmeaReceived(long timestamp, String nmea) {
parseNmeaString(nmea);
}
};
public void registerLocationManager(Context context) {
mLocationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
mLocationManager.addNmeaListener(mNmeaListener);
}
private void parseNmeaString(String line) {
if (line.startsWith("$")) {
String[] tokens = line.split(",");
String type = tokens[0];
// Parse altitude above sea level, Detailed description of NMEA string here http://aprs.gids.nl/nmea/#gga
if (type.startsWith("$GPGGA")) {
if (!tokens[9].isEmpty()) {
mLastMslAltitude = Double.parseDouble(tokens[9]);
}
}
}
}
ロケーションリスナーを介して受信した最後の場所オブジェクトの高度を交換するか、NMEAを介して新しい場所全体を解析できます。
GPSよりも高度を取得する他の方法があります。バロメーターを使用できますが、気圧センサーを備えたデバイスはまだ多くないため(新しいもののみ)。 Webサービスを使用して、目的のデータを取得することをお勧めします。
ここにあなたを助けるべき質問があります: Androidの経度と緯度で高度を取得します
新人のために、私はLocationManagerをrxjava Observablesにラップするライブラリを作成し、NMEA/GPGGA MRE情報から海面Altitutdeを取得するための観察可能なヘルパーを追加しました ここ
大きなテーブルでこれらのルックアップを行うAPIを提供するオープンソースCS-Mapなどのライブラリがあります。座標を指定すると、「実際の」オルソメートルの高さを取得するために、その場所の楕円体の高さに適用する必要がある高さのオフセットがわかります。
注:CS-Mapを以前に使用したことがあるので、それをプラグインするのはまったく簡単な5分間のジョブではありません。一連のLAT座標で単一のAPIを呼び出して取得するよりも複雑であることを事前に警告します高さを戻します。 私はもはやこの種の仕事をしていた会社で働いていないので、残念ながらコードを調べて、どのAPIを呼び出すかを正確に言うことはできません。
Google検索を今すぐ検索している(2019)、CS-MapはOsgeo、「オープンソースの地理空間財団「プロジェクト。同じ検索が私を導きました この古いCSマップwiki としても proj githubページ, 、ProjはCS-Mapと同様のプロジェクトであると思われます。
使用することをお勧めします nmealistener, 、Sladstaetterが提案したように 彼の答え. 。しかし、によれば NMEAドキュメント, 、「$ gpgga」は、あなたが取得できる唯一の文ではありません。 「GGA」文($ -GGA)を探す必要があります。
正規表現はそのために素晴らしいです、例:
@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!
}
}