Skip to content

05 Route calculation

Overview

In this tutorial you will learn how to calculate a route from A to B and how to influence the routing by setting your vehicle parameters.

Base

You can use your results from Tutorial04 as a base for our new project.

Prerequisites

Please copy the following files from the Tutorial05 folder to your project directory:

  • CalcRouteRunnable.cpp
  • CalcRouteRunnable.h
  • GPSPushLocationRunnable.cpp
  • GPSPushLocationRunnable.h
  • SDKJobQueue.cpp
  • SDKJobQueue.h

Because there are many small and simple changes in our MapWidget class, please replace the files

  • MapWidget.cpp
  • MapWidget.h

also.

Add the new files to the CMakeLists.txt file:

set(Tutorial_SRCS
    ...
    SDKJobQueue.cpp
    CalcRouteRunnable.cpp
    GPSPushLocationRunnable.cpp    
)

set(Tutorial_HEADER
    ... 
    SDKJobQueue.h
    CalcRouteRunnable.h
    GPSPushLocationRunnable.h
)

Call cmake ../ in the build directory or build the ALL_BUILD project of the solution to update it. Also, always trigger a rebuild after copying to ensure that replaced files will be rebuilt.

Calculating a route

Every long lasting operation should be performed in a background thread to avoid stalling the GUI thread and therefore the user interactions. So we put long lasting operations in a seperate thread. The NavigationSDK helps you with a simple worker thread (the SDKJobQueue) where you can queue your long lasting NavigationSDK operations.

SDKJobQueue.cpp:

...
SDKJobQueue::SDKJobQueue()
{
    mThreadPool = new QThreadPool();
    mThreadPool->setMaxThreadCount(1);
}

void SDKJobQueue::push(QRunnable * runnable)
{
    mThreadPool->start(runnable);
}

void SDKJobQueue::waitForDone()
{
    mThreadPool->waitForDone();
}
...

The queue uses the QThreadPool for queueing jobs. We set the maximum parallel threads to one, so we queue the jobs sequentially. We have a function called push(), which will add a QRunnable to the queue and a function waitForDone(), which will wait until the current job has ended.

Hint

You can easily use your own asynchronous mechanism. But be aware that most of the NavigationSDK functions are currently mutual exclusive and cannot be called concurrently. So try to call only one NavigationSDK method at a time to avoid locks in your application.

To calculate a route, we create a QRunnable with all the route calculation operations and push it via SDKJobQueue::getInstance()->push() to the SDKJobQueue. The run() function implements all the code we need to calculate a route from our current position to a given destination.
So, let us take a look at the class CalculateRouteRunnable:

CalcRouteRunnable.cpp:

void CalcRouteRunnable::run()
{
    SDK_Waypoint start;
    SDK_InitWaypoint(&start);

    SDK_GPSData gps;
    SDK_InitGPSData(&gps);

    // get the current gps position
    SDK_ERROR rc = GPSManager::getInstance()->getCurrentPosition(gps);

    start.x = gps.GPSPositionMerc.x;
    start.y = gps.GPSPositionMerc.y;

    SDK_Tour * tour;
    SDK_CreateTour(&tour, start);

    SDK_AddStationToTour(tour, mDestination);

    SDK_INT2 sectionError = 0;

    rc = SDK_CalculateTour(tour, progressCallback, &sectionError);

    SDK_DeleteTour(tour);

    if (rc == SDK_ERROR_Ok)
    {
        SDK_Position pos;
        SDK_InitPosition(&pos);

        pos.x = mDestination.x;
        pos.y = mDestination.y;

        mMap->setTargetPin(pos);

    }

    emit finished((int)rc);
}

SDK_INT4 SDK_API CalcRouteRunnable::progressCallback(SDK_INT4 current, SDK_INT4 total, SDK_INT4 job)
{
    emit pThis->progress(current);
    return 1;
}

