Skip to content

Export Track

In this guide you will learn how to play back a previously recorded position (GPS) log of a navigation, to demonstrate how to display dynamic path tracking/tracing of the traveled path on an interactive map, and then save the track in a desired format, such as .gpx or .nmea

Travel path rendering on map

Export Track example

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

Export Track example

How it works

In Qt, go to the File menu and select Open File or Project…

then browse to the ExportTrack example folder and open ExportTrack.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.

Setup

In main.qml, in the Component.onCompleted: block, the datasource is set by specifying the filename of a previously recorded [GPS] position log:

ServicesManager.dataSource.playbackFile = Qt.resolvedUrl("gpslog_paris.nmea");

Also the content type that will be downloaded upon demand is specified:

let updater = ServicesManager.contentUpdater(ContentItem.Type.RoadMap);

The MapView displaying the interactive map also has 5 buttons, the one on the bottom left of the viewport to start/stop the position datasource playback, and the one on the bottom right to start/resume following position.

Playback

Export Track example
 1Button {
 2    text: ServicesManager.dataSource.type === DataSource.Type.Live
 3    ? "Position Log playback" : "Live position"
 4    background: Rectangle {
 5        opacity: parent.hovered ? 1 : 0.5
 6        color: enabled ? parent.down ? "#aa00aa" :
 7               (parent.hovered ? "#0000ff" : "#2000ff") : "#aaaaaa"
 8    }
 9    palette { buttonText: "#ffffff"; }
10    onClicked: ServicesManager.dataSource.type = ServicesManager.dataSource.type
11    === DataSource.Type.Live ? DataSource.Type.Playback : DataSource.Type.Live;
12}

Playback starts automatically when the data source type is set to DataSource.Type.Playback and stops when the data source type is set to DataSource.Type.Live which means that the position indicator on the map shows the actual position of the device, obtained from the location (GPS) sensor.

Thus, if the device is on the road, it can track/trace a live path of its actual motion outside in live mode.

To restart playback from the beginning, click Live position to switch to live GPS position sensor input, thus turning off playback mode, then click Position Log playback to restart the pre-recorded navigation playback from the beginning.

Export Format

The second button is to cycle through the available formats to export the track. The default is gpx

 1Button {
 2   id: cycleSaveFormat
 3   text: formatToSave.pathFileFormat[formatToSave.index]
 4   property int maxElements: 0
 5   background: Rectangle {
 6      opacity: parent.hovered ? 1 : 0.5
 7      color: enabled ? parent.down ? "#aa00aa" :
 8         (parent.hovered ? "#0000ff" : "#2000ff") : "#aaaaaa"
 9   }
10   palette { buttonText: "#ffffff"; }
11   onClicked: {
12      formatToSave.maxElements = formatToSave.pathFileFormat.length;
13      formatToSave.index += 1;
14      if ( formatToSave.index >= formatToSave.maxElements )
15         formatToSave.index = 0;
16      console.log("Current format to save tracks is " + formatToSave.index + ", "
17         + formatToSave.pathFileFormat[formatToSave.index]);
18   }
19}

Save Track

The third button is to save the path track/trace obtained so far. This button is enabled only when path tracking/tracing is active.

 1Button {
 2   id: saveButton
 3   text: "Save Track"
 4   enabled: false
 5   background: Rectangle {
 6      opacity: parent.hovered ? 1 : 0.5
 7      color: enabled ? parent.down ? "#aa00aa" :
 8         (parent.hovered ? "#0000ff" : "#2000ff") : "#aaaaaa"
 9   }
10   palette { buttonText: "#ffffff"; }
11   onClicked: {
12      let filename = generateFileName(formatToSave.pathFileFormat[formatToSave.index]);
13      mapView.extensions.exportAs(filename,formatToSave.index);
14      fileSaved.text = "Saved: " + filename;
15      console.log(fileSaved.text);
16   }
17}

