Add Markers¶
Setup¶
Prerequisites¶
Build and Run¶
Navigate to the add_markers
directory within the Flutter examples directory. This is the project folder for this example.
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:
flutter upgrade
run the following terminal commands in the project directory,
where the pubspec.yaml
file is located:
flutter clean
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
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
flutter run --release
How It Works¶
The example app demonstrates the following features:
Display a large number of markers on the map.
1import 'dart:math';
2import 'dart:typed_data';
3import 'package:flutter/material.dart';
4import 'package:flutter/services.dart' show rootBundle;
5import 'package:gem_kit/core.dart';
6import 'package:gem_kit/map.dart';
7
8Future<void> main() async {
9 const projectApiToken = String.fromEnvironment('GEM_TOKEN');
10 await GemKit.initialize(appAuthorization: projectApiToken);
11 runApp(const MyApp());
12}
This imports the necessary packages, initializes GemKit, and sets up the main entry point of the app.
UI and Map Integration¶
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: 'Add Markers',
9 home: MyHomePage(),
10 );
11 }
12}
13
14class MyHomePage extends StatefulWidget {
15 const MyHomePage({super.key});
16
17 @override
18 State<MyHomePage> createState() => _MyHomePageState();
19}
20
21class _MyHomePageState extends State<MyHomePage> {
22 late GemMapController _mapController;
23
24 @override
25 void dispose() {
26 GemKit.release();
27 super.dispose();
28 }
29
30 @override
31 Widget build(BuildContext context) {
32 return Scaffold(
33 appBar: AppBar(
34 backgroundColor: Colors.deepPurple[900],
35 title: const Text('Hello Map', style: TextStyle(color: Colors.white)),
36 ),
37 body: GemMap(
38 onMapCreated: _onMapCreated,
39 ),
40 );
41 }
42
43 Future<void> _onMapCreated(GemMapController controller) async {
44 _mapController = controller;
45 await addMarkers();
46 }
This code sets up the basic structure of the app, including the map and the app bar, and initializes the map when it is created.
Adding and Displaying Markers¶
1Future<void> addMarkers() async {
2 final listPngs = await loadPngs();
3 final ByteData imageData = await rootBundle.load('assets/pois/GroupIcon.png');
4 final Uint8List imageBytes = imageData.buffer.asUint8List();
5
6 Random random = Random();
7 double minLat = 35.0; // Southernmost point of Europe
8 double maxLat = 71.0; // Northernmost point of Europe
9 double minLon = -10.0; // Westernmost point of Europe
10 double maxLon = 40.0; // Easternmost point of Europe
11
12 List<MarkerWithRenderSettings> markers = [];
13
14 // Generate random coordinates for markers.
15 for (int i = 0; i < 8000; ++i) {
16 double randomLat = minLat + random.nextDouble() * (maxLat - minLat);
17 double randomLon = minLon + random.nextDouble() * (maxLon - minLon);
18
19 final marker = MarkerJson(
20 coords: [Coordinates(latitude: randomLat, longitude: randomLon)],
21 name: "POI $i",
22 );
23
24 final renderSettings = MarkerRenderSettings(
25 image: GemImage(image: listPngs[random.nextInt(listPngs.length)], format: ImageFileFormat.png),
26 labelTextSize: 2.0);
27
28 final markerWithRenderSettings = MarkerWithRenderSettings(marker, renderSettings);
29
30 markers.add(markerWithRenderSettings);
31 }
32
33 final settings = MarkerCollectionRenderSettings();
34 settings.labelGroupTextSize = 2;
35 settings.pointsGroupingZoomLevel = 35;
36 settings.image = GemImage(image: imageBytes, format: ImageFileFormat.png);
37
38 _mapController.preferences.markers.addList(list: markers, settings: settings, name: "Markers");
39}
40
41Future<List<Uint8List>> loadPngs() async {
42 List<Uint8List> pngs = [];
43 for (int i = 83; i < 183; ++i) {
44 try {
45 final ByteData imageData = await rootBundle.load('assets/pois/poi$i.png');
46 final Uint8List png = imageData.buffer.asUint8List();
47 pngs.add(png);
48 } catch (e) {
49 throw ("Error loading png $i");
50 }
51 }
52 return pngs;
53}
This code creates and adds a large number of markers to the map, generating random coordinates across Europe for demonstration purposes. It loads PNG images from assets to be used as marker icons.