Google Maps and Reverse Geocoding In Flutter

In my last post I showed you how to display a Google Map and display your current location on the map by way of geolocation. In this post we will enhance our app in two ways and both changes relate to what happens when your location is geolocated. These enhancements are:

  1. Show the address of that location (known as reverse geocoding).
  2. Animate the map to move to the current location.

Let's dive in!

Reverse Geocoding

We will begin by creating a new method that will return an address given a Position. To do this we will take advantage of the Flutter Geolocator plugin placemarkFromCoordinates API. This API returns a list of Placemarks and typically this list will only contain the one entry you are after. However in the event the coordinates can't be resolved into a single Placemark, the list may contain multiple entries. We'll assume in this demo we just have a single Placemark. Here is our code for getting an address based on Position.

  Future<String> _getAddress(Position pos) async {
    List<Placemark> placemarks = await Geolocator()
        .placemarkFromCoordinates(pos.latitude, pos.longitude);
    if (placemarks != null && placemarks.isNotEmpty) {
      final Placemark pos = placemarks[0];
      return pos.thoroughfare + ', ' + pos.locality;
    }
    return "";
  }

Note: thoroughfare is the street address of the Placemark and locality is the city. Feel free to explore the Placemark.dart source code to see what other address information is available to you.

Animate the Camera

Geolocation is cool, but it's not really complete until you make the Google map automatically pan/zoom to a location. Let's implement a feature to pan/zoom to your current location.

  Future<void> _moveToPosition(Position pos) async {
    final GoogleMapController mapController = await _controller.future;
    if(mapController == null) return;
    print('moving to position ${pos.latitude}, ${pos.longitude}');
    mapController.animateCamera(CameraUpdate.newCameraPosition(
      CameraPosition(
          target: LatLng(pos.latitude, pos.longitude),
          zoom: 15.0,
        )
      )
    );
  }

In the above code we introduced a new class - the GoogleMapController. This class is from the Google Maps Plugin and is what you use whenever you need to control the view of your Google map. In our case, we are using this controller to call the animateCamera API which performs an animated pan/zoom to our geolocated position.

Putting it all Together

In our prior code example I introduced you to the GoogleMapController. Let's declare a class field to hold a reference to this controller and assign that reference. At the top of your class, add the following snippet:

Completer<GoogleMapController> _controller = Completer();

Next, implement the Google map's onMapCreated event. Inside this event we assign the _controller as follows:

  void _onMapCreated(GoogleMapController controller) {
    setState(() {
      _controller.complete(controller);
    });
  }

All that is left at this point is to call the two new methods to reverse geocode and move the camera position. We'll do this by modifying the _getLocation method that was first created in a prior article.

Here is the new code for _getLocation. Notice the infoWindow property on the Marker we create has been updated to display the address obtained from reverse geocoding.

  void _getLocation() async {
    var currentLocation = await Geolocator()
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.best);
    print('got current location as ${currentLocation.latitude}, ${currentLocation.longitude}');    
    var currentAddress = await _getAddress(currentLocation);    
    await _moveToPosition(currentLocation);

    setState(() {
      _markers.clear();
      final marker = Marker(
          markerId: MarkerId("curr_loc"),
          position: LatLng(currentLocation.latitude, currentLocation.longitude),
          infoWindow: InfoWindow(title: currentAddress),
      );
      _markers["Current Location"] = marker;            
    });    
  }

Summary

With these two enhancements in place, our geolocation using Google Maps example feels more complete. Want to see more on Google Maps in Flutter? Drop me a comment saying so! Until then....

Leave a Reply

Your email address will not be published. Required fields are marked *