import 'package:geolocator/geolocator.dart'; import 'package:permission_handler/permission_handler.dart'; import 'dart:math' as math; class LocationService { static Future checkLocationPermission() async { LocationPermission permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); } return permission == LocationPermission.whileInUse || permission == LocationPermission.always; } static Future checkCameraPermission() async { PermissionStatus status = await Permission.camera.status; if (status.isDenied) { status = await Permission.camera.request(); } return status.isGranted; } static Future getCurrentPosition() async { try { bool hasPermission = await checkLocationPermission(); if (!hasPermission) return null; return await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.high, ); } catch (e) { return null; } } static Stream? getPositionStream() async* { bool hasPermission = await checkLocationPermission(); if (!hasPermission) { yield* Stream.empty(); return; } const LocationSettings locationSettings = LocationSettings( accuracy: LocationAccuracy.high, distanceFilter: 1, ); yield* Geolocator.getPositionStream(locationSettings: locationSettings); } static double calculateDistance( double lat1, double lon1, double lat2, double lon2, ) { return Geolocator.distanceBetween(lat1, lon1, lat2, lon2); } static bool isWithinRange( double currentLat, double currentLon, double targetLat, double targetLon, { double rangeInMeters = 50.0, }) { double distance = calculateDistance( currentLat, currentLon, targetLat, targetLon, ); return distance <= rangeInMeters; } static double getBearing( double startLat, double startLng, double endLat, double endLng, ) { final startLatRad = startLat * (math.pi / 180); final startLngRad = startLng * (math.pi / 180); final endLatRad = endLat * (math.pi / 180); final endLngRad = endLng * (math.pi / 180); double dLng = endLngRad - startLngRad; double y = math.sin(dLng) * math.cos(endLatRad); double x = math.cos(startLatRad) * math.sin(endLatRad) - math.sin(startLatRad) * math.cos(endLatRad) * math.cos(dLng); double bearing = math.atan2(y, x); return (bearing * (180 / math.pi) + 360) % 360; } }