Track rögzítés javítása, távolság limit idő alapú módosítása, Fix #9 @30m
This commit is contained in:
@@ -329,17 +329,35 @@ class TrackingController extends GetxController {
|
|||||||
pos.latitude,
|
pos.latitude,
|
||||||
pos.longitude,
|
pos.longitude,
|
||||||
);
|
);
|
||||||
// Szűrés: ugrásszerű változás (pl. GPS lock elvesztése) ignorálása
|
|
||||||
if (segmentDist > 100) {
|
// Szűrés: valóban LEHETETLEN ugrás kiszűrése (pl. GPS lock-
|
||||||
|
// vesztés utáni téves fix) — az ELTELT IDŐT is figyelembe véve.
|
||||||
|
// A korábbi, sima 100 m-es távolság-küszöb gyorsabb haladásnál
|
||||||
|
// (pl. földúton autóval) egy rövid, teljesen normál jel-
|
||||||
|
// kimaradás után érkező, VALÓS pontokat is kiszűrt, mert
|
||||||
|
// néhány másodperc alatt egy autó simán megtesz 100+ métert.
|
||||||
|
final elapsedSec =
|
||||||
|
point.timestamp.difference(_lastPoint!.timestamp).inMilliseconds /
|
||||||
|
1000.0;
|
||||||
|
final impliedSpeedMs =
|
||||||
|
elapsedSec > 0 ? segmentDist / elapsedSec : double.infinity;
|
||||||
|
|
||||||
|
// ~50 m/s = 180 km/h — terepen, földúton ennél gyorsabban senki
|
||||||
|
// nem halad, tehát ami ennél nagyobb sebességet implikálna, az
|
||||||
|
// GPS-hiba, nem valódi mozgás.
|
||||||
|
const maxPlausibleSpeedMs = 50.0;
|
||||||
|
|
||||||
|
if (impliedSpeedMs > maxPlausibleSpeedMs) {
|
||||||
AppLogger.w(
|
AppLogger.w(
|
||||||
'_onPosition',
|
'_onPosition',
|
||||||
'GPS ugrás kiszűrve: ${segmentDist.toStringAsFixed(0)}m '
|
'GPS ugrás kiszűrve: ${segmentDist.toStringAsFixed(0)}m / '
|
||||||
'(pts: ${livePoints.length})');
|
'${elapsedSec.toStringAsFixed(1)}s '
|
||||||
_lastPoint = point; // reset — következő pont ettől mér
|
'(${(impliedSpeedMs * 3.6).toStringAsFixed(0)} km/h, '
|
||||||
|
'pts: ${livePoints.length})');
|
||||||
|
_lastPoint = point;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_accumulatedDistance += segmentDist;
|
_accumulatedDistance += segmentDist;
|
||||||
sessionDistance.value = _accumulatedDistance;
|
sessionDistance.value = _accumulatedDistance;
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ class PhoneGpsSource implements LocationSource {
|
|||||||
/// Minimális elmozdulás méterben új pont előtt.
|
/// Minimális elmozdulás méterben új pont előtt.
|
||||||
final double distanceFilter;
|
final double distanceFilter;
|
||||||
|
|
||||||
|
/// Egymást követő sikertelen újraindítási kísérletek száma — véd a
|
||||||
|
/// végtelen, szoros hiba-ciklus ellen, ha valami tartósan elromlott.
|
||||||
|
int _retryCount = 0;
|
||||||
|
static const _maxRetries = 5;
|
||||||
|
Timer? _retryTimer;
|
||||||
|
|
||||||
PhoneGpsSource({
|
PhoneGpsSource({
|
||||||
this.intervalMs = 1000,
|
this.intervalMs = 1000,
|
||||||
this.distanceFilter = 1.0,
|
this.distanceFilter = 1.0,
|
||||||
@@ -59,33 +65,66 @@ class PhoneGpsSource implements LocationSource {
|
|||||||
// notification biztosítja a jogszerű háttér-használatot.
|
// notification biztosítja a jogszerű háttér-használatot.
|
||||||
foregroundNotificationConfig: const ForegroundNotificationConfig(
|
foregroundNotificationConfig: const ForegroundNotificationConfig(
|
||||||
notificationText: 'Track rögzítése folyamatban',
|
notificationText: 'Track rögzítése folyamatban',
|
||||||
notificationTitle: 'Terepi Segéd – Nyomvonal',
|
notificationTitle: 'Terepi Segéd - Nyomvonal',
|
||||||
enableWakeLock: true,
|
enableWakeLock: true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await _positionSub?.cancel();
|
||||||
|
|
||||||
_positionSub = Geolocator.getPositionStream(
|
_positionSub = Geolocator.getPositionStream(
|
||||||
locationSettings: settings,
|
locationSettings: settings,
|
||||||
).listen(
|
).listen((Position pos) {
|
||||||
(Position pos) {
|
_retryCount = 0;
|
||||||
_controller?.add(SourcePosition(
|
_controller?.add(SourcePosition(
|
||||||
latitude: pos.latitude,
|
latitude: pos.latitude,
|
||||||
longitude: pos.longitude,
|
longitude: pos.longitude,
|
||||||
altitude: pos.altitude,
|
altitude: pos.altitude,
|
||||||
accuracy: pos.accuracy,
|
accuracy: pos.accuracy,
|
||||||
verticalAccuracy: pos.altitudeAccuracy,
|
verticalAccuracy: pos.altitudeAccuracy,
|
||||||
speed: pos.speed,
|
speed: pos.speed,
|
||||||
heading: pos.heading,
|
heading: pos.heading,
|
||||||
timestamp: pos.timestamp,
|
timestamp: pos.timestamp,
|
||||||
source: displayName,
|
source: displayName,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
onError: (e) => _controller?.addError(e),
|
onError: (e) => _handleStreamError,
|
||||||
);
|
onDone: () =>
|
||||||
|
_handleStreamError(Exception('A GPS-stream váratlanul lezárult.')));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Geolocator stream NEM öngyógyuló: ha egyszer hibát dob (terepen,
|
||||||
|
/// zötykölődő telefonnal ez elő szokott fordulni), magától többé NEM
|
||||||
|
/// küld pozíciót. Ezért itt — a korábbi "csak továbbadjuk és feladjuk"
|
||||||
|
/// helyett — manuálisan újraindítjuk a mögöttes streamet. Végleges,
|
||||||
|
/// nem-helyreállítható hibáknál (jogosultság/szolgáltatás kikapcsolva)
|
||||||
|
/// viszont TOVÁBBADJUK, hogy a TrackingController korrekten leállítsa
|
||||||
|
/// a rögzítést, ahogy eddig is.
|
||||||
|
void _handleStreamError(Object e) {
|
||||||
|
if (e is LocationServiceDisabledException ||
|
||||||
|
e is PermissionDeniedException) {
|
||||||
|
_controller?.addError(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_retryCount++;
|
||||||
|
if (_retryCount > _maxRetries) {
|
||||||
|
// Tartósan hibás állapot — ezt már valóban jelezni kell.
|
||||||
|
_controller?.addError(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rövid várakozás, majd friss stream indítása. A _controller
|
||||||
|
// (amit a TrackingController figyel) változatlan marad — onnan
|
||||||
|
// nézve ez csak egy pillanatnyi szünet a pozíciókban, nem egy
|
||||||
|
// végleges leállás.
|
||||||
|
_retryTimer?.cancel();
|
||||||
|
_retryTimer = Timer(const Duration(seconds: 1), _startListening);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
|
_retryTimer?.cancel();
|
||||||
await _positionSub?.cancel();
|
await _positionSub?.cancel();
|
||||||
await _controller?.close();
|
await _controller?.close();
|
||||||
_controller = null;
|
_controller = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user