# Гибридный GPS подход в AISMap

## Проблема

Изначально приложение пыталось получать все GPS данные через NMEA сообщения, но столкнулось с нестабильностью получения RMC сообщений (курс, скорость). NMEA сообщения могут приходить нерегулярно или вообще не приходить, что делает невозможным получение критически важной навигационной информации.

## Решение: Гибридный подход

Мы реализовали **гибридный подход**, который комбинирует два источника данных:

### 1. Android Location API (основной источник координат)
- **Что получаем**: Координаты (широта/долгота), точность, время фикса, качество фикса
- **Преимущества**: Стабильный, надежный, работает на всех устройствах
- **Класс**: `GPSLocationListener`

### 2. NMEA сообщения (дополнительные данные)
- **Что получаем**: Курс, скорость, количество спутников, DOP (PDOP/HDOP/VDOP), высота
- **Преимущества**: Детальная навигационная информация, стандарт морской навигации
- **Класс**: `AndroidNMEAListener` + `NMEAParser`

## Архитектура

```
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   MainActivity  │    │  AppController   │    │   MapInterface  │
└─────────────────┘    └──────────────────┘    └─────────────────┘
         │                       │                       │
         │                       │                       │
         ▼                       ▼                       ▼
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│ GPSLocation     │    │   NMEAParser     │    │   Карта         │
│ Listener        │    │   (гибридный)    │    │                 │
│ (координаты)    │    │   (курс, DOP)    │    │                 │
└─────────────────┘    └──────────────────┘    └─────────────────┘
         │                       │
         │                       │
         ▼                       ▼
┌─────────────────┐    ┌──────────────────┐
│ Android NMEA    │    │   UDP Listener   │
│ Listener        │    │   (AIS данные)   │
│ (NMEA сообщения)│    │                  │
└─────────────────┘    └──────────────────┘
```

## Ключевые компоненты

### GPSLocationListener
- Получает координаты через `LocationManager.requestLocationUpdates()`
- Отслеживает количество спутников через `GnssStatus.Callback`
- Предоставляет точность позиции в метрах
- Определяет качество фикса (GPS, DGPS, RTK)

### NMEAParser (гибридный режим)
- В гибридном режиме **НЕ обновляет координаты** из NMEA
- Парсит только дополнительные данные:
  - **GGA**: количество спутников, высота
  - **RMC**: курс, скорость
  - **VTG**: курс, скорость (альтернативный источник)
  - **GSA**: DOP значения, активные спутники
  - **GSV**: спутники в поле зрения

### AppController
- Координирует работу всех компонентов
- Объединяет данные из разных источников в единый объект `Vessel`
- Управляет жизненным циклом слушателей

## Преимущества гибридного подхода

### ✅ Надежность
- Координаты всегда доступны через Location API
- Не зависит от стабильности NMEA сообщений

### ✅ Полнота данных
- Получаем все необходимые навигационные параметры
- DOP значения для оценки качества GPS

### ✅ Совместимость
- Работает на всех версиях Android
- Поддерживает как старый GPS API, так и новый GNSS API

### ✅ Производительность
- Location API оптимизирован системой
- NMEA парсинг только для дополнительных данных

## Использование

### Включение гибридного режима
```java
// В AppController
nmeaParser.setHybridMode(true);
nmeaParser.setGPSLocationListener(gpsLocationListener);

// Запуск слушателей
appController.setGPSLocationEnabled(true);    // Для координат
appController.setAndroidNMEAEnabled(true);    // Для дополнительных данных
```

### Получение данных
```java
Vessel vessel = appController.getOwnVessel();

// Координаты (из Location API)
double lat = vessel.getLatitude();
double lon = vessel.getLongitude();
float accuracy = vessel.getAccuracy();

// Навигационные данные (из NMEA)
double course = vessel.getCourse();
double speed = vessel.getSpeed();
int satellites = vessel.getSatellites();

// Качество GPS (из NMEA + Location API)
double pdop = vessel.getPdop();
double hdop = vessel.getHdop();
double vdop = vessel.getVdop();
String quality = vessel.getGPSQualityDescription();
```

## Тестирование

Для тестирования создан класс `GPSHybridTest`, который демонстрирует работу гибридного подхода:

```java
GPSHybridTest test = new GPSHybridTest(context);
test.startTest();  // Запускает тест
test.stopTest();   // Останавливает тест
test.cleanup();    // Освобождает ресурсы
```

## Логирование

Приложение ведет детальное логирование для отладки:

- `📍` - GPS Location данные
- `📡` - NMEA данные
- `📊` - DOP значения
- `🛰️` - Информация о спутниках
- `🚢` - Статус судна

## Заключение

Гибридный подход решает проблему нестабильности NMEA сообщений, обеспечивая надежное получение координат через Location API и дополнительных навигационных данных через NMEA. Это дает нам лучшее из двух миров: надежность Android системы и богатство морских навигационных данных.