Standard route and tour calculations are processed with the function SDK_CalculateTour(). This function requires an SDK_Tour object, which holds the start position and one or many target stations. The SDK_Tour has to be created with SDK_CreateTour(). It will set the given station as the start station. After creating the SDK_Tour, you can add one or more stations by calling SDK_AddStationToTour() or SDK_AddSVPsToTour(). For now, we only want to calculate a simple A-B route with a start station and a standard station as destination.

So first, we create the tour by calling:

    SDK_Tour * tour;
    SDK_CreateTour(&tour, start);

This will create an SDK_Tour with "start" as the start station. Adding the destination is done with:

    SDK_AddStationToTour(tour, mDestination);
We add our destination with SDK_AddStationToTour() to our SDK_Tour. SDK_AddStationToTour() adds a so called "regular" station to the tour. This type of station has only a coordinate and an optional course. It is also possible to add a path to the tour by using SDK_AddSVPsToTour(). We will cover this topic in Tutorial10.

Now we call:

rc = SDK_CalculateTour(tour, progressCallback, &sectionError);

SDK_DeleteTour(tour);

This calculates the route. The sectionError variable is used to get a detailed error description in case we have a multi station tour. It will be set to the route snippet where the error occurred. We also delete the tour we created, because we don't need it anymore.

SDK_CalculateTour() has the following parameters:

Type Parameter Description
const SDK_Tour* tour The tour which should be calculated
SDK_ProgressCBFuncT pCallBackFunc Optional pointer to a callback method, indicates the actual status of the routing progress
SDK_INT2* pSectionErrorBelongsTo If an error returns, the error belongs to the returned tour section

We also implemented a callback for showing the progress in a dialog box. CalcRouteRunnable::progressCallback() will be called by the SDK with the current progress. We emit this progress to our GUI thread (we later connect this signal to a slot in our MainWindow to show the progress in a progress dialog).

Attention

Try to avoid calling other NavigationSDK methods on another thread while the route calculation is running. For example drawing the map on the GUI thread while calculating the route will lock the GUI thread because most NavigationSDK methods are protected by the same mutex and cannot be called in a concurrent way.

To avoid calling other NavigationSDK methods on another thread, we push our NavigationLoop and the SDK_SetLocation() method from our GPSManager also to the SDKJobQueue. The NavigationLoop will be pushed in the updateTimer() function, so we change MainWindow::updateTimer().

Change the following in the MainWindow class:

MainWindow.cpp:

void MainWindow::updateTimer()
{
    if(mTimerEnabled)
        SDKJobQueue::getInstance()->push(mNavigationLoop);
}

Instead of calling directly the run() function of the NavigationLoop as in our last Tutorial, we now push the runnable to the queue (which will call the run() method of the NavigationLoop itself).

Second, we create a new class GPSPushLocationRunnable, that we can push to the queue instead of calling SDK_SetLocation() directly.

Take a look at its run() function:

void GPSPushLocationRunnable::run()
{
    SDK_ERROR rc = SDK_SetLocation(&mGPSData);
}
Here we simply do a call to SDK_SetLocation().

In the GPSManager::positionUpdated() function, we push the GPSPushLocationRunnable to the queue.

We first add the needed headers and then change the positionUpdated function.

Add/Change the following in the GPSManager class:

GPSManager.cpp:

...

#include "SDKJobQueue.h"
#include "GPSPushLocationRunnable.h"

...

void GPSManager::positionUpdated(const SDK_GPSData& gpsData)
{
    SDKJobQueue::getInstance()->push(new GPSPushLocationRunnable(gpsData));
}

...

To avoid rendering the map while calculating the route (which would lock the GUI thread), we add a check to almost every MapWidget function that calls an SDK method (we check mUpdatesAllowed, which must be set from outside the MapWidget). Also, because we now have a target we would like to show on our map, we add a new function to add and remove a target pin.
To show the route trace after the route calculation, we have to call the function SDK_SendMapViewEvent() in our paintEvent() with an SDK_NavigationInformation struct. If this is 0, no route trace will be rendered, even if there is one available. Calling the function with a new initialized struct is all you need to show the route trace.
To nicely zoom the map view to the route trace after the route calculation, we added also a function called MapWidget::zoom2route():

