Files
Fondex-Driver/lib/controllers/parcel_tracking_controller.dart
2025-12-08 23:25:00 +05:00

865 lines
31 KiB
Dart

// import 'dart:async';
// import 'dart:convert';
// import 'dart:developer';
// import 'package:driver/constant/collection_name.dart';
// import 'package:driver/constant/constant.dart';
// import 'package:driver/constant/show_toast_dialog.dart';
// import 'package:driver/themes/app_them_data.dart';
// import 'package:driver/utils/fire_store_utils.dart';
// import 'package:flutter_polyline_points/flutter_polyline_points.dart';
// import 'package:get/get.dart';
// import 'package:google_maps_flutter/google_maps_flutter.dart';
// import 'package:latlong2/latlong.dart' as location;
// import 'package:flutter_map/flutter_map.dart' as flutterMap;
// import 'package:http/http.dart' as http;
// import '../models/parcel_order_model.dart';
// import '../models/user_model.dart';
// import 'package:flutter/material.dart';
//
// class ParcelTrackingController extends GetxController {
// GoogleMapController? mapController;
// final flutterMap.MapController osmMapController = flutterMap.MapController();
//
// Rx<UserModel> driverUserModel = UserModel().obs;
// Rx<ParcelOrderModel> orderModel = ParcelOrderModel().obs;
// RxBool isLoading = true.obs;
// RxString type = "parcelOrder".obs;
//
// StreamSubscription? orderSubscription;
// StreamSubscription? driverSubscription;
//
// // Google Map markers & polylines
// RxMap<MarkerId, Marker> markers = <MarkerId, Marker>{}.obs;
// RxMap<PolylineId, Polyline> polyLines = <PolylineId, Polyline>{}.obs;
//
// // OSM map markers & route
// RxList<flutterMap.Marker> osmMarkers = <flutterMap.Marker>[].obs;
// RxList<location.LatLng> routePoints = <location.LatLng>[].obs;
//
// BitmapDescriptor? pickupIcon;
// BitmapDescriptor? dropoffIcon;
// BitmapDescriptor? driverIcon;
//
// PolylinePoints polylinePoints = PolylinePoints(apiKey: Constant.mapAPIKey);
//
// Rx<location.LatLng> source = location.LatLng(0.0, 0.0).obs;
// Rx<location.LatLng> destination = location.LatLng(0.0, 0.0).obs;
//
// @override
// void onInit() {
// super.onInit();
// _loadIcons();
// _initArguments();
// }
//
// @override
// void onClose() {
// orderSubscription?.cancel();
// driverSubscription?.cancel();
// ShowToastDialog.closeLoader();
// super.onClose();
// }
//
// Future<void> _initArguments() async {
// final args = Get.arguments;
// if (args != null && args['parcelOrder'] != null) {
// orderModel.value = args['parcelOrder'];
// type.value = args['type'] ?? "parcelOrder";
// _listenToOrder();
// } else {
// ShowToastDialog.showToast("Order data not found");
// Get.back();
// }
// }
//
// /// Listen to order and driver updates
// void _listenToOrder() {
// orderSubscription = FireStoreUtils.fireStore.collection(CollectionName.parcelOrders).doc(orderModel.value.id).snapshots().listen((event) {
// if (event.data() != null) {
// orderModel.value = ParcelOrderModel.fromJson(event.data()!);
//
// // listen driver
// if (orderModel.value.driverId != null) {
// driverSubscription = FireStoreUtils.fireStore.collection(CollectionName.users).doc(orderModel.value.driverId).snapshots().listen((driverSnap) {
// if (driverSnap.data() != null) {
// driverUserModel.value = UserModel.fromJson(driverSnap.data()!);
// _updateTracking();
// }
// });
// }
//
// if (orderModel.value.status == Constant.orderCompleted) {
// Get.back();
// }
// }
// });
//
// isLoading.value = false;
// }
//
// void _updateTracking() {
// if (Constant.selectedMapType == 'google') {
// _updateGoogleMap();
// } else {
// _updateOsmMap();
// }
// }
//
// void _updateGoogleMap() async {
// final driverLat = driverUserModel.value.location?.latitude?.toDouble();
// final driverLng = driverUserModel.value.location?.longitude?.toDouble();
// if (driverLat == null || driverLng == null) return;
//
// double? dstLat;
// double? dstLng;
//
// if (orderModel.value.status == Constant.driverAccepted) {
// dstLat = orderModel.value.senderLatLong?.latitude?.toDouble();
// dstLng = orderModel.value.senderLatLong?.longitude?.toDouble();
// } else {
// dstLat = orderModel.value.receiverLatLong?.latitude?.toDouble();
// dstLng = orderModel.value.receiverLatLong?.longitude?.toDouble();
// }
//
// if (dstLat == null || dstLng == null) return;
//
// final result = await polylinePoints.getRouteBetweenCoordinates(
// request: PolylineRequest(
// origin: PointLatLng(driverLat, driverLng),
// destination: PointLatLng(dstLat, dstLng),
// mode: TravelMode.driving,
// ),
// );
//
// final List<LatLng> routeCoords = [];
// for (var p in result.points) {
// routeCoords.add(LatLng(p.latitude, p.longitude));
// }
//
// markers.clear();
// polyLines.clear();
//
// _addGoogleMarker(driverLat, driverLng, "Driver", driverIcon!);
// _addGoogleMarker(orderModel.value.senderLatLong?.latitude?.toDouble(), orderModel.value.senderLatLong?.longitude?.toDouble(), "Pickup", pickupIcon!);
// _addGoogleMarker(orderModel.value.receiverLatLong?.latitude?.toDouble(), orderModel.value.receiverLatLong?.longitude?.toDouble(), "Dropoff", dropoffIcon!);
//
// if (routeCoords.isNotEmpty) {
// PolylineId id = const PolylineId("route");
// Polyline polyline = Polyline(
// polylineId: id,
// color: AppThemeData.primary300,
// width: 6,
// points: routeCoords,
// );
// polyLines[id] = polyline;
// }
//
// if (routeCoords.length >= 2) {
// await _animateCameraBounds(routeCoords.first, routeCoords.last);
// }
//
// update();
// }
//
// void _addGoogleMarker(double? lat, double? lng, String id, BitmapDescriptor icon) {
// if (lat == null || lng == null) return;
// markers[MarkerId(id)] = Marker(
// markerId: MarkerId(id),
// position: LatLng(lat, lng),
// icon: icon,
// );
// }
//
// Future<void> _animateCameraBounds(LatLng src, LatLng dest) async {
// if (mapController == null) return;
//
// LatLngBounds bounds;
// if (src.latitude > dest.latitude && src.longitude > dest.longitude) {
// bounds = LatLngBounds(southwest: dest, northeast: src);
// } else if (src.longitude > dest.longitude) {
// bounds = LatLngBounds(southwest: LatLng(src.latitude, dest.longitude), northeast: LatLng(dest.latitude, src.longitude));
// } else if (src.latitude > dest.latitude) {
// bounds = LatLngBounds(southwest: LatLng(dest.latitude, src.longitude), northeast: LatLng(src.latitude, dest.longitude));
// } else {
// bounds = LatLngBounds(southwest: src, northeast: dest);
// }
//
// CameraUpdate cameraUpdate = CameraUpdate.newLatLngBounds(bounds, 60);
// await mapController?.animateCamera(cameraUpdate);
// }
//
// void _updateOsmMap() async {
// final driverLat = driverUserModel.value.location?.latitude?.toDouble() ?? 0.0;
// final driverLng = driverUserModel.value.location?.longitude?.toDouble() ?? 0.0;
//
// double? dstLat;
// double? dstLng;
//
// if (orderModel.value.status == Constant.driverAccepted) {
// dstLat = orderModel.value.senderLatLong?.latitude?.toDouble();
// dstLng = orderModel.value.senderLatLong?.longitude?.toDouble();
// } else {
// dstLat = orderModel.value.receiverLatLong?.latitude?.toDouble();
// dstLng = orderModel.value.receiverLatLong?.longitude?.toDouble();
// }
//
// if (dstLat == null || dstLng == null) return;
//
// source.value = location.LatLng(driverLat, driverLng);
// destination.value = location.LatLng(dstLat, dstLng);
//
// await _fetchOsmRoute(source.value, destination.value);
//
// // Update OSM markers
// osmMarkers.clear();
// osmMarkers.addAll([
// flutterMap.Marker(
// point: source.value,
// width: 40,
// height: 40,
// child: Image.asset('assets/images/food_delivery.png', width: 40),
// ),
// flutterMap.Marker(
// point: location.LatLng(
// orderModel.value.senderLatLong?.latitude?.toDouble() ?? 0.0,
// orderModel.value.senderLatLong?.longitude?.toDouble() ?? 0.0,
// ),
// width: 40,
// height: 40,
// child: Image.asset('assets/images/pickup.png', width: 40),
// ),
// flutterMap.Marker(
// point: location.LatLng(
// orderModel.value.receiverLatLong?.latitude?.toDouble() ?? 0.0,
// orderModel.value.receiverLatLong?.longitude?.toDouble() ?? 0.0,
// ),
// width: 40,
// height: 40,
// child: Image.asset('assets/images/dropoff.png', width: 40),
// ),
// ]);
//
// osmMapController.move(source.value, 14);
// update();
// }
//
// Future<void> _fetchOsmRoute(location.LatLng src, location.LatLng dest) async {
// try {
// final url =
// Uri.parse('https://router.project-osrm.org/route/v1/driving/${src.longitude},${src.latitude};${dest.longitude},${dest.latitude}?overview=full&geometries=geojson');
// final response = await http.get(url);
// if (response.statusCode == 200) {
// final decoded = json.decode(response.body);
// final geometry = decoded['routes'][0]['geometry']['coordinates'];
// routePoints.clear();
// for (var coord in geometry) {
// final lon = coord[0];
// final lat = coord[1];
// routePoints.add(location.LatLng(lat, lon));
// }
// }
// } catch (e) {
// log("Error fetching OSM route: $e");
// }
// }
//
// Future<void> _loadIcons() async {
// if (Constant.selectedMapType == 'google') {
// pickupIcon = BitmapDescriptor.fromBytes(await Constant().getBytesFromAsset('assets/images/pickup.png', 100));
// dropoffIcon = BitmapDescriptor.fromBytes(await Constant().getBytesFromAsset('assets/images/dropoff.png', 100));
// driverIcon = BitmapDescriptor.fromBytes(await Constant().getBytesFromAsset('assets/images/food_delivery.png', 80));
// }
// }
// }
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:driver/constant/collection_name.dart';
import 'package:driver/constant/constant.dart';
import 'package:driver/constant/show_toast_dialog.dart';
import 'package:driver/themes/app_them_data.dart';
import 'package:driver/utils/fire_store_utils.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:get/get.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:latlong2/latlong.dart' as location;
import 'package:flutter_map/flutter_map.dart' as flutterMap;
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import '../models/parcel_order_model.dart';
import '../models/user_model.dart';
class ParcelTrackingController extends GetxController {
GoogleMapController? mapController;
final flutterMap.MapController osmMapController = flutterMap.MapController();
Rx<UserModel> driverUserModel = UserModel().obs;
Rx<ParcelOrderModel> orderModel = ParcelOrderModel().obs;
RxBool isLoading = true.obs;
RxString type = "parcelOrder".obs;
StreamSubscription? orderSubscription;
StreamSubscription? driverSubscription;
// Google Maps
RxMap<MarkerId, Marker> markers = <MarkerId, Marker>{}.obs;
RxMap<PolylineId, Polyline> polyLines = <PolylineId, Polyline>{}.obs;
// OSM Map
RxList<flutterMap.Marker> osmMarkers = <flutterMap.Marker>[].obs;
RxList<location.LatLng> routePoints = <location.LatLng>[].obs;
BitmapDescriptor? pickupIcon;
BitmapDescriptor? dropoffIcon;
BitmapDescriptor? driverIcon;
PolylinePoints polylinePoints = PolylinePoints(apiKey: Constant.mapAPIKey);
Rx<location.LatLng> source = location.LatLng(0.0, 0.0).obs;
Rx<location.LatLng> destination = location.LatLng(0.0, 0.0).obs;
@override
void onInit() {
super.onInit();
_initArguments();
}
@override
void onClose() {
orderSubscription?.cancel();
driverSubscription?.cancel();
ShowToastDialog.closeLoader();
super.onClose();
}
Future<void> _initArguments() async {
await _loadIcons();
final args = Get.arguments;
if (args != null && args['parcelOrder'] != null) {
orderModel.value = args['parcelOrder'];
type.value = args['type'] ?? "parcelOrder";
_listenToOrder();
} else {
ShowToastDialog.showToast("Order data not found");
Get.back();
}
isLoading.value = false;
}
void _listenToOrder() {
orderSubscription =
FireStoreUtils.fireStore.collection(CollectionName.parcelOrders).doc(orderModel.value.id).snapshots().listen((event) {
if (event.data() != null) {
orderModel.value = ParcelOrderModel.fromJson(event.data()!);
// Listen to driver updates
if (orderModel.value.driverId != null) {
driverSubscription =
FireStoreUtils.fireStore.collection(CollectionName.users).doc(orderModel.value.driverId).snapshots().listen((driverSnap) {
if (driverSnap.data() != null) {
driverUserModel.value = UserModel.fromJson(driverSnap.data()!);
_updateTracking();
}
});
}
if (orderModel.value.status == Constant.orderCompleted) {
Get.back();
}
}
});
}
void _updateTracking() {
if (Constant.selectedMapType == 'google') {
_updateGoogleMap();
} else {
_updateOsmMap();
}
}
void _updateGoogleMap() async {
final driverLat = driverUserModel.value.location?.latitude?.toDouble();
final driverLng = driverUserModel.value.location?.longitude?.toDouble();
if (driverLat == null || driverLng == null) return;
double? dstLat;
double? dstLng;
// Decide destination based on order status
if (orderModel.value.status == Constant.driverAccepted) {
dstLat = orderModel.value.senderLatLong?.latitude?.toDouble();
dstLng = orderModel.value.senderLatLong?.longitude?.toDouble();
} else if ([Constant.orderInTransit].contains(orderModel.value.status)) {
dstLat = orderModel.value.receiverLatLong?.latitude?.toDouble();
dstLng = orderModel.value.receiverLatLong?.longitude?.toDouble();
} else {
return;
}
if (dstLat == null || dstLng == null) return;
final result = await polylinePoints.getRouteBetweenCoordinates(
request: PolylineRequest(
origin: PointLatLng(driverLat, driverLng),
destination: PointLatLng(dstLat, dstLng),
mode: TravelMode.driving,
),
);
final List<LatLng> routeCoords = [];
for (var p in result.points) {
routeCoords.add(LatLng(p.latitude, p.longitude));
}
markers.clear();
polyLines.clear();
// Add markers
_addGoogleMarker(driverLat, driverLng, "Driver", driverIcon!);
if (orderModel.value.status == Constant.driverAccepted) {
_addGoogleMarker(orderModel.value.senderLatLong?.latitude?.toDouble(), orderModel.value.senderLatLong?.longitude?.toDouble(),
"Pickup", pickupIcon!);
} else {
_addGoogleMarker(orderModel.value.receiverLatLong?.latitude?.toDouble(), orderModel.value.receiverLatLong?.longitude?.toDouble(),
"Dropoff", dropoffIcon!);
}
// Add polyline
if (routeCoords.isNotEmpty) {
PolylineId id = const PolylineId("route");
Polyline polyline = Polyline(
polylineId: id,
color: AppThemeData.primary300,
width: 6,
points: routeCoords,
);
polyLines[id] = polyline;
}
if (routeCoords.length >= 2) {
await _animateCameraBounds(routeCoords.first, routeCoords.last);
}
update();
}
void _addGoogleMarker(double? lat, double? lng, String id, BitmapDescriptor icon) {
if (lat == null || lng == null) return;
markers[MarkerId(id)] = Marker(
markerId: MarkerId(id),
position: LatLng(lat, lng),
icon: icon,
);
}
Future<void> _animateCameraBounds(LatLng src, LatLng dest) async {
if (mapController == null) return;
LatLngBounds bounds;
if (src.latitude > dest.latitude && src.longitude > dest.longitude) {
bounds = LatLngBounds(southwest: dest, northeast: src);
} else if (src.longitude > dest.longitude) {
bounds = LatLngBounds(southwest: LatLng(src.latitude, dest.longitude), northeast: LatLng(dest.latitude, src.longitude));
} else if (src.latitude > dest.latitude) {
bounds = LatLngBounds(southwest: LatLng(dest.latitude, src.longitude), northeast: LatLng(src.latitude, dest.longitude));
} else {
bounds = LatLngBounds(southwest: src, northeast: dest);
}
CameraUpdate cameraUpdate = CameraUpdate.newLatLngBounds(bounds, 60);
await mapController?.animateCamera(cameraUpdate);
}
void _updateOsmMap() async {
final driverLat = driverUserModel.value.location?.latitude?.toDouble() ?? 0.0;
final driverLng = driverUserModel.value.location?.longitude?.toDouble() ?? 0.0;
double? dstLat;
double? dstLng;
if (orderModel.value.status == Constant.driverAccepted) {
dstLat = orderModel.value.senderLatLong?.latitude?.toDouble();
dstLng = orderModel.value.senderLatLong?.longitude?.toDouble();
} else if ([Constant.orderInTransit].contains(orderModel.value.status)) {
dstLat = orderModel.value.receiverLatLong?.latitude?.toDouble();
dstLng = orderModel.value.receiverLatLong?.longitude?.toDouble();
} else {
return;
}
if (dstLat == null || dstLng == null) return;
source.value = location.LatLng(driverLat, driverLng);
destination.value = location.LatLng(dstLat, dstLng);
await _fetchOsmRoute(source.value, destination.value);
// Update OSM markers
osmMarkers.clear();
osmMarkers.add(
flutterMap.Marker(
point: source.value,
width: 40,
height: 40,
child: CachedNetworkImage(
width: 50,
height: 50,
imageUrl: Constant.sectionModel!.markerIcon.toString(),
placeholder: (context, url) => Constant.loader(),
errorWidget: (context, url, error) => SizedBox(
width: 30,
height: 30,
child: CircularProgressIndicator(strokeWidth: 2),
),
),
),
);
if (orderModel.value.status == Constant.driverAccepted) {
osmMarkers.add(
flutterMap.Marker(
point: location.LatLng(
orderModel.value.senderLatLong?.latitude?.toDouble() ?? 0.0,
orderModel.value.senderLatLong?.longitude?.toDouble() ?? 0.0,
),
width: 40,
height: 40,
child: Image.asset('assets/images/pickup.png', width: 40),
),
);
} else {
osmMarkers.add(
flutterMap.Marker(
point: location.LatLng(
orderModel.value.receiverLatLong?.latitude?.toDouble() ?? 0.0,
orderModel.value.receiverLatLong?.longitude?.toDouble() ?? 0.0,
),
width: 40,
height: 40,
child: Image.asset('assets/images/dropoff.png', width: 40),
),
);
}
osmMapController.move(source.value, 14);
update();
}
Future<void> _fetchOsmRoute(location.LatLng src, location.LatLng dest) async {
try {
final url = Uri.parse(
'https://router.project-osrm.org/route/v1/driving/${src.longitude},${src.latitude};${dest.longitude},${dest.latitude}?overview=full&geometries=geojson');
final response = await http.get(url);
if (response.statusCode == 200) {
final decoded = json.decode(response.body);
final geometry = decoded['routes'][0]['geometry']['coordinates'];
routePoints.clear();
for (var coord in geometry) {
final lon = coord[0];
final lat = coord[1];
routePoints.add(location.LatLng(lat, lon));
}
}
} catch (e) {
log("Error fetching OSM route: $e");
}
}
Future<void> _loadIcons() async {
if (Constant.selectedMapType == 'google') {
pickupIcon = BitmapDescriptor.fromBytes(await Constant().getBytesFromAsset('assets/images/pickup.png', 100));
dropoffIcon = BitmapDescriptor.fromBytes(await Constant().getBytesFromAsset('assets/images/dropoff.png', 100));
driverIcon = BitmapDescriptor.fromBytes(Constant.sectionModel!.markerIcon == null || Constant.sectionModel!.markerIcon!.isEmpty
? await Constant().getBytesFromAsset('assets/images/ic_cab.png', 50)
: await Constant().getBytesFromUrl(Constant.sectionModel!.markerIcon.toString(), width: 120));
}
}
}
// import 'dart:async';
// import 'dart:convert';
// import 'dart:typed_data';
// import 'package:driver/constant/collection_name.dart';
// import 'package:driver/constant/constant.dart';
// import 'package:driver/constant/show_toast_dialog.dart';
// import 'package:driver/themes/app_them_data.dart';
// import 'package:driver/utils/fire_store_utils.dart';
// import 'package:flutter_polyline_points/flutter_polyline_points.dart';
// import 'package:get/get.dart';
// import 'package:google_maps_flutter/google_maps_flutter.dart';
// import 'package:latlong2/latlong.dart' as location;
// import 'package:flutter_map/flutter_map.dart' as flutterMap;
// import 'package:http/http.dart' as http;
// import '../models/parcel_order_model.dart';
// import '../models/user_model.dart';
//
// class ParcelTrackingController extends GetxController {
// GoogleMapController? mapController;
//
// Rx<UserModel> driverUserModel = UserModel().obs;
// Rx<ParcelOrderModel> orderModel = ParcelOrderModel().obs;
//
// RxBool isLoading = true.obs;
// RxString type = "".obs;
//
// StreamSubscription? orderSubscription;
// StreamSubscription? driverSubscription;
//
// RxMap<MarkerId, Marker> markers = <MarkerId, Marker>{}.obs;
// RxMap<PolylineId, Polyline> polyLines = <PolylineId, Polyline>{}.obs;
//
// BitmapDescriptor? departureIcon;
// BitmapDescriptor? destinationIcon;
// BitmapDescriptor? driverIcon;
//
// PolylinePoints polylinePoints = PolylinePoints(apiKey: Constant.mapAPIKey);
//
// // OSM
// final flutterMap.MapController osmMapController = flutterMap.MapController();
// Rx<location.LatLng> source = location.LatLng(0.0, 0.0).obs;
// Rx<location.LatLng> destination = location.LatLng(0.0, 0.0).obs;
// RxList<location.LatLng> routePoints = <location.LatLng>[].obs;
//
// @override
// void onInit() {
// addMarkerSetup();
// getArgument();
// super.onInit();
// }
//
// @override
// void onClose() {
// orderSubscription?.cancel();
// driverSubscription?.cancel();
// ShowToastDialog.closeLoader();
// super.onClose();
// }
//
// Future<void> getArgument() async {
// dynamic argumentData = Get.arguments;
// if (argumentData != null) {
// type.value = argumentData['type'] ?? "parcelOrder";
// if (type.value == "parcelOrder") {
// ParcelOrderModel argumentOrderModel = argumentData['parcelOrder'];
//
// /// Listen to Order
// orderSubscription = FireStoreUtils.fireStore.collection(CollectionName.parcelOrders).doc(argumentOrderModel.id).snapshots().listen((event) {
// if (event.data() != null) {
// orderModel.value = ParcelOrderModel.fromJson(event.data()!);
//
// /// Listen to Driver Live Location
// driverSubscription = FireStoreUtils.fireStore.collection(CollectionName.users).doc(orderModel.value.driverId).snapshots().listen((event) {
// if (event.data() != null) {
// driverUserModel.value = UserModel.fromJson(event.data()!);
//
// /// Update Map (Google or OSM)
// _updateTracking();
// }
// });
//
// if (orderModel.value.status == Constant.orderCompleted) {
// Get.back();
// }
// }
// });
// }
// }
// isLoading.value = false;
// update();
// }
//
// /// Update Tracking depending on order status
// void _updateTracking() {
// if (Constant.selectedMapType == 'google') {
// _updateGoogleMap();
// } else {
// _updateOsmMap();
// }
// }
//
// ///Google Map Route
// void _updateGoogleMap() async {
// double? srcLat = driverUserModel.value.location?.latitude?.toDouble();
// double? srcLng = driverUserModel.value.location?.longitude?.toDouble();
//
// double? dstLat;
// double? dstLng;
//
// if (orderModel.value.status == Constant.driverAccepted) {
// // Driver → Pickup
// dstLat = orderModel.value.senderLatLong?.latitude?.toDouble();
// dstLng = orderModel.value.senderLatLong?.longitude?.toDouble();
// } else {
// // Pickup → Destination
// dstLat = orderModel.value.receiverLatLong?.latitude?.toDouble();
// dstLng = orderModel.value.receiverLatLong?.longitude?.toDouble();
// }
//
// if (srcLat == null || srcLng == null || dstLat == null || dstLng == null) return;
//
// // Get Polyline
// List<LatLng> polylineCoordinates = [];
// PolylineRequest polylineRequest = PolylineRequest(
// origin: PointLatLng(srcLat, srcLng),
// destination: PointLatLng(dstLat, dstLng),
// mode: TravelMode.driving,
// );
//
// PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
// request: polylineRequest,
// );
//
// polylineCoordinates.clear();
// if (result.points.isNotEmpty) {
// for (var point in result.points) {
// polylineCoordinates.add(LatLng(point.latitude, point.longitude));
// }
// }
//
// // Add Markers
// markers.clear();
// addMarker(
// latitude: orderModel.value.senderLatLong?.latitude?.toDouble(),
// longitude: orderModel.value.senderLatLong?.longitude?.toDouble(),
// id: "Pickup",
// descriptor: departureIcon!,
// rotation: 0.0,
// );
// addMarker(
// latitude: orderModel.value.receiverLatLong?.latitude?.toDouble(),
// longitude: orderModel.value.receiverLatLong?.longitude?.toDouble(),
// id: "Dropoff",
// descriptor: destinationIcon!,
// rotation: 0.0,
// );
// addMarker(
// latitude: srcLat,
// longitude: srcLng,
// id: "Driver",
// descriptor: driverIcon!,
// rotation: driverUserModel.value.rotation?.toDouble() ?? 0.0,
// );
//
// // Add Polyline
// polyLines.clear();
// _addPolyLine(polylineCoordinates);
// }
//
// ///OSM Route
// void _updateOsmMap() async {
// source.value = location.LatLng(
// driverUserModel.value.location?.latitude?.toDouble() ?? 0.0,
// driverUserModel.value.location?.longitude?.toDouble() ?? 0.0,
// );
//
// if (orderModel.value.status == Constant.driverAccepted) {
// destination.value = location.LatLng(
// orderModel.value.senderLatLong?.latitude?.toDouble() ?? 0.0,
// orderModel.value.senderLatLong?.longitude?.toDouble() ?? 0.0,
// );
// } else {
// destination.value = location.LatLng(
// orderModel.value.receiverLatLong?.latitude?.toDouble() ?? 0.0,
// orderModel.value.receiverLatLong?.longitude?.toDouble() ?? 0.0,
// );
// }
//
// await fetchRoute(source.value, destination.value);
// animateToSource();
// }
//
// /// Google Add Marker
// void addMarker({
// required double? latitude,
// required double? longitude,
// required String id,
// required BitmapDescriptor descriptor,
// required double? rotation,
// }) {
// MarkerId markerId = MarkerId(id);
// Marker marker = Marker(
// markerId: markerId,
// icon: descriptor,
// position: LatLng(latitude ?? 0.0, longitude ?? 0.0),
// rotation: rotation ?? 0.0,
// );
// markers[markerId] = marker;
// }
//
// /// Setup Marker Icons
// Future<void> addMarkerSetup() async {
// if (Constant.selectedMapType == 'google') {
// final Uint8List pickup = await Constant().getBytesFromAsset('assets/images/pickup.png', 100);
// final Uint8List dropoff = await Constant().getBytesFromAsset('assets/images/dropoff.png', 100);
// final Uint8List driver = await Constant().getBytesFromAsset('assets/images/food_delivery.png', 60);
// departureIcon = BitmapDescriptor.fromBytes(pickup);
// destinationIcon = BitmapDescriptor.fromBytes(dropoff);
// driverIcon = BitmapDescriptor.fromBytes(driver);
// }
// }
//
// /// Google Add Polyline
// void _addPolyLine(List<LatLng> polylineCoordinates) {
// if (polylineCoordinates.isEmpty) return;
// PolylineId id = const PolylineId("poly");
// Polyline polyline = Polyline(
// polylineId: id,
// points: polylineCoordinates,
// width: 6,
// color: AppThemeData.primary300,
// );
// polyLines[id] = polyline;
// updateCameraLocation(polylineCoordinates.first, polylineCoordinates.last, mapController);
// }
//
// Future<void> updateCameraLocation(
// LatLng source,
// LatLng destination,
// GoogleMapController? mapController,
// ) async {
// if (mapController == null) return;
//
// LatLngBounds bounds;
// if (source.latitude > destination.latitude && source.longitude > destination.longitude) {
// bounds = LatLngBounds(southwest: destination, northeast: source);
// } else if (source.longitude > destination.longitude) {
// bounds = LatLngBounds(southwest: LatLng(source.latitude, destination.longitude), northeast: LatLng(destination.latitude, source.longitude));
// } else if (source.latitude > destination.latitude) {
// bounds = LatLngBounds(southwest: LatLng(destination.latitude, source.longitude), northeast: LatLng(source.latitude, destination.longitude));
// } else {
// bounds = LatLngBounds(southwest: source, northeast: destination);
// }
//
// CameraUpdate cameraUpdate = CameraUpdate.newLatLngBounds(bounds, 50);
// await mapController.animateCamera(cameraUpdate);
// }
//
// /// OSM Fetch Route
// Future<void> fetchRoute(location.LatLng source, location.LatLng destination) async {
// final url = Uri.parse(
// 'https://router.project-osrm.org/route/v1/driving/${source.longitude},${source.latitude};${destination.longitude},${destination.latitude}?overview=full&geometries=geojson',
// );
// final response = await http.get(url);
// if (response.statusCode == 200) {
// final decoded = json.decode(response.body);
// final geometry = decoded['routes'][0]['geometry']['coordinates'];
// routePoints.clear();
// for (var coord in geometry) {
// final lon = coord[0];
// final lat = coord[1];
// routePoints.add(location.LatLng(lat, lon));
// }
// }
// }
//
// void animateToSource() {
// osmMapController.move(source.value, 16);
// }
// }