• Optimization
  • Navigation
  • Tracking
  • Maps
  • Places

Draw Route Line

This example shows:

  • Draw Route Line

    • await navNextBillionMap.drawRoute(routes)
  • Toggle Alternative Routes Visibility

    • navNextBillionMap.toggleAlternativeVisibilityWith(value)
  • Toggle Route Duration Symbol Visibility

    • navNextBillionMap.toggleDurationSymbolVisibilityWith(value)
Android snapshotiOS snapshot

For all code examples, refer to Flutter Navigation Code Example

DrawRouteLine 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
import 'dart:math';

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

class DrawRouteLine extends StatefulWidget {
  static const String title = "Draw Route Line";

  @override
  DrawRouteLineState createState() => DrawRouteLineState();
}

class DrawRouteLineState extends State<DrawRouteLine> {
  NextbillionMapController? controller;
  List<DirectionsRoute> routes = [];
  late NavNextBillionMap navNextBillionMap;

  LatLng origin = LatLng( 17.457302037173775, 78.37463792413473);
  LatLng dest = LatLng(17.466320809357967, 78.3726774987914);

  bool enableAlternativeRoutes = true;
  bool enableRouteDurationSymbol = true;

  void _onMapCreated(NextbillionMapController controller) {
    this.controller = controller;
  }

  void _onStyleLoaded() {
    if (controller != null) {
      navNextBillionMap = NavNextBillionMap(controller!);
    }
  }

  _onMapClick(Point<double> point, LatLng coordinates) {
    navNextBillionMap.addRouteSelectedListener(coordinates, (selectedRouteIndex) {
      if (routes.isNotEmpty && selectedRouteIndex != 0) {
        var selectedRoute = routes[selectedRouteIndex];
        routes.removeAt(selectedRouteIndex);
        routes.insert(0, selectedRoute);
        setState(() {
          routes = routes;
        });
        navNextBillionMap.drawRoute(routes);
      }
    });
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var screenHeight = MediaQuery.of(context).size.height;

    return Scaffold(
      appBar: AppBar(
        title: const Text(DrawRouteLine.title),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Container(
              constraints: BoxConstraints(maxHeight: screenHeight * 0.6),
              child: NBMap(
                onMapCreated: _onMapCreated,
                initialCameraPosition: CameraPosition(
                  target: LatLng(origin.latitude, origin.longitude),
                  zoom: 13.0,
                ),
                onStyleLoadedCallback: _onStyleLoaded,
                onMapClick: _onMapClick,
              ),
            ),
            _buttonWidget(),
            _switchButton(),
          ],
        ),
      ),
    );
  }

  void _fetchRoute() async {
    RouteRequestParams requestParams = RouteRequestParams(
      origin: origin,
      destination: dest,
      alternatives: true,
      mode: ValidModes.car,
      geometryType: SupportedGeometry.polyline,
    );

    await NBNavigation.fetchRoute(requestParams, (routes, error) async {
      if (routes.isNotEmpty) {
        setState(() {
          this.routes = routes;
        });
        drawRoutes(routes);
      } else if (error != null) {
        print("====error====${error}");
      }
    });
  }

  void _startNavigation() {
    if (routes.isEmpty) return;
    NavigationLauncherConfig config = NavigationLauncherConfig(route: routes.first, routes: routes);
    config.locationLayerRenderMode = LocationLayerRenderMode.GPS;
    config.enableDissolvedRouteLine = false;
    config.themeMode = NavigationThemeMode.system;
    config.useCustomNavigationStyle = false;
    NBNavigation.startNavigation(config);
  }

  Future<void> drawRoutes(List<DirectionsRoute> routes) async {
    navNextBillionMap.clearRoute();
    await navNextBillionMap.drawRoute(routes);
  }

  @override
  void dispose() {
    super.dispose();
  }

  _buttonWidget() {
    return Padding(
      padding: const EdgeInsets.only(left: 8, top: 18.0),
      child: Row(
        children: [
          ElevatedButton(
            style: ButtonStyle(
              backgroundColor: MaterialStateProperty.all(Colors.blueAccent),
            ),
            onPressed: () {
              _fetchRoute();
            },
            child: const Text("Fetch Route"),
          ),
          const Padding(padding: EdgeInsets.only(left: 8)),
          ElevatedButton(
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(routes.isEmpty ? Colors.grey : Colors.blueAccent),
                enableFeedback: routes.isNotEmpty),
            onPressed: () {
              _startNavigation();
            },
            child: const Text("Start Navigation"),
          ),
        ],
      ),
    );
  }

  _switchButton() {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Text("Display Alternative Route"),
              Switch(
                  value: enableAlternativeRoutes,
                  onChanged: (value) {
                    setState(() {
                      enableAlternativeRoutes = value;
                    });
                    navNextBillionMap.toggleAlternativeVisibilityWith(value);
                  })
            ],
          ),
          Row(
            children: [
              Text("Display Route Duration Symbol"),
              Switch(
                  value: enableRouteDurationSymbol,
                  onChanged: (value) {
                    setState(() {
                      enableRouteDurationSymbol = value;
                    });
                    navNextBillionMap.toggleDurationSymbolVisibilityWith(value);
                  })
            ],
          )
        ],
      ),
    );
  }
}

Code summary

The above code snippet demonstrates how to draw a route line on a map, toggle the visibility of alternative routes, and toggle the visibility of route duration symbols. The app uses the nb_maps_flutter and nb_navigation_flutter packages for map rendering and navigation-related functionality.

Draw Route Line:

  • The NBMap widget from the nb_maps_flutter package is used to display the map.
  • When the "Fetch Route" button is pressed, the _fetchRoute function is called. It sends a route request to the navigation service (NBNavigation.fetchRoute) with the specified origin and destination coordinates. The response contains a list of DirectionsRoute objects representing different possible routes from the origin to the destination.
  • The drawRoutes function is used to draw the fetched routes on the map using the NavNextBillionMap controller.

Toggle Alternative Routes Visibility:

  • The "Display Alternative Route" switch allows the user to toggle the visibility of alternative routes on the map.
  • The enableAlternativeRoutes variable keeps track of the switch state.
  • When the switch is toggled, the _switchButton function calls the toggleAlternativeVisibilityWith method of NavNextBillionMap to change the visibility of alternative routes accordingly.

Toggle Route Duration Symbol Visibility:

  • The "Display Route Duration Symbol" switch allows the user to toggle the visibility of route duration symbols on the map.

  • The enableRouteDurationSymbol variable keeps track of the switch state.

  • When the switch is toggled, the _switchButton function calls the toggleDurationSymbolVisibilityWith method of NavNextBillionMap to change the visibility of route duration symbols accordingly.

Start Navigation:

  • The "Start Navigation" button is used to initiate turn-by-turn navigation using the selected route.

  • When the button is pressed, the _startNavigation function is called. It launches the navigation using NBNavigation.startNavigation with the first route from the list.

Map Interaction:

  • The _onMapCreated callback function is used to get the map controller when the map is created.

  • The _onMapClick function is used to handle map click events. When a route is selected on the map, it is moved to the top of the routes list and redrawn.

  • Overall, the app provides an interface for fetching routes between two specified coordinates, drawing those routes on the map, and toggling the visibility of alternative routes and route duration symbols.