GPX NMEA Playback¶
Setup¶
Prerequisites¶
Setting your API key token¶
To set your API key token, define it like this:
#define API_TOKEN "YOUR_API_KEY_TOKEN"
replacing YOUR_API_KEY_TOKEN
with your actual API key token text, within the quotes.
This can be done in the main()
function, before the following line:
#if defined(API_TOKEN)
or outside the main()
function, further up, or in a header file.
Although it is also possible to define your API key token as the text value of the GEM_TOKEN
environment variable, this is not recommended, as it is not secure.
Build and run¶
In Visual Studio, right-click on the GpxNmeaPlayback
project, and select
Set as Startup Project
then press F5
to run.
How it works¶
1int main( int argc, char** argv )
2{
3 std::string projectApiToken = "";
4#define API_TOKEN "YOUR_API_KEY_TOKEN"
5#if defined(API_TOKEN)
6 projectApiToken = std::string( API_TOKEN );
7#endif
8 // Sdk objects can be created & used below this line
9 Environment::SdkSession session(projectApiToken, { argc > 1 ? argv[1] : "" });
10
11 // Create an interactive map view
12 CTouchEventListener pTouchEventListener;
13 gem::StrongPointer<gem::MapView> mapView = gem::MapView::produce(session.produceOpenGLContext(
14 Environment::WindowFrameworks::ImGUI, "GpxNmeaPlayback", &pTouchEventListener, getUiRender()));
15 if ( !mapView )
16 {
17 GEM_LOGE( "Error creating gem::MapView: %d", GEM_GET_API_ERROR() );
18 }
19 WAIT_UNTIL_WINDOW_CLOSE();
20 return 0;
21}
First, the API key token is set.
Environment::SdkSession session(projectApiToken, { argc > 1 ? argv[1] : "" });
CTouchEventListener pTouchEventListener;
MapView
interactive map instance is created, using an OpenGL context for rendering,
and selecting ImGui for the graphic control interface.gem::StrongPointer<gem::MapView> mapView = gem::MapView::produce(session.produceOpenGLContext(Environment::WindowFrameworks::ImGUI,
"GpxNmeaPlayback", &pTouchEventListener, getUiRender()));
Finally, the getUiRender()
function is passed in, which uses ImGui to render GUI elements,
capture user control input, and call the appropriate SDK functions.
1auto getUiRender()
2{
3 std::string sdkResrcPath = Environment::GetInstance().GetResourcesPath();
4 std::string projectRelativePath = "/Data/Res/";
5 std::string projectAbsolutePath = sdkResrcPath + projectRelativePath;
6 std::string inputGPXlogFile = projectAbsolutePath +
7 "testParis.gpx";
8 std::string inputNMEAlogFile = projectAbsolutePath +
9 "strasbourg.nmea";
10 gem::String logsdir(sdkResrcPath + "GPSLogs");
11 std::pair<gem::sense::DataSourcePtr, int> dataSourceGPX = gem::sense::produceLogDataSource(inputGPXlogFile.c_str());
12 std::pair<gem::sense::DataSourcePtr, int> dataSourceNMEA = gem::sense::produceLogDataSource(inputNMEAlogFile.c_str());
13
14 return std::bind([dataSourceGPX, dataSourceNMEA, logsdir](gem::StrongPointer<gem::MapView> mapView)
15 {
16 ImGuiIO& io = ImGui::GetIO();
17 const ImGuiViewport* main_viewport = ImGui::GetMainViewport();
18 ImGui::SetNextWindowPos(ImVec2(main_viewport->WorkPos.x + 0, main_viewport->WorkPos.y + 20), ImGuiCond_FirstUseEver);
19 ImGui::Begin("panel", nullptr, ImGuiWindowFlags_NoMove
20 | ImGuiWindowFlags_NoDecoration
21 | ImGuiWindowFlags_AlwaysAutoResize
22 | ImGuiWindowFlags_NoSavedSettings);
23 if (ImGui::Button("Click to play back a pre-recorded GPX route"))
24 {
25 if (dataSourceGPX.first)
26 {
27 gem::PositionService().setDataSource(dataSourceGPX.first);
28 }
29 }
30 if (ImGui::Button("Click to play back a pre-recorded NMEA route"))
31 {
32 if (dataSourceNMEA.first)
33 {
34 gem::PositionService().setDataSource(dataSourceNMEA.first);
35 }
36 }
37 if (!mapView->isFollowingPosition())
38 {
39 if (ImGui::Button("Follow position"))
40 {
41 mapView->startFollowingPosition();
42 }
43 }
44 else
45 {
46 ImGui::Text("Following position!");
47 }
48 ImGui::End();
49 }
50 , std::placeholders::_1);
51}
Outside the lambda function, the paths and the GPS navigation position log input file names are defined. Inside the lambda function:
First, the main ImGui viewport is obtained, and the x,y position of the ImGui window, with the identifier “panel”, in pixels, is set within the SDK OpenGL viewport.
ImGui::Begin()
function.ImGui::Button()
which the user can click to start playback of a .gpx
or an .nmea
GPS position log, respectively.gem::PositionService().setDataSource(dataSourceNMEA.first);
std::pair<gem::sense::DataSourcePtr, int> dataSourceNMEA = gem::sense::produceLogDataSource(inputNMEAlogFile.c_str());
mapView->startFollowingPosition();
ImGui::Text("Following position!");
is displayed
instead of the button, to indicate this mode.