add geolocation View and controller and services, routes and bindings
This commit is contained in:
354
lib/controllers/geolocation_advanced_controller.dart
Normal file
354
lib/controllers/geolocation_advanced_controller.dart
Normal file
@@ -0,0 +1,354 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import '../services/geolocation.dart';
|
||||
import '../utils/geo_utils.dart';
|
||||
|
||||
/// Erweiterte Geolocation Controller Klasse mit zusätzlichen Features
|
||||
class GeolocationAdvancedController extends GetxController {
|
||||
// Reactive Variablen
|
||||
final _currentPosition = Rxn<Position>();
|
||||
final _previousPosition = Rxn<Position>();
|
||||
final _statusText = 'Noch keine Position ermittelt'.obs;
|
||||
final _isTracking = false.obs;
|
||||
final _isLoading = false.obs;
|
||||
final _totalDistance = 0.0.obs;
|
||||
final _averageSpeed = 0.0.obs;
|
||||
final _maxSpeed = 0.0.obs;
|
||||
final _trackingDuration = 0.obs;
|
||||
final _positionHistory = <Position>[].obs;
|
||||
|
||||
// Timer für Tracking-Dauer
|
||||
DateTime? _trackingStartTime;
|
||||
|
||||
// Getter für reactive Variablen
|
||||
Position? get currentPosition => _currentPosition.value;
|
||||
Position? get previousPosition => _previousPosition.value;
|
||||
String get statusText => _statusText.value;
|
||||
bool get isTracking => _isTracking.value;
|
||||
bool get isLoading => _isLoading.value;
|
||||
double get totalDistance => _totalDistance.value;
|
||||
double get averageSpeed => _averageSpeed.value;
|
||||
double get maxSpeed => _maxSpeed.value;
|
||||
int get trackingDuration => _trackingDuration.value;
|
||||
List<Position> get positionHistory => _positionHistory;
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
stopTracking();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
/// Holt die aktuelle Position einmalig
|
||||
Future<void> getCurrentPosition() async {
|
||||
try {
|
||||
_isLoading.value = true;
|
||||
_statusText.value = 'Position wird ermittelt...';
|
||||
|
||||
Position? position = await GeolocationService.getCurrentPosition();
|
||||
|
||||
if (position != null) {
|
||||
_updatePosition(position);
|
||||
_statusText.value = GeolocationService.positionToString(position);
|
||||
|
||||
Get.snackbar(
|
||||
'Position ermittelt',
|
||||
'Genauigkeit: ${position.accuracy.toStringAsFixed(1)}m',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} else {
|
||||
_statusText.value = 'Position konnte nicht ermittelt werden';
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Position konnte nicht ermittelt werden',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Abrufen der Position: $e';
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Unerwarteter Fehler: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} finally {
|
||||
_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Startet kontinuierliches Position Tracking mit Statistiken
|
||||
Future<void> startTracking() async {
|
||||
if (_isTracking.value) return;
|
||||
|
||||
try {
|
||||
_isLoading.value = true;
|
||||
_statusText.value = 'Tracking wird gestartet...';
|
||||
|
||||
// Reset Statistiken
|
||||
_resetTrackingStats();
|
||||
_trackingStartTime = DateTime.now();
|
||||
|
||||
bool success = await GeolocationService.startPositionStream(
|
||||
onPositionChanged: (Position position) {
|
||||
_updatePosition(position);
|
||||
_updateTrackingStats(position);
|
||||
_statusText.value = _buildTrackingStatusText(position);
|
||||
},
|
||||
onError: (String error) {
|
||||
_statusText.value = 'Tracking Fehler: $error';
|
||||
_isTracking.value = false;
|
||||
Get.snackbar(
|
||||
'Tracking Fehler',
|
||||
error,
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
},
|
||||
accuracy: LocationAccuracy.high,
|
||||
distanceFilter: 3, // Updates alle 3 Meter für genauere Statistiken
|
||||
);
|
||||
|
||||
if (success) {
|
||||
_isTracking.value = true;
|
||||
_statusText.value = 'Tracking aktiv - Warten auf erste Position...';
|
||||
|
||||
// Starte Timer für Tracking-Dauer
|
||||
_startDurationTimer();
|
||||
|
||||
Get.snackbar(
|
||||
'Tracking gestartet',
|
||||
'Sammle GPS-Daten und Statistiken...',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} else {
|
||||
_statusText.value = 'Tracking konnte nicht gestartet werden';
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Tracking konnte nicht gestartet werden',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Starten des Trackings: $e';
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Tracking-Fehler: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} finally {
|
||||
_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Stoppt das Position Tracking
|
||||
Future<void> stopTracking() async {
|
||||
if (!_isTracking.value) return;
|
||||
|
||||
try {
|
||||
await GeolocationService.stopPositionStream();
|
||||
_isTracking.value = false;
|
||||
_trackingStartTime = null;
|
||||
|
||||
String summary = _buildTrackingSummary();
|
||||
_statusText.value = 'Tracking gestoppt\n$summary';
|
||||
|
||||
Get.snackbar(
|
||||
'Tracking gestoppt',
|
||||
summary,
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
duration: const Duration(seconds: 5),
|
||||
);
|
||||
} catch (e) {
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Fehler beim Stoppen des Trackings: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Prüft Permission Status
|
||||
Future<void> checkPermissions() async {
|
||||
try {
|
||||
_isLoading.value = true;
|
||||
_statusText.value = 'Berechtigungen werden geprüft...';
|
||||
|
||||
LocationPermission permission = await GeolocationService.checkPermission();
|
||||
bool serviceEnabled = await GeolocationService.isLocationServiceEnabled();
|
||||
|
||||
_statusText.value = 'Service aktiv: $serviceEnabled\n'
|
||||
'Berechtigung: ${LocationPermissionHelper.getPermissionStatusText(permission)}';
|
||||
|
||||
String permissionStatus = LocationPermissionHelper.getPermissionStatusText(permission);
|
||||
Get.snackbar(
|
||||
'Berechtigungs-Status',
|
||||
'Location Service: ${serviceEnabled ? "Aktiv" : "Inaktiv"}\n$permissionStatus',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
duration: const Duration(seconds: 4),
|
||||
);
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Prüfen der Berechtigungen: $e';
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Berechtigungen konnten nicht geprüft werden: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} finally {
|
||||
_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Private Methoden
|
||||
|
||||
void _updatePosition(Position position) {
|
||||
_previousPosition.value = _currentPosition.value;
|
||||
_currentPosition.value = position;
|
||||
_positionHistory.add(position);
|
||||
}
|
||||
|
||||
void _updateTrackingStats(Position position) {
|
||||
if (_previousPosition.value != null) {
|
||||
// Berechne Distanz zur vorherigen Position
|
||||
double distance = GeoUtils.calculateDistanceKm(
|
||||
startLat: _previousPosition.value!.latitude,
|
||||
startLng: _previousPosition.value!.longitude,
|
||||
endLat: position.latitude,
|
||||
endLng: position.longitude,
|
||||
);
|
||||
|
||||
_totalDistance.value += distance;
|
||||
|
||||
// Aktualisiere max Geschwindigkeit
|
||||
double currentSpeedKmh = GeoUtils.mpsToKmh(position.speed);
|
||||
if (currentSpeedKmh > _maxSpeed.value) {
|
||||
_maxSpeed.value = currentSpeedKmh;
|
||||
}
|
||||
|
||||
// Berechne Durchschnittsgeschwindigkeit
|
||||
if (_trackingStartTime != null) {
|
||||
double hours = DateTime.now().difference(_trackingStartTime!).inMinutes / 60.0;
|
||||
if (hours > 0) {
|
||||
_averageSpeed.value = _totalDistance.value / hours;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _resetTrackingStats() {
|
||||
_totalDistance.value = 0.0;
|
||||
_averageSpeed.value = 0.0;
|
||||
_maxSpeed.value = 0.0;
|
||||
_trackingDuration.value = 0;
|
||||
_positionHistory.clear();
|
||||
}
|
||||
|
||||
String _buildTrackingStatusText(Position position) {
|
||||
return 'TRACKING AKTIV\n'
|
||||
'Position: ${position.latitude.toStringAsFixed(6)}, ${position.longitude.toStringAsFixed(6)}\n'
|
||||
'Genauigkeit: ${position.accuracy.toStringAsFixed(1)}m\n'
|
||||
'Geschwindigkeit: ${GeoUtils.mpsToKmh(position.speed).toStringAsFixed(1)} km/h\n'
|
||||
'Distanz: ${(_totalDistance.value * 1000).toStringAsFixed(0)}m\n'
|
||||
'Dauer: ${_formatDuration(_trackingDuration.value)}';
|
||||
}
|
||||
|
||||
String _buildTrackingSummary() {
|
||||
return 'Gesamtdistanz: ${(_totalDistance.value * 1000).toStringAsFixed(0)}m\n'
|
||||
'Max. Geschwindigkeit: ${_maxSpeed.value.toStringAsFixed(1)} km/h\n'
|
||||
'Ø Geschwindigkeit: ${_averageSpeed.value.toStringAsFixed(1)} km/h\n'
|
||||
'Dauer: ${_formatDuration(_trackingDuration.value)}\n'
|
||||
'Punkte: ${_positionHistory.length}';
|
||||
}
|
||||
|
||||
void _startDurationTimer() {
|
||||
// Update duration every second while tracking
|
||||
Future.doWhile(() async {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
if (_isTracking.value && _trackingStartTime != null) {
|
||||
_trackingDuration.value = DateTime.now().difference(_trackingStartTime!).inSeconds;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
String _formatDuration(int seconds) {
|
||||
int hours = seconds ~/ 3600;
|
||||
int minutes = (seconds % 3600) ~/ 60;
|
||||
int secs = seconds % 60;
|
||||
|
||||
if (hours > 0) {
|
||||
return '${hours}h ${minutes}m ${secs}s';
|
||||
} else if (minutes > 0) {
|
||||
return '${minutes}m ${secs}s';
|
||||
} else {
|
||||
return '${secs}s';
|
||||
}
|
||||
}
|
||||
|
||||
// Zusätzliche Helper-Methoden
|
||||
|
||||
/// Togglet das Tracking (Start/Stop)
|
||||
Future<void> toggleTracking() async {
|
||||
if (_isTracking.value) {
|
||||
await stopTracking();
|
||||
} else {
|
||||
await startTracking();
|
||||
}
|
||||
}
|
||||
|
||||
/// Öffnet die Location Einstellungen
|
||||
Future<void> openLocationSettings() async {
|
||||
await GeolocationService.openLocationSettings();
|
||||
}
|
||||
|
||||
/// Öffnet die App Einstellungen
|
||||
Future<void> openAppSettings() async {
|
||||
await GeolocationService.openAppSettings();
|
||||
}
|
||||
|
||||
/// Exportiert Tracking-Daten als Map
|
||||
Map<String, dynamic> exportTrackingData() {
|
||||
return {
|
||||
'totalDistance': _totalDistance.value,
|
||||
'averageSpeed': _averageSpeed.value,
|
||||
'maxSpeed': _maxSpeed.value,
|
||||
'duration': _trackingDuration.value,
|
||||
'pointCount': _positionHistory.length,
|
||||
'positions': _positionHistory.map((p) => {
|
||||
'latitude': p.latitude,
|
||||
'longitude': p.longitude,
|
||||
'accuracy': p.accuracy,
|
||||
'speed': p.speed,
|
||||
'timestamp': p.timestamp.toIso8601String(),
|
||||
}).toList(),
|
||||
};
|
||||
}
|
||||
|
||||
/// Berechnet Mittelpunkt aller getrackten Positionen
|
||||
Map<String, double>? getTrackCenter() {
|
||||
if (_positionHistory.isEmpty) return null;
|
||||
return GeoUtils.calculateCentroid(_positionHistory);
|
||||
}
|
||||
|
||||
/// Berechnet Bounding Box aller getrackten Positionen
|
||||
Map<String, double>? getTrackBounds() {
|
||||
if (_positionHistory.isEmpty) return null;
|
||||
return GeoUtils.calculateBoundingBox(_positionHistory);
|
||||
}
|
||||
|
||||
/// Resettet alle Werte
|
||||
void reset() {
|
||||
stopTracking();
|
||||
_currentPosition.value = null;
|
||||
_previousPosition.value = null;
|
||||
_statusText.value = 'Noch keine Position ermittelt';
|
||||
_resetTrackingStats();
|
||||
}
|
||||
|
||||
// Getter für UI
|
||||
bool get hasPosition => _currentPosition.value != null;
|
||||
double get currentAccuracy => _currentPosition.value?.accuracy ?? 0.0;
|
||||
double get currentSpeedKmh => GeoUtils.mpsToKmh(_currentPosition.value?.speed ?? 0.0);
|
||||
String get formattedPosition {
|
||||
if (_currentPosition.value == null) return 'Keine Position verfügbar';
|
||||
return GeolocationService.positionToString(_currentPosition.value!);
|
||||
}
|
||||
}
|
||||
270
lib/controllers/geolocation_controller.dart
Normal file
270
lib/controllers/geolocation_controller.dart
Normal file
@@ -0,0 +1,270 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import '../../services/geolocation.dart';
|
||||
|
||||
/// GetX Controller für Geolocation Funktionalität
|
||||
class GeolocationController extends GetxController {
|
||||
// Reactive Variablen
|
||||
final _currentPosition = Rxn<Position>();
|
||||
final _statusText = 'Noch keine Position ermittelt'.obs;
|
||||
final _isTracking = false.obs;
|
||||
final _isLoading = false.obs;
|
||||
|
||||
// Getter für reactive Variablen
|
||||
Position? get currentPosition => _currentPosition.value;
|
||||
String get statusText => _statusText.value;
|
||||
bool get isTracking => _isTracking.value;
|
||||
bool get isLoading => _isLoading.value;
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// Cleanup beim Schließen des Controllers
|
||||
stopTracking();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
/// Holt die aktuelle Position einmalig
|
||||
Future<void> getCurrentPosition() async {
|
||||
try {
|
||||
_isLoading.value = true;
|
||||
_statusText.value = 'Position wird ermittelt...';
|
||||
|
||||
Position? position = await GeolocationService.getCurrentPosition();
|
||||
|
||||
if (position != null) {
|
||||
_currentPosition.value = position;
|
||||
_statusText.value = GeolocationService.positionToString(position);
|
||||
|
||||
// Erfolgs-Snackbar anzeigen
|
||||
Get.snackbar(
|
||||
'Position ermittelt',
|
||||
'Aktuelle Position wurde erfolgreich abgerufen',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} else {
|
||||
_statusText.value = 'Position konnte nicht ermittelt werden';
|
||||
|
||||
// Fehler-Snackbar anzeigen
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Position konnte nicht ermittelt werden',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Abrufen der Position: $e';
|
||||
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Unerwarteter Fehler: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} finally {
|
||||
_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Startet kontinuierliches Position Tracking
|
||||
Future<void> startTracking() async {
|
||||
if (_isTracking.value) return;
|
||||
|
||||
try {
|
||||
_isLoading.value = true;
|
||||
_statusText.value = 'Tracking wird gestartet...';
|
||||
|
||||
bool success = await GeolocationService.startPositionStream(
|
||||
onPositionChanged: (Position position) {
|
||||
_currentPosition.value = position;
|
||||
_statusText.value = GeolocationService.positionToString(position);
|
||||
},
|
||||
onError: (String error) {
|
||||
_statusText.value = 'Tracking Fehler: $error';
|
||||
_isTracking.value = false;
|
||||
|
||||
Get.snackbar(
|
||||
'Tracking Fehler',
|
||||
error,
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
},
|
||||
accuracy: LocationAccuracy.high,
|
||||
distanceFilter: 5, // Updates alle 5 Meter
|
||||
);
|
||||
|
||||
if (success) {
|
||||
_isTracking.value = true;
|
||||
_statusText.value = 'Tracking aktiv - Warten auf erste Position...';
|
||||
|
||||
Get.snackbar(
|
||||
'Tracking gestartet',
|
||||
'Position wird kontinuierlich überwacht',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} else {
|
||||
_statusText.value = 'Tracking konnte nicht gestartet werden';
|
||||
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Tracking konnte nicht gestartet werden',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Starten des Trackings: $e';
|
||||
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Tracking-Fehler: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} finally {
|
||||
_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Stoppt das Position Tracking
|
||||
Future<void> stopTracking() async {
|
||||
if (!_isTracking.value) return;
|
||||
|
||||
try {
|
||||
await GeolocationService.stopPositionStream();
|
||||
_isTracking.value = false;
|
||||
_statusText.value = 'Tracking gestoppt';
|
||||
|
||||
Get.snackbar(
|
||||
'Tracking gestoppt',
|
||||
'Position wird nicht mehr überwacht',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} catch (e) {
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Fehler beim Stoppen des Trackings: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Togglet das Tracking (Start/Stop)
|
||||
Future<void> toggleTracking() async {
|
||||
if (_isTracking.value) {
|
||||
await stopTracking();
|
||||
} else {
|
||||
await startTracking();
|
||||
}
|
||||
}
|
||||
|
||||
/// Prüft Permission Status
|
||||
Future<void> checkPermissions() async {
|
||||
try {
|
||||
_isLoading.value = true;
|
||||
_statusText.value = 'Berechtigungen werden geprüft...';
|
||||
|
||||
LocationPermission permission = await GeolocationService.checkPermission();
|
||||
bool serviceEnabled = await GeolocationService.isLocationServiceEnabled();
|
||||
|
||||
_statusText.value = 'Service aktiv: $serviceEnabled\n'
|
||||
'Berechtigung: ${LocationPermissionHelper.getPermissionStatusText(permission)}';
|
||||
|
||||
// Detaillierte Information in Snackbar
|
||||
String permissionStatus = LocationPermissionHelper.getPermissionStatusText(permission);
|
||||
Get.snackbar(
|
||||
'Berechtigungs-Status',
|
||||
'Location Service: ${serviceEnabled ? "Aktiv" : "Inaktiv"}\n$permissionStatus',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
duration: const Duration(seconds: 4),
|
||||
);
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Prüfen der Berechtigungen: $e';
|
||||
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Berechtigungen konnten nicht geprüft werden: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} finally {
|
||||
_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Öffnet die Location Einstellungen
|
||||
Future<void> openLocationSettings() async {
|
||||
try {
|
||||
bool opened = await GeolocationService.openLocationSettings();
|
||||
|
||||
if (opened) {
|
||||
Get.snackbar(
|
||||
'Einstellungen geöffnet',
|
||||
'Location-Einstellungen wurden geöffnet',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} else {
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Location-Einstellungen konnten nicht geöffnet werden',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Fehler beim Öffnen der Location-Einstellungen: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Öffnet die App Einstellungen
|
||||
Future<void> openAppSettings() async {
|
||||
try {
|
||||
bool opened = await GeolocationService.openAppSettings();
|
||||
|
||||
if (opened) {
|
||||
Get.snackbar(
|
||||
'Einstellungen geöffnet',
|
||||
'App-Einstellungen wurden geöffnet',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
} else {
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'App-Einstellungen konnten nicht geöffnet werden',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Fehler beim Öffnen der App-Einstellungen: $e',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Formatiert die aktuelle Position als lesbaren String
|
||||
String get formattedPosition {
|
||||
if (_currentPosition.value == null) return 'Keine Position verfügbar';
|
||||
return GeolocationService.positionToString(_currentPosition.value!);
|
||||
}
|
||||
|
||||
/// Prüft ob eine Position verfügbar ist
|
||||
bool get hasPosition => _currentPosition.value != null;
|
||||
|
||||
/// Holt die Genauigkeit der aktuellen Position
|
||||
double get currentAccuracy => _currentPosition.value?.accuracy ?? 0.0;
|
||||
|
||||
/// Holt die Geschwindigkeit der aktuellen Position in km/h
|
||||
double get currentSpeedKmh {
|
||||
if (_currentPosition.value?.speed == null) return 0.0;
|
||||
return (_currentPosition.value!.speed * 3.6); // m/s zu km/h
|
||||
}
|
||||
|
||||
/// Resettet alle Werte auf ihre Anfangszustände
|
||||
void reset() {
|
||||
stopTracking();
|
||||
_currentPosition.value = null;
|
||||
_statusText.value = 'Noch keine Position ermittelt';
|
||||
_isTracking.value = false;
|
||||
_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user