Skip to content

Speed Watcher

In this guide, you will learn how to monitor speed using an interactive map, calculate a route based on GPS data, and visualize navigation instructions.

Speed Watcher - example Flutter screenshot

Setup

First, get an API key token, see the Getting Started guide.

Prerequisites

Make sure you completed the Environment Setup - Flutter Examples guide before starting this guide.

Build and run

Go to the speed_watcher directory, within the Flutter examples directory - that is the name of this example project.

Note - the gem_kit directory containing the Maps SDK for Flutter should be in the plugins directory of the example, e.g. example_pathname/plugins/gem_kit - see the environment setup guide above. Replace example_pathname with the actual example path name, such as address_search

Download project dependencies:

example flutter upgrade screenshot

flutter upgrade

example flutter clean screenshot

run the following terminal commands in the project directory, where the pubspec.yaml file is located:

flutter clean

example flutter pub get screenshot

flutter pub get

Run the example:

First, verify that the ANDROID_SDK_ROOT environment variable is set to the root path of your android SDK.

In android/build.gradle add the maven {} block as shown, within the allprojects {} block, for both debug and release builds, without the line numbers, those are for reference:

1allprojects {
2    repositories {
3        google()
4        mavenCentral()
5        maven {
6           url "${rootDir}/../plugins/gem_kit/android/build"
7        }
8    }
9}

in android/app/build.gradle within the android {} block, in the defaultConfig {} block, the android SDK version minSdk must be set as shown below.

Additionally, for release builds, in android/app/build.gradle, within the android {} block, add the buildTypes {} block as shown:

Replace example_pathname with the actual example pathname, such as center_coordinates

 1android {
 2    defaultConfig {
 3        applicationId "com.magiclane.gem_kit.examples.example_pathname"
 4        minSdk 21
 5        targetSdk flutter.targetSdk
 6        versionCode flutterVersionCode.toInteger()
 7        versionName flutterVersionName
 8    }
 9    buildTypes {
10        release {
11            minifyEnabled false
12            shrinkResources false
13
14            // TODO: Add your own signing config for the release build.
15            // Signing with the debug keys for now, so `flutter run --release` works.
16            signingConfig signingConfigs.debug
17        }
18    }
19}

Then run the project:

flutter run --debug
or
flutter run --release

In the ios/Podfile configuration text file, at the top, set the minimum ios platform to 13 like this:

platform :ios, '13.0'

Then run the project:

flutter run --debug
or
flutter run --release

How it works

Speed Watcher - example Flutter screenshot

 1import 'package:gem_kit/core.dart';
 2import 'package:gem_kit/map.dart';
 3import 'package:gem_kit/navigation.dart';
 4import 'package:gem_kit/routing.dart';
 5import 'package:flutter/material.dart';
 6
 7Future<void> main() async {
 8  const projectApiToken = String.fromEnvironment('GEM_TOKEN');
 9  await GemKit.initialize(appAuthorization: projectApiToken);
10  runApp(const MyApp());
11}
12
13class MyApp extends StatelessWidget {
14  const MyApp({super.key});
15
16  @override
17  Widget build(BuildContext context) {
18    return const MaterialApp(
19      debugShowCheckedModeBanner: false,
20      title: 'Speed Watcher',
21      home: MyHomePage(),
22    );
23  }
24}

Speed Watcher - example Flutter screenshot

The Dart material package is imported, along with the required gem_kit packages. The map is rendered within a widget that serves as the root of the application.

1void _onMapCreated(GemMapController controller) {
2  _mapController = controller; // Save controller for further usage
3}

This callback function is triggered when the interactive map is initialized and ready to use.

 1void _onBuildRouteButtonPressed(BuildContext context) {
 2  final departureLandmark = Landmark.withLatLng(latitude: 41.898499, longitude: 12.526655);
 3  final destinationLandmark = Landmark.withLatLng(latitude: 41.891037, longitude: 12.492692);
 4  final routePreferences = RoutePreferences();
 5  _showSnackBar(context, message: 'The route is calculating.');
 6
 7  RoutingService.calculateRoute(
 8    [departureLandmark, destinationLandmark], routePreferences,
 9    (err, routes) {
10      ScaffoldMessenger.of(context).clearSnackBars();
11
12      if (err == GemError.success) {
13        final routesMap = _mapController.preferences.routes;
14
15        for (final route in routes!) {
16          routesMap.add(route, route == routes.first, label: route.getMapLabel());
17        }
18
19        _mapController.centerOnRoutes(routes); // Center camera on routes
20      }
21    },
22  );
23}

This function is called when the “Build Route” button is pressed. It defines the departure and destination landmarks, calculates the route, and displays it on the map.

 1void _startSimulation() {
 2  final routes = _mapController.preferences.routes;
 3
 4  _navigationHandler = NavigationService.startSimulation(routes.mainRoute, (type, instruction) {
 5    if (type == NavigationEventType.destinationReached || type == NavigationEventType.error) {
 6      setState(() {
 7        _isSimulationActive = false;
 8        _cancelRoute();
 9      });
10      return;
11    }
12    _isSimulationActive = true;
13
14    if (instruction != null) {
15      setState(() => currentInstruction = instruction);
16    }
17  });
18
19  _mapController.startFollowingPosition(); // Follow position during navigation
20}

This method initiates the navigation simulation, allowing users to monitor their speed in real-time as they navigate along the route.

Flutter Examples

Maps SDK for Flutter Examples can be downloaded or cloned with Git