it-swarm.com.de

Android: Wie bekomme ich eine genaue Höhe?

Ich brauche eine genaue Höhenmessung nur mit GPS.

Ich habe Location.getAltitude() ausprobiert, aber das ist furchtbar ungenau.

44
ask

Bei der Verwendung der GPS-Höhe eines Smartphones/Tablets gibt es zwei Probleme:

  1. Die Höhe ist die Höhe über dem Referenzellipsoid WGS84. Es ist nicht die Höhe über dem Boden oder dem Meeresspiegel. Hier ist mehr Details dazu: http://www.gpspassion.com/forumsen/topic.asp?TOPIC_ID=10915 . Dieser Fehler kann korrigiert werden. Hier ist eine Beschreibung, wie das von Hand gemacht wird: http://www.unavco.org/edu_outreach/tutorial/geoidcorr.html . Der Web-Artikel enthält einen Link zu einem Taschenrechner, um die Geoidhöhe zur Korrektur abzurufen. Ich weiß nicht, ob für diese Berechnung auch ein Webservice verfügbar ist.
  2. Die GPS-Höhe ist für relativ billige GPS-Empfänger fürchterlich ungenau. Hier ist ein Artikel dazu: http://gpsinformation.net/main/altitude.htm . Eine Methode, um mit dieser Art von Ungenauigkeit fertig zu werden, besteht darin, die Höhendaten zu filtern. Ich verwendete eine kreisförmige Array-Datenstruktur, um mich an die letzten (ich verwendete 4) Höhenmessungen zu erinnern und den Durchschnitt zu berechnen. Dies reichte aus, um für meine Anwendung eine relativ genaue Messung der Vertikalgeschwindigkeit zu erhalten.
50
Stefan

Ein anderer Weg wäre das Parsen von NMEA-Strings. Der $ GPGGA-Satz enthält bereits die korrigierten Höhendaten über dem Meeresspiegel. 

Erstellen Sie einfach einen Listener für NMEA-Zeichenfolgen für Ihren LocationManager und analysieren Sie die Nachrichten: 

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]);
                }
            }
        }
    }

Sie können entweder die Höhe des zuletzt über einen Standortlistener empfangenen Location-Objekts ersetzen oder den gesamten neuen Standort über NMEA analysieren. 

3
sladstaetter

Es gibt andere Wege, um die Höhe zu ermitteln, als per GPS. Sie können das Barometer verwenden, aber es gibt noch nicht viele Geräte mit barometrischen Sensoren (nur die neuen). Ich werde empfehlen, einen Webservice zu verwenden, um die gewünschten Daten zu erhalten. 

Hier ist eine Frage, die Ihnen helfen sollte: In Android Höhe und Breite berechnen

1
7heViking

Es gibt Bibliotheken wie die Open-Source-CS-Map, die eine API bereitstellen, die diese Suchvorgänge in großen Tabellen ausführt. Sie geben die Koordinaten an und erfahren, welcher Höhenversatz auf die Ellipsoidhöhe an dieser Stelle angewendet werden muss, um die "reale" orthometrische Höhe zu erhalten.

Hinweis: Nachdem Sie zuvor CS-Map verwendet haben, ist es nicht ganz einfach, es in 5 Minuten einzubinden. Sie werden im Voraus gewarnt, dass es komplizierter ist, eine einzelne API mit einem Satz von Lat-Long-Koordinaten aufzurufen und abzurufen eine Höhe zurück. Ich arbeite nicht mehr in dem Unternehmen, in dem wir diese Art von Arbeit ausgeführt haben, und kann daher leider nicht im Code nachschlagen, um genau anzugeben, welche API aufgerufen werden soll.

Bei einer aktuellen Google-Suche (2019) scheint CS-Map in OSGeo, dem Projekt " Open Source Geospatial Foundation ", mit MetaCRS zusammengeführt worden zu sein. Dieselbe Suche führte mich zu diesem alten CS-Map-Wiki sowie der PROJ-GitHub-Seite , wo PROJ ein ähnliches Projekt zu sein scheint wie CS-Map.

0
Stéphane

Ein anderer Ansatz besteht darin, die Höhe vom Barometer zu messen. 

Mit Hilfe des Drucks können Sie die Höhe des Benutzers berechnen. Ich bin mir nicht sicher, wie genau dies ist und ob es genauer ist als der Ansatz der anderen Antwort. 

Mit der hypsometrischen Formel können Sie die Höhe berechnen: 

 hypsometric formula

Variablendefinition:

P0: Sea-level pressure 
P: Atmospheric pressure 
T: Temperature 

Sie können den Druck in Android von den Umgebungssensoren erhalten

SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE,pressure)
0
Jonas Praem

Für Neulinge habe ich eine Bibliothek erstellt, die LocationManager in rxjava-Observables einbindet und einige beobachtbare Helfer hinzufügt, um die Meereshöhe von Nmea/GPGGA zu ermitteln. Weitere Informationen hier

0
Samuel Eminet

Ich würde empfehlen, NmeaListener zu verwenden, wie sladstaetter in seine Antwort vorschlug. Laut NMEA-Dokumentation ist "$ GPGGA" jedoch nicht der einzige Satz, den Sie erhalten können. Sie sollten nach einem "GGA" -Satz ($ - GGA) suchen.

Dafür sind reguläre Ausdrücke gut geeignet, z.

@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!
    }
}
0
Berťák