MapView Polyline

Introduction

This example shows how to add PolyLines in MapView

  1. Add Polyline to Mapview from a set of LatLng
  2. Set Polyline opacity
  3. Set polyline visibility
  4. Move Polyline position
Android snapshot iOS snapshot

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

LinePage view source

1import 'dart:async';
2import 'dart:typed_data';
3
4import 'package:flutter/material.dart';
5import 'package:flutter/services.dart';
6import 'package:nb_maps_flutter/nb_maps_flutter.dart';
7
8import 'page.dart';
9
10class LinePage extends ExamplePage {
11 LinePage() : super(const Icon(Icons.share), 'Line');
12
13 
14 Widget build(BuildContext context) {
15   return const LineBody();
16 }
17}
18
19class LineBody extends StatefulWidget {
20 const LineBody();
21
22 
23 State<StatefulWidget> createState() => LineBodyState();
24}
25
26class LineBodyState extends State<LineBody> {
27 LineBodyState();
28
29 static final LatLng center = const LatLng(-33.86711, 151.1947171);
30
31 NextbillionMapController? controller;
32 int _lineCount = 0;
33 Line? _selectedLine;
34 final String _linePatternImage = "assets/fill/cat_silhouette_pattern.png";
35
36 void _onMapCreated(NextbillionMapController controller) {
37   this.controller = controller;
38   controller.onLineTapped.add(_onLineTapped);
39 }
40
41 
42 void dispose() {
43   controller?.onLineTapped.remove(_onLineTapped);
44   super.dispose();
45 }
46
47 /// Adds an asset image to the currently displayed style
48 Future<void> addImageFromAsset(String name, String assetName) async {
49   final ByteData bytes = await rootBundle.load(assetName);
50   final Uint8List list = bytes.buffer.asUint8List();
51   return controller!.addImage(name, list);
52 }
53
54 _onLineTapped(Line line) async {
55   await _updateSelectedLine(
56     LineOptions(lineColor: "#ff0000"),
57   );
58   setState(() {
59     _selectedLine = line;
60   });
61   await _updateSelectedLine(
62     LineOptions(lineColor: "#ffe100"),
63   );
64 }
65
66 _updateSelectedLine(LineOptions changes) async {
67   if (_selectedLine != null) controller!.updateLine(_selectedLine!, changes);
68 }
69
70 void _add() {
71   controller!.addLine(
72     LineOptions(
73         geometry: [
74           LatLng(-33.86711, 151.1947171),
75           LatLng(-33.86711, 151.1947171),
76           LatLng(-32.86711, 151.1947171),
77           LatLng(-33.86711, 152.1947171),
78         ],
79         lineColor: "#ff0000",
80         lineWidth: 14.0,
81         lineOpacity: 0.5,
82         draggable: true),
83   );
84   setState(() {
85     _lineCount += 1;
86   });
87 }
88
89 _move() async {
90   final currentStart = _selectedLine!.options.geometry![0];
91   final currentEnd = _selectedLine!.options.geometry![1];
92   final end =
93       LatLng(currentEnd.latitude + 0.001, currentEnd.longitude + 0.001);
94   final start =
95       LatLng(currentStart.latitude - 0.001, currentStart.longitude - 0.001);
96   await controller!
97       .updateLine(_selectedLine!, LineOptions(geometry: [start, end]));
98 }
99
100 void _remove() {
101   controller!.removeLine(_selectedLine!);
102   setState(() {
103     _selectedLine = null;
104     _lineCount -= 1;
105   });
106 }
107
108 Future<void> _changeLinePattern() async {
109   String? current =
110       _selectedLine!.options.linePattern == null ? "assetImage" : null;
111   await _updateSelectedLine(
112     LineOptions(linePattern: current),
113   );
114 }
115
116 Future<void> _changeAlpha() async {
117   double? current = _selectedLine!.options.lineOpacity;
118   if (current == null) {
119     // default value
120     current = 1.0;
121   }
122
123   await _updateSelectedLine(
124     LineOptions(lineOpacity: current < 0.1 ? 1.0 : current * 0.75),
125   );
126 }
127
128 Future<void> _toggleVisible() async {
129   double? current = _selectedLine!.options.lineOpacity;
130   if (current == null) {
131     // default value
132     current = 1.0;
133   }
134   await _updateSelectedLine(
135     LineOptions(lineOpacity: current == 0.0 ? 1.0 : 0.0),
136   );
137 }
138
139 _onStyleLoadedCallback() async {
140   addImageFromAsset("assetImage", _linePatternImage);
141   await controller!.addLine(
142     LineOptions(
143       geometry: [LatLng(37.4220, -122.0841), LatLng(37.4240, -122.0941)],
144       lineColor: "#ff0000",
145       lineWidth: 14.0,
146       lineOpacity: 0.5,
147     ),
148   );
149 }
150
151 
152 Widget build(BuildContext context) {
153   return Column(
154     mainAxisAlignment: MainAxisAlignment.spaceEvenly,
155     crossAxisAlignment: CrossAxisAlignment.stretch,
156     children: <Widget>[
157       Center(
158         child: SizedBox(
159           height: 400.0,
160           child: NBMap(
161             onMapCreated: _onMapCreated,
162             onStyleLoadedCallback: _onStyleLoadedCallback,
163             initialCameraPosition: const CameraPosition(
164               target: LatLng(-33.852, 151.211),
165               zoom: 11.0,
166             ),
167           ),
168         ),
169       ),
170       Expanded(
171         child: SingleChildScrollView(
172           child: Row(
173             mainAxisAlignment: MainAxisAlignment.spaceEvenly,
174             children: <Widget>[
175               Column(
176                 children: <Widget>[
177                   Row(
178                     children: <Widget>[
179                       TextButton(
180                         child: const Text('add'),
181                         onPressed: (_lineCount == 12) ? null : _add,
182                       ),
183                       TextButton(
184                         child: const Text('remove'),
185                         onPressed: (_selectedLine == null) ? null : _remove,
186                       ),
187                       TextButton(
188                         child: const Text('move'),
189                         onPressed: (_selectedLine == null)
190                             ? null
191                             : () async {
192                                 await _move();
193                               },
194                       ),
195                       TextButton(
196                         child: const Text('change line-pattern'),
197                         onPressed: (_selectedLine == null)
198                             ? null
199                             : _changeLinePattern,
200                       ),
201                     ],
202                   ),
203                   Row(
204                     children: <Widget>[
205                       TextButton(
206                         child: const Text('change alpha'),
207                         onPressed:
208                             (_selectedLine == null) ? null : _changeAlpha,
209                       ),
210                       TextButton(
211                         child: const Text('toggle visible'),
212                         onPressed:
213                             (_selectedLine == null) ? null : _toggleVisible,
214                       ),
215                       TextButton(
216                         child: const Text('print current LatLng'),
217                         onPressed: (_selectedLine == null)
218                             ? null
219                             : () async {
220                                 var latLngs = await controller!
221                                     .getLineLatLngs(_selectedLine!);
222                                 for (var latLng in latLngs) {
223                                   print(latLng.toString());
224                                 }
225                               },
226                       ),
227                     ],
228                   ),
229                 ],
230               ),
231             ],
232           ),
233         ),
234       ),
235     ],
236   );
237 }
238}

