MobilApp/lib/models/satellite_info.dart

226 lines
6.1 KiB
Dart
Raw Permalink Normal View History

import 'dart:math' as math;
enum GnssConstellation {
gps,
glonass,
galileo,
beidou,
qzss,
sbas,
navic,
mixed,
unknown,
}
// ─── SatelliteInfo modell ──────────────────────────────────────────────────
/// Egyetlen látható műhold adatai — a skyplot és az SNR diagram alapja.
class SatelliteInfo {
/// Műhold PRN/SVID azonosítója
final int prn;
/// Eleváció fokban (090°, 90 = zenit)
final int elevation;
/// Azimut fokban (0359°, 0/360 = É, 90 = K)
final int azimuth;
/// Jelerősség dB-Hz-ben (099, 0 = nem tracking)
final int snr;
/// A műhold konstellációja
final GnssConstellation constellation;
// Opcionális: NMEA signal ID (pl. L1/L2/E1/...)
final int? signalId;
const SatelliteInfo(
{required this.prn,
required this.elevation,
required this.azimuth,
required this.snr,
required this.constellation,
this.signalId});
String get system => 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',
};
/// Egyedi kulcs ugyanazon konstellacio azonos muholdjahoz
String get satelliteKey => '${constellation.name}:$prn';
/// Egyedi kulcs ugyanazon signal streamhez
String get signalKey => '${constellation.name}:$prn:${signalId ?? -1}';
/// Human-readable sav/frekvencia becsles signalId alapjan
String get bandLabel => _bandLabel(constellation, signalId);
// ── Minősítési segédek ────────────────────────────────────────────
/// Erős jel — fixben megbízhatóan részt vesz
bool get isStrong => snr >= 40;
/// Jelszint alapjan varhatoan hasznalhato jel.
/// A valodi "used in fix" allapotot a GSA mondatok alapjan allapitsuk meg.
bool get hasUsableSignal => snr >= 30;
/// Gyenge de látható jel
bool get isWeak => snr > 0 && snr < 30;
/// Egyáltalán látható-e (snr > 0)
bool get isVisible => snr > 0;
// ── Polár koordináta számítás a skyplot CustomPainter-hez ────────
/// Normalizált sugár (0.0 = zenit, 1.0 = horizont)
double get polarRadius => 1.0 - (elevation / 90.0);
/// Szög radiánban a polár koordinátához
/// (azimut → matematikai szög: É=felső, K=jobb)
double get polarAngleRad => (azimuth - 90) * math.pi / 180.0;
/// Polár koordináta pixel pozíciójának kiszámítása
/// [center] a kör középpontja, [radius] a horizont kör sugara
({double dx, double dy}) toOffset(
double centerX, double centerY, double radius) {
return (
dx: centerX + radius * polarRadius * math.cos(polarAngleRad),
dy: centerY + radius * polarRadius * math.sin(polarAngleRad),
);
}
@override
String toString() {
final signal = signalId == null ? '-' : signalId.toString();
return 'SatelliteInfo($system PRN$prn elev=$elevation az=$azimuth snr=$snr signal=$signal band=$bandLabel)';
}
static GnssConstellation constellationFromTalker(String talkerId) {
switch (talkerId) {
case 'GP':
return GnssConstellation.gps;
case 'GL':
return GnssConstellation.glonass;
case 'GA':
return GnssConstellation.galileo;
case 'GB':
case 'BD':
return GnssConstellation.beidou;
case 'GQ':
case 'QZ':
return GnssConstellation.qzss;
case 'GI':
case 'IN':
return GnssConstellation.navic;
case 'GN':
return GnssConstellation.mixed;
default:
return GnssConstellation.unknown;
}
}
static String _bandLabel(GnssConstellation constellation, int? signalId) {
if (signalId == null) return 'Unknown';
switch (constellation) {
case GnssConstellation.gps:
switch (signalId) {
case 1:
return 'L1 C/A';
case 5:
return 'L2C';
case 6:
return 'L5';
default:
return 'GPS sig $signalId';
}
case GnssConstellation.glonass:
switch (signalId) {
case 1:
return 'G1';
case 3:
return 'G2';
default:
return 'GLO sig $signalId';
}
case GnssConstellation.galileo:
switch (signalId) {
case 1:
return 'E1';
case 6:
return 'E5a';
case 7:
return 'E5b';
case 8:
return 'E5 AltBOC';
default:
return 'GAL sig $signalId';
}
case GnssConstellation.beidou:
switch (signalId) {
case 1:
return 'B1I';
case 3:
return 'B2I';
case 5:
return 'B1C';
case 7:
return 'B2a';
default:
return 'BDS sig $signalId';
}
case GnssConstellation.qzss:
switch (signalId) {
case 1:
return 'L1 C/A';
case 4:
return 'L1S';
case 5:
return 'L2C';
case 6:
return 'L5';
default:
return 'QZSS sig $signalId';
}
case GnssConstellation.sbas:
switch (signalId) {
case 1:
return 'L1';
case 6:
return 'L5';
default:
return 'SBAS sig $signalId';
}
case GnssConstellation.navic:
switch (signalId) {
case 1:
return 'L5';
case 2:
return 'S';
default:
return 'NavIC sig $signalId';
}
case GnssConstellation.mixed:
return 'Mixed sig $signalId';
case GnssConstellation.unknown:
return 'Unknown';
}
}
}