import 'dart:async';
import 'package:geolocator/geolocator.dart';
import 'package:latlong2/latlong.dart';
/// Location access used by map, guide and routing features.
class LocationService {
const LocationService();
Future<bool> ensurePermission() async {
try {
final serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) return false;
var permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
}
return permission == LocationPermission.whileInUse ||
permission == LocationPermission.always;
} catch (_) {
return false;
}
}
Future<LatLng?> currentPosition() async {
try {
if (!await ensurePermission()) return null;
final position = await Geolocator.getCurrentPosition(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.high,
timeLimit: Duration(seconds: 12),
),
);
return LatLng(position.latitude, position.longitude);
} on TimeoutException {
return _lastKnownPosition();
} catch (_) {
// Use the last known position after a transient location error.
return _lastKnownPosition();
}
}
Future<LatLng?> _lastKnownPosition() async {
try {
final position = await Geolocator.getLastKnownPosition();
if (position == null) return null;
return LatLng(position.latitude, position.longitude);
} catch (_) {
return null;
}
}
Stream<LatLng> watchPosition() async* {
try {
if (!await ensurePermission()) return;
const settings = LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 4,
);
await for (final position in Geolocator.getPositionStream(
locationSettings: settings,
)) {
yield LatLng(position.latitude, position.longitude);
}
} catch (_) {
// Location errors are handled by callers.
return;
}
}
}

