Full Navigation Experience Example

这篇文档目前尚未提供译文,将以原文展示。

Introduction

  1. This example shows:
    1. Display a MapView
    2. Track Current Location
    3. onMapClick
    4. onMapLongClick
    5. onUserLocationUpdate
  2. Customize marker image of route origin and destination
  3. Fetch route with RouteRequestParams
    1. NBNavigation.fetchRoute(requestParams, (routes, error) async
  4. Draw routes with route result
  5. navNextBillionMap.drawRoute(routes);
  6. Start Navigation with LauncherConfig
    1. NBNavigation.startNavigation(config)
Android snapshot iOS snapshot

For all code examples, refer to Flutter Navigation Code Example

FullNavigationExample view source

1import 'dart:math';
2
3import 'package:flutter/material.dart';
4import 'package:flutter/services.dart';
5import 'package:fluttertoast/fluttertoast.dart';
6import 'package:nb_navigation_flutter/nb_navigation_flutter.dart';
7import 'package:nb_maps_flutter/nb_maps_flutter.dart';
8
9class FullNavigationExample extends StatefulWidget {
10  static const String title = "Full Navigation Experience Example";
11
12  
13  FullNavigationExampleState createState() => FullNavigationExampleState();
14}
15
16class FullNavigationExampleState extends State<FullNavigationExample> {
17  NextbillionMapController? controller;
18  List<DirectionsRoute> routes = [];
19  late NavNextBillionMap navNextBillionMap;
20  Symbol? mapMarkerSymbol;
21
22  String locationTrackImage = "assets/location_on.png";
23  UserLocation? currentLocation;
24  List<LatLng> waypoints = [];
25
26  void _onMapCreated(NextbillionMapController controller) {
27    this.controller = controller;
28  }
29
30  _onStyleLoadedCallback() async {
31    if (controller != null) {
32      navNextBillionMap = NavNextBillionMap(controller!);
33      loadAssetImage();
34    }
35    Fluttertoast.showToast(msg: "Long click to select destination and fetch a route");
36    Future.delayed(const Duration(milliseconds: 80), () {
37      controller?.updateMyLocationTrackingMode(MyLocationTrackingMode.Tracking);
38    });
39  }
40
41  _onMapLongClick(Point<double> point, LatLng coordinates) {
42    _fetchRoute(coordinates);
43  }
44
45
46  _onMapClick(Point<double> point, LatLng coordinates) {
47    navNextBillionMap.addRouteSelectedListener(coordinates, (selectedRouteIndex) {
48      if (routes.isNotEmpty && selectedRouteIndex != 0) {
49        var selectedRoute = routes[selectedRouteIndex];
50        routes.removeAt(selectedRouteIndex);
51        routes.insert(0, selectedRoute);
52        setState(() {
53          routes = routes;
54        });
55        navNextBillionMap.drawRoute(routes);
56      }
57    });
58  }
59
60  _onUserLocationUpdate(UserLocation location) {
61    currentLocation = location;
62  }
63
64  _onCameraTrackingChanged() {
65    setState(() {
66      locationTrackImage = 'assets/location_off.png';
67    });
68  }
69
70  
71  Widget build(BuildContext context) {
72    return Stack(
73      children: [
74        NBMap(
75          onMapCreated: _onMapCreated,
76          onStyleLoadedCallback: _onStyleLoadedCallback,
77          initialCameraPosition: const CameraPosition(
78            target: LatLng(0, 0),
79            zoom: 14.0,
80          ),
81          trackCameraPosition: true,
82          myLocationEnabled: true,
83          myLocationTrackingMode: MyLocationTrackingMode.Tracking,
84          onMapLongClick: _onMapLongClick,
85          onUserLocationUpdated: _onUserLocationUpdate,
86          onCameraTrackingDismissed: _onCameraTrackingChanged,
87          onMapClick: _onMapClick,
88        ),
89        Padding(
90          padding: const EdgeInsets.all(8.0),
91          child: Column(
92            mainAxisAlignment: MainAxisAlignment.end,
93            crossAxisAlignment: CrossAxisAlignment.start,
94            children: [
95              Padding(
96                padding: const EdgeInsets.all(8.0),
97                child: GestureDetector(
98                    child: Image(
99                      image: AssetImage(locationTrackImage),
100                      width: 28,
101                      height: 28,
102                    ),
103                    onTap: () {
104                      controller?.updateMyLocationTrackingMode(MyLocationTrackingMode.Tracking);
105                      setState(() {
106                        locationTrackImage = 'assets/location_on.png';
107                      });
108                    }),
109              ),
110              const Padding(padding: EdgeInsets.only(top: 35)),
111              Row(
112                mainAxisAlignment: MainAxisAlignment.center,
113                children: [
114                  ElevatedButton(
115                      style: ButtonStyle(
116                          backgroundColor: MaterialStateProperty.all(routes.isEmpty ? Colors.grey : Colors.blueAccent),
117                          enableFeedback: routes.isNotEmpty),
118                      onPressed: () {
119                        clearRouteResult();
120                        waypoints.clear();
121                      },
122                      child: const Text("Clear Routes")),
123                  const Padding(padding: EdgeInsets.only(left: 8)),
124                  ElevatedButton(
125                      style: ButtonStyle(
126                          backgroundColor: MaterialStateProperty.all(routes.isEmpty ? Colors.grey : Colors.blueAccent),
127                          enableFeedback: routes.isNotEmpty),
128                      onPressed: () {
129                        _startNavigation();
130                      },
131                      child: const Text("Start Navigation")),
132                ],
133              ),
134              const Padding(padding: EdgeInsets.only(top: 48)),
135              // Padding(
136              //   padding: const EdgeInsets.only(top: 8.0),
137              //   child: Text("route response: ${routeResult}"),
138              // ),
139            ],
140          ),
141        )
142      ],
143    );
144  }
145
146
147  void _fetchRoute(LatLng destination) async {
148    if (currentLocation == null) {
149      return;
150    }
151    LatLng origin = currentLocation!.position;
152    waypoints.add(destination);
153    RouteRequestParams requestParams = RouteRequestParams(
154      origin: origin,
155      destination: waypoints.last,
156      // overview: ValidOverview.simplified,
157      // avoid: [SupportedAvoid.toll, SupportedAvoid.ferry],
158      // option: SupportedOption.flexible,
159      // truckSize: [200, 200, 600],
160      // truckWeight: 100,
161      // unit: SupportedUnits.imperial,
162      alternatives: true,
163      mode: ValidModes.car,
164      geometryType: SupportedGeometry.polyline,
165    );
166
167    if (waypoints.length > 1) {
168      requestParams.waypoints = waypoints.sublist(0, waypoints.length - 1);
169    }
170
171    await NBNavigation.fetchRoute(requestParams, (routes, error) async {
172      if (routes.isNotEmpty) {
173        clearRouteResult();
174        setState(() {
175          this.routes = routes;
176        });
177        await drawRoutes(routes);
178        addImageFromAsset(destination);
179      } else if (error != null) {
180        print("====error====${error}");
181      }
182    });
183  }
184
185  Future<void> drawRoutes(List<DirectionsRoute> routes) async {
186    // navNextBillionMap.toggleDurationSymbolVisibilityWith(false);
187    await navNextBillionMap.drawRoute(routes);
188  }
189
190  void clearRouteResult() {
191    navNextBillionMap.clearRoute();
192    controller?.clearSymbols();
193    setState(() {
194      routes.clear();
195    });
196  }
197
198  void _startNavigation() {
199    if (routes.isEmpty) return;
200    NavigationLauncherConfig config = NavigationLauncherConfig(route: routes.first, routes: routes);
201    config.locationLayerRenderMode = LocationLayerRenderMode.GPS;
202    config.enableDissolvedRouteLine = false;
203    config.shouldSimulateRoute = false;
204    config.themeMode = NavigationThemeMode.system;
205    config.useCustomNavigationStyle = false;
206    NBNavigation.startNavigation(config);
207  }
208
209  Future<void> loadAssetImage() async {
210    final ByteData bytes = await rootBundle.load("assets/map_marker_light.png");
211    final Uint8List list = bytes.buffer.asUint8List();
212    await controller?.addImage("ic_marker_destination", list);
213  }
214
215  Future<void> addImageFromAsset(LatLng coordinates) async {
216    controller?.clearSymbols();
217    var symbolOptions = SymbolOptions(
218      geometry: coordinates,
219      iconImage: "ic_marker_destination",
220    );
221    await controller?.addSymbol(symbolOptions);
222    controller?.symbolManager?.setTextAllowOverlap(false);
223  }
224
225  
226  void initState() {
227    super.initState();
228  }
229
230  
231  void dispose() {
232    // TODO: implement dispose
233    super.dispose();
234  }
235
236  
237  void didUpdateWidget(FullNavigationExample oldWidget) {
238    // TODO: implement didUpdateWidget
239    super.didUpdateWidget(oldWidget);
240  }
241
242  
243  void didChangeDependencies() {
244    // TODO: implement didChangeDependencies
245    super.didChangeDependencies();
246  }
247}

Code summary

The above code snippet demonstrates a full navigation experience using the "nb_navigation_flutter" and "nb_maps_flutter" packages. It provides functionalities to display a map with a user's current location, select a destination by long-pressing on the map, fetch a route from the user's current location to the selected destination, and start navigation with turn-by-turn directions.

How to display NBMap Widget:

  1. The NBMap widget is displayed using the **"NBMap" **class from the "nb_maps_flutter" package. It is placed in the stack of widgets and is provided with various properties like onMapCreated, initialCameraPosition, myLocationEnabled, etc., to configure its behavior.

Customize marker image of route origin and destination:

The marker image for the route origin and destination is customized using the method loadAssetImage. It loads a custom marker image from the assets folder and adds it to the map using the "addImage" method of the "NextbillionMapController".

Fetch route with RouteRequestParams: The route is fetched using the _fetchRoute method. It takes the destination coordinates, constructs a RouteRequestParams object with various route parameters like origin, destination, unit, mode, and geometryType, and then calls the NBNavigation.fetchRoute method to retrieve the route information.

Draw routes with route result: The drawn routes are displayed on the map using the drawRoutes method. It takes a list of DirectionsRoute objects and calls navNextBillionMap.drawRoute to render the route on the map.

Start Navigation with LauncherConfig: The navigation is started using the _startNavigation method. It constructs a NavigationLauncherConfig object with various configuration options like route, locationLayerRenderMode, enableDissolvedRouteLine, shouldSimulateRoute, etc., and then calls NBNavigation.startNavigation to begin the navigation.

The code also includes various event handlers like _onMapCreated, _onStyleLoadedCallback, _onMapLongClick, _onMapClick, _onUserLocationUpdate, and _onCameraTrackingChanged, which handle map interactions, user location updates, and camera tracking changes.

没找到你要找的内容?