Mapview Annotations Callbacks

Introduction

This example shows how to add Polygons in MapView

  • Add different types of annotations from a set of Latlng
  • Add onTap events for the annotations
docs-imagedocs-image
Android snapshotiOS snapshot

For all code examples, refer to Flutter Maps SDK Code Examples

ClickAnnotationsPage view source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import 'package:flutter/material.dart';
import 'package:nb_maps_flutter/nb_maps_flutter.dart';

import 'page.dart';

class ClickAnnotationPage extends ExamplePage {
 ClickAnnotationPage()
     : super(const Icon(Icons.check_circle), 'Annotation tap');

 @override
 Widget build(BuildContext context) {
   return const ClickAnnotationBody();
 }
}

class ClickAnnotationBody extends StatefulWidget {
 const ClickAnnotationBody();

 @override
 State<StatefulWidget> createState() => ClickAnnotationBodyState();
}

class ClickAnnotationBodyState extends State<ClickAnnotationBody> {
 ClickAnnotationBodyState();

 static const LatLng center = const LatLng(-33.88, 151.16);
 bool overlapping = false;

 NextbillionMapController? controller;

 void _onMapCreated(NextbillionMapController controller) {
   this.controller = controller;
   controller.onFillTapped.add(_onFillTapped);
   controller.onCircleTapped.add(_onCircleTapped);
   controller.onLineTapped.add(_onLineTapped);
   controller.onSymbolTapped.add(_onSymbolTapped);
 }

 @override
 void dispose() {
   controller?.onFillTapped.remove(_onFillTapped);
   controller?.onCircleTapped.remove(_onCircleTapped);
   controller?.onLineTapped.remove(_onLineTapped);
   controller?.onSymbolTapped.remove(_onSymbolTapped);
   super.dispose();
 }

 _showSnackBar(String type, String id) {
   final snackBar = SnackBar(
       content: Text('Tapped $type $id',
           style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
       backgroundColor: Theme.of(context).primaryColor);
   ScaffoldMessenger.of(context).clearSnackBars();
   ScaffoldMessenger.of(context).showSnackBar(snackBar);
 }

 void _onFillTapped(Fill fill) {
   _showSnackBar('fill', fill.id);
 }

 void _onCircleTapped(Circle circle) {
   _showSnackBar('circle', circle.id);
 }

 void _onLineTapped(Line line) {
   _showSnackBar('line', line.id);
 }

 void _onSymbolTapped(Symbol symbol) {
   _showSnackBar('symbol', symbol.id);
 }

 void _onStyleLoaded() {
   controller!.addCircle(
     CircleOptions(
       geometry: LatLng(-33.881979408447314, 151.171361438502117),
       circleStrokeColor: "#00FF00",
       circleStrokeWidth: 2,
       circleRadius: 16,
     ),
   );
   controller!.addCircle(
     CircleOptions(
       geometry: LatLng(-33.894372606072309, 151.17576679759523),
       circleStrokeColor: "#00FF00",
       circleStrokeWidth: 2,
       circleRadius: 30,
     ),
   );
   controller!.addSymbol(
     SymbolOptions(
         geometry: LatLng(-33.894372606072309, 151.17576679759523),
         iconImage: "fast-food-15",
         iconSize: 2),
   );
   controller!.addLine(
     LineOptions(
       geometry: [
         LatLng(-33.874867744475786, 151.170627211986584),
         LatLng(-33.881979408447314, 151.171361438502117),
         LatLng(-33.887058805548882, 151.175032571079726),
         LatLng(-33.894372606072309, 151.17576679759523),
         LatLng(-33.900060683994681, 151.15765587687909),
       ],
       lineColor: "#0000FF",
       lineWidth: 20,
     ),
   );

   controller!.addFill(
     FillOptions(
       geometry: [
         [
           LatLng(-33.901517742631846, 151.178099204457737),
           LatLng(-33.872845324482071, 151.179025547977773),
           LatLng(-33.868230472039514, 151.147000529140399),
           LatLng(-33.883172899638311, 151.150838238009328),
           LatLng(-33.894158309528244, 151.14223647675135),
           LatLng(-33.904812805307806, 151.155999294764086),
           LatLng(-33.901517742631846, 151.178099204457737),
         ],
       ],
       fillColor: "#FF0000",
       fillOutlineColor: "#000000",
     ),
   );
 }

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     body: NBMap(
       annotationOrder: [
         AnnotationType.fill,
         AnnotationType.line,
         AnnotationType.circle,
         AnnotationType.symbol,
       ],
       onMapCreated: _onMapCreated,
       onStyleLoadedCallback: _onStyleLoaded,
       initialCameraPosition: const CameraPosition(
         target: center,
         zoom: 12.0,
       ),
     ),
     floatingActionButton: ElevatedButton(
         onPressed: () {
           setState(() {
             overlapping = !overlapping;
           });
           controller!.setSymbolIconAllowOverlap(overlapping);
           controller!.setSymbolIconIgnorePlacement(overlapping);

           controller!.setSymbolTextAllowOverlap(overlapping);
           controller!.setSymbolTextIgnorePlacement(overlapping);
         },
         child: Padding(
           padding: const EdgeInsets.all(8.0),
           child: Text("Toggle overlapping"),
         )),
   );
 }
}

Code summary

The above code snippet displays a nbMap with various annotations (fills, circles, lines, symbols) and allows interactions with these annotations through tapping. The nb_maps_flutter package is used for map-related functionalities, and the map annotations are organized in a specific order (fills, lines, circles, symbols) specified in the annotationOrder parameter.

ClickAnnotationPage Class: extends the ExamplePage class and represents a page in the app that demonstrates annotation tapping. The page is associated with an icon (check_circle icon) and a title (Annotation tap). The build method returns a ClickAnnotationBody widget.

ClickAnnotationBody Class: is a StatefulWidget class representing the main body of the ClickAnnotationPage. It manages the state of the ClickAnnotationPage and contains the map and a toggle button to control overlapping of symbols and texts.

ClickAnnotationBodyState Class: This is the state class for the ClickAnnotationBody widget. It handles the interactions with the map, such as setting up the map controller, adding listeners for various annotation types (fill, circle, line, symbol), and displaying SnackBars when annotations are tapped. The onStyleLoaded method is used to add circles, lines, symbols, and fills to the map.

_showSnackBar Method: A private method to show a SnackBar with information about the type and id of the tapped annotation.

build Method: returns a Scaffold widget containing an NBMap widget, which displays the map with various annotations. The annotation order is specified to determine the z-order of annotations (fills, lines, circles, symbols). A floating action button (ElevatedButton) is used to toggle the overlapping behavior of symbols and texts. When the button is pressed, overlapping is toggled, and relevant map controller methods are called accordingly to handle overlapping behavior.


Have Questions ?