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 ? , bool isMocked ) callback , BuildContext context ) {
void done ( Position position ) {
//AppStorage.sp.saveLocation(position);
bool isMocked = position . isMocked ;
LatLng ? myCurrentLocation = LatLng ( position . latitude , position . longitude ) ;
callback ( myCurrentLocation , isMocked ) ;
}
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 < 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 ,
} ) {
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 ! ) ;
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 ) ;
}
}
}