• Optimization
  • Navigation
  • Tracking
  • Maps
  • Places

Mapview Polygon

This example shows how to add Polygons in MapView

  • Add Polygon from a set of Latlng
  • Set Polygon visibility
  • Set Polygon color
Android snapshotiOS snapshot

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

PlaceFillPage 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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:nb_maps_flutter/nb_maps_flutter.dart';

import 'page.dart';

class PlaceFillPage extends ExamplePage {
 PlaceFillPage() : super(const Icon(Icons.check_circle), 'Place fill');

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

class PlaceFillBody extends StatefulWidget {
 const PlaceFillBody();

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

class PlaceFillBodyState extends State<PlaceFillBody> {
 PlaceFillBodyState();

 static final LatLng center = const LatLng(-33.86711, 151.1947171);
 final String _fillPatternImage = "assets/fill/cat_silhouette_pattern.png";

 final List<List<LatLng>> _defaultGeometry = [
   [
     LatLng(-33.719, 151.150),
     LatLng(-33.858, 151.150),
     LatLng(-33.866, 151.401),
     LatLng(-33.747, 151.328),
     LatLng(-33.719, 151.150),
   ],
   [
     LatLng(-33.762, 151.250),
     LatLng(-33.827, 151.250),
     LatLng(-33.833, 151.347),
     LatLng(-33.762, 151.250),
   ]
 ];

 NextbillionMapController? controller;
 int _fillCount = 0;
 Fill? _selectedFill;

 void _onMapCreated(NextbillionMapController controller) {
   this.controller = controller;
   controller.onFillTapped.add(_onFillTapped);
   this.controller!.onFeatureDrag.add(_onFeatureDrag);
 }

 void _onFeatureDrag(id,
     {required current,
     required delta,
     required origin,
     required point,
     required eventType}) {
   DragEventType type = eventType;
   switch (type) {
     case DragEventType.start:
       // TODO: Handle this case.
       break;
     case DragEventType.drag:
       // TODO: Handle this case.
       break;
     case DragEventType.end:
       // TODO: Handle this case.
       break;
   }
 }

 void _onStyleLoaded() {
   addImageFromAsset("assetImage", _fillPatternImage);
 }

 /// Adds an asset image to the currently displayed style
 Future<void> addImageFromAsset(String name, String assetName) async {
   final ByteData bytes = await rootBundle.load(assetName);
   final Uint8List list = bytes.buffer.asUint8List();
   return controller!.addImage(name, list);
 }

 @override
 void dispose() {
   controller?.onFillTapped.remove(_onFillTapped);
   super.dispose();
 }

 void _onFillTapped(Fill fill) {
   setState(() {
     _selectedFill = fill;
   });
 }

 void _updateSelectedFill(FillOptions changes) {
   controller!.updateFill(_selectedFill!, changes);
 }

 void _add() {
   controller!.addFill(
     FillOptions(
         geometry: _defaultGeometry,
         fillColor: "#FF0000",
         fillOutlineColor: "#FF0000"),
   );
   setState(() {
     _fillCount += 1;
   });
 }

 void _remove() {
   controller!.removeFill(_selectedFill!);
   setState(() {
     _selectedFill = null;
     _fillCount -= 1;
   });
 }

 void _changePosition() {
   List<List<LatLng>>? geometry = _selectedFill!.options.geometry;

   if (geometry == null) {
     geometry = _defaultGeometry;
   }

   _updateSelectedFill(FillOptions(
       geometry: geometry
           .map((list) => list
               .map(
                   // Move to right with 0.1 degree on longitude
                   (latLng) => LatLng(latLng.latitude, latLng.longitude + 0.1))
               .toList())
           .toList()));
 }

 void _changeDraggable() {
   bool? draggable = _selectedFill!.options.draggable;
   if (draggable == null) {
     // default value
     draggable = false;
   }
   _updateSelectedFill(
     FillOptions(draggable: !draggable),
   );
 }

 Future<void> _changeFillOpacity() async {
   double? current = _selectedFill!.options.fillOpacity;
   if (current == null) {
     // default value
     current = 1.0;
   }

   _updateSelectedFill(
     FillOptions(fillOpacity: current < 0.1 ? 1.0 : current * 0.75),
   );
 }

 Future<void> _changeFillColor() async {
   String? current = _selectedFill!.options.fillColor;
   if (current == null) {
     // default value
     current = "#FF0000";
   }

   _updateSelectedFill(
     FillOptions(fillColor: "#FFFF00"),
   );
 }

