import 'dart:async'; import 'dart:math'; import 'dart:ui'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_directions_api/google_directions_api.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:mohem_flutter_app/classes/app_permissions.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/theme/colors.dart'; // import 'package:geodesy/geodesy.dart' as geodesy; //Created By Mr.Zohaib class Location { static _Map map = _Map(); static void havePermission(Function(bool) callback) { Geolocator.checkPermission().then((value) async { if (value == LocationPermission.denied) { value = await Geolocator.requestPermission(); callback(![LocationPermission.denied, LocationPermission.deniedForever].contains(value)); } else { callback(true); } }); } static void isEnabled(Function(bool) callback) { Geolocator.isLocationServiceEnabled().then((value) => callback(value)); } static bool _listeningSettingChange = true; static void listenGPS({bool change = true, Function(bool)? onChange}) async { _listeningSettingChange = change; if (change == false) return; Future.doWhile(() async { await Utils.delay(1000); var enable = await Geolocator.isLocationServiceEnabled(); onChange!(enable); return _listeningSettingChange; }); } static void getCurrentLocation(Function(LatLng?) callback, BuildContext context) { void done(Position position) { //AppStorage.sp.saveLocation(position); LatLng? myCurrentLocation = LatLng(position.latitude, position.longitude); callback(myCurrentLocation); } AppPermissions.location((granted) { if (granted) { Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) { if (value == null) { Geolocator.getCurrentPosition().then((value) { done(value); }); } else { done(value); } }); } else { // AppPermissions } }, context); } // static LatLng locationAwayFrom( // {required LatLng loc1, num distanceMeters = 200.0, num bearing = 270.0}) { // geodesy.LatLng l1 = geodesy.LatLng(loc1.latitude, loc1.longitude); // geodesy.LatLng destinationPoint = geodesy.Geodesy() // .destinationPointByDistanceAndBearing(l1, distanceMeters, bearing); // return LatLng(destinationPoint.latitude, destinationPoint.longitude); // } static Future distanceTo(LatLng destination) async { var myLoc = await Geolocator.getLastKnownPosition(); var distance = 0.0; if (myLoc != null) { distance = Geolocator.distanceBetween(destination.latitude, destination.longitude, myLoc.latitude, myLoc.longitude); } return distance; } } class _Map { Marker createMarker( String id, { required LatLng coordinates, BitmapDescriptor? icon, VoidCallback? onTap, }) { MarkerId markerId = MarkerId(id); return Marker( icon: icon ?? BitmapDescriptor.defaultMarker, markerId: markerId, position: coordinates, flat: false, // infoWindow: InfoWindow(title: id, snippet: '*'), onTap: onTap, ); } CameraPosition initialCamera({required Completer mapController, LatLng? position, double zoom = 12}) { position = position ?? LatLng(24.7249303, 46.5416656); CameraPosition riyadhEye = CameraPosition( target: position, zoom: zoom, ); mapController.future.then((controller) { controller.animateCamera(CameraUpdate.newCameraPosition(riyadhEye)); }); return riyadhEye; } CameraPosition moveTo(LatLng location, {double zoom = 12, double direction = 0.0, required Completer mapController, bool? animation}) { var camera = CameraPosition(target: location, zoom: zoom, bearing: direction); mapController.future.then((controller) { animation ?? false ? controller.animateCamera(CameraUpdate.newCameraPosition(camera)) : controller.moveCamera(CameraUpdate.newCameraPosition(camera)); }); return camera; } void moveCamera(CameraPosition camera, @required Completer mapController, bool animation) { mapController.future.then((controller) { animation ? controller.animateCamera(CameraUpdate.newCameraPosition(camera)) : controller.moveCamera(CameraUpdate.newCameraPosition(camera)); }); } void scrollBy({double x = 0, double y = 0, required Completer mapController, bool animation = true}) { var camera = CameraUpdate.scrollBy(x, y); mapController.future.then((controller) { animation ? controller.animateCamera(camera) : controller.moveCamera(camera); }); } // void goToCurrentLocation({Completer? mapController, double? direction = 0.0, bool? animation}) { // Location.getCurrentLocation((location) { // moveTo(location!, zoom: 17, mapController: mapController!, animation: animation, direction: direction!); // }); // } var routes = Map(); void setRoutePolylines(LatLng? source, LatLng? destination, Set polylines, Completer mapController, Function(DirectionsRoute?) completion) { if (source == null || destination == null) { completion(null); return; } var origin = '${source.latitude},${source.longitude}'; var destin = '${destination.latitude},${destination.longitude}'; var routeId = '$origin->$destination'; void createPolyline(DirectionsRoute results) { List polylineCoordinates = results.overviewPath!.map((e) => LatLng(e.latitude, e.longitude)).toList(); PolylineId id = PolylineId("route"); Polyline polyline = Polyline( polylineId: id, color: accentColor, width: 5, jointType: JointType.round, startCap: Cap.roundCap, endCap: Cap.roundCap, points: polylineCoordinates, ); polylines.removeWhere((element) => true); polylines.add(polyline); LatLngBounds bound = getBounds(coordinates: polylineCoordinates); focusCameraToLatLngBounds(bound: bound, mapController: mapController, padding: 100); completion(routes[routeId]); } var availableRoute = routes[routeId]; if (availableRoute == null) { var request = DirectionsRequest(origin: origin, destination: destin); DirectionsService().route(request, (response, status) { if (status == DirectionsStatus.ok && response.routes!.isNotEmpty) { routes[routeId] = response.routes!.first; createPolyline(response.routes!.first); } }); } else { createPolyline(availableRoute); } } LatLngBounds getBounds({required List coordinates}) { var lngs = coordinates.map((c) => c.longitude).toList(); var lats = coordinates.map((c) => c.latitude).toList(); double bottomMost = lngs.reduce(min); double topMost = lngs.reduce(max); double leftMost = lats.reduce(min); double rightMost = lats.reduce(max); LatLngBounds bounds = LatLngBounds( northeast: LatLng(rightMost, topMost), southwest: LatLng(leftMost, bottomMost), ); return bounds; double? x0, x1, y0, y1; for (LatLng latLng in coordinates) { if (x0 == null) { x0 = x1 = latLng.latitude; y0 = y1 = latLng.longitude; } else { if (latLng.latitude > x1!) x1 = latLng.latitude; if (latLng.latitude < x0) x0 = latLng.latitude; if (latLng.longitude > y1!) y1 = latLng.longitude; if (latLng.longitude < y0!) y0 = latLng.longitude; } } return LatLngBounds(northeast: LatLng(x1!, y1!), southwest: LatLng(x0!, y0!)); } void focusCameraToLatLngBounds({LatLngBounds? bound, Completer? mapController, double? padding}) async { if (bound == null) return; CameraUpdate camera = CameraUpdate.newLatLngBounds(bound, padding!); GoogleMapController controller = await mapController!.future; controller.animateCamera(camera); } void focusCameraTo2Points({LatLng? point1, LatLng? point2, Completer? mapController, double? padding}) async { var source = point1; var destination = point2; if (source != null && destination != null) { // 'package:google_maps_flutter_platform_interface/src/types/location.dart': Failed assertion: line 72 pos 16: 'southwest.latitude <= northeast.latitude': is not true. LatLngBounds bound; if (source.latitude <= destination.latitude) { bound = LatLngBounds(southwest: source, northeast: destination); } else { bound = LatLngBounds(southwest: destination, northeast: source); } if (bound == null) return; focusCameraToLatLngBounds(bound: bound, mapController: mapController, padding: padding); } } }