Domanda

Ho bisogno di ottenere una misura accurata di altitudine tramite GPS solo.

Ho provato Location.getAltitude(), ma che è terribilmente impreciso.Qualche consiglio?

È stato utile?

Soluzione

Esistono due problemi con l'utilizzo dell'altitudine di uno smartphone / tablet GPS:

  1. L'altitudine è l'altitudine sopra l'ellissoide di riferimento WGS84. Non è l'altitudine fuori dal livello del suolo o il livello del mare. Ecco più dettagli su questo: http://www.gpspassaon.com/forumsen/topic.asp?topic_id=10915. Questo errore può essere corretto; Ecco una descrizione come farlo a mano: http://www.unavco.org/edu_outreach/tutorial/geoidcor.html. L'articolo Web si collega a un calcolatore per ottenere l'altezza del geoide per la correzione; Non so se esiste anche un servizio Web disponibile per questo calcolo.
  2. L'altitudine GPS è terribilmente imprecisa per i ricevitori GPS relativamente economici. Ecco un articolo su questo: http://gpsinformation.net/main/altitude.htm. Un metodo per far fronte a questo tipo di inesattezza è filtrare i dati di altitudine. Ho usato una struttura di dati dell'array circolare per ricordare le ultime letture di altitudine (ho usato 4) e calcolare la media. Questo è stato sufficiente per ottenere una lettura relativamente accurata della velocità verticale per la mia applicazione.

Altri suggerimenti

Un altro modo sarebbe analizzare le corde NMEA. Il $ Gpgga frase Contiene già i dati di altitudine corretti al di fuori del livello del mare.

Quindi, crea semplicemente un ascoltatore a NMEA-Strings per la tua posizione e analizza i messaggi:

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

È possibile sostituire l'altitudine dell'ultimo oggetto di posizione ricevuto tramite un ascoltatore di posizione o analizzare l'intera nuova posizione tramite NMEA.

Esistono altri modi per ottenere l'altitudine che dal GPS. Puoi usare il barometro ma poiché non ci sono molti dispositivi con sensori barometrici (solo quelli nuovi). Consiglierò di utilizzare un servizio Web per acquisire i dati desiderati.

Ecco una domanda che dovrebbe aiutarti attraverso: Ottieni l'altitudine per longitudine e latitudine in Android

Un altro approccio è misurare l'altitudine dal barometro.

Usando la pressione è possibile calcolare l'altitudine dell'utente. Non sono sicuro del livello di precisione di questo e se è più accurato dell'approccio dell'altra risposta.

Usando il formula ipsometrica Puoi calcolare l'altitudine:

hypsometric formula

Definizione variabile:

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

Puoi ottenere la pressione in Android da sensori ambientali

SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE,pressure)

Per i nuovi arrivati ho fatto una libreria che avvolgono LocationManager in rxjava osservabili e aggiungere alcune osservabili aiutanti per ottenere il livello del mare altitutde da Nmea/GPGGA mre info qui

Esistono biblioteche, come il CS-Map open source che fornisce un'API che esegue queste ricerche in grandi tavoli. Si specificano le coordinate e ti dirà l'offset di altezza che deve essere applicata all'altezza ellissoidale in quella posizione per ottenere l'altezza ortometrica del mondo "reale".

Nota: dopo aver usato CS-Map in precedenza, non è esattamente un lavoro di 5 minuti diretto per collegarlo. Avvertiti in anticipo che è più complicato che chiamare una singola API con una serie di coordinate a lungo termine e ottenere schiena un'altezza. Non lavoro più nell'azienda in cui stavamo facendo questo tipo di lavoro, quindi purtroppo non posso cercare il codice per dire esattamente quale API chiamare.

Facendo una ricerca su Google per ora (2019), sembra che CS-Map sia stato unito ai metacrs di Osgeo, il "Fondazione geospaziale open source"Progetto. Quella stessa ricerca mi ha portato a Questo vecchio wiki CS-Map così come La pagina Proj GitHub, dove ProJ sembra essere un progetto simile a CS-Map.

Consiglierei di usare Nmealistener, come suggerito da Sladstaetter la sua risposta. Tuttavia, secondo Documentazione NMEA, "$ Gpgga" non è l'unica frase che puoi ottenere. Dovresti cercare qualsiasi frase "GGA" ($-GGA).

Le espressioni regolari sono fantastiche per questo, ad esempio:

@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!
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top