Pregunta

Necesito obtener una medición precisa de la altitud utilizando solo GPS.

Lo intenté Location.getAltitude(), pero eso es terriblemente inexacto. ¿Algún consejo?

¿Fue útil?

Solución

Hay dos problemas con el uso de la altitud de un teléfono inteligente / tableta GPS:

  1. La altitud es la altitud por encima del elipsoide de referencia WGS84. No es la altitud sobre el nivel del suelo o el nivel del mar. Aquí hay más detalle sobre eso: http://www.gpspassion.com/forumsen/topic.asp?topic_id=10915. Este error se puede corregir; Aquí hay una descripción cómo hacerlo a mano: http://www.unavco.org/edu_outreach/tutorial/geoidcorr.html. El artículo web vincula a una calculadora para obtener la altura geoidal para la corrección; No sé si también hay un servicio web disponible para este cálculo.
  2. La altitud GPS es terriblemente inexacta para receptores GPS relativamente baratos. Aquí hay un artículo sobre eso: http://gpsinformation.net/main/altitude.htm. Un método para hacer frente a este tipo de inexactitud es filtrar los datos de altitud. Utilicé una estructura de datos de matriz circular para recordar las últimas (usé 4) lecturas de altitud y calcular el promedio. Esto es suficiente para obtener una lectura relativamente precisa de la velocidad vertical para mi aplicación.

Otros consejos

Otra forma sería analizar las cuerdas NMEA. los $ GPGGA SENCIÓN ya contiene los datos de altitud corregidos por encima del nivel del mar.

Por lo tanto, simplemente cree un oyente a las cuerdas NMEA para su manager de ubicación y analice los mensajes:

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

Puede reemplazar la altitud del último objeto de ubicación recibido a través de un oyente de ubicación, o analizar toda la ubicación nueva a través de NMEA.

Hay otras formas de obtener la altitud que por GPS. Puede usar el barómetro, pero ya que aún no hay muchos dispositivos con sensores barométricos (solo los nuevos). Recomendaré utilizar un servicio web para adquirir los datos deseados.

Aquí hay una pregunta que debería ayudarlo a través de: Obtenga altitud por longitud y latitud en Android

Otro enfoque es medir la altitud del barómetro.

Al usar la presión, puede calcular la altitud del usuario. No estoy seguro del nivel de precisión de esto y si es más preciso que el enfoque de la otra respuesta.

Usando el fórmula hipsométrica Puedes calcular la altitud:

hypsometric formula

Definición variable:

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

Puedes obtener la presión en Android del sensores de medio ambiente

SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE,pressure)

Para los recién llegados, hice una biblioteca que envuelve el manago de ubicación en Rxjava Observables y agregué algunos ayudantes observables para obtener Altitutde de nivel del mar de NMEA/GPGGA MRE Info aquí

Hay bibliotecas, como el mapa CS de código abierto que proporcionan una API que hace estas búsquedas en tablas grandes. Usted especifica las coordenadas y le dirá el desplazamiento de altura que debe aplicarse a la altura elipsoidal en ese lugar para obtener la altura ortométrica del "mundo real".

Nota: Habiendo usado CS-MAP antes, no es exactamente un trabajo de 5 minutos directo para enchufarlo. Advirtiéndole de antemano que es más complicado que llamar a una sola API con un conjunto de coordenadas LAT y obtener hacia atrás una altura. Ya no trabajo en la compañía donde estábamos haciendo este tipo de trabajo, por lo que desafortunadamente no puedo buscar el código para decir exactamente a qué API llamar.

Haciendo una búsqueda en Google en este momento (2019), parece que CS-MAP se ha fusionado en Metacrs en Osgeo, el "Fundación geoespacial de código abierto"Proyecto. Esa misma búsqueda me llevó a esta vieja wiki de mapas CS tanto como la página Proj Github, donde PROJ parece ser un proyecto similar a CS-MAP.

Recomendaría usar NMealistener, como Sladstaetter sugirió en su respuesta. Sin embargo, según Documentación de NMEA, "$ GPGGA" no es la única oración que puedes obtener. Debe buscar cualquier oración "GGA" ($-GGA).

Las expresiones regulares son excelentes para eso, por ejemplo:

@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!
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top