Вопрос

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

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

Это было полезно?

Решение

Есть две проблемы с использованием высоты 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) показания высоты и вычислил среднее значение. Этого было достаточно, чтобы получить относительно точное чтение вертикальной скорости для моего применения.

Другие советы

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

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

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. Вы можете использовать барометр, но, поскольку еще не так много устройств с барометрическими датчиками (только новые). Я рекомендую использовать веб -сервис для получения желаемых данных.

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

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

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

С помощью Гипсометрическая формула Вы можете рассчитать высоту:

hypsometric formula

Переменная определение:

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

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

SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE,pressure)

Для новичков я составил библиотеку, которая обертывает местоположение в Rxjava Observables и добавил несколько наблюдаемых помощников, чтобы получить Altitutde на уровне моря из NMEA/GPGGA MRE здесь

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

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

Выполняя поиск в Google прямо сейчас (2019 г.), кажется, что CS-Map был объединен с MetaCRS в OSGeo, "Геопространственный фонд с открытым исходным кодом" проект.Тот же самый поиск привел меня к эта старая вики CS-Map а также страница 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!
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top