MobilApp/lib/gnss_sentences/gngsv.dart

117 lines
4.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ─── GSV mondatelemző ──────────────────────────────────────────────────────
import 'package:nmea/nmea.dart';
import 'package:terepi_seged/models/satellite_info.dart';
/// GSV — GNSS Satellites in View
///
/// Formátum (max 4 műhold/mondat):
/// $GPGSV,3,1,11,01,70,042,45,03,55,218,48,07,22,085,35,10,35,315,40*73
/// │ │ │ │ │ │ │
/// │ │ │ PRN El Az SNR (×4 max)
/// │ │ └── összes látható műhold száma
/// │ └───── ezen mondat sorszáma (1-től)
/// └─────── összes GSV mondat ebben a ciklusban
///
/// Több mondat alkotja az epochot:
/// GPGSV (GPS) + GLGSV (GLONASS) + GAGSV (Galileo) + GBGSV (BeiDou)
class Gngsv extends TalkerSentence {
static const String id = 'GNGSV';
Gngsv({required super.raw});
@override
bool get valid =>
super.valid && fields.length >= 8; // min: típus + 3 fejléc + 1×4 műhold
// ── Fejléc mezők ─────────────────────────────────────────────────
/// Összes GSV mondat ezen rendszerhez ebben az epochban
int get totalMessages => int.tryParse(fields[1]) ?? 1;
/// Az aktuális mondat sorszáma
int get messageNumber => int.tryParse(fields[2]) ?? 1;
/// Összes látható műhold száma az adott stream-ben
int get totalSatellitesInView => int.tryParse(fields[3]) ?? 0;
/// Ez az utolsó mondat az adott rendszer GSV sorozatában?
bool get isLastMessage => messageNumber == totalMessages;
String get talkerId => raw.length >= 3 ? raw.substring(1, 3) : 'GN';
GnssConstellation get constellation =>
SatelliteInfo.constellationFromTalker(talkerId);
String get systemName => switch (constellation) {
GnssConstellation.gps => 'GPS',
GnssConstellation.glonass => 'GLONASS',
GnssConstellation.galileo => 'Galileo',
GnssConstellation.beidou => 'BeiDou',
GnssConstellation.qzss => 'QZSS',
GnssConstellation.sbas => 'SBAS',
GnssConstellation.navic => 'NavIC',
GnssConstellation.mixed => 'Mixed',
GnssConstellation.unknown => 'Unknown',
};
/// Opcionális NMEA Signal ID
///
/// Header: 4 mezo
/// Minden muhold: 4 mezo
/// Ha marad +1 mezo, az a signalId
int? get signalId {
final payloadCount = fields.length - 4;
if (payloadCount <= 0) return null;
final hasSignalId = payloadCount % 4 == 1;
if (!hasSignalId) return null;
final rawSignal = fields.last.split('*').first.trim();
if (rawSignal.isEmpty) return null;
return int.tryParse(rawSignal);
}
/// Egy stream kulcsa: ugyanazon talker, ugyanazon signal
String get streamKey => '$talkerId:${signalId ?? -1}';
// ── Műholdak ebben a mondatban ───────────────────────────────────
/// A mondatban szereplő műholdak listája (max 4)
List<SatelliteInfo> get satellites {
final sats = <SatelliteInfo>[];
// Minden műhold 4 mezőt foglal: PRN, eleváció, azimut, SNR
// fields[4]-től kezdődnek, fields[0] = mondattípus
for (int i = 0; i < 4; i++) {
final base = 4 + i * 4;
// Ellenőrzés: van-e elég mező
if (base + 3 >= fields.length) break;
final prn = int.tryParse(_field(base));
final elev = int.tryParse(_field(base + 1)) ?? 0;
final az = int.tryParse(_field(base + 2)) ?? 0;
final snr = int.tryParse(_field(base + 3).split('*').first) ?? 0;
if (prn != null && prn > 0) {
sats.add(SatelliteInfo(
prn: prn,
elevation: elev,
azimuth: az,
snr: snr,
constellation: constellation,
signalId: signalId,
));
}
}
return sats;
}
String _field(int index) {
if (index < 0 || index >= fields.length) return '';
return fields[index].trim();
}
}