Change Map Style¶
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 ChangeMapStyle
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, "ChangeMapStyle", &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,
"ChangeMapStyle", &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 return std::bind([](gem::StrongPointer<gem::MapView> mapView)
4 {
5 static bool isNightStyle = false;
6 ImGuiIO& io = ImGui::GetIO();
7 const ImGuiViewport* main_viewport = ImGui::GetMainViewport();
8 ImGui::SetNextWindowPos(ImVec2(main_viewport->WorkPos.x + 0, main_viewport->WorkPos.y + 20), ImGuiCond_FirstUseEver);
9 ImGui::Begin("panel", nullptr, ImGuiWindowFlags_NoMove
10 | ImGuiWindowFlags_NoDecoration
11 | ImGuiWindowFlags_AlwaysAutoResize
12 | ImGuiWindowFlags_NoSavedSettings);
13 if ( ImGui::Button( "Click to apply map style" ) )
14 {
15 ImGui::SameLine();
16 ImGui::Text("Getting map style...");
17 isNightStyle = !isNightStyle;
18
19 ProgressListener listener;
20 auto searchAndApply = [&]()
21 {
22 auto styles = gem::ContentStore().getStoreContentList( gem::EContentType::CT_ViewStyleLowRes ).first;
23 gem::ContentStoreItem nightStyle;
24 gem::ContentStoreItem dayStyle;
25 // Find first night map style
26 for ( auto style : styles )
27 {
28 auto backGroundColor = style.getContentParameters().findParameter( "Background-Color" );
29 if ( backGroundColor && !gem::Rgba( backGroundColor.getValue<int>() ).isLight() )
30 {
31 // Night map style found - download if needed
32 if ( style.getStatus() == gem::EContentStoreItemStatus::CIS_Unavailable )
33 {
34 listener.Reset();
35 style.asyncDownload( &listener );
36
37 WAIT_UNTIL( std::bind( &ProgressListener::IsFinished, &listener ), INT_MAX );
38 }
39 nightStyle = style;
40 break;
41 }
42 }
43 // Find first day map style
44 for ( auto style : styles )
45 {
46 auto backGroundColor = style.getContentParameters().findParameter( "Background-Color" );
47 if ( backGroundColor && gem::Rgba( backGroundColor.getValue<int>() ).isLight() )
48 {
49 // Day map style found - download if needed
50 if ( style.getStatus() == gem::EContentStoreItemStatus::CIS_Unavailable )
51 {
52 listener.Reset();
53 style.asyncDownload( &listener );
54
55 WAIT_UNTIL( std::bind( &ProgressListener::IsFinished, &listener ), INT_MAX );
56 }
57 dayStyle = style;
58 break;
59 }
60 }
61 if ( isNightStyle && nightStyle && nightStyle.isCompleted() )
62 return GEM_TEST_NOEXCEPT(mapView->preferences().setMapStyle( nightStyle )) == gem::KNoError;
63 else if ( !isNightStyle && dayStyle && dayStyle.isCompleted() )
64 return GEM_TEST_NOEXCEPT(mapView->preferences().setMapStyle( dayStyle )) == gem::KNoError;
65 else
66 return false;
67 };
68 // Try with local list
69 if ( !searchAndApply() )
70 {
71 // Get available content store map styles
72 gem::ContentStore().asyncGetStoreContentList( gem::EContentType::CT_ViewStyleLowRes, &listener );
73 WAIT_UNTIL( std::bind( &ProgressListener::IsFinished, &listener ), INT_MAX );
74 searchAndApply();
75 }
76 }
77 ImGui::SameLine();
78 ImGui::Text("%s", isNightStyle ? "Night map style set!" : "Day map style set!");
79 //ImGui::Text( "Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate );
80 ImGui::End();
81 }
82 , std::placeholders::_1);
83}
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 set a map style.
Each subsequent click toggles the map style between a day style and a night style.ImGui::Text()
element which displays whether a day or night
map style was just set by the last tap/click on the button.auto styles = gem::ContentStore().getStoreContentList( gem::EContentType::CT_ViewStyleLowRes ).first;
auto backGroundColor = style.getContentParameters().findParameter( "Background-Color" );
if ( backGroundColor && !gem::Rgba( backGroundColor.getValue<int>() ).isLight() )
if ( style.getStatus() == gem::EContentStoreItemStatus::CIS_Unavailable )
listener.Reset();
style.asyncDownload( &listener );
WAIT_UNTIL()
macro to wait for the download to completeWAIT_UNTIL( std::bind( &ProgressListener::IsFinished, &listener ), INT_MAX );
nightStyle = style;
Repeat the above steps to get a pointer to the first day map style, except check that it IS a light colored map style.
setMapStyle()
function to set a previously downloaded map style
to be used for rendering the interactive map:return GEM_TEST_NOEXCEPT(mapView->preferences().setMapStyle( nightStyle )) == gem::KNoError;
The WAIT_UNTIL
macro is used to wait for the route calculation to complete and
check the success/error status, and whether the resulting route list has at least one route.