MobilApp/lib/services/ble_gnss_source.dart

77 lines
2.4 KiB
Dart

import 'dart:async';
import 'location_source.dart';
/// BLE GNSS vevőből érkező helymeghatározási forrás.
///
/// A meglévő Bluetooth + NMEA parsing logikát köti be a
/// [LocationSource] interfészbe, így a TrackingController
/// forrásváltás nélkül tud működni.
///
/// TEENDŐK a BLE verzió elkészültével:
/// 1. Injektáld a BluetoothConnection referenciát (vagy egy
/// stream-et a NMEA mondatokból).
/// 2. Parsold a GNGGA mondatokat (ugyanaz a [Gngga] osztály
/// ami a MapSurveyController-ben is megvan).
/// 3. Alkalmazd a geoid-korrekciót [GeoidGrid] segítségével.
/// 4. Töltsd fel a [SourcePosition]-t a korrekt mezőkkel.
class BleGnssSource implements LocationSource {
@override
String get displayName => 'BLE GNSS';
// TODO: Stream<String> nmeaStream — a BLE controller adja
final Stream<String>? nmeaStream;
StreamController<SourcePosition>? _controller;
StreamSubscription? _sub;
BleGnssSource({this.nmeaStream});
@override
bool get isAvailable => _sub != null;
@override
Stream<SourcePosition> get positionStream {
_controller = StreamController<SourcePosition>.broadcast();
if (nmeaStream == null) {
_controller!.addError(Exception(
'BLE GNSS forrás nincs bekötve. '
'Adj meg egy nmeaStream-et a konstruktorban.',
));
return _controller!.stream;
}
_sub = nmeaStream!.listen((line) {
if (!line.startsWith('\$GNGGA')) return;
// TODO: Gngga parser + GeoidGrid korreckció beépítése
// Példa váz:
//
// final sentence = nmeaDecoder.decode(line);
// if (sentence is! Gngga || !sentence.valid) return;
// final ellipsoidal =
// sentence.altitudeAboveMeanSeaLevel + sentence.geoidSeparation;
// final eovZ = geoidGrid.toEovHeight(
// sentence.latitude, sentence.longitude,
// sentence.altitudeAboveMeanSeaLevel, sentence.geoidSeparation);
//
// _controller?.add(SourcePosition(
// latitude: sentence.latitude,
// longitude: sentence.longitude,
// altitude: eovZ ?? ellipsoidal,
// accuracy: null, // GNGST-ből lehetne
// timestamp: DateTime.now(),
// source: displayName,
// ));
});
return _controller!.stream;
}
@override
Future<void> dispose() async {
await _sub?.cancel();
await _controller?.close();
}
}