Skip to content

Map styles

This example explains how to download and apply different map styles, including styles for day and night, some of which feature topography.

map_styles - 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 map_styles directory within the Flutter examples directory. This is the name of the 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

This example demonstrates how to use the gem_kit package to interact with a map and dynamically change its styles.

map_styles - example flutter screenshot

Import necessary packages

First, import the required packages in your Dart code.

1import 'package:gem_kit/content_store.dart';
2import 'package:gem_kit/core.dart';
3import 'package:gem_kit/map.dart';
4import 'package:flutter/material.dart';
5import 'dart:async';

Initialize GemKit

In the main function, initialize GemKit with your project API token.

1Future<void> main() async {
2  const projectApiToken = String.fromEnvironment('GEM_TOKEN');
3  await GemKit.initialize(appAuthorization: projectApiToken);
4  runApp(const MyApp());
5}

Build the main application

Define the main application widget, MyApp.

 1class MyApp extends StatelessWidget {
 2  const MyApp({super.key});
 3
 4  @override
 5  Widget build(BuildContext context) {
 6    return const MaterialApp(
 7      debugShowCheckedModeBanner: false,
 8      title: 'Map Styles',
 9      home: MyHomePage(),
10    );
11  }
12}

Handle map styles in the stateful widget

Create the stateful widget, MyHomePage, which will handle map styles.

map_styles - example flutter screenshot

1class MyHomePage extends StatefulWidget {
2  const MyHomePage({super.key});
3
4  @override
5  State<MyHomePage> createState() => _MyHomePageState();
6}

Define state variables and methods

Within _MyHomePageState, define the necessary state variables and methods to interact with the map and manage styles.

  1class _MyHomePageState extends State<MyHomePage> {
  2  late GemMapController _mapController;
  3  final _stylesList = <ContentStoreItem>[];
  4  int _indexOfCurrentStyle = 0;
  5  bool _isDownloadingStyle = false;
  6
  7  @override
  8  void dispose() {
  9    GemKit.release();
 10    super.dispose();
 11  }
 12
 13  @override
 14  Widget build(BuildContext context) {
 15    return Scaffold(
 16      appBar: AppBar(
 17        backgroundColor: Colors.deepPurple[900],
 18        title: const Text(
 19          'Map Styles',
 20          style: TextStyle(color: Colors.white),
 21        ),
 22        actions: [
 23          if (_isDownloadingStyle)
 24            const SizedBox(
 25              width: 20,
 26              height: 20,
 27              child: Center(
 28                child: CircularProgressIndicator(
 29                  color: Colors.white,
 30                ),
 31              ),
 32            ),
 33          IconButton(
 34              onPressed: () => _onMapButtonTap(context),
 35              icon: const Icon(Icons.map_outlined, color: Colors.white))
 36        ],
 37      ),
 38      body: GemMap(onMapCreated: _onMapCreated),
 39    );
 40  }
 41
 42  void _onMapCreated(GemMapController controller) async {
 43    _mapController = controller;
 44    SdkSettings.setAllowOffboardServiceOnExtraChargedNetwork(
 45        ServiceGroupType.contentService, true);
 46    getStyles();
 47  }
 48
 49  void getStyles() {
 50    ContentStore.asyncGetStoreContentList(ContentType.viewStyleLowRes,
 51        (err, items, isCached) {
 52      if (err == GemError.success && items != null) {
 53        _stylesList.addAll(items);
 54        ScaffoldMessenger.of(context).clearSnackBars();
 55      }
 56    });
 57  }
 58
 59  Future<bool> _downloadStyle(ContentStoreItem style) async {
 60    setState(() {
 61      _isDownloadingStyle = true;
 62    });
 63    Completer<bool> completer = Completer<bool>();
 64    style.asyncDownload((err) {
 65      if (err != GemError.success) {
 66        completer.complete(false);
 67        setState(() {
 68          _isDownloadingStyle = false;
 69        });
 70        return;
 71      }
 72      completer.complete(true);
 73      setState(() {
 74        _isDownloadingStyle = false;
 75      });
 76    }, onProgressCallback: (progress) {
 77      print('progress: $progress');
 78    }, allowChargedNetworks: true);
 79    return await completer.future;
 80  }
 81
 82  void _showSnackBar(BuildContext context,
 83      {required String message, Duration duration = const Duration(hours: 1)}) {
 84    final snackBar = SnackBar(
 85      content: Text(message),
 86      duration: duration,
 87    );
 88    ScaffoldMessenger.of(context).showSnackBar(snackBar);
 89  }
 90
 91  Future<void> _onMapButtonTap(BuildContext context) async {
 92    if (_stylesList.isEmpty) {
 93      _showSnackBar(context, message: "The map styles are loading.");
 94      getStyles();
 95      return;
 96    }
 97
 98    final indexOfNextStyle = (_indexOfCurrentStyle >= _stylesList.length - 1)
 99        ? 0
100        : _indexOfCurrentStyle + 1;
101    ContentStoreItem currentStyle = _stylesList[indexOfNextStyle];
102
103    if (!currentStyle.isCompleted) {
104      final didDownloadSuccessfully = await _downloadStyle(currentStyle);
105      if (!didDownloadSuccessfully) return;
106    }
107
108    _indexOfCurrentStyle = indexOfNextStyle;
109    final String filename = currentStyle.fileName;
110    _mapController.preferences.setMapStyleByPath(filename);
111    setState(() {});
112  }
113}

Explanation of the key components

  • GemMapController: This is used to interact with the map.

  • ContentStoreItem: Represents a downloadable map style.

  • getStyles: Loads available map styles.

  • _downloadStyle: Downloads a selected style.

  • _onMapButtonTap: Changes the current map style.

map_styles - example flutter screenshot

Map Styles

The example supports various map styles, including: - Day and Night Styles: Provides different visual representations for day and night. - Topography Styles: Adds terrain relief to the map.

night style - example flutter screenshot

night style - example flutter screenshot

relief style - example flutter screenshot

night style - example flutter screenshot

relief style - example flutter screenshot

night style - example flutter screenshot

Flutter Examples

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