Skip to content

Save favorites

In this guide you will learn how to save/delete a favorite location and view the list of favorites.

save_favorites - example flutter screenshot

Setup

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

Prerequisites

It is required that you complete the Environment Setup - Flutter Examples guide before starting this guide.

Build and run

Start a terminal/command prompt and go to the save_favorites directory, within the flutter examples directory - that is the name of this example project.

save_favorites - example flutter screenshot

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:

flutter run

select chrome - example flutter screenshot

If such a question appears, select the chrome browser; in the above example, press 2.

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            // TODO: Add your own signing config for the release build.
12            // Signing with the debug keys for now, so `flutter run --release` works.
13            minifyEnabled false
14            shrinkResources false
15            signingConfig signingConfigs.debug
16        }
17    }
18}

Then build the apk:

flutter build apk --debug
or
flutter build apk --release
the apk file is located in the build/app/outputs/apk/debug or build/app/outputs/apk/release subdirectory, for debug or release build respectively, within the current project directory, such as center_coordinates
The apk file name is app-release.apk or app-debug.apk
You can copy the apk to an android device using adb, for example:
adb push app-release.apk sdcard

And then click on the apk in the file browser on the device to install and run it.

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

platform :ios, '13.0'

Run pod install in the [ios folder] ./ios/
Then go back to the repository root folder and type flutter build ios to build a Runner.app.
Type flutter run to build and run on an attached device.
You can open the <path/to>/ios/Runner.xcworkspace project in Xcode and execute and debug from there.

How it works

save_favorites - example flutter screenshot

In the example project directory, such as center_coordinates, there is a text file named pubspec.yaml which contains project configuration and dependencies. The most important lines from this file are shown here:

 1name: center_coordinates
 2description: A Flutter example using Maps SDK for Flutter.
 3
 4version: 1.0.0+1
 5
 6environment:
 7  sdk: '>=3.0.5 <4.0.0'
 8
 9dependencies:
10  flutter:
11    sdk: flutter
12  gem_kit:
13    path: plugins/gem_kit
14
15  cupertino_icons: ^1.0.2
16
17  dev_dependencies:
18    flutter_test:
19      sdk: flutter
20
21    flutter_lints: ^3.0.2
22
23# The following section is specific to Flutter packages.
24flutter:
25  uses-material-design: true

The project must have a name and version. The dependencies list the Flutter SDK, and the gem_kit, Maps for Flutter SDK.

The source code is in example_pathname/lib/main.dart Replace example_pathname with the actual example path name, such as center_coordinates

1import 'package:gem_kit/core.dart';
2import 'package:gem_kit/landmark_store.dart';
3import 'package:gem_kit/map.dart';
4
5import 'favorites_page.dart';
6import 'landmark_panel.dart';
7
8import 'package:flutter/material.dart' hide Route;

The dart material package is imported, as well as the required gem_kit packages.

 1// The callback for when map is ready to use.
 2void _onMapCreated(GemMapController controller) {
 3  // Save controller for further usage.
 4  _mapController = controller;
 5
 6  // Retrieves the LandmarkStore with the given name.
 7  _favoritesStore = LandmarkStoreService.getLandmarkStoreByName(favoritesStoreName);
 8
 9  // If there is no LandmarkStore with this name, then create it.
10  _favoritesStore ??= LandmarkStoreService.createLandmarkStore(favoritesStoreName);
11
12  // Listen for map landmark selection events.
13  _registerLandmarkTapCallback();
14}
Each favorite is a Landmark instance, containing longitude and latitude coordinates. The favorites are stored in a LandmarkStore with the preset name:
final favoritesStoreName = 'Favorites';
and is obtained from the LandmarkStoreService after the map is initialized, as shown above.

save_favorites - example flutter screenshot

 1void _onFavoritesLandmarkPanelTap() {
 2  _checkIfFavourite();
 3
 4  if (_isLandmarkFavorite) {
 5    // Remove the landmark to the store.
 6    _favoritesStore!.removeLandmark(_focusedLandmark!);
 7  } else {
 8    // Add the landmark to the store.
 9    _favoritesStore!.addLandmark(_focusedLandmark!);
10  }
11  setState(() {
12    _isLandmarkFavorite = !_isLandmarkFavorite;
13  });
14}

Once a landmark is selected on the map, it can be added as a favorite, if it is not already, using the _favoritesStore!.addLandmark() function.

The selected landmark can be removed from the list of favorites, if it has been previously added, using the _favoritesStore!.removeLandmark() function.

 1// Utility method to check if the highlighted landmark is favourite.
 2void _checkIfFavourite() {
 3  final focusedLandmarkCoords = _focusedLandmark!.coordinates;
 4  final favourites = _favoritesStore!.getLandmarks();
 5  for (final lmk in favourites) {
 6    late Coordinates coords;
 7    coords = lmk.coordinates;
 8    if (focusedLandmarkCoords.latitude == coords.latitude && focusedLandmarkCoords.longitude == coords.longitude) {
 9      setState(() {
10        _isLandmarkFavorite = true;
11      });
12      return;
13    }
14  }
15  setState(() {
16    _isLandmarkFavorite = false;
17  });
18}
To verify if the selected landmark is already in the list of favorites, its coordinates are obtained:
final focusedLandmarkCoords = _focusedLandmark!.coordinates;
and compared to the coordinates of all landmarks in the favorites store of landmarks:
final favourites = _favoritesStore!.getLandmarks();

save_favorites - example flutter screenshot

 1void _registerLandmarkTapCallback() {
 2  _mapController.registerTouchCallback((pos) async {
 3    // Select the object at the tap position.
 4     _mapController.setCursorScreenPosition(pos);
 5
 6    // Get the selected landmarks.
 7    final landmarks = _mapController.cursorSelectionLandmarks();
 8
 9    // Check if there is a selected Landmark.
10    if (landmarks.isNotEmpty) {
11      _highlightLandmarks(landmarks);
12      return;
13    }
14    // Get the selected overlays.
15    final overlays = _mapController.cursorSelectionOverlayItems();
16
17    // Check if there is a selected overlay.
18    if (overlays.isNotEmpty) {
19      _highlightLandmarks(overlays);
20      return;
21    }
22    // Get the selected streets.
23    final streets = _mapController.cursorSelectionStreets();
24
25    // Check if there is a selected street.
26    if (streets.isNotEmpty) {
27      _highlightLandmarks(streets);
28      return;
29    }
30    final coordinates = _mapController.transformScreenToWgs(XyType(x: pos.x as int, y: pos.y as int));
31    if (coordinates == null) return;
32
33    // If no landmark was found, we create one.
34    final lmk = Landmark.withCoordinates(coordinates);
35    lmk.name = '${coordinates.latitude} ${coordinates.longitude}';
36    lmk.setImageFromIconId(GemIcon.searchResultsPin);
37
38    _highlightLandmarks([lmk]);
39  });
40}

When a POI (point of interest) landmark is tapped on the map, it is focused, and can be added to, or removed from, the favorites.

If a point on the map which is not a POI is tapped (short tap), then a landmark is created from the coordinates of that point, so it can also be added to, or removed from, the favorites:
final lmk = Landmark.withCoordinates(coordinates);

Flutter Examples

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