Mapview Polygon

This example shows how to add Polygons in MapView

  • Add Polygon from a set of Latlng
  • Set Polygon visibility
  • Set Polygon color
docs-imagedocs-image
Android snapshotiOS snapshot

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

PlaceFillPage view source

1
import 'dart:async';
2
import 'dart:typed_data';
3
4
import 'package:flutter/material.dart';
5
import 'package:flutter/services.dart';
6
import 'package:nb_maps_flutter/nb_maps_flutter.dart';
7
8
import 'page.dart';
9
10
class PlaceFillPage extends ExamplePage {
11
PlaceFillPage() : super(const Icon(Icons.check_circle), 'Place fill');
12
13
@override
14
Widget build(BuildContext context) {
15
return const PlaceFillBody();
16
}
17
}
18
19
class PlaceFillBody extends StatefulWidget {
20
const PlaceFillBody();
21
22
@override
23
State<StatefulWidget> createState() => PlaceFillBodyState();
24
}
25
26
class PlaceFillBodyState extends State<PlaceFillBody> {
27
PlaceFillBodyState();
28
29
static final LatLng center = const LatLng(-33.86711, 151.1947171);
30
final String _fillPatternImage = "assets/fill/cat_silhouette_pattern.png";
31
32
final List<List<LatLng>> _defaultGeometry = [
33
[
34
LatLng(-33.719, 151.150),
35
LatLng(-33.858, 151.150),
36
LatLng(-33.866, 151.401),
37
LatLng(-33.747, 151.328),
38
LatLng(-33.719, 151.150),
39
],
40
[
41
LatLng(-33.762, 151.250),
42
LatLng(-33.827, 151.250),
43
LatLng(-33.833, 151.347),
44
LatLng(-33.762, 151.250),
45
]
46
];
47
48
NextbillionMapController? controller;
49
int _fillCount = 0;
50
Fill? _selectedFill;
51
52
void _onMapCreated(NextbillionMapController controller) {
53
this.controller = controller;
54
controller.onFillTapped.add(_onFillTapped);
55
this.controller!.onFeatureDrag.add(_onFeatureDrag);
56
}
57
58
void _onFeatureDrag(id,
59
{required current,
60
required delta,
61
required origin,
62
required point,
63
required eventType}) {
64
DragEventType type = eventType;
65
switch (type) {
66
case DragEventType.start:
67
// TODO: Handle this case.
68
break;
69
case DragEventType.drag:
70
// TODO: Handle this case.
71
break;
72
case DragEventType.end:
73
// TODO: Handle this case.
74
break;
75
}
76
}
77
78
void _onStyleLoaded() {
79
addImageFromAsset("assetImage", _fillPatternImage);
80
}
81
82
/// Adds an asset image to the currently displayed style
83
Future<void> addImageFromAsset(String name, String assetName) async {
84
final ByteData bytes = await rootBundle.load(assetName);
85
final Uint8List list = bytes.buffer.asUint8List();
86
return controller!.addImage(name, list);
87
}
88
89
@override
90
void dispose() {
91
controller?.onFillTapped.remove(_onFillTapped);
92
super.dispose();
93
}
94
95
void _onFillTapped(Fill fill) {
96
setState(() {
97
_selectedFill = fill;
98
});
99
}
100
101
void _updateSelectedFill(FillOptions changes) {
102
controller!.updateFill(_selectedFill!, changes);
103
}
104
105
void _add() {
106
controller!.addFill(
107
FillOptions(
108
geometry: _defaultGeometry,
109
fillColor: "#FF0000",
110
fillOutlineColor: "#FF0000"),
111
);
112
setState(() {
113
_fillCount += 1;
114
});
115
}
116
117
void _remove() {
118
controller!.removeFill(_selectedFill!);
119
setState(() {
120
_selectedFill = null;
121
_fillCount -= 1;
122
});
123
}
124
125
void _changePosition() {
126
List<List<LatLng>>? geometry = _selectedFill!.options.geometry;
127
128
if (geometry == null) {
129
geometry = _defaultGeometry;
130
}
131
132
_updateSelectedFill(FillOptions(
133
geometry: geometry
134
.map((list) => list
135
.map(
136
// Move to right with 0.1 degree on longitude
137
(latLng) => LatLng(latLng.latitude, latLng.longitude + 0.1))
138
.toList())
139
.toList()));
140
}
141
142
void _changeDraggable() {
143
bool? draggable = _selectedFill!.options.draggable;
144
if (draggable == null) {
145
// default value
146
draggable = false;
147
}
148
_updateSelectedFill(
149
FillOptions(draggable: !draggable),
150
);
151
}
152
153
Future<void> _changeFillOpacity() async {
154
double? current = _selectedFill!.options.fillOpacity;
155
if (current == null) {
156
// default value
157
current = 1.0;
158
}
159
160
_updateSelectedFill(
161
FillOptions(fillOpacity: current < 0.1 ? 1.0 : current * 0.75),
162
);
163
}
164
165
Future<void> _changeFillColor() async {
166
String? current = _selectedFill!.options.fillColor;
167
if (current == null) {
168
// default value
169
current = "#FF0000";
170
}
171
172
_updateSelectedFill(
173
FillOptions(fillColor: "#FFFF00"),
174
);
175
}
176
177
Future<void> _changeFillOutlineColor() async {
178
String? current = _selectedFill!.options.fillOutlineColor;
179
if (current == null) {
180
// default value
181
current = "#FF0000";
182
}
183
184
_updateSelectedFill(
185
FillOptions(fillOutlineColor: "#FFFF00"),
186
);
187
}
188
189
Future<void> _changeFillPattern() async {
190
String? current =
191
_selectedFill!.options.fillPattern == null ? "assetImage" : null;
192
_updateSelectedFill(
193
FillOptions(fillPattern: current),
194
);
195
}
196
197
@override
198
Widget build(BuildContext context) {
199
return Column(
200
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
201
crossAxisAlignment: CrossAxisAlignment.stretch,
202
children: <Widget>[
203
Center(
204
child: SizedBox(
205
width: 300.0,
206
height: 200.0,
207
child: NBMap(
208
onMapCreated: _onMapCreated,
209
onStyleLoadedCallback: _onStyleLoaded,
210
initialCameraPosition: const CameraPosition(
211
target: LatLng(-33.852, 151.211),
212
zoom: 7.0,
213
),
214
),
215
),
216
),
217
Expanded(
218
child: SingleChildScrollView(
219
child: Row(
220
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
221
children: <Widget>[
222
Row(
223
children: <Widget>[
224
Column(
225
children: <Widget>[
226
TextButton(
227
child: const Text('add'),
228
onPressed: (_fillCount == 12) ? null : _add,
229
),
230
TextButton(
231
child: const Text('remove'),
232
onPressed: (_selectedFill == null) ? null : _remove,
233
),
234
],
235
),
236
Column(
237
children: <Widget>[
238
TextButton(
239
child: const Text('change fill-opacity'),
240
onPressed: (_selectedFill == null)
241
? null
242
: _changeFillOpacity,
243
),
244
TextButton(
245
child: const Text('change fill-color'),
246
onPressed:
247
(_selectedFill == null) ? null : _changeFillColor,
248
),
249
TextButton(
250
child: const Text('change fill-outline-color'),
251
onPressed: (_selectedFill == null)
252
? null
253
: _changeFillOutlineColor,
254
),
255
TextButton(
256
child: const Text('change fill-pattern'),
257
onPressed: (_selectedFill == null)
258
? null
259
: _changeFillPattern,
260
),
261
TextButton(
262
child: const Text('change position'),
263
onPressed:
264
(_selectedFill == null) ? null : _changePosition,
265
),
266
TextButton(
267
child: const Text('toggle draggable'),
268
onPressed:
269
(_selectedFill == null) ? null : _changeDraggable,
270
),
271
],
272
),
273
],
274
)
275
],
276
),
277
),
278
),
279
],
280
);
281
}
282
}

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.

© 2024 NextBillion.ai all rights reserved.