import 'package:nmea/nmea.dart'; class Gnrmc extends TalkerSentence { static const String id = 'GxRMC'; Gnrmc({required super.raw}); @override 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; } 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; final result = deg + (min / 60.0); return direction == 'W' ? -result : result; } }