import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'dart:math' as math; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:google_polyline_algorithm/google_polyline_algorithm.dart'; import 'package:location/location.dart'; import 'package:ride/constant/colors.dart'; import 'package:ride/constant/credential.dart'; import 'package:ride/constant/links.dart'; import 'package:ride/constant/style.dart'; import 'package:ride/controller/functions/crud.dart'; class MapController extends GetxController { bool isloading = true; TextEditingController placeController = TextEditingController(); List data = []; List bounds = []; List places = []; LatLngBounds? boundsdata; List markers = []; List polylines = []; late LatLng mylocation; LatLng mydestination = const LatLng(32.115295, 36.064773); final List polylineCoordinates = []; BitmapDescriptor markerIcon = BitmapDescriptor.defaultMarker; double height = 200; final location = Location(); late LocationData currentLocation; changeHeight() { if (places.isEmpty) { height = 0; update(); } height = 200; update(); } hidePlaces() { height = 0; update(); } Future getPlaces() async { var url = '${AppLink.googleMapsLink}place/nearbysearch/json?keyword=${placeController.text}&location=32.111946,${mylocation.longitude}&radius=10000&type=restaurant&language=ar&key=${AppCredintials.mapAPIKEY}'; var response = await CRUD().getGoogleApi(link: url, payload: {}); places = response['results']; print(places); update(); } LatLng fromString(String location) { List parts = location.split(','); double lat = double.parse(parts[0]); double lng = double.parse(parts[1]); return LatLng(lat, lng); } void clearpolyline() { polylines = []; polylineCoordinates.clear(); update(); } void addCustomPicker() { ImageConfiguration config = const ImageConfiguration( size: Size(20, 20), // scale: 1.0, ); BitmapDescriptor.fromAssetImage(config, 'assets/images/picker.png') .then((value) { markerIcon = value; update(); }); } Future getLocation() async { bool serviceEnabled; PermissionStatus permissionGranted; // Check if location services are enabled serviceEnabled = await location.serviceEnabled(); if (!serviceEnabled) { serviceEnabled = await location.requestService(); if (!serviceEnabled) { // Location services are still not enabled, handle the error return; } } // Check if the app has permission to access location permissionGranted = await location.hasPermission(); if (permissionGranted == PermissionStatus.denied) { permissionGranted = await location.requestPermission(); if (permissionGranted != PermissionStatus.granted) { // Location permission is still not granted, handle the error return; } } // Get the current location LocationData _locationData = await location.getLocation(); mylocation = (_locationData.latitude != null && _locationData.longitude != null ? LatLng(_locationData.latitude!, _locationData.longitude!) : null)!; // print(currentLocation.accuracy); // print(currentLocation.latitude); // print(currentLocation.time); // print('//////////////////////////////////////'); update(); } GoogleMapController? mapController; void onMapCreated(GoogleMapController controller) { mapController = controller; controller.getVisibleRegion(); update(); } getMap(String origin, destination) async { var origin1 = fromString(origin); var destination1 = fromString(destination); isloading = false; mydestination = destination1; mylocation = origin1; update(); var url = ('${AppLink.googleMapsLink}directions/json?&language=en&avoid=tolls|ferries&destination=$destination&origin=$origin&key=${AppCredintials.mapAPIKEY}'); var response = await CRUD().getGoogleApi(link: url, payload: {}); data = response['routes'][0]['legs']; final points = decodePolyline(response["routes"][0]["overview_polyline"]["points"]); for (int i = 0; i < points.length; i++) { double lat = points[i][0].toDouble(); double lng = points[i][1].toDouble(); polylineCoordinates.add(LatLng(lat, lng)); } // Define the northeast and southwest coordinates final bounds = response["routes"][0]["bounds"]; LatLng northeast = LatLng(bounds['northeast']['lat'], bounds['northeast']['lng']); LatLng southwest = LatLng(bounds['southwest']['lat'], bounds['southwest']['lng']); // Create the LatLngBounds object LatLngBounds boundsData = LatLngBounds(northeast: northeast, southwest: southwest); // Calculate padding for the bounding box double distance = math.sqrt( math.pow(northeast.latitude - southwest.latitude, 2) + math.pow(northeast.longitude - southwest.longitude, 2), ); // Define the map padding final double padding = 50.0; // Get the screen dimensions final screenSize = Get.size; print(screenSize.width); print('================'); // Adjust the bounding box to include padding LatLngBounds adjustedBounds = LatLngBounds( southwest: LatLng(boundsData.southwest.latitude - padding, boundsData.southwest.longitude - padding), northeast: LatLng(boundsData.northeast.latitude + padding, boundsData.northeast.longitude + padding), ); // Calculate the zoom level based on the distance and screen size double zoomLevel = getZoomLevel(distance, screenSize.width); // Animate the camera to the adjusted bounds mapController!.animateCamera(CameraUpdate.newLatLngBounds( adjustedBounds, screenSize.width, )); if (polylines.isNotEmpty) { clearpolyline(); } else { var polyline = Polyline( polylineId: PolylineId(response["routes"][0]["summary"]), points: polylineCoordinates, width: 10, color: Colors.blue, ); polylines.add(polyline); update(); } } double getZoomLevel(double distance, double screenWidth) { const double zoomFactor = 15.0; const double pixelRatio = 156543.03392; // Earth circumference in pixels at zoom level 0 double zoomLevel = (math.log(pixelRatio * screenWidth / (distance * zoomFactor))) / math.log(2); return zoomLevel; } double getDistanceFromText(String distanceText) { // Remove any non-digit characters from the distance text String distanceValue = distanceText.replaceAll(RegExp(r'[^0-9.]+'), ''); // Parse the extracted numerical value as a double double distance = double.parse(distanceValue); return distance; } void bottomSheet() { String distanceText = data[0]['distance']['text']; String durationText = data[0]['duration']['text']; double distance = getDistanceFromText(distanceText); double duration = getDistanceFromText(durationText); double cost = distance * 0.21; double costDuration = duration * 0.05; double totalPassenger = cost + costDuration; Get.bottomSheet( Container( height: 130, color: AppColor.secondaryColor, child: data.isEmpty ? Center( child: Text( 'Where are you want to go..', style: AppStyle.title, )) : Center( child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text( 'distance is ${data[0]['distance']['text']}', style: AppStyle.title, ), Text( 'duration is ${data[0]['duration']['text']}', style: AppStyle.title, ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text( 'Cost for .21/km $cost ', style: AppStyle.title, ), Text( 'Cost duration .05/m $costDuration ', style: AppStyle.title, ), ], ), Text( 'Total cost $totalPassenger ', style: AppStyle.title, ), ], ), ), ), elevation: 6, enableDrag: true, isDismissible: true, useRootNavigator: true, backgroundColor: AppColor.secondaryColor, barrierColor: AppColor.accentColor.withOpacity(.4), persistent: true, ); } List polylineCoordinate = []; double calculateCost(double distance) { const double costRate = 0.27; // double distanceInKm = distance / 1000; // convert distance to kilometers double cost = costRate * distance; return cost; } @override void onInit() { // getPolyLine(); // getMap(); addCustomPicker(); getLocation(); super.onInit(); } }