GPX Routing and Navigation¶
In this guide you will learn how to use RoutingService to compute a route based on GPX data, and NavigationService to start a real or simulated navigation on that route.See the Landmark List guide on how to calculate a route, and simulate navigation along that route, between interactively user selected start (departure) and end (destination) points.
See the Routing and Navigation guide on how to calculate a route, and simulate navigation along that route, between preset or programmatically selected start (departure) and end (destination) points.
First, get an API key token, see the Getting Started guide.
Qt should be installed to continue.The Maps SDK for Qt should be installed, see the Setup Maps SDK for Qt guide.
Overview¶
GpxRoutingNavigation
demonstrates using RoutingService
to
calculate a route between preset start (departure), a GPX path as
the middle waypoint, and end (destination) points, and
NavigationService
to simulate navigation on the computed route.
How it works
In Qt, go to the File menu and select Open File or Project…
then browse to the GpxRoutingNavigation example folder and open GpxRoutingNavigation.pro
You may want to have a look at Setting your API Key to see how to open and configure a project and set your API Key.
In main.qml, we import the GeneralMagic QML plugin. Next, we need to make sure we allow online access, and that we are using the latest data.
1import QtQuick.Window 2.12
2import GeneralMagic 2.0
3
4Window
5{
6 visible: true
7 width: 640
8 height: 480
9 title: qsTr("Routing and Navigation Example")
10
11 Component.onCompleted:
12 {
13 ServicesManager.settings.token = __my_secret_token;
14 ServicesManager.settings.allowInternetConnection = true;
15
16 var updater = ServicesManager.contentUpdater(ContentItem.Type.RoadMap);
17 updater.autoApplyWhenReady = true;
18 updater.update();
19 }
The __my_secret_token property in the above QML code is set in C++ like this.
1// C++ code
2QQmlApplicationEngine engine;
3//...
4//! [Set API Key token safely]
5// go to https://developer.magiclane.com to get your token
6engine.rootContext()->setContextProperty("__my_secret_token", "YOUR_TOKEN");
7//! [Set API Key token safely]
8
9engine.load(url);
In this example, in main.cpp, replace YOUR_TOKEN with your actual Magic Lane Maps API Key.
To start a simulation/navigation there are three steps involved:
Compute the route(s)
The first step is to declare a RoutingService
1RoutingService
2{
3 id: routingService
4 preferences
5 {
6 type: RoutePreferences.Type.Fastest
7 transportMode: RoutePreferences.TransportMode.Bicycle
8 }
9 waypoints: LandmarkList
10 {
11 // departure position is optional.
12 // If missing it will use the first path coordinate as the departure
13 Landmark
14 {
15 name: "departure"
16 coordinates: Coordinates
17 {
18 latitude: 48.849289
19 longitude: 2.346027
20 }
21 }
22
23 Landmark
24 {
25 name: "gpx waypoint"
26 path: ServicesManager.loadPathFromGpxFile(":/testParis.gpx") // load it from resources
27 }
28
29 // destination position is optional as well.
30 // If missing it will use the last path coordinate as the destination
31 Landmark
32 {
33 name: "destination"
34 coordinates: Coordinates
35 {
36 latitude: 48.874630
37 longitude: 2.331512
38 }
39 }
40 }
41 onCompleted:
42 {
43 mapView.preferences.routeCollection.set(routes);
44 mapView.centerOnRoutes(routes);
45 }
46}
to be used for calculating the route(s).
Note that ServicesManager::loadPathFromGpxFile
is used to load a
GPX file.
Thus the start (departure) and end (destination) points of the route do
not have to be specified.
The second step is to declare a NavigationService
to be used for the simulation/navigation.
1function distance(meters)
2{
3 return meters >= 1000 ? (meters / 1000.).toFixed(3)
4 + " Km" : meters.toFixed(0) + " m";
5}
6
7NavigationService
8{
9 id: navigation
10 route: mapView.preferences.routeCollection.mainRoute
11 simulation: true // change it to false (default) to perform real turn by turn navigation
12 onActiveChanged:
13 {
14 if (active)
15 {
16 mapView.startFollowingPosition();
17 mapView.preferences.routeCollection.clear();
18 mapView.preferences.routeCollection.add(
19 mapView.preferences.routeCollection.mainRoute);
20 }
21 }
22 navigationListener: NavigationListener
23 {
24 onWaypointReached: console.log("WaypointReached :" + waypoint.name);
25 onDestinationReached: mapView.preferences.routeCollection.clear();
26 onNavigationError:
27 {
28 console.log("NavigationError :" + error);
29 mapView.preferences.routeCollection.clear();
30 }
31 onRouteChanged:
32 {
33 console.log("RouteUpdated :" + route.summary);
34 mapView.preferences.routeCollection.clear();
35 mapView.preferences.routeCollection.add(route);
36 }
37 onNavigationInstructionUpdated:
38 {
39 nextTurnIcon.iconSource = navigationInstruction.nextTurnDynamicIcon;
40 nextTurnInfo.text = navigationInstruction.nextStreetName + " ("
41 + distance(navigationInstruction.distanceToNextTurn) + ")";
42 }
43 }
44}
Do simulation/navigation
1Button
2{
3 text: "Compute route(s)"
4 enabled: ServicesManager.settings.connected && !navigation.active
5 onClicked: routingService.update()
6}
Show everything on a MapView
The last step is to follow the navigation/simulation on the route(s) shown on the map.
1MapView
2{
3 id: mapView
4 anchors.fill: parent
5 viewAngle: 25
6 preferences.cursorVisibility: false
7
8 onRouteSelected:
9 {
10 preferences.routeCollection.mainRoute = route;
11 centerOnRoute(route);
12 }
13}