void MapWidget::zoom2Route()
{
    if (!mUpdatesAllowed)
        return;

    SDK_ERROR rc = SDK_SetMapViewParameter(mMapId, SDK_SV_ZoomToRoute, 0, 0, 0, 0, 0, 0);
}
...

void MapWidget::setMapMarker(const SDK_Position& pos, SDK_INT4 course, bool northenAdjusted, SDK_INT4 mapMarkerStyle)
{
    if (!mUpdatesAllowed)
        return;
    ...
}

...

void MapWidget::paintEvent(QPaintEvent *event)
{
    if (mUpdatesAllowed)
    {
        SDK_ERROR rc = SDK_SendMapViewEvent(mMapId, mNavigationInformation, SDK_wmPAINT, 0, 0, mBuffer);
    }
    ...
}

...

void MapWidget::setTargetPin(const SDK_Position& pos)
{
    if (mTargetPinId < 0)
        SDK_AddImage(L"arw_destination.png", L"", &pos, &mTargetPinId);
    else
        SDK_PositionImage(mTargetPinId, &pos);
}

void MapWidget::removeTargetPin()
{
    if (mTargetPinId >= 0)
    {
        SDK_DeleteImage(mTargetPinId);
    mTargetPinId = -1;
    }
}

void MapWidget::removeAllPins()
{
    SDK_DeleteImages();
    mPinId = -1;
    mTargetPinId = -1;
}

All relevant functions - which might be called in a thread - include a check if updates are allowed to avoid locking the GUI thread. This is just a simple approach to avoid locks. As you can see, if updates are not allowed, we do nothing or return a default value. A better approach would be to buffer the values if an update is not allowed and set the buffered values later when updates are allowed again. But this is not showcased in this tutorial.

Now add the following code to the MainWindow class:

MainWindow.h

    ...
    #include "CalcRouteRunnable.h"
    #include <QProgressDialog>

    ...

private:
    SDK_NavigationInformation * mNavigationInformation;
    QProgressDialog * mProgressDialog;
    SDK_Position mCurrentDestination;

    ...

We add the SDKJobQueue header to the MainWindow, initialize our progress dialog pointer to 0 and setAutoDelete() of our NavigationLoop to false (if the flag is set to true in a QRunnable, the runnable will be automatically deleted after execution. We do not want this, so we set the flag to false).
Also, we give a newly created SDK_NavigationInformation struct to the MapWidget to be able to show the route trace.

Add the following to the MainWindow class:

MainWindow.cpp:

    ...
#include "SDKJobQueue.h"
    ...
MainWindow::MainWindow(QMainWindow * parent) : QMainWindow(parent)
{
    ...
    mProgressDialog = 0;
    mNavigationLoop->setAutoDelete(false);

    mNavigationInformation = new SDK_NavigationInformation;

    SDK_InitNavigationInformation(mNavigationInformation);
    ui.map->setNavigationInformation(mNavigationInformation);
}

Change the destructor so it looks like this:

MainWindow:: ~MainWindow()
{
    if (mTimer)
    {
        mTimer->stop();
        delete mTimer;
    }

    SDKJobQueue::getInstance()->waitForDone();

    if (mNavigationLoop)
        delete mNavigationLoop;

    if (mProgressDialog)
        delete mProgressDialog;

    if (mNavigationInformation)
        delete mNavigationInformation;

    mGPSManager.closeGPS();
}

First, we stop pushing the NavigationLoop to the queue by stopping the timer. Then we call SDKJobQueue::getInstance()->waitForDone() to wait for a possible running thread job to end. This avoids crashes when the MainWindow will be destroyed but the thread is still accessing a member of our MainWindow.
We also delete the progress dialog and the mNavigationInformation member.

