import ' dart:async ' ;
import ' dart:math ' ;
import ' dart:ui ' ;
import ' package:flutter/material.dart ' ;
import ' package:flutter/rendering.dart ' ;
import ' package:geolocator/geolocator.dart ' ;
import ' package:google_maps_flutter/google_maps_flutter.dart ' ;
import ' package:mc_common_app/utils/app_permission_handler.dart ' ;
import ' package:mc_common_app/utils/utils.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 ) {
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 ) ;
}
} ) ;
}
} ) ;
}
// 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 < double > 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 ,
} ) {
final 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 < GoogleMapController > 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 < GoogleMapController > 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 < GoogleMapController > 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 < GoogleMapController > mapController , bool animation = true } ) {
var camera = CameraUpdate . scrollBy ( x , y ) ;
mapController . future . then ( ( controller ) {
animation ? controller . animateCamera ( camera ) : controller . moveCamera ( camera ) ;
} ) ;
}
void goToCurrentLocation ( { Completer < GoogleMapController > ? mapController , double ? direction = 0.0 , bool ? animation } ) {
Location . getCurrentLocation ( ( location ) {
moveTo ( location ! , zoom: 17 , mapController: mapController ! , animation: animation , direction: direction ! ) ;
} ) ;
}
// var routes = Map<String, DirectionsRoute>();
//
// void setRoutePolylines(LatLng? source, LatLng? destination, Set<Polyline> polylines, Completer<GoogleMapController> 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<LatLng> 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 < LatLng > coordinates } ) {
var lngs = coordinates . map < double > ( ( c ) = > c . longitude ) . toList ( ) ;
var lats = coordinates . map < double > ( ( 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 < GoogleMapController > ? mapController , double ? padding } ) async {
if ( bound = = null ) return ;
CameraUpdate camera = CameraUpdate . newLatLngBounds ( bound , padding ! ) ;
final GoogleMapController controller = await mapController ! . future ;
controller . animateCamera ( camera ) ;
}
void focusCameraTo2Points ( { LatLng ? point1 , LatLng ? point2 , Completer < GoogleMapController > ? 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 ) ;
}
}
}