import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_polyline_algorithm/google_polyline_algorithm.dart'; import 'package:sefer_driver/constant/api_key.dart'; import 'package:sefer_driver/constant/box_name.dart'; import 'package:sefer_driver/constant/links.dart'; import 'package:sefer_driver/controller/functions/crud.dart'; import 'package:sefer_driver/controller/functions/tts.dart'; import '../../../main.dart'; /// Handles map-related logic: fetching routes, drawing polylines, and managing markers. class NavigationService extends GetxService { final CRUD _crud = CRUD(); final TextToSpeechController _tts = Get.put(TextToSpeechController()); final RxSet markers = {}.obs; final RxSet polylines = {}.obs; final RxString currentInstruction = "".obs; BitmapDescriptor carIcon = BitmapDescriptor.defaultMarker; BitmapDescriptor passengerIcon = BitmapDescriptor.defaultMarker; BitmapDescriptor startIcon = BitmapDescriptor.defaultMarker; BitmapDescriptor endIcon = BitmapDescriptor.defaultMarker; @override void onInit() { super.onInit(); _loadCustomIcons(); } void _loadCustomIcons() async { carIcon = await _createBitmapDescriptor('assets/images/car.png'); passengerIcon = await _createBitmapDescriptor('assets/images/picker.png'); startIcon = await _createBitmapDescriptor('assets/images/A.png'); endIcon = await _createBitmapDescriptor('assets/images/b.png'); } Future _createBitmapDescriptor(String assetName) { return BitmapDescriptor.fromAssetImage( ImageConfiguration( size: const Size(30, 35), devicePixelRatio: Get.pixelRatio), assetName, ); } Future?> getRoute({ required LatLng origin, required LatLng destination, }) async { final url = '${AppLink.googleMapsLink}directions/json?language=${box.read(BoxName.lang)}&destination=${destination.latitude},${destination.longitude}&origin=${origin.latitude},${origin.longitude}&key=${AK.mapAPIKEY}'; final response = await _crud.getGoogleApi(link: url, payload: {}); if (response != null && response['routes'].isNotEmpty) { return response['routes'][0]; } return null; } void drawRoute(Map routeData, {Color color = Colors.blue}) { final pointsString = routeData["overview_polyline"]["points"]; final points = decodePolyline(pointsString) .map((p) => LatLng(p[0].toDouble(), p[1].toDouble())) .toList(); final polyline = Polyline( polylineId: PolylineId(routeData["summary"] ?? DateTime.now().toString()), points: points, width: 8, color: color, ); polylines.add(polyline); } void updateCarMarker(LatLng position, double heading) { markers.removeWhere((m) => m.markerId.value == 'MyLocation'); markers.add( Marker( markerId: MarkerId('MyLocation'.tr), position: position, icon: carIcon, rotation: heading, anchor: const Offset(0.5, 0.5), flat: true, ), ); } void setInitialMarkers( LatLng passengerLocation, LatLng passengerDestination) { markers.clear(); markers.add(Marker( markerId: const MarkerId('passengerLocation'), position: passengerLocation, icon: passengerIcon, )); markers.add(Marker( markerId: const MarkerId('passengerDestination'), position: passengerDestination, icon: endIcon, )); } void clearRoutes() { polylines.clear(); currentInstruction.value = ""; } }