top of page
Search

How to Use Google Map API with Flutter to Access Nearby Places and Details

  • Writer: Aarthi Krishnan
    Aarthi Krishnan
  • May 17, 2024
  • 5 min read

Google Map API with Flutter Complete Guide
Google Map API with Flutter

Integrating location-based services has become increasingly important. Flutter, Google's UI toolkit for building natively compiled applications for mobile from a single codebase, offers seamless integration with Google Maps and Google Places APIs. In this detailed guide, we will walk through the step-by-step process of fetching nearby places and their details from Google Maps using Flutter. By the end of this tutorial, you will have a solid understanding of how to utilize the power of location-based services within your Flutter applications.





Step 1: Setting Up Your Flutter Project


First, ensure you have Flutter installed on your system. If not, follow the official Flutter installation guide (https://flutter.dev/docs/get-started/install) to set it up. Once Flutter is installed, create a new Flutter project by running the following command in your terminal:


flutter create nearby_places_app

This command creates a new Flutter project named nearby_places_app. You can change the project name.


Step 2: Adding Dependencies


Navigate to the pubspec.yaml file in your Flutter project directory. We need all the below packages to get all places Add all the dependencies for Google Maps and Google Places APIs:



dependencies:
  flutter:
    sdk: flutter
  google_maps_flutter: ^2.1.1
  flutter_google_places_hoc081098: ^0.0.4
  google_place: ^0.1.4
  google_maps_webservice: ^0.6.0

These dependencies include packages for displaying Google Maps, searching for places, and interacting with Google's APIs.


Step 3: Setting Up Google API Keys


To interact with Google Maps and Google Places APIs, you need API keys. Navigate to the Google Cloud Console (https://console.cloud.google.com/) and create a new project if you haven't already. Enable the Google Maps and Places APIs for your project, and then generate API keys for each API.


Google Map API with Flutter: Once you have the API keys, add them to your Flutter project. Create a new file named keys.dart in the lib directory of your project and define your API keys as constants:



class Keys {
  static const String googleMapsApiKey = 'YOUR_GOOGLE_MAPS_API_KEY';

  static const String googlePlacesApiKey = 'YOUR_GOOGLE_PLACES_API_KEY';
}


Replace 'YOUR_GOOGLE_MAPS_API_KEY' and 'YOUR_GOOGLE_PLACES_API_KEY' with your actual API keys.


Step 4: Building the User Interface


Now, let's create the user interface for our Flutter application. Open the lib/main.dart file and replace its contents with the following code:



import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_google_places_hoc081098/flutter_google_places_hoc081098.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_place/google_place.dart' as google_place;
import 'package:google_maps_webservice/places.dart'
    as google_maps_webservice;
import 'package:uuid/uuid.dart';
import 'keys.dart'; // Import your keys.dart file

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Nearby Places Demo',
      home: MapScreen(),
    );
  }
}

// Define MapScreen and its state

class MapScreen extends StatefulWidget {

  @override
  _MapScreenState createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {

  // Define variables and controllers
  GoogleMapController? mapController;
  LatLng? _selectedLocation;
  List<google_place.SearchResult> _nearbyBusinesses = [];
  google_place.GooglePlace googlePlace =
      google_place.GooglePlace(Keys.googlePlacesApiKey);

  // Function to handle map creation
  void _onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }


This code sets up the basic structure of our Flutter application and imports the necessary dependencies and keys.


Step 5: Implementing Map Interaction


Continuing from where we left off in lib/main.dart, let's implement the map interaction functionalities:


 
 // Function to handle map taps
  void _onMapTapped(LatLng location) async {
    setState(() {
      _selectedLocation = location;
    });

    // Call Places API to get nearby places
    var response = await googlePlace.search.getNearBySearch(
      google_place.Location(
        lat: location.latitude,
        lng: location.longitude,
      ),
      20, // Radius of 50 meters
    );

    if (response != null && response.results != null) {
      setState(() {
        _nearbyBusinesses = response.results!;
      });

      // Sort the list of nearby businesses based on their distance from the tapped location
      _nearbyBusinesses.sort((a, b) {
        double distanceToA = _calculateDistance(
          _selectedLocation!.latitude,
          _selectedLocation!.longitude,
          a.geometry!.location!.lat,
          a.geometry!.location!.lng,
        );
        double distanceToB = _calculateDistance(
          _selectedLocation!.latitude,
          _selectedLocation!.longitude,
          b.geometry!.location!.lat,
          b.geometry!.location!.lng,
        );
        return distanceToA.compareTo(distanceToB);
      });

      // Show bottom sheet with nearby businesses
      _showNearbyBusinessesBottomSheet(context);
    }
  }


In this code snippet, we define the _onMapTapped function, which is called when the user taps on the map. Inside this function, we use the Google Places API to fetch nearby places based on the tapped location. We then sort the list of nearby businesses based on their distance from the tapped location and display them in a bottom sheet.


Step 6: Implementing Place Search Functionality


Next, let's implement the place search functionality:



