Android: как получить точную высоту? - PullRequest
51 голосов
/ 20 февраля 2012

Мне нужно получить точное измерение высоты, используя только GPS.

Я пытался Location.getAltitude(), но это ужасно неточно.Любой совет?

Ответы [ 7 ]

56 голосов
/ 24 февраля 2012

Существует две проблемы с использованием высоты GPS смартфона / планшета:

  1. Высота - это высота над эталонным эллипсоидом WGS84. Это не высота над уровнем земли или над уровнем моря. Вот более подробно об этом: http://www.gpspassion.com/forumsen/topic.asp?TOPIC_ID=10915. Эта ошибка может быть исправлена; Вот описание, как это сделать вручную: http://www.unavco.org/edu_outreach/tutorial/geoidcorr.html. Веб-статья ссылается на калькулятор, чтобы получить высоту геоида для коррекции; Я не знаю, есть ли также веб-сервис для этого вычисления.
  2. Высота GPS ужасно неточна для относительно дешевых GPS-приемников. Вот статья на эту тему: http://gpsinformation.net/main/altitude.htm. Один из способов справиться с такой неточностью - это отфильтровать данные о высоте. Я использовал структуру данных круглого массива, чтобы запомнить последние несколько (я использовал 4) показаний высоты и вычислить среднее значение. Этого было достаточно, чтобы получить относительно точное показание вертикальной скорости для моего приложения.
4 голосов
/ 13 июня 2017

Другим способом будет разбор строк NMEA.Предложение $ GPGGA уже содержит исправленные данные о высоте над уровнем моря.

Итак, просто создайте прослушиватель NMEA-строк для вашего LocationManager и проанализируйте сообщения:

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

Вы можете заменить высоту последнего объекта Location, полученного через слушателя местоположения,или разобрать всю новую локацию через NMEA.

1 голос
/ 31 января 2019

Другой подход заключается в измерении высоты с помощью барометра.

Используя давление, вы можете рассчитать высоту пользователя. Я не уверен в точности уровня этого и является ли он более точным, чем подход другого ответа.

Используя гипсометрическую формулу , вы можете рассчитать высоту:

hypsometric formula

Определение переменной:

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

Вы можете получить давление в Android от датчиков окружающей среды

SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE,pressure)
1 голос
/ 26 января 2013

Есть и другие способы получить высоту, кроме GPS.Вы можете использовать барометр, но пока не так много устройств с барометрическими датчиками (только новые).Я рекомендую использовать веб-сервис для получения желаемых данных.

Вот вопрос, который должен помочь вам: Получить высоту по долготе и широте в Android

0 голосов
/ 01 июля 2019

Я бы порекомендовал использовать 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!
    }
}
0 голосов
/ 24 июня 2019

Существуют библиотеки, такие как CS-Map с открытым исходным кодом, которые предоставляют API, который выполняет поиск в больших таблицах. Вы указываете координаты, и вам будет указано смещение высоты, которое необходимо применить к эллипсоидальной высоте в этом месте, чтобы получить ортометрическую высоту "реального мира".

Примечание. Используя CS-Map ранее, подключить ее не так просто, как 5-минутную работу. Заранее предупреждаю, что это сложнее, чем вызывать один API с набором значений lat-long. координаты и возвращение высоты. Я больше не работаю в компании, где мы выполняли такую ​​работу, поэтому, к сожалению, не могу найти код, чтобы точно сказать, какой API вызывать.

Выполняя поиск в Google прямо сейчас (2019), кажется, что CS-Map была объединена с MetaCRS в OSGeo, проекте Open Source Geospatial Foundation . Этот же поиск привел меня к этой старой вики CS-Map , а также странице PROJ GitHub , где PROJ, похоже, похож на проект CS-Map.

0 голосов
/ 02 ноября 2018

Для новичков я создал библиотеку, которая упаковывает LocationManager в наблюдаемые rxjava и добавляет несколько наблюдаемых помощников, чтобы получить высоту уровня моря из информации Nmea / GPGGA здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...