Files
tripz/lib/controller/home/map_page_controller.dart
Hamza-Ayed 1b79e49872 first ios1
2023-08-06 18:47:20 +03:00

303 lines
9.4 KiB
Dart

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<LatLng> bounds = [];
List places = [];
LatLngBounds? boundsdata;
List<Marker> markers = [];
List<Polyline> polylines = [];
late LatLng mylocation;
LatLng mydestination = const LatLng(32.115295, 36.064773);
final List<LatLng> 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<String> 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<void> 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<LatLng> 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();
}
}