  // Function to search for places
  Future<void> _searchPlaces() async {
    final p = await PlacesAutocomplete.show(
      context: context,
      logo: Text(""),
      mode: Mode.overlay,
      apiKey: Keys.googlePlacesApiKey,
      onError: (response) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(response.errorMessage ?? 'Unknown error'),
          ),
        );
      },
    );

    if (p != null) {
      final places = google_maps_webservice.GoogleMapsPlaces(
        apiKey: Keys.googlePlacesApiKey,
      );
      final details = await places.getDetailsByPlaceId(p.placeId!);
      final lat = details.result.geometry!.location.lat;
      final lng = details.result.geometry!.location.lng;

      setState(() {
        _selectedLocation = LatLng(lat, lng);
      });

      // Call _onMapTapped to fetch nearby businesses and update _nearbyBusinesses list
      _onMapTapped(LatLng(lat, lng));

      // Move camera to the selected location
      mapController?.animateCamera(
        CameraUpdate.newLatLngZoom(
          LatLng(lat, lng),
          16.0, // You can adjust the zoom level as needed
        ),
      );
    }
  }


This code defines the _searchPlaces function, which is called when the user clicks on the search icon in the app bar. It opens a search bar where users can search for a place, and upon selecting a place, the map moves to that location and nearby businesses are fetched.


Step 7: Calculating Distance


Now, let's implement the _calculateDistance function, which calculates the distance between two sets of latitude and longitude coordinates:



  // Function to calculate distance between two sets of coordinates
  double _calculateDistance(double? startLatitude, double? startLongitude,
      double? endLatitude, double? endLongitude) {
    if (startLatitude == null ||
        startLongitude == null ||
        endLatitude == null ||
        endLongitude == null) {
      return double.infinity;
    }
    const int radiusOfEarth = 6371000; // in meters
    double lat1 = startLatitude * (pi / 180);
    double lat2 = endLatitude * (pi / 180);
    double lon1 = startLongitude * (pi / 180);
    double lon2 = endLongitude * (pi / 180);
    double deltaLat = lat2 - lat1;
    double deltaLon = lon2 - lon1;
    double a = (pow(sin(deltaLat / 2), 2)) +
        (cos(lat1) * cos(lat2) * (pow(sin(deltaLon / 2), 2)));
    double c = 2 * atan2(sqrt(a), sqrt(1 - a));
    return radiusOfEarth * c;
  }


This function calculates the distance between two sets of latitude and longitude coordinates using the Haversine formula, which accurately calculates distances on a sphere in Google Map API with Flutter.


Step 8: Displaying Nearby Businesses


Lastly, let's implement the _showNearbyBusinessesBottomSheet function to display a bottom sheet with a list of nearby businesses:



  // Function to display a bottom sheet with nearby businesses
  void _showNearbyBusinessesBottomSheet(BuildContext context) {
    showModalBottomSheet(
      context: context,
      builder: (BuildContext context) {
        return Container(
          padding: EdgeInsets.all(16),
          child: ListView(
            shrinkWrap: true,
            children: [
              Text(
                'Nearby Businesses:',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 18,
                ),
              ),
              SizedBox(height: 10),
              for (var business in _nearbyBusinesses)
                ListTile(
                  title: Text(business.name!),
                  subtitle: Text(business.vicinity!),
                  onTap: () {
                    print('Selected Place: ${business.name}');
                    print('Address: ${business.vicinity}');
                    print('Lat: ${business.geometry!.location!.lat}');
                    print('Long: ${business.geometry!.location!.lng}');
                  },
                ),
            ],
          ),
        );
      },
    );
  }

This function displays a bottom sheet with a list of nearby businesses fetched from the Google Places API. Users can tap on a business to view its details.


 
 

Conclusion:


In this guide, we've covered the step-by-step process of fetching nearby places and their details from Google Maps using Flutter. By setting up a Flutter project, integrating Google Maps and Google Places APIs, and implementing map interaction functionalities, place search functionality, and business details display, you now have a robust foundation for creating location-based Flutter applications. Experiment with additional features and customization options to enhance the functionality and user experience of your app.



Happy coding!❤️


Kommentare


bottom of page