Skip to content

Calculate Route Multi View

Calculate 4 routes and add them in 4 separate interactive map views.

Calculate Route Multi View - cpp example screenshot

Setup

First, get an API key token, see the Getting Started guide.

Prerequisites

It is required that you complete the Environment Setup - CPP Examples guide before starting this guide.

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.

Use case

Calculate multiple routes and display them in separate independent map views.

How to use the sample

When you open the sample, you’ll be viewing the scene from above. The screen will be split into 4 identical interactive map views. Each view will fly to a different calculated route rendered on the map and zoomed such that it fits in its viewport..

How it works

  1. Create an instance of Environment and set your API key token:

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] : "" });
  1. The SDK is initialized with your API key token string and the log file path, where to write the application logs. Note that the log file path is not initialized by default, the empty string above, after the API key token, which means that no logs are written. The log file path is initialized with the first command line argument, if any. Create a gem::Screen using an OpenGL context for 3D graphics, the SDK environment created above, and a touch event listener for interactive user touch and mouse input, such as pan and zoom. gem::Screen is used to enable holding multiple gem::MapView instances.

1// Create an interactive map view
2CTouchEventListener pTouchEventListener;
3gem::StrongPointer<gem::Screen> screen = gem::Screen::produce(session.produceOpenGLContext(
4   Environment::WindowFrameworks::Available, "CalculateRouteMultiView", &pTouchEventListener));
  1. Create 4 MapView interactive map objects.

1// Map view in lower left viewport
2gem::StrongPointer<gem::MapView> mapView1 = gem::MapView::produce(screen, gem::RectF(0.f, 0.f, 0.5f, 0.5f));
3// Map view in upper left viewport
4gem::StrongPointer<gem::MapView> mapView2 = gem::MapView::produce(screen, gem::RectF(0.f, 0.5f, 0.5f, 1.0f));
5// Map view in lower right viewport
6gem::StrongPointer<gem::MapView> mapView3 = gem::MapView::produce(screen, gem::RectF(0.5f, 0.f, 1.0f, 0.5f));
7// Map view in upper right viewport
8gem::StrongPointer<gem::MapView> mapView4 = gem::MapView::produce(screen, gem::RectF(0.5f, 0.5f, 1.f, 1.f));
  1. Create 4 routes, one for each map. At least 2 waypoints define a route, the first is the departure position, and the last is the destination. There can be zero or more intermediate waypoints through which the route passes in the order they are listed. The coordinates are {latitude,longitude} in degrees; the landmark name is optional and can be an empty string.

 1gem::LandmarkList waypoints1({
 2     { "San Francisco", { 37.77903, -122.41991 } },
 3     { "San Jose", { 37.33619, -121.89058 } }
 4     });
 5gem::LandmarkList waypoints2({
 6     { "London", { 51.516128, -0.142828 } },
 7     { "Paris", { 48.848462, 2.327315 } }
 8     });
 9gem::LandmarkList waypoints3({
10     { "Andorra", { 42.50971 , 1.53787 } },
11     { "Port Verdes", { 42.51851 , 3.10359 } }
12     });
13gem::LandmarkList waypoints4({
14     { "Strasbourg", { 48.51999 , 7.73254 } },
15     { "Oslo", { 59.9265 , 10.7511 } }
16     });
  1. Calculate the routes - car / fastest / without alternatives in result. The results of each route calculation is stored in its corresponding RouteList and each route calculation also has its own progress listener, so we know when the calculation, which occurs on a separate thread, so it does not block, is complete.

 1gem::RouteList routes1, routes2, routes3, routes4;
 2ProgressListener routeListener1, routeListener2, routeListener3, routeListener4;
 3
 4gem::RoutingService().calculateRoute(routes1, waypoints1,
 5   gem::RoutePreferences().setTransportMode(gem::RTM_Car).setRouteType(gem::RT_Fastest).setAlternativesSchema(gem::AS_Never), &routeListener1);
 6gem::RoutingService().calculateRoute(routes2, waypoints2,
 7   gem::RoutePreferences().setTransportMode(gem::RTM_Car).setRouteType(gem::RT_Fastest).setAlternativesSchema(gem::AS_Never), &routeListener2);
 8gem::RoutingService().calculateRoute(routes3, waypoints3,
 9   gem::RoutePreferences().setTransportMode(gem::RTM_Car).setRouteType(gem::RT_Fastest).setAlternativesSchema(gem::AS_Never), &routeListener3);
10gem::RoutingService().calculateRoute(routes4, waypoints4,
11   gem::RoutePreferences().setTransportMode(gem::RTM_Car).setRouteType(gem::RT_Fastest).setAlternativesSchema(gem::AS_Never), &routeListener4);
  1. Use the progress listener for each route calculation to wait for each to finish. If there was no error, and the resulting route list contains at least one route for each of the 4 calculated route collections, add the first calculated route (at index 0) of each collection to their corresponding map view, and center on the route rendered on the interactive map. Keep the window until the user closes it.

 1 // Wait until route calculation finished & check success
 2 if (WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &routeListener1), 30000) && routeListener1.GetError() == gem::KNoError
 3     && WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &routeListener2), 30000) && routeListener2.GetError() == gem::KNoError
 4     && WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &routeListener3), 30000) && routeListener3.GetError() == gem::KNoError
 5     && WAIT_UNTIL(std::bind(&ProgressListener::IsFinished, &routeListener4), 30000) && routeListener4.GetError() == gem::KNoError
 6     && !routes1.empty()
 7     && !routes2.empty()
 8     && !routes3.empty()
 9     && !routes4.empty())
10 {
11     // Draw computed route on map view in lower left viewport
12     mapView1->preferences().routes().add(routes1[0]);
13     mapView1->centerOnRoute(routes1[0], gem::Rect(), gem::Animation(gem::AnimationLinear, gem::ProgressListener(), 2000));
14     // Draw computed route on map view in upper left viewport
15     mapView2->preferences().routes().add(routes2[0]);
16     mapView2->centerOnRoute(routes2[0], gem::Rect(), gem::Animation(gem::AnimationLinear, gem::ProgressListener(), 2000));
17     // Draw computed route on map view in lower right viewport
18     mapView3->preferences().routes().add(routes3[0]);
19     mapView3->centerOnRoute(routes3[0], gem::Rect(), gem::Animation(gem::AnimationLinear, gem::ProgressListener(), 2000));
20     // Draw computed route on map view in upper right viewport
21     mapView4->preferences().routes().add(routes4[0]);
22     mapView4->centerOnRoute(routes4[0], gem::Rect(), gem::Animation(gem::AnimationLinear, gem::ProgressListener(), 2000));
23 }
24 WAIT_UNTIL_WINDOW_CLOSE();
25 return 0;
26}

C++ Examples

Maps SDK for C++ Examples can be downloaded or cloned with Git