2025-02-21 08:26:27 +01:00
|
|
|
import 'package:nmea/nmea.dart';
|
|
|
|
|
|
|
|
|
|
class Gnrmc extends TalkerSentence {
|
2026-05-19 00:37:18 +02:00
|
|
|
static const String id = 'GxRMC';
|
|
|
|
|
|
2025-02-21 08:26:27 +01:00
|
|
|
Gnrmc({required super.raw});
|
|
|
|
|
|
|
|
|
|
@override
|
2026-05-19 00:37:18 +02:00
|
|
|
bool get valid => super.valid && fields.length >= 10;
|
|
|
|
|
|
|
|
|
|
String get messageId => _field(0);
|
|
|
|
|
|
|
|
|
|
String get utcOfPositionFix => _field(1);
|
|
|
|
|
|
|
|
|
|
String get status => _field(2).toUpperCase();
|
|
|
|
|
|
|
|
|
|
String get latitudeDirection => _field(4).toUpperCase();
|
|
|
|
|
|
|
|
|
|
double get latitude => _parseLatitude(_field(3), latitudeDirection) ?? 0.0;
|
|
|
|
|
|
|
|
|
|
String get longitudeDirection => _field(6).toUpperCase();
|
|
|
|
|
|
|
|
|
|
double get longitude => _parseLongitude(_field(5), longitudeDirection) ?? 0.0;
|
|
|
|
|
|
|
|
|
|
double get speedOverGroundKnots => _parseDouble(_field(7), fallback: 0.0);
|
|
|
|
|
|
|
|
|
|
double get courseOverGround => _parseDouble(_field(8), fallback: 0.0);
|
|
|
|
|
|
|
|
|
|
String get date => _field(9);
|
|
|
|
|
|
|
|
|
|
// Opcionális mezők -> nullable getterek
|
|
|
|
|
double? get magneticVariation => _parseDoubleOrNull(_field(10));
|
|
|
|
|
|
|
|
|
|
String get magneticVariationDirection => _field(11).toUpperCase();
|
|
|
|
|
|
|
|
|
|
String get positioningSystemModeIndicator => _field(12).toUpperCase();
|
|
|
|
|
|
|
|
|
|
String _field(int index) {
|
|
|
|
|
if (index < 0 || index >= fields.length) return '';
|
|
|
|
|
return fields[index].trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double _parseDouble(String value, {required double fallback}) {
|
|
|
|
|
return double.tryParse(value) ?? fallback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double? _parseDoubleOrNull(String value) {
|
|
|
|
|
if (value.isEmpty) return null;
|
|
|
|
|
return double.tryParse(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double? _parseLatitude(String value, String direction) {
|
|
|
|
|
if (value.length < 4) return null; // ddmm.mmmm
|
|
|
|
|
final deg = double.tryParse(value.substring(0, 2));
|
|
|
|
|
final min = double.tryParse(value.substring(2));
|
|
|
|
|
if (deg == null || min == null) return null;
|
|
|
|
|
|
|
|
|
|
final result = deg + (min / 60.0);
|
|
|
|
|
return direction == 'S' ? -result : result;
|
2025-02-21 08:26:27 +01:00
|
|
|
}
|
|
|
|
|
|
2026-05-19 00:37:18 +02:00
|
|
|
double? _parseLongitude(String value, String direction) {
|
|
|
|
|
if (value.length < 5) return null; // dddmm.mmmm
|
|
|
|
|
final deg = double.tryParse(value.substring(0, 3));
|
|
|
|
|
final min = double.tryParse(value.substring(3));
|
|
|
|
|
if (deg == null || min == null) return null;
|
2025-02-21 08:26:27 +01:00
|
|
|
|
2026-05-19 00:37:18 +02:00
|
|
|
final result = deg + (min / 60.0);
|
|
|
|
|
return direction == 'W' ? -result : result;
|
2025-02-21 08:26:27 +01:00
|
|
|
}
|
|
|
|
|
}
|