Record GPS Position Log¶
In this guide you will learn how to play back
a previously recorded GPS position log, using DataSource
on an interactive map, and use this as input
to record a GPS position log using DataSourceRecorder
.
Prior to recording, the sensor data types to be recorded
are selected and their availability is validated.
A frame per second (FPS) counter is also displayed.
GPS Log Data Source¶
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¶
RecordGPSPositionLog
demonstrates how easy it is to record a
GPS position log using a previously recorded GPS position log file
as input, so that GPS log recording can be demonstrated on a desktop
computer as well. Typically, the GPS log data source is the
GPS sensor on a device, such as a phone.*.nmea
file, which
can also be generated using free web-based nmea generator
tools.*.gm
file, intended for debugging.How it works
In Qt, go to the File menu and select Open File or Project…
then browse to the RecordGPSPositionLog example folder and open RecordGPSPositionLog.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, in the Component.onCompleted:
block, the datasource is
set by specifying the filename of a previously recorded (or web-generated)
[GPS] position log, strasbourg.nmea
in this case:
1ServicesManager.dataSource.playbackFile = Qt.resolvedUrl("strasbourg.nmea");
2ServicesManager.dataSource.type = DataSource.Type.Playback;
This implies that the strasbourg.nmea
data file is located in the
project directory of this example, and configured in the qml.qrc
file,
so that Qt.resolvedUrl()
can find it.
Additionally, the following options are set for the GPS log data source recorder:
1ServicesManager.dataSourceRecorder.chunkDurationMinutes = 1;
2ServicesManager.dataSourceRecorder.continuousRecording = true;
3ServicesManager.dataSourceRecorder.deleteOlderThanKeepMin = false;
4ServicesManager.dataSourceRecorder.keepMinMinutes = 60;
5ServicesManager.dataSourceRecorder.dataSourceTypesToRecord = DataSourceRecorder.Position;
chunkDurationMinutes
;
the keepMinMinutes
setting specifies the size of the moving
window of recorded GPS log data to keep, implying that data older than
this amount of time, in minutes, is deleted.deleteOlderThanKeepMin
flag set to false indicates that
no data shall be deleted, all recorded GPS log data is kept.
This may be useful for testing purposes.The content type that will be downloaded upon demand is also specified:
let updater = ServicesManager.contentUpdater(ContentItem.Type.RoadMap);
The MapView
displaying the interactive map has 4 buttons:
Start / Stop recording
and Faster / Slower playback
in the top
left corner;Playback - switch to live
/ Live - switch to playback
in the lower
left corner; andFollow position
in the lower right corner.Select source and sensors¶
1CheckBox {
2 id: checkBattery
3 enabled: !ServicesManager.dataSourceRecorder.active
4 checked: false
5 indicator.width: 18
6 indicator.height: 18
7 text: qsTr("Battery")
8}
9CheckBox {
10 id: checkCompass
11 enabled: !ServicesManager.dataSourceRecorder.active
12 checked: false
13 indicator.width: 18
14 indicator.height: 18
15 text: qsTr("Compass")
16}
17CheckBox {
18 id: checkImprovedPosition
19 enabled: !ServicesManager.dataSourceRecorder.active
20 checked: true
21 indicator.width: 18
22 indicator.height: 18
23 text: qsTr("ImprovedPosition") //calculated, map-matched position
24}
Additionally, on the right margin, checkboxes for sensors that can be selected to be recorded are displayed. The user can select any or all of these. The Position sensor checkbox is not enabled because that is the location (GPS) sensor, which is always recorded in a position (GPS) log.
1Button {
2 id: livePlaybackButton
3 enabled: !ServicesManager.dataSourceRecorder.active
4 anchors.left: parent.left
5 anchors.bottom: parent.bottom
6 text: ServicesManager.dataSource.type === DataSource.Type.Live
7 ? "Live - switch to playback" : "Playback - switch to live"
8 background: Rectangle {
9 opacity: parent.hovered ? 1 : 0.5
10 color: enabled ? parent.down ? "#aa00aa" :
11 (parent.hovered ? "#0000ff" : "#2000ff") : "#aaaaaa"
12 }
13 palette { buttonText: "#ffffff"; }
14 onClicked: {
15 ServicesManager.dataSource.type =
16 ServicesManager.dataSource.type === DataSource.Type.Live
17 ? DataSource.Type.Playback : DataSource.Type.Live;
18 }
19}
The button to switch between live and playback input data source sets
the ServicesManager.dataSource.type
qml property to either
DataSource.Type.Playback
or DataSource.Type.Live
The Live/Playback data source must be selected before recording starts. In a real on the road navigation, the Live data source is selected for GPS log recording. To demonstrate GPS log recording functionality on a desktop computer, a playback data source (.nmea file included in this example) is used, so Playback is selected.
Start recording¶
1Button {
2 id: startStopButton
3 text: ServicesManager.dataSourceRecorder.active
4 ? "Stop recording" : "Start recording"
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 //validate available data types only if switching recording to on
13 if (!ServicesManager.dataSourceRecorder.active) {
14 //position (raw GPS sensor input) is always recorded
15 ServicesManager.dataSourceRecorder.dataSourceTypesToRecord = DataSourceRecorder.Position
16 | (checkAcceleration.checked ? DataSourceRecorder.Acceleration : 0)
17 | (checkBattery.checked ? DataSourceRecorder.Battery : 0)
18 | (checkCamera.checked ? DataSourceRecorder.Camera : 0)
19 | (checkCompass.checked ? DataSourceRecorder.Compass : 0)
20 | (checkMagneticField.checked ? DataSourceRecorder.MagneticField : 0)
21 | (checkOrientation.checked ? DataSourceRecorder.Orientation : 0)
22 | (checkImprovedPosition.checked ? DataSourceRecorder.ImprovedPosition : 0)
23 | (checkTemperature.checked ? DataSourceRecorder.Temperature : 0);
24 //clear checkboxes of unavailable datatypes, as those can not be recorded
25 if (!ServicesManager.dataSourceRecorder.isDataTypeAvailable(DataSourceRecorder.Acceleration))
26 checkAcceleration.checked = false;
27 if (!ServicesManager.dataSourceRecorder.isDataTypeAvailable(DataSourceRecorder.Battery))
28 checkBattery.checked = false;
29 if (!ServicesManager.dataSourceRecorder.isDataTypeAvailable(DataSourceRecorder.Camera))
30 checkCamera.checked = false;
31 if (!ServicesManager.dataSourceRecorder.isDataTypeAvailable(DataSourceRecorder.Compass))
32 checkCompass.checked = false;
33 if (!ServicesManager.dataSourceRecorder.isDataTypeAvailable(DataSourceRecorder.MagneticField))
34 checkMagneticField.checked = false;
35 if (!ServicesManager.dataSourceRecorder.isDataTypeAvailable(DataSourceRecorder.Orientation))
36 checkOrientation.checked = false;
37 if (!ServicesManager.dataSourceRecorder.isDataTypeAvailable(DataSourceRecorder.ImprovedPosition))
38 checkImprovedPosition.checked = false;
39 if (!ServicesManager.dataSourceRecorder.isDataTypeAvailable(DataSourceRecorder.Temperature))
40 checkTemperature.checked = false;
41 }
42 //start/stop recording position (GPS) log
43 ServicesManager.dataSourceRecorder.active = !ServicesManager.dataSourceRecorder.active;
44 }
45}
Then click Follow position
so the camera follows the green position
arrow, and click Start recording
to start the GPS logger.
Before recording actually starts, the sensors for the selected checkboxes are validated to verify their availability. Those sensors that are not available for recording on the current device, are automatically unchecked.
The available sensors from the user selected list of sensors are then OR-ed
together in an int bitfield which is then set into the
ServicesManager.dataSourceRecorder.dataSourceTypesToRecord
property.
The checkboxes are disabled while recording is active because it is not possible to change the recorded datasources while recording. To do that, stop recording first, then select the desired datasources.
Recording is started by setting the ServicesManager.dataSourceRecorder.active
property to true, and is stopped by setting this property to false.
While recording is active, it is not possible to change data sources (live/playback)
or recorded data types, so those controls are disabled.
The live/playback button is enabled/disabled using its id and the enabled property:
livePlaybackButton.enabled
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}
The follow position button is enabled only if the camera is not already following the green position arrow on the map.
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.
The green position arrow plays back the previously recorded positions on the map, from the data source specified above.
If the map is panned/dragged to one side, the camera no longer follows
the green position arrow, and the Follow position
button is activated
again, so it can be clicked to resume following the position arrow.
Playback speed¶
1Button {
2 text: ServicesManager.dataSource.playbackSpeedMultiplier == 9
3 ? "Slower playback" : "Faster playback"
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 ServicesManager.dataSource.playbackSpeedMultiplier =
12 ServicesManager.dataSource.playbackSpeedMultiplier == 9 ? 1 : 9;
13 }
14}
The faster/slower playback button toggles the playback speed between 1x (normal) and 9x (visibly fast).
Next, click Faster playback
to see that the simulation runs faster.
Click Slower playback
to see that the simulation runs again
at normal speed.
Stop and save recording¶
Click Stop recording
after at least 1 minute elapsed after
Start recording
was clicked, or after the playback ends,
to save the recorded GPS log.
Recordings shorter than 1 minute are not saved.
The GPS log file has a .gm
extension and is saved
in this directory:
~/.local/share/APPNAME/
where APPNAME in this case is
the name of this example, RecordGPSPositionLog
The .gm file can be used as playback input just like an
.nmea
GPS log file.
Implementation details¶
The MapView
interactive map has these settings for
display and user touch input:
1id: mapView
2anchors.fill: parent
3viewAngle: 25
4zoomLevel: 69
5viewPerspective: MapView.ViewPerspective.View3D
6buildingsVisibility: MapView.BuildingsVisibility.Show3D
7detailsQualityLevel: MapView.DetailsQualityLevel.Medium
8gestures: MapView.Gesture.Pan
9 | MapView.Gesture.PanEnableVelocity
10 | MapView.Gesture.Pinch
11 | MapView.Gesture.Rotate
12 | MapView.Gesture.Tilt
anchors.fill: parent
causes the map to fill the containing viewport,
which is Window
in this case. The zoomLevel
has a higher value,
the closer the camera is to the ground.
1Text {
2 anchors.right: parent.right
3 anchors.top: parent.top
4 text: fpsCounter.fps
5}
The frames-per-second (fps) counter is displayed in the top right corner of the map.
1<RCC>
2 <qresource prefix="/">
3 <file>main.qml</file>
4 <file>strasbourg.nmea</file>
5 </qresource>
6</RCC>
The qml.qrc
file lists the strasbourg.nmea
GPS position log file.