The name of the file saved is generated from the current date and time, as well as the selected file format, and is displayed in the upper left corner of the screen in a text label:

 1Label {
 2   id: fileSaved
 3   anchors.left: parent.left
 4   anchors.top: parent.top
 5   text: ""
 6   background: Rectangle {
 7      opacity: 0.5
 8      color: "#008000"
 9   }
10   color: "#ffffff"
11}

Start / Stop Tracking

Export Track example

When tracking is active, a new point is added every milliSecondsSampleFrequency milliseconds, as specified in the call to start tracking: mapView.extensions.startTrackPositions(milliSecondsSampleFrequency,markerListRenderSettings); and a polyline is rendered dynamically on the map, tracing the motion of the device, regardless if the motion is real, or simulated, as in playback from a pre-recorded position log, as in this example.

The green position arrow plays back the previously recorded GPS positions log file, which is in the .nmea format, on the interactive map, from the data source file specified above.

A circle icon is configured to indicate a new point being added to the track/trace. A triangle icon is configured to indicate any grouping of icons, low, medium or high.

Different icons can be chosen for different levels of marker groupings, but that is not relevant in this example. See the Markers and MarkersProgrammatic examples for more on that.

 1Button {
 2   id: startStopTracking
 3   text: mapView.extensions.isTrackedPositions ? "Stop Tracking" : "Start Tracking"
 4   background: Rectangle {
 5       opacity: parent.hovered ? 1 : 0.5
 6       color: enabled ? parent.down ? "#aa00aa" :
 7                                      (parent.hovered ? "#0000ff" : "#2000ff") : "#aaaaaa"
 8   }
 9   palette { buttonText: "#ffffff"; }
10   onClicked: {
11      if (mapView.extensions.isTrackedPositions)
12      {
13         mapView.extensions.stopTrackPositions();
14      }
15      else
16      {
17         let milliSecondsSampleFrequency = 500;
18         let markerListRenderSettings = ServicesManager.createMarkerListRenderSettings();
19         markerListRenderSettings.imageSize = 32;
20         markerListRenderSettings.icon = ServicesManager.createIconFromFile("qrc:/violetcircle.png");
21         markerListRenderSettings.labelingMode = MarkerRenderSettings.Group;
22         markerListRenderSettings.pointsGroupingZoomLevel = 98;
23         markerListRenderSettings.lowDensityPointsGroupMaxCount = 6;
24         markerListRenderSettings.mediumDensityPointsGroupMaxCount = 9;
25         markerListRenderSettings.highDensityPointsGroupMaxCount = 12;
26         markerListRenderSettings.lowDensityPointsGroupIcon = ServicesManager.createIconFromFile("qrc:/bluetriangle.png");
27         markerListRenderSettings.mediumDensityPointsGroupIcon = ServicesManager.createIconFromFile("qrc:/bluetriangle.png");
28         markerListRenderSettings.highDensityPointsGroupIcon = ServicesManager.createIconFromFile("qrc:/bluetriangle.png");
29
30         mapView.extensions.startTrackPositions(milliSecondsSampleFrequency,markerListRenderSettings);
31      }
32      startStopTracking.text = (mapView.extensions.isTrackedPositions) ? "Stop Tracking" : "Start Tracking";
33   }
34}

Follow Position

 1Button {
 2    anchors.right: parent.right
 3    anchors.bottom: parent.bottom
 4    text: qsTr("Follow position")
 5    enabled: !mapView.followingPosition
 6    background: Rectangle {
 7        opacity: parent.hovered ? 1 : 0.5
 8        color: enabled ? parent.down ? "#aa00aa" :
 9        (parent.hovered ? "#0000ff" : "#2000ff") : "#aaaaaa"
10    }
11    palette { buttonText: "#ffffff"; }
12    onClicked: mapView.followingPosition = true
13}

Panning the map during simulation/playback will stop follow position, and the button needs to be clicked again to resume following position.

Follow position means that the camera flies to the position of the green arrow and then follows the simulated position arrow. This is necessary, as the arrow is likely to be located elsewhere on the map, not at the current location of the camera.

QML Examples

Maps SDK for Qt Examples can be downloaded or cloned with Git