MobilApp/lib/gnss_sentences/gngsa.dart

107 lines
3.3 KiB
Dart
Raw Permalink Normal View History

import 'package:nmea/nmea.dart';
import 'package:terepi_seged/models/satellite_info.dart';
/// GSA — GNSS DOP és aktív műholdak
///
/// Formátum:
/// $GNGSA,A,3,01,02,03,04,05,06,07,08,09,10,11,12,2.1,1.2,1.7*XX
/// │ │ └─────────── 12 db PRN ────────┘ │ │ │
/// │ └── Fix típus: 1=nincs, 2=2D, 3=3D │ │ └─ VDOP
/// └──── Mód: M=kézi, A=auto │ └───── HDOP
/// └───────── PDOP
///
/// NMEA 4.1+: opcionális rendszer azonosító (fields[18])
/// Minden rendszerhez érkezik egy-egy GSA mondat.
class Gngsa extends TalkerSentence {
static const String id = 'GNGSA';
Gngsa({required super.raw});
@override
bool get valid => super.valid && fields.length >= 18;
/// Módválasztás: 'M' = kézi, 'A' = automatikus
String get selectionMode => fields[1];
/// Fix típus: 1 = nincs, 2 = 2D, 3 = 3D
int get fixType => int.tryParse(fields[2]) ?? 1;
/// Fixben használt műholdak PRN számai (max 12, üres mezők kihagyva)
List<int> get activeSatellitePrns {
final prns = <int>[];
for (int i = 3; i <= 14; i++) {
if (i >= fields.length) break;
final prn = int.tryParse(fields[i]);
if (prn != null && prn > 0) prns.add(prn);
}
return prns;
}
/// PDOP — 3D pozíció pontossági szorzó
double get pdop => _parseDouble(fields[15]);
/// HDOP — vízszintes pontossági szorzó
double get hdop => _parseDouble(fields[16]);
/// VDOP — függőleges pontossági szorzó
/// Az utolsó mező checksum előtti részét veszi
double get vdop {
if (fields.length <= 17) return 0.0;
return _parseDouble(fields[17].split('*').first);
}
/// GDOP számítása: √(PDOP² + TDOP²)
/// Közelítés TDOP nélkül: GDOP ≈ PDOP * 1.1
double get gdopApprox => pdop * 1.1;
/// Talker azonosító — rendszer meghatározásához
/// GP=GPS, GL=GLONASS, GA=Galileo, GB/BD=BeiDou, GN=vegyes
String get talkerId => raw.length >= 3 ? raw.substring(1, 3) : 'GN';
/// Rendszer neve a talker alapján
String get systemName => switch (talkerId) {
'GP' => 'GPS',
'GL' => 'GLONASS',
'GA' => 'Galileo',
'GB' || 'BD' => 'BeiDou',
'GN' => 'Mixed',
_ => 'Unknown',
};
int? get systemId {
if (fields.length <= 18) return null;
final rawSys = fields[18].split('*').first.trim();
if (rawSys.isEmpty) return null;
return int.tryParse(rawSys);
}
GnssConstellation get constellation {
switch (systemId) {
case 1:
return GnssConstellation.gps;
case 2:
return GnssConstellation.glonass;
case 3:
return GnssConstellation.galileo;
case 4:
return GnssConstellation.beidou;
case 5:
return GnssConstellation.qzss;
default:
return SatelliteInfo.constellationFromTalker(talkerId);
}
}
String get constellationKey => constellation.name;
List<String> get activeSatelliteKeys =>
activeSatellitePrns.map((prn) => '$constellationKey:$prn').toList();
int get usedSatelliteCount => activeSatellitePrns.length;
double _parseDouble(String? s) {
if (s == null || s.isEmpty) return 0.0;
return double.tryParse(s) ?? 0.0;
}
}