Navigation Icon Color¶
In this guide you will learn how to change the colors of the
navigation turn icons, displayed during a real or simulated navigation;
RoutingService
is used to compute a route and NavigationService
to start a real or simulated navigation on that route.
Change navigation icon rendering colors¶
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¶
NavigationIconColor
demonstrates how to change the colors of the
navigation turn icons, displayed during a real or simulated navigation.
The Compute route(s)
button causes the RoutingService
to
calculate a route between preset start (departure) and end (destination) points,
and render the route on the map.
The Start simulation
button starts the simulated navigation along
the resulting route using NavigationService
The turn icons are displayed using the default colors.
Press the Custom icon color 1
button to change the color of the icons
displayed after the next turn. The color of the icons that are already on
screen are not changed.
How it works
In Qt, go to the File menu and select Open File or Project…
then browse to the NavigationIconColor example folder and open NavigationIconColor.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.
1import QtQuick 2.12
2import QtQuick.Controls 2.12
3import QtQuick.Layouts 1.12
4import QtQuick.Window 2.12
5import GeneralMagic 2.0
6
7Window {
8 visible: true
9 width: 640
10 height: 480
11 title: qsTr("Navigation Icon Color Example")
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.
1property var updater: ServicesManager.contentUpdater(ContentItem.Type.RoadMap)
2Component.onCompleted: {
3 //! [Set token safely]
4 ServicesManager.settings.token = __my_secret_token;
5 //! [Set token safely]
6 ServicesManager.settings.allowInternetConnection = true; // enable connection to online services
7
8 updater.autoApplyWhenReady = true;
9 updater.update();
10}
The __my_secret_token
property in the above QML code is set in C++
like this. In this example, in main.cpp
, replace YOUR_TOKEN
with your actual General Magic Maps API Key token string.
1// C++ code
2QQmlApplicationEngine engine;
3//...
4//! [Set API Key token safely]
5// go to https://developer.generalmagic.com to get your token
6engine.rootContext()->setContextProperty("__my_secret_token", "YOUR_API_KEY_TOKEN_STRING");
7//! [Set API Key token safely]
8
9engine.load(url);
To start a simulation/navigation there are three steps involved:
Compute the route(s)¶
1RoutingService {
2 id: routingService
3 type: Route.Type.Fastest
4 transportMode: Route.TransportMode.Car
5
6 waypoints: LandmarkList {
7 Landmark {
8 name: "start"
9 coordinates: Coordinates {
10 latitude: 52.37164
11 longitude: 4.88220
12 }
13 }
14 Landmark {
15 name: "waypoint1"
16 coordinates: Coordinates {
17 latitude: 52.37118
18 longitude: 4.88136
19 }
20 }
21 Landmark {
22 name: "waypoint2"
23 coordinates: Coordinates {
24 latitude: 52.37164
25 longitude: 4.88220
26 }
27 }
28 Landmark {
29 name: "stop"
30 coordinates: Coordinates {
31 latitude: 52.37118
32 longitude: 4.88136
33 }
34 }
35 }
36 onFinished: {
37 mapView.routeCollection.set(routeList);
38 mapView.centerOnRouteList(routeList);
39 }
40}
The first step is to declare a RoutingService
to be used for calculating the route(s).
A minimum of two Landmarks
are needed in a LandmarkList
where the first one is the departure and the last one is the
destination. There can be 0 or more intermediate waypoint
landmarks. In this case, there are 2 intermediate waypoints,
for a total of 4 landmarks through which the route must pass.
In the onFinished:
section, the resulting route list
is given to the MapView
instance, identified as mapView
to be rendered, and centerOnRouteList()
causes the camera
to fly to the rendered routes, at the appropriate altitude so
that they fit in the viewport.
1function distance(meters)
2{
3 return meters >= 1000 ? (meters / 1000.).toFixed(3) + " Km" : meters.toFixed(0) + " m";
4}
5NavigationService {
6 id: navigation
7 route: mapView.routeCollection.mainRoute
8 simulation: true // change it to false (default) to perform real turn by turn navigation
9 onActiveChanged: {
10 if (active) {
11 mapView.startFollowingPosition();
12 mapView.routeCollection.clear(true /*keepMainRoute*/);
13 }
14 }
15 onCurrentInstructionChanged: {
16 // WORKS ONLY with Qt 5.15.x or Qt 6.x
17 const nextspeedlimit = currentInstruction.nextSpeedLimitVariation();
18 console.log(nextspeedlimit.distance, nextspeedlimit.speed,
19 nextspeedlimit.coordinates.latitude, nextspeedlimit.coordinates.longitude);
20 }
21 onWaypointReached: console.log("WaypointReached :" + waypoint.name);
22 onDestinationReached: mapView.routeCollection.clear();
23 onNavigationError: {
24 console.log("NavigationError :" + error);
25 mapView.routeCollection.clear();
26 }
27 onNavigationRouteUpdated: {
28 console.log("RouteUpdated :" + route.summary);
29 mapView.routeCollection.add(route, true);
30 mapView.routeCollection.clear(true);
31 }
32}
The second step is to declare a NavigationService
to be used for the simulation/navigation.
Do simulation/navigation¶
1Button {
2 text: "Compute route(s)"
3 enabled: ServicesManager.settings.connected && !navigation.active
4 onClicked: routingService.update()
5}
6//! [RoutingNavigation compute routing]
7Button {
8 enabled: mapView.routeCollection.mainRoute.valid
9 text: navigation.active ? "Stop simulation" : "Start simulation"
10 onClicked: navigation.active = !navigation.active
11}
Within the MapView
block,
the Compute route(s)
button causes the RoutingService
to
calculate a route between preset start (departure) and end (destination) points,
and render the route on the map.
The Start simulation
button is enabled once a calculated route
has been set as the main route, and starts the simulated navigation along
the calculated route.
Show everything on a MapView
¶
1Rectangle {
2 color: Qt.rgba(.8, 1, 1, 0.6)
3 visible: navigation.active
4 anchors.top: parent.top
5 anchors.left: parent.left
6 anchors.right: parent.right
7 height: 96
8 RowLayout {
9 anchors.fill: parent
10 anchors.margins: 10
11 DynamicIconView {
12 id: iconLeft
13 Layout.fillHeight: true
14 Layout.maximumWidth: height
15 width: height
16 arrowInner: "darkblue"
17 arrowOuter: "gold"
18 slotInner: "grey"
19 slotOuter: arrowOuter
20
21 iconSource: navigation.currentInstruction.nextTurnDynamicIcon
22 }
23 Label {
24 Layout.fillWidth: true
25 font.pixelSize: 16
26
27 text: navigation.currentInstruction.nextStreetName + " ("
28 + distance(navigation.currentInstruction.distanceToNextTurn) + ")";
29 }
30 DynamicIconView {
31 id: iconRight
32 Layout.fillHeight: true
33 Layout.maximumWidth: height
34 width: height
35 arrowInner: "darkgrey"
36 arrowOuter: "black"
37 slotInner: "grey"
38 slotOuter: "darkgreen"
39
40 iconSource: navigation.currentInstruction.nextNextTurnDynamicIcon
41 }
42 Label {
43 font.pixelSize: 16
44 text: distance(navigation.currentInstruction.distanceToNextNextTurn)
45 }
46 }
47}
The last step is to follow the navigation/simulation on the routes shown on the map.
The above Rectangle
panel within the MapView
block, appears at the top of
the map during simulated navigation, and shows a DynamicIconView
with the next
turn icon on the left, and the next next turn icon (the icon after the next turn)
on the right.
1Button {
2 text: "Custom icon color 1"
3 onClicked: {
4 iconLeft.setArrowInner ( "blue")
5 iconLeft.setArrowOuter ( "cyan")
6 iconLeft.setSlotInner ( "yellow")
7 iconLeft.setSlotOuter ( "red")
8 iconRight.setArrowInner( "yellow")
9 iconRight.setArrowOuter( "cyan")
10 iconRight.setSlotInner ( "red")
11 iconRight.setSlotOuter ( "magenta")
12 }
13}
14Button {
15 text: "Custom icon color 2"
16 onClicked: {
17 iconLeft.setArrowInner ( "blue")
18 iconLeft.setArrowOuter ( "cyan")
19 iconLeft.setSlotInner ( "orange")
20 iconLeft.setSlotOuter ( "cyan")
21 iconRight.setArrowInner( "green")
22 iconRight.setArrowOuter( "magenta")
23 iconRight.setSlotInner ( "yellow")
24 iconRight.setSlotOuter ( "magenta")
25 }
26}
27Button {
28 text: "Custom icon color 3"
29 onClicked: {
30 iconLeft.setArrowInner ( "magenta")
31 iconLeft.setArrowOuter ( "cyan")
32 iconLeft.setSlotInner ( "white")
33 iconLeft.setSlotOuter ( "magenta")
34 iconRight.setArrowInner( "cyan")
35 iconRight.setArrowOuter( "magenta")
36 iconRight.setSlotInner ( "white")
37 iconRight.setSlotOuter ( "red")
38 }
39}
Finally, there are 3 buttons, each one setting a different set of rendering colors for both the left (next turn) and the right (next next turn) icons. To set/modify the colors of a turn icon, the color of 4 attributes must be set:
1setArrowInner()
2setArrowOuter()
3setSlotInner ()
4setSlotOuter ()
The arrow inner color is the color of the turn arrow, and the arrow outer is its outline, for the road that will be taken/followed at the next turn. The slot inner color is the color of any sideroad which will not be taken, and slot outer is the outline of that sideroad.