import 'dart:async'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_polyline_points/flutter_polyline_points.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:location/location.dart'; class TrackDriver extends StatefulWidget { final OrderModel order; TrackDriver({this.order}); @override State createState() => _TrackDriverState(); } class _TrackDriverState extends State { OrderModel _order; Completer _controller = Completer(); double CAMERA_ZOOM = 16; double CAMERA_TILT = 0; double CAMERA_BEARING = 30; LatLng SOURCE_LOCATION = null; LatLng DEST_LOCATION = null; // for my drawn routes on the map Set _polylines = Set(); List polylineCoordinates = []; PolylinePoints polylinePoints; Set _markers = Set(); BitmapDescriptor sourceIcon; // for my custom marker pins BitmapDescriptor destinationIcon; // for my custom marker pins Location location;// wrapper around the location API @override void initState() { _order = widget.order; DEST_LOCATION = _order.shippingAddress.getLocation(); location = new Location(); polylinePoints = PolylinePoints(); setSourceAndDestinationIcons(); } @override Widget build(BuildContext context) { return new Scaffold( body: GoogleMap( myLocationEnabled: true, compassEnabled: true, markers: _markers, polylines: _polylines, mapType: MapType.normal, initialCameraPosition: _orderDeliveryLocationCamera(), onMapCreated: (GoogleMapController controller) { _controller.complete(controller); showPinsOnMap(); }, ), floatingActionButton: FloatingActionButton.extended( onPressed: _goToDriver, label: Text('To the lake!'), icon: Icon(Icons.directions_boat), ), ); } void setSourceAndDestinationIcons() async { sourceIcon = await BitmapDescriptor.fromAssetImage( ImageConfiguration(devicePixelRatio: 2.5), 'assets/images/map_markers/source_map_marker.png'); destinationIcon = await BitmapDescriptor.fromAssetImage( ImageConfiguration(devicePixelRatio: 2.5), 'assets/images/map_markers/destination_map_marker.png'); } CameraPosition _orderDeliveryLocationCamera(){ final CameraPosition orderDeliveryLocCamera = CameraPosition( bearing: CAMERA_BEARING, target: DEST_LOCATION, tilt: CAMERA_TILT, zoom: CAMERA_ZOOM); return orderDeliveryLocCamera; } CameraPosition _driverLocationCamera(){ final CameraPosition driverLocCamera = CameraPosition( bearing: CAMERA_BEARING, target: SOURCE_LOCATION, tilt: CAMERA_TILT, zoom: CAMERA_ZOOM); return driverLocCamera; } Future _goToOrderDeliveryLocation() async { final GoogleMapController controller = await _controller.future; final CameraPosition orderDeliveryLocCamera = _orderDeliveryLocationCamera(); controller.animateCamera(CameraUpdate.newCameraPosition(orderDeliveryLocCamera)); } Future _goToDriver() async { final GoogleMapController controller = await _controller.future; final CameraPosition driverLocCamera = _driverLocationCamera(); controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); } Future _fitCameraBetweenBothPoints() async { final GoogleMapController controller = await _controller.future; final CameraPosition driverLocCamera = CameraPosition( bearing: CAMERA_BEARING, target: SOURCE_LOCATION, tilt: CAMERA_TILT, zoom: CAMERA_ZOOM); controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); } void showPinsOnMap() { // source pin if(SOURCE_LOCATION != null){ setState(() { var pinPosition = SOURCE_LOCATION; _markers.add(Marker( markerId: MarkerId('sourcePin'), position: pinPosition, icon: sourceIcon )); }); } // destination pin if(DEST_LOCATION != null){ setState(() { var destPosition = DEST_LOCATION; _markers.add(Marker( markerId: MarkerId('destPin'), position: destPosition, icon: destinationIcon )); }); } // set the route lines on the map from source to destination // for more info follow this tutorial // drawRoute(); } void updatePinOnMap() async { // create a new CameraPosition instance // every time the location changes, so the camera // follows the pin as it moves with an animation CameraPosition cPosition = CameraPosition( zoom: CAMERA_ZOOM, tilt: CAMERA_TILT, bearing: CAMERA_BEARING, target: SOURCE_LOCATION, ); final GoogleMapController controller = await _controller.future; controller.animateCamera(CameraUpdate.newCameraPosition(cPosition)); // do this inside the setState() so Flutter gets notified // that a widget update is due setState(() { // updated position var pinPosition = SOURCE_LOCATION; // the trick is to remove the marker (by id) // and add it again at the updated location _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); _markers.add(Marker( markerId: MarkerId('sourcePin'), position: pinPosition, // updated position icon: sourceIcon )); }); } void drawRoute() async { return; // Ignore draw Route List result = await polylinePoints.getRouteBetweenCoordinates( GOOGLE_API_KEY, SOURCE_LOCATION.latitude, SOURCE_LOCATION.longitude, DEST_LOCATION.latitude, DEST_LOCATION.longitude); if(result.isNotEmpty){ result.forEach((PointLatLng point){ polylineCoordinates.add( LatLng(point.latitude,point.longitude) ); }); setState(() { _polylines.add(Polyline( width: 5, // set the width of the polylines polylineId: PolylineId('poly'), color: Color.fromARGB(255, 40, 122, 198), points: polylineCoordinates )); }); } } }