A Flutter application to demonstrate how to implement Google maps

google_maps_flutter_example

A new Flutter application to demonstrate how to implement flutter google maps in a flutter application and perfoem advanced tasks on it.

Adding Map To the App

  1. Get an API key at https://cloud.google.com/maps-platform/.

  2. Enable Google Map SDK for each platform.

    • Go to Google Developers Console.
    • Choose the project that you want to enable Google Maps on.
    • Select the navigation menu and then select "Google Maps".
    • Select "APIs" under the Google Maps menu.
    • To enable Google Maps for Android, select "Maps SDK for Android" in the "Additional APIs" section, then select "ENABLE".
    • To enable Google Maps for iOS, select "Maps SDK for iOS" in the "Additional APIs" section, then select "ENABLE".
    • Make sure the APIs you enabled are under the "Enabled APIs" section.
  3. In android/app/src/main/AndroidManifest.xml inside Application tag add your key

<manifest ...
  <application ...
    <meta-data android:name="com.google.android.geo.API_KEY"
               android:value="YOUR KEY HERE"/>
  1. In ios/Runner/AppDelegate.swift add the following lines
import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("YOUR KEY HERE")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
  1. Use the GoogleMapsWidget.dart inside the lib/widget folder as normal widget and use it where you want.

Adding Custom Marker To the map

Adding normal marker

  1. Declare a Set of Markers that will be shown on the map
Set<Marker> _markers = Set<Marker>();
  1. Add the set of markers to GoogleMap widget
GoogleMap(
      markers: _markers,
  1. Update the set of markers after the map is created in onMapCreated
GoogleMap(
      onMapCreated: (GoogleMapController controller) {
              _controller.complete(controller);
              _setMapPins([LatLng(30.029585, 31.022356)]);
            }
  1. Using this function the map will be updated with the given markers on it
_setMapPins(List<LatLng> markersLocation) {
    _markers.clear();
    setState(() {
      markersLocation.forEach((markerLocation) {
        _markers.add(Marker(
          markerId: MarkerId(markerLocation.toString()),
          position: markerLocation,
        ));
      });
    });
  }

Customizing the markers

  1. Declare a BitmapDescriptor which will hold the customIcon
late BitmapDescriptor customIcon;
  1. Inside initState() Assign the needed png to the customIcon
@override
  void initState() {
    BitmapDescriptor.fromAssetImage(ImageConfiguration(size: Size(50, 50)),
            'assets/images/marker_car.png')
        .then((icon) {
      customIcon = icon;
    });
    super.initState();
  }
  1. Finally add the customIcon to the marker
Marker(
     markerId: MarkerId(markerLocation.toString()),
     position: markerLocation,
     icon: customIcon,
   )

Map Customization (Light/Dark mode)

Prepare the map styles

  1. Go to https://mapstyle.withgoogle.com/
  2. Choose the old version of the site by choosing No thanks, take me to the old style wizard
  3. You will find a lot of options, play with it until you get the desired style.
  4. Click Finish and a pop-up will show with the json code of your style, copy it and add it as a json file in your assets folder
    Don't forgot to mention it in your pubspec.yaml
    You can find two styles in the project's assets folder

Adding styles to the map

  1. Declare Strings that will hold your style's json and a bool to control which mode is shown on the map
bool mapDarkMode = true;
late String _darkMapStyle;
late String _lightMapStyle;
  1. In initState declare the styles
Future _loadMapStyles() async {
    _darkMapStyle = await rootBundle.loadString('assets/map_style/dark.json');
    _lightMapStyle = await rootBundle.loadString('assets/map_style/light.json');
  }
  1. After creating the map, set the style
onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
          _setMapPins([LatLng(30.029585, 31.022356)]);
          _setMapStyle();
        },
Future _setMapStyle() async {
    final controller = await _controller.future;
    if (mapDarkMode)
      controller.setMapStyle(_darkMapStyle);
    else
      controller.setMapStyle(_lightMapStyle);
  }
  1. To change the style we created a button on the map using the stack widget
Positioned(
   top: 100,
   right: 30,
   child: Container(
     height: 30,
     width: 30,
     child: IconButton(
       icon: Icon(
         mapDarkMode ? Icons.brightness_4 : Icons.brightness_5,
         color: Theme.of(context).primaryColor,
       ),
       onPressed: () {
         setState(() {
           mapDarkMode = !mapDarkMode;
           _setMapStyle();
         });
       },
     ),
   )),

Drawing routes

Activating Directions API

  1. Go to Google Developers Console.
  2. Choose the project that you want to enable Google Maps on.
  3. Select the navigation menu and then select "Google Maps".
  4. Select "APIs" under the Google Maps menu.
  5. Enable Google Directions, select "Directions API" in the "Additional APIs" section, then select "ENABLE".
  6. Make sure the APIs you enabled are under the "Enabled APIs" section.

Adding route to the map

  1. Declare your start and end points
final LatLng initialLatLng = LatLng(30.029585, 31.022356);
final LatLng destinationLatLng = LatLng(30.060567, 30.962413);
  1. Declare polyline and polylineCoordinates
Set<Polyline> _polyline = {};
List<LatLng> polylineCoordinates = [];
  1. After creating the map, set the polyline
onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
          _setMapPins([LatLng(30.029585, 31.022356)]);
          _setMapStyle();
          _addPolyLines();
        },
_addPolyLines() {
    setState(() {
      lat = (initialLatLng.latitude + destinationLatLng.latitude)/2;
      lng= (initialLatLng.longitude + destinationLatLng.longitude)/2;
      _moveCamera(13.0);
      _setPolyLines();
    });
  }
  1. To set polyline we send a get request to https://www.maps.googleapis.com/maps/api/directions/json with the start location, end location and the api key
final result = await MapRepository()
        .getRouteCoordinates(initialLatLng, destinationLatLng);
final route = result.data["routes"][0]["overview_polyline"]["points"];
  1. Then we translate the results to a polyline using the MapUtils
_polyline.add(Polyline(
    polylineId: PolylineId("tripRoute"),
    //pass any string here
    width: 3,
    geodesic: true,
    points: MapUtils.convertToLatLng(MapUtils.decodePoly(route)),
    color: Theme.of(context).primaryColor));

GitHub

https://github.com/heshamerfan97/flutter_google_maps_example