 Future<void> _changeFillOutlineColor() async {
   String? current = _selectedFill!.options.fillOutlineColor;
   if (current == null) {
     // default value
     current = "#FF0000";
   }

   _updateSelectedFill(
     FillOptions(fillOutlineColor: "#FFFF00"),
   );
 }

 Future<void> _changeFillPattern() async {
   String? current =
       _selectedFill!.options.fillPattern == null ? "assetImage" : null;
   _updateSelectedFill(
     FillOptions(fillPattern: current),
   );
 }

 @override
 Widget build(BuildContext context) {
   return Column(
     mainAxisAlignment: MainAxisAlignment.spaceEvenly,
     crossAxisAlignment: CrossAxisAlignment.stretch,
     children: <Widget>[
       Center(
         child: SizedBox(
           width: 300.0,
           height: 200.0,
           child: NBMap(
             onMapCreated: _onMapCreated,
             onStyleLoadedCallback: _onStyleLoaded,
             initialCameraPosition: const CameraPosition(
               target: LatLng(-33.852, 151.211),
               zoom: 7.0,
             ),
           ),
         ),
       ),
       Expanded(
         child: SingleChildScrollView(
           child: Row(
             mainAxisAlignment: MainAxisAlignment.spaceEvenly,
             children: <Widget>[
               Row(
                 children: <Widget>[
                   Column(
                     children: <Widget>[
                       TextButton(
                         child: const Text('add'),
                         onPressed: (_fillCount == 12) ? null : _add,
                       ),
                       TextButton(
                         child: const Text('remove'),
                         onPressed: (_selectedFill == null) ? null : _remove,
                       ),
                     ],
                   ),
                   Column(
                     children: <Widget>[
                       TextButton(
                         child: const Text('change fill-opacity'),
                         onPressed: (_selectedFill == null)
                             ? null
                             : _changeFillOpacity,
                       ),
                       TextButton(
                         child: const Text('change fill-color'),
                         onPressed:
                             (_selectedFill == null) ? null : _changeFillColor,
                       ),
                       TextButton(
                         child: const Text('change fill-outline-color'),
                         onPressed: (_selectedFill == null)
                             ? null
                             : _changeFillOutlineColor,
                       ),
                       TextButton(
                         child: const Text('change fill-pattern'),
                         onPressed: (_selectedFill == null)
                             ? null
                             : _changeFillPattern,
                       ),
                       TextButton(
                         child: const Text('change position'),
                         onPressed:
                             (_selectedFill == null) ? null : _changePosition,
                       ),
                       TextButton(
                         child: const Text('toggle draggable'),
                         onPressed:
                             (_selectedFill == null) ? null : _changeDraggable,
                       ),
                     ],
                   ),
                 ],
               )
             ],
           ),
         ),
       ),
     ],
   );
 }
}

Code summary

The above code snippet displays a map with various functionalities related to polygons. The user can interact with the map, add and remove fills, change fill properties (such as color, opacity, outline color, and pattern), move fills, and toggle the fill's draggable state. It utilizes the nb_maps_flutter package for map-related functionalities.

PlaceFillPage Class: extends the ExamplePage class and represents a page in the app that demonstrates fill-related functionalities. The page is associated with an icon (check_circle icon) and a title ('Place fill'). The build method returns a PlaceFillBody widget.

PlaceFillBody Class: is a StatefulWidget class representing the main body of the PlaceFillPage. It manages the state of the PlaceFillPage and contains the map and various buttons for interacting with the fills.

PlaceFillBodyState Class: This is the state class for the PlaceFillBody widget. It handles the interactions with the map, such as adding fills, updating fill properties, and removing fills. Some key methods include:

  • _onMapCreated: A callback method called when the map is created. It sets the map controller and adds listeners for fill taps and feature drags (used for dragging the fill on the map).
  • _onFeatureDrag: A method called when a feature (fill) on the map is dragged. It currently handles the start, drag, and end events for dragging.
  • _onStyleLoaded: A callback method called when the map style is loaded. It adds an image from an asset to the style.

build Method: The build method returns a Column widget containing a map (NBMap) and a set of buttons for interacting with the fills. The buttons include 'add', 'remove', 'change fill-opacity', 'change fill-color', 'change fill-outline-color', 'change fill-pattern', 'change position', and 'toggle draggable'. The map displays fills, and when a fill is tapped, it becomes selected, and its properties can be modified using the buttons.