Our MainWindow::actionSearchAddressTriggered() function (this is where we create the search dialog and handle the result) must be altered.

Change the following in the MainWindow class:

MainWindow.cpp:

void MainWindow::actionSearchAddressTriggered(bool triggered)
{
    disableNavigationLoopTimer();

    SDKJobQueue::getInstance()->waitForDone();
    SDK_SearchResult result;
    SDK_InitSearchResult(&result);

    int retVal = 0;
    SDK_ERROR rc = SDK_ERROR_UnInitialized;

    ui.map->removeTargetPin();

    // to ensure, that the destructor of SearchDialog and with it the finalization of the mapview in it is called before we 
    // start to calculate a route (which would end in a mutex lock), we enclose the creation in brackets
    {
        SearchDialog dialog(this);
        retVal = dialog.exec();
        if (retVal == QDialog::Accepted)
        {
            // get the result from the search dialog
            rc = dialog.getCurrentSearchResult(result);
        }
    }

    if (retVal == QDialog::Accepted && rc == SDK_ERROR_Ok)
    {
        ui.map->denyUpdates();

        SDK_InitPosition(&mCurrentDestination);
        mCurrentDestination = result.pos;

        // setDefaultRoutingOptions();

        if (!mProgressDialog)
        {
            mProgressDialog = new QProgressDialog("Calculating route...", "Cancel", 0, 100, this, Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
            mProgressDialog->setWindowModality(Qt::WindowModal);
            mProgressDialog->setCancelButton(0);
        }
        else
            mProgressDialog->show();

        CalcRouteRunnable * runnable = new CalcRouteRunnable(mCurrentDestination, ui.map);

        connect(runnable, SIGNAL(progress(int)), this, SLOT(onProgress(int)));
        connect(runnable, SIGNAL(finished(int)), this, SLOT(onCalcRouteFinished(int)));

        SDKJobQueue::getInstance()->push(runnable);
    }
    else
        enableNavigationLoopTimer();

}

Again we wait for our job queue to finish to not get in a mutex lock situation. Then we start the SearchDialog. If the user clicked a result and the result is valid, we call

    ui.map->denyUpdates();

to avoid manipulating the map by panning or something else that would end in a GUI thread lock.
If the progress dialog is not already created, we do this now and create our CalculateRouteRunnable with the destination and our map view as parameters. The map view parameter is used to allow the runnable to set the target pin on the map. We set the destination to the result we got above and connect the progress() and finished() signals of the CalcRouteRunnable to the slots MainWindow::onProgress() and MainWindow::onCalcRouteFinished(). Then we push the runnable to the job queue. This will spawn a new thread, in which the run() method of our runnable will be called.

Retrieving progress information

Users should be notified about the progress of every long lasting operation. Therefore most of the long lasting operations in the NavigationSDK can be called with an optional callback. This callback is called frequently by the SDK with updated progress information.

Attention

The callback will be called from the thread in which the route calculation was started from. So in our example from the SDKJobQueue thread. To update a GUI element, we have to bring the execution back to the GUI thread. This is automatically done by Qt with the signal/slot functionality. Signals in Qt are internally sent by an event to the GUI threads event loop if the sender runs not in the same thread as the receiver. So onProgress() is called on the GUI thread and we can update the progress dialog safely.

Add the following to the MainWindow class:

MainWindow.h:

... 

protected slots:
    void onCalcRouteFinished(int error);
    void onProgress(int progress);

...

MainWindow.cpp:

... 

void MainWindow::onProgress(int progress)
{
    if (mProgressDialog)
        mProgressDialog->setValue(progress);
}

void MainWindow::onCalcRouteFinished(int error)
{
    ui.map->allowUpdates();
    enableNavigationLoopTimer();

    if ((SDK_ERROR)error == SDK_ERROR_Ok)
    {
        ui.map->zoom2Route();
        ui.map->update();   
    }
}

...

We update the progress dialog when a new progress event arrives:

After the route calculation has finished, the onCalcRouteFinished() slot will be called, where we allow updates of the map again. We also reenable the NavigationLoop timer. The CalculateRouteRunnable sends the returned error code from SDK_CalculateTour() after finishing the calculation. So we check this and if the route calculation hase succeeded, we zoom the map to show the whole route:

RoutingOptions

The NavigationSDK brings several methods to influence the result of the route calculation. For example you can avoid toll roads, decide what kind of vehicle is used or if you like a routing optimized for shortest way or time. You can manually change every single routing parameter, but many of the parameters need a deeper knowledge on how they influence the routing to get the desired effect on the route (like i.e. speed tables).

Loading a vehicle profile

To avoid setting the routing options manually and to get a quick way to set them for a particular vehicle, we use so called profiles which describes certain standard vehicles like trucks, cars, transporters and so on. In these profiles (which are text files) the values for the relevant routing and lorry options are preset (some of the options are not in the profiles file, but will be adapted internally to the used vehicle). We highly recommend to use the profile loading mechanism which the SDK provides instead of setting the options manually, especially the speed tables.

Loading a profile is done by calling the method SDK_LoadVehicleProfile(). The function takes as parameter the full path to the profile file to load.

We deliver a set of profiles in a directory called 'profiles' under the data directory of the tutorial app data.

Add the following to the MainWindow class:

MainWindow.h:

... 

protected:
    void loadProfile();    
...

MainWindow.cpp:

... 
MainWindow::MainWindow(QMainWindow * parent) : QMainWindow(parent)
{
    ...
    loadProfile();
}

void MainWindow::loadProfile()
{
    QString profilePath = Constants::getDataPath() + "profiles/truck75.dat";
    SDK_ERROR rc = SDK_LoadVehicleProfile(profilePath.toStdWString().c_str());
    if (rc == SDK_ERROR_Ok)
    {
        SDK_WCHAR_T * profileName = 0;
        rc = SDK_GetProfileName(profilePath.toStdWString().c_str(), L"GB", &profileName);

        if (rc == SDK_ERROR_Ok)
        {
            QString profileNameQt = QString::fromStdWString(profileName);
            free(profileName);

            QString outputMessage = "Loaded profile: ";
            outputMessage += profileNameQt;
            statusBar()->showMessage(outputMessage);
        }   
    }
}

...

We load the profile "truck75.dat", which has all options set for a 7.5t truck. We also set the status bar text to the english translation of the profile name by calling SDK_GetProfileName().

SDK_GetProfileName() has the following parameters:

Type Parameter Description
const SDK_WCHAR_T * pFileName The name of the profile file (with full path) to load
const SDK_WCHAR_T * cc The country code for the translation. If null, an english translation will be returned (if available)
SDK_WCHAR_T ** pProfileName The translated name of the profile

The cc is of type SDK_ccf_ISO_2. See the documentation for more details.

Manually setting the routing options

Setting the routing options manually is also possible. As you can see in the list below, there are a bunch of options which could be set. Some of these should only be changed manually if a deeper knowledge of the parameter is given. We highly recommend to use the profile loading functionality described above for a start. In our example, we set one option manually: The RouteCalculationType. This decides whether alternative routes should be calculated or not. Because we don't want alternatives in this tutorial, we set the option to 'SDK_RouteClassic' in MainWindow::setDefaultRoutingOptions().
Before setting an option, we call SDK_GetRoutingOptions() to retrieve the current set SDK_RouteOptions. Afterwards, we alter the RouteCalculationType and write the options back with SDK_SetRoutingOptions().

The struct SDK_RouteOptions has the following members:

Type Name Description
SDK_HDRINFO size Size of structure - for controlling
SDK_HDRINFO version version of the structure - for controlling. Use SDK_RouteOptionsVERSION
SDK_INT4 TimeFactor This parameter can be used to set the desired time factor. This factor can be used to influence the weight of distance and duration in the evaluation of routes. If set to 0, the time has no influence and the shortest route is searched. If the factor is set to 100 (percent), time is considered as very important so the result is the fastest route prefering motorways and fast by-passes.
SDK_INT4 AltRoute This parameter can be used to set the alternative route that should be exported. For now only one alternative route is supported. This default route has to be calculated first! 0 indicates default route, 1 the alternative route
SDK_INT4 AltRouteMalus This parameter can be used to set the AltRoutesMalus. This malus allows to influence how much the alternative route may deviate from the basic route. Streets that were already used in the privious routes are considered more "expensive" in subsequent calculations. Not yet implemented
SDK_BOOL RouteWithoutAutoroute Flag for controlling whether the route should avoid motorways. This is only supported for routes up to 150km. For longer distances the route can nevertheless contain motorways.
SDK_BOOL RouteWithoutFerry Flag for controlling whether the route should avoid ferries.
SDK_SpeedTable SpeedTable_Calc This option can be used to set the desired speed profile for route calculation. RoutingVehicle=SDK_rvUSER has to be specified to enable this table! The values are scaled in steps of three speeds belonging together (fast, medium and slow) for motorways, national, country, urban and access roads as well as ferries. The values are always in km/h, independent of the option UseMetricSystem. Users should avoid using modified speedtables if possible!
SDK_SpeedTable SpeedTable_RouteList This option can be used to set the desired speed profile for the route lists time calculation. RoutingVehicle=SDK_rvUSER has to be specified to enable this table! The values are scaled in steps of three speeds belonging together (fast, medium and slow) for motorways, national, country, urban and access roads as well as ferries. The values are always in km/h, independent of the option UseMetricSystem. Users should avoid using modified speedtables if possible!
SDK_INT4 UTurnMalus This parameter allows to control the handling of U-turns during the route calculation. The value specifies, how much lengthening without an U-turn is accepted instead of performing an U-turn. Allowed values range from 0 to 50000 seconds as impact for the route with U-turn.
SDK_INT4 RoutingVehicle Vehicle Type. See RoutingVehicles
SDK_INT4 MatchDistStart Matching distance for roads at the start [Mercator units]. Mercator units for central europe are 1-2m; for an exact conversion please use SDK_TransformCoordinates
SDK_INT4 MatchDistDestination Matching distance for roads at the destination [Mercator units]. Mercator units for central europe are 1-2m; for an exact conversion please use SDK_TransformCoordinates
SDK_BOOL AvoidFerryOnStart If SDK_TRUE don't link to ferries on start. May be useful if the start is an offroad position.
SDK_BOOL AvoidFerryOnDestination If SDK_TRUE don't link to ferries on destination. May be useful if the destination is an offroad position.
SDK_BOOL AvoidMotorwayOnStart If SDK_TRUE don't link to motorways on start. May be useful if the start is an offroad position.
SDK_BOOL AvoidMotorwayOnDestination If SDK_TRUE don't link to motorways on destination. May be useful if the destination is an offroad position.
SDK_BOOL bAvoidTunnelOnStart If SDK_TRUE don't link to tunnels on start. May be useful if the start is an offroad position.
SDK_BOOL bAvoidTunnelOnDestination If SDK_TRUE don't link to tunnels on destination. May be useful if the destination is an offroad position.
SDK_BOOL bAvoidPedestrianZoneOnStart If SDK_TRUE don't link to segments in pedestrian zones on start
SDK_BOOL bAvoidPedestrianZoneOnDestination If SDK_TRUE don't link to segments in pedestrian zones on destination
SDK_BOOL bPedestrianRoutingFromStart If SDK_TRUE the route starts at the nearest segment outside the pedestrian zone. A trace through the pedestrian zone is prepended to the route. There will be no guidance in the pedastrian zone itself! Does not work with bAvoidPedestrianZoneOnDestination == true!
SDK_BOOL bPedestrianRoutingToDestination If SDK_TRUE the route leads to the nearest segment outside the pedestrian zone. A trace through the pedestrian zone is added to the route. There will be no guidance in the pedastrian zone itself! Does not work with bAvoidPedestrianZoneOnDestination == true!
SDK_BOOL bPremisesRouting If SDK_TRUE, it is possible to route through gates of premises at start and target.
SDK_BOOL bViolateLorryRescrictions If SDK_TRUE, it is possible to ignore LorryRestrictions at start and target.
SDK_BOOL Lorry Set lorry restrictions which should be taken into consideration during route calculation.
SDK_BOOL bNiceTransit If set to SDK_TRUE, a cross map routing will use detail level maps in transit countries if available. Otherwise it will only use the major roads map, which reduces the memory impact and reduces time for route calculation.
SDK_BOOL bForceMRRouting If set to SDK_TRUE, a cross map routing will be formed even if start and destination are within the same map. Otherwise it will only use the local map, which reduces the memory impact and reduces time for route calculation.
SDK_BOOL bUseRRTLayers If set to SDKK_TRUE, .rrt layers will be evaluated for route calculation. Default is SDK_TRUE.
SDK_INT1 ClassOfDangerousGoods Class of dangerous goods. May be 'A', 'B', 'C', 'D', 'E'.
  • A means no restrictions
  • B means restrictions B,C,D,E are considered
  • C means restrictions C,D,E are considered
  • D means restrictions D,E are considered
  • E means restriction E is considered
SDK_BOOL bUseTollLayer If set to SDK_TRUE, layers with toll (.lot) will be evaluated for route calculation. Default is SDK_FALSE.
SDK_UINT4 TollFactor The factor is to be understood as % additional charge of cost of a segments with toll. Default is 150.
SDK_BOOL bUseTruckTollLayer If set to SDK_TRUE, layers with trucktoll (.etx) will be evaluated for route calculation. Default is SDK_FALSE.
SDK_UINT4 TruckTollFactor The factor is to be understood as % additional charge of cost of a segments with truck toll. Default is 100.
SDK_INT4 AmountIgnoredTiles Count of tiles in the start/target zone
SDK_UINT1 AdditionalCostFactorRestrictionArea Additional costs in % for ignored truck segments in start/target zone (max 256)
SDK_BOOL bOpenGenerelRestrictions Ignore general truck restriction in the start/target zone
SDK_BOOL bOpenGenerelRestrictionsAndWeight Ignore general and weight restrictions for trucks in the start/target zone
SDK_BOOL bOpenDeliveryRestrictions Ignore restrictions with residential or delivery flag
SDK_UINT4 TrafficFactor The factor is to be understood as a switch to turn on or off the traffic consideration while calculating a route. 0 means do not consider traffic while route calculation, > 0 means consider it
SDK_INT4 RouteCalculationType Route calculation type, like standard or with alternatives. See RouteCalculationTypes

Add the following to the MainWindow class:

MainWindow.h:

...

protected:
    void setDefaultRoutingOptions();

...

MainWindow.cpp:

void MainWindow::setDefaultRoutingOptions()
{   
    SDK_RouteOptions routeOptions;
    SDK_InitRouteOptions(&routeOptions);

    SDK_ERROR rc = SDK_GetRoutingOptions(&routeOptions);

    routeOptions.RouteCalculationType = SDK_RouteClassic;

    rc = SDK_SetRoutingOptions(&routeOptions);
}
We can call this function in our actionSearchAddressTriggered() before starting the route calculation:

void MainWindow::actionSearchAddressTriggered(bool triggered)
{
    ...
    if (retVal == QDialog::Accepted && rc == SDK_ERROR_Ok)
    {
        ...
        setDefaultRoutingOptions();

        if (!mProgressDialog)
        {
            ...
        }
        else
            ...

        CalcRouteRunnable * runnable = new CalcRouteRunnable(mCurrentDestination, ui.map);

        ...