C++ Tutorial
Brief
TA SDK provides best-in-class navigation and location-based services for precise and personalized driving experiences.
It's easy and quick to build your application with TA SDK and a map data package designed by Telenav.
Package
The folder structure of TA SDK package looks like below:
| ${PLATFORM_NAME}/
+ include
+ lib
+ resources
|
The libraries of TA SDK
are dynamic libraries.
Note
TA SDK
dynamically loads the map engine at runtime through a plugin mechanism. The map engine is also a dynamic library whose name ends with plugin.so
, plugin.dll
or plugin.dylib
. TA SDK
loads this library from the folder path provided by clients through tn::foundation::System::Builder::setDynamicLibraryPath
. Clients need to make sure the map engine dynamic library is available under this folder
Minimum Requirements
To ensure the proper integration of the TA SDK, it is essential to meet certain fundamental requirements.
C++11
or higher is required to build the TA SDK
OpenSSL
is required for TLS 1.2
or higher secure connections in the TA SDK
Setup
Some macro definitions are required to use the TA SDK.
- Definitions for platform
- Definitions for libraries to be linked as shared libraries
Please add the following definitions to your CMakeLists.txt
according to the platform or toolchain.
Platform |
Macro |
Windows 64/Visual Studio 2015 |
add_definitions(-DTN_PLATFORM_WIN64_VS14 -DTN_PLATFORM_WIN64 -DTN_PLATFORM_WIN) |
Windows 32/Visual Studio 2015 |
add_definitions(-DTN_PLATFORM_WIN32_VS14 -DTN_PLATFORM_WIN32 -DTN_PLATFORM_WIN) |
OSX |
add_definitions(-DTN_PLATFORM_OSX -DTN_PLATFORM_OSX -DTN_PLATFORM_MAC -DTN_PLATFORM_UNIX) |
OSX M1 |
add_definitions(-DTN_PLATFORM_OSX_ARM64 -DTN_PLATFORM_OSX -DTN_PLATFORM_MAC -DTN_PLATFORM_UNIX) |
Ubuntu 1804 |
add_definitions(-DTN_PLATFORM_LINUX_UBUNTU_18_04 -DTN_PLATFORM_LINUX_UBUNTU -DTN_PLATFORM_LINUX -DTN_PLATFORM_UNIX) |
Centos 7 |
add_definitions(-DTN_PLATFORM_LINUX_CENTOS7 -DTN_PLATFORM_LINUX_CENTOS -DTN_PLATFORM_LINUX -DTN_PLATFORM_UNIX) |
Linaro |
add_definitions(-DTN_PLATFORM_LINUX_ARM_LINARO -DPLATFORM_LINUX_ARM -DTN_PLATFORM_LINUX -DTN_PLATFORM_UNIX) |
QNX 700 |
add_definitions(-DTN_PLATFORM_QNX_700 -DTN_PLATFORM_QNX -DTN_PLATFORM_LINUX -DTN_PLATFORM_UNIX) |
QNX 710 |
add_definitions(-DTN_PLATFORM_QNX_710 -DTN_PLATFORM_QNX -DTN_PLATFORM_LINUX -DTN_PLATFORM_UNIX) |
Please add the following definitions to your CMakeLists.txt
to
link all libraries as shared libraries.
| add_definitions(-DTASDK_ALL_DYN_LINK)
|
Get Started
Base Data
You need to get base data from Telenav.
The folder structure of the base data looks as follows:
| TelenavMapData
├── junction
├── landmarks_3_d
├── map
└── index
|
If you opt for the One Data Package solution, Telenav will furnish the data view name.
This name is an integral component of the data license.
Any use of an unauthorized data view name will result in a failure of SDK initialization.
data view name: xxxx
Cloud
Telenav provides a unified cloud portal for versatile cloud features, such as cloud routing, streaming data and live traffic etc.
You should get the CouldURL
、 ApplicationKey
、Secret
and Region
from Telenav
for example:
CouldURL: https://eu-stg.telenav.com
ApplicationKey: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Secret:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Region: EU
Initialize the SDK
The following CMakeLists.txt tells you how to import the SDK library into your project.
| cmake_minimum_required(VERSION 3.8)
project(SDK_Demo)
set(TARGET SDK_Demo)
set(CMAKE_CXX_STANDARD 11)
# replace with your platform macro
set(TN_PLATFORM_OSX 1)
add_definitions(-DTN_PLATFORM_OSX -DTN_PLATFORM_OSX -DTN_PLATFORM_MAC -DTN_PLATFORM_UNIX)
add_definitions(-DTASDK_ALL_DYN_LINK)
if(DEFINED TN_PLATFORM_OSX)
set(DYN_LIB_SUFFIX ".dylib")
set(DYN_LIB_NATURAL_SUFFIX ".dylib")
elseif(DEFINED TN_PLATFORM_WIN)
set(DYN_LIB_SUFFIX ".lib")
set(DYN_LIB_NATURAL_SUFFIX ".dll")
else()
set(DYN_LIB_SUFFIX ".so")
set(DYN_LIB_NATURAL_SUFFIX ".so")
endif()
if(WIN32)
set(LIB_NAME_PREFIX "")
set(LIB_NAME_SUFFIX ".lib")
set(LIB_MODULE_NAME_PREFIX "")
set(LIB_MODULE_NAME_SUFFIX ".lib")
else(UNIX)
set(LIB_NAME_PREFIX "lib")
set(LIB_NAME_SUFFIX ".a")
set(LIB_MODULE_NAME_PREFIX "lib")
set(LIB_MODULE_NAME_SUFFIX ".a")
endif(WIN32)
function(tn_import_shared_libraries modulesDir sharedLibs...)
set(ALL_LIBS "")
list(APPEND ALL_LIBS ${ARGV1} ${ARGN})
set(IMPORTED_LIBS "")
foreach(lib ${ALL_LIBS})
if (TARGET ${lib})
message(STATUS "Shared library ${lib} has been imported already!")
else()
add_library(${lib} SHARED IMPORTED)
list(APPEND IMPORTED_LIBS ${lib})
endif()
endforeach()
if (CMAKE_CONFIGURATION_TYPES)
foreach(cfg ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${cfg} upper_cfg)
string(TOLOWER ${cfg} lower_cfg)
message(STATUS "Import shared library: cfg: ${cfg}, ${upper_cfg}, ${lower_cfg}")
foreach(lib ${IMPORTED_LIBS})
set_target_properties(${lib} PROPERTIES
IMPORTED_LOCATION_${upper_cfg} ${modulesDir}/lib/${lower_cfg}/${LIB_NAME_PREFIX}${lib}${DYN_LIB_NATURAL_SUFFIX}
)
endforeach()
if (DEFINED TN_PLATFORM_WIN)
foreach(lib ${IMPORTED_LIBS})
set_target_properties(${lib} PROPERTIES
IMPORTED_IMPLIB_${upper_cfg} ${modulesDir}/lib/${lower_cfg}/${LIB_NAME_PREFIX}${lib}${DYN_LIB_SUFFIX}
)
endforeach()
endif()
endforeach()
elseif (CMAKE_BUILD_TYPE)
string(TOUPPER ${CMAKE_BUILD_TYPE} upper_cfg)
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_cfg)
message(STATUS "Import shared library: cfg: ${CMAKE_BUILD_TYPE}, ${upper_cfg}, ${lower_cfg}")
foreach(lib ${IMPORTED_LIBS})
set_target_properties(${lib} PROPERTIES
IMPORTED_LOCATION_${upper_cfg} ${modulesDir}/lib/${lower_cfg}/${LIB_NAME_PREFIX}${lib}${DYN_LIB_NATURAL_SUFFIX}
)
endforeach()
# When we do not use the Visual Studio generator on Windows(for example, ninja), the configuration is as follows
# Type is absent, but we still need to import implicit libraries.
if (DEFINED TN_PLATFORM_WIN)
foreach(lib ${IMPORTED_LIBS})
set_target_properties(${lib} PROPERTIES
IMPORTED_IMPLIB_${upper_cfg} ${modulesDir}/lib/${lower_cfg}/${LIB_NAME_PREFIX}${lib}${DYN_LIB_SUFFIX}
)
endforeach()
endif()
endif()
endfunction(tn_import_shared_libraries)
if(TN_PLATFORM_WIN)
set(TASDK_LIBS tasdknavcore)
else()
set(TASDK_NAV_SERVICE_LIB tasdknavigation)
set(TASDK_MAP_LIB tasdkmap)
set(TASDK_USER_LIB tasdkuser)
set(TASDK_NAV_PLUGIN_LIB ngxplugin)
set(TASDK_NAV_MODELS_LIB navmodels)
set(TASDK_FOUNDATION_LIB tasdkfoundation)
set(TASDK_LIBS
${TASDK_NAV_SERVICE_LIB}
${TASDK_MAP_LIB}
${TASDK_USER_LIB}
${TASDK_NAV_PLUGIN_LIB}
${TASDK_NAV_MODELS_LIB}
${TASDK_FOUNDATION_LIB}
)
endif()
# change it to your sdk root path
set(TN_MODULES_DIR ${PROJECT_SOURCE_DIR}/osx)
add_definitions(-DTELENAV_PATH="${TN_MODULES_DIR}")
# import the TA SDK shared libraries
tn_import_shared_libraries(${TN_MODULES_DIR} ${TASDK_LIBS})
# Set the TASDK include directory as the system include path.
include_directories(SYSTEM ${TN_MODULES_DIR}/include/TASDK)
add_executable(${TARGET} ${PROJECT_SOURCE_DIR}/main.cpp)
# link the TA SDK libraries
target_link_libraries(${TARGET}
${TASDK_LIBS}
)
|
On Windows, it is important to distinguish whether your program is 64-bit or 32-bit.
If your platform is Windows 64/Visual Studio 2015
, the CMake command would typically look like the following:
| cmake -G "Visual Studio 14 2015 Win64" path/to/your/source/code
|
FAQ
How to handle sdk logs?
The sdk provides a log callback processing method, you can register your own processor.
| #include <foundation/log/logging_helper.h>
...
// change the log level to error
tn::foundation::LoggingHelper::SetLevel(tn::foundation::eNavLogLevel_Error);
// handle the sdk log to std::cout
tn::foundation::LoggingHelper::SetHandler([](const tn::foundation::Message &msg){
std::cout << msg.level << " " << msg.topic_name << " " << msg.log_message << std::endl;
});
|
How to check whether the initialization of MapContent is completed?
The initialization of MapContent is asynchronous and requires polling to determine if the initialization of MapContent has completed.
| tn::mapcontent::ContentVersionInfo version;
while (true)
{
auto error = map_content->getVersion(version);
if (error == tn::mapcontent::E_MAPCONTENT_ERRCODE_OK)
{
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
|
How to calculation a route?
The sdk provides task wrappers for calculating routes
| tn::direction::models::v2::GeoLocation origin(59.924386, 10.743484);
tn::direction::models::v2::GeoLocation destination(59.91042988207182, 10.724420220982003);
auto route_builder = direction_service->createRouteRequestBuilder();
route_builder->setRouteCount(3);
route_builder->setOrigin(origin);
route_builder->setDestination(destination);
auto task = direction_service->createRouteCalculationTask(route_builder->build(),
tn::direction::api::CalculationMode::Offboard);
if (task)
{
tn::shared_ptr<tn::direction::api::RouteResponse> response;
auto ret = task->runSync([&response](tn::foundation::ErrorCode ec,
tn::shared_ptr<tn::direction::api::RouteResponse> r) {
if (ec == tn::foundation::SDKError::OK && r)
{
response = r;
}
});
...
}
|
How to start simulation navigation?
| auto session = drive_session->startSimulationNavigation(route, 10);
|