Code summary

The above code snippet demonstrates the implementation of a Flutter application that utilizes the nb_maps_flutter package to display a map with various functionalities related to lines and markers.

LinePage Class: extends the ExamplePage class and represents a page in the app that demonstrates line-related functionalities. The page is associated with an icon (share icon) and a title ('Line'). The build method returns a LineBody widget.

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

LineBodyState Class: is the state class for the LineBody widget. It handles the interactions with the map, such as adding lines, updating line properties, and removing lines. Some key methods include:

  1. _onMapCreated: A callback method called when the map is created. It sets the map controller and adds a listener for when a line is tapped.
  2. dispose: A method called when the widget is disposed. It removes the listener for line taps.
  3. addImageFromAsset: A method for adding an image from an asset to the currently displayed style of the map.
  4. _onLineTapped: A callback method called when a line on the map is tapped. It updates the line color to red when tapped and to yellow when tapped again.
  5. _add: A method for adding a new line to the map with specific properties such as color, width, opacity, and whether it is draggable.
  6. _move: A method for moving the currently selected line on the map.
  7. _remove: A method for removing the currently selected line from the map.
  8. _changeLinePattern: A method for changing the pattern of the currently selected line.
  9. _changeAlpha: A method for changing the opacity of the currently selected line.
  10. _toggleVisible: A method for toggling the visibility of the currently selected line.
  11. _onStyleLoadedCallback: A callback method called when the map style is loaded. It adds an image from an asset to the style and initializes a line on the map with specific properties.

build Method: The build method returns a Column widget containing a map (NBMap) and a set of buttons for interacting with the map. The buttons include 'add', 'remove', 'move', 'change line-pattern', 'change alpha', 'toggle visible', and 'print current LatLng'. The map displays lines, and when a line is tapped, its color changes, and the selected line's properties can be modified using the buttons.

DIDN'T FIND WHAT YOU LOOKING FOR?