You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
9.0 KiB
Dart
252 lines
9.0 KiB
Dart
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<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);
|
|
}
|
|
}
|
|
}
|