The challenge often encountered by teams developing embedded mapping applications is to have the ability to track many thousands of dynamic objects from various sensors in real-time.
This is a requirement common to most types of operational type applications whether being C4ISR, GPS tracking of emergency vehicles being used by first responders, displaying the location of UAVs and IoT applications using input from many types of dynamic and static sensors.
Envitia’s MapLink Pro Tracks SDK provides the ability to quickly and easily visualise your moving objects or sensor feeds, with real-time location and attribute update. You can display breadcrumbs to show where your tracked objects have been or are projected to go in the future, with a playback feature so that the tracks can be recorded and replayed.
You can configure the map to follow your tracked object and even re-project your map in real- time to ensure that the mapping information is as accurate as possible, wherever your objects take you in the world.


In this blog, you will learn how to add tracked objects and sensor feeds to the map in your MapLink Pro-based application. You will be shown how to update the location and attribution of your objects and how to visualise the historical locations of your tracked objects.
The Tracks SDK is available for C++ and C# developers and is available on Windows and Linux operating systems. You can find sample code for an example C++, Qt-based Tracks application in our GitHub.
Tracks SDK Class Diagram
Before we get to the fun bit, the coding, it will be useful to see the major classes of the Tracks SDK and how they relate to each other.

The TSLTrackDisplayManager object is associated with one or more drawing surfaces which will display the tracks information in a map view.
The TSLTrack class represents a real-world tracked object, dynamic feature or sensor feed. Each track object should be associated with one or more TSLTrackPointSymbol in order for the track to be displayed on the map.
Create a Tracks Layer In Your Map View
The display of track objects in a MapLink Pro view is managed by the TSLTrackDisplayManager class. A track display manager object is associated with one or more drawing surfaces, meaning that several views of the same tracks information can exist simultaneously.
// Create the track display manager.
TSLTrackDisplayManager * theTrackDisplayManager = TSLTrackDisplayManager::create();
// Associate the track display manager with a drawing surface. Remember the surface ID!
int surfaceId = theTrackDisplayManager->addDrawingSurface(aDrawingSurface, "DrawingSurfaceName");
Create a Track Object
To create a track object, the following simple steps are followed:
1. Create a track point symbol object which will be used to visualise your track object on the map
TSLSymbol* createSymbol(int configuredSymbolId, int symbolSizeInPixels, TSLRGBA colour)
{
// Create a symbol object
TSLRenderingAttributes attribs; // Will define the symbol's appearance.
attribs.m_symbolStyle = configuredSymbolId; // This is the ID of a configured point symbol -
identifies the symbol to draw.
attribs.m_symbolColour = colour.composeRGB(); // integer defining the symbol's RGB value.
attribs.m_symbolSizeFactor = symbolSizeInPixels; // Size of the symbol in pixels.
attribs.m_symbolSizeFactorUnits = TSLDimensionUnitsPixels; // Tell MapLink that m_symbolSizeFactor
is a pixel value.
TSLSymbol * symbol = TSLSymbol::create(0, 0, 0); // Create the symbol object...
symbol->setRendering(attribs); // ... and define the symbol's appearance.
return symbol;
}
// Create the track point symbol object to represent an aeroplane.
TSLTrackPointSymbol * aeroplaneTrackPointSymbol = TSLTrackPointSymbol::create();
// Give it a visualisation - in this case, a simple red aeroplane symbol.
TSLSymbol* redAeroplane = createSymbol(
6002, // The ID of an aeroplane symbol provided by MapLink Pro's default configuration
35, // 35 pixels high
TSLRGBA(0xff, 0x00, 0x00, 0xff) // Red with transparent background.
);
aeroplaneTrackPointSymbol->addSymbolEntity(
redAeroplane,
true); // true = automatically rotate the symbol to the object's heading, false = no rotation
2. Create the track object, associating it with its point symbol.
TSLTrack * aeroplaneTrack = TSLTrack::create(aeroplaneTrackPointSymbol);
We could add further symbols to our track object so that our track can be shown with differing levels of detail at different zoom levels, but we’ll keep it simple here.
3. Add the track object to the Track Display Manager.
theTrackDisplayManager->addTrack(
trackNumber, // Unique identifier for the track.
aeroplaneTrack // Our aeroplane track object.
);
You might have many tracks to display, in which case you’ll want to use the addTracks method which takes an array of track objects to add to the display manager simultaneously.
Set Your Track’s Location
We now have a tracked aeroplane object that will be managed by a track display manager. Unfortunately, our aeroplane track cannot yet be displayed on the map because it doesn’t have a location. Let’s remedy this.
aeroplaneTrack->move(latitude, longitude);
That didn’t take long. Our aeroplane now has a location on the Earth and will be displayed on the map!
Every time your real-world object moves, call the move method again to update the track object’s location on the map. This can be updated in real- time to give the best possible accuracy. If you have lots of track objects moving constantly, you’ll want to update the locations of them all at the same time. You can do this by calling the moveTracks() method on the track display manager.
And because we instructed the aeroplane track point symbol to automatically rotate to the heading, the object’s symbol also gives an indication of the aeroplane’s heading.

Visualise the Path Your Track Has Taken
It can be useful to depict the path that track objects have taken, to gain insights into the behaviour of objects and their interactions. A common way to show the path of objects is to display breadcrumbs – like the object has been dropping breadcrumbs on the floor at regular intervals.
Breadcrumbs, or history points, must be configured on the track display manager for each drawing surface that will show them:
theTrackDisplayManager->historyPointsVisible(surfaceId, true); // Enable breadcrumbs on the specified
drawing surface.
theTrackDisplayManager->historicDataExpiry(60*60); // Keep one hour of history.
theTrackDisplayManager->historyPointDistance(5000); // Distance between breadcrumbs in map units.
theTrackDisplayManager->numHistoryPoints(100); // Maximum number of breadcrumbs which will be displayed per
track.
You’ll also need to configure the colour and size of the breadcrumb symbol:
theTrackDisplayManager->historyPointType(TSLTrackDisplayManager::HistoryPointTypeSquare); // Square
breadcrumbs are the most efficient to draw.
TSLTrackHistorySymbol * historySymbol = TSLTrackHistorySymbol::create();
historySymbol->colour(0xff00ffff);
historySymbol->size(35);
historySymbol->sizeUnits(TSLDimensionUnitsPixels);
historySymbol->symbolID(1);
theTrackDisplayManager->historyPointSymbol(historySymbol);
Tracks added to the track display manager will now be displayed with breadcrumbs!

Track Playback
The track display manager can be configured to record updates of tracked objects and allow the display time to be set to any moment in the resulting recorded history, ultimately allowing for the playback of the tracks’ histories. To support playback, the track display manager has two distinct concepts of time:
- Current time: a timestamp for the most up-to-date information about the tracks. Updates to tracks, such as setting tracked objects’ locations, affect the tracked objects at the current time. In real-time systems, current time will equal now.
- Display time: the moment displayed by the track display manager. This may either be the same as the current time, or some moment in the past.
Therefore, an application can implement a time slider that sets the track display manager’s display time to be any moment in the recorded history. The track display will automatically be updated to indicate the track objects’ location, altitude and speed at the moment specified by the slider.
To enable playback the display manager must be configured with the duration for which historical information should be kept, using the TSLTrackDispl ayManager.historicDataExpiry() method. Every time tracks are updated, the display manager should be timestamped with the current time, using the TSLTrackDisplayManager.currentTime() method:
// getCurrentTime() is an application function that returns the timestamp of the latest track states
theTrackDisplayManager->currentTime(getCurrentTime());
// All updates are recorded against the current time
theTrackDisplayManager->moveTracks(numTracks, trackIDs, latitudes, longitudes);
...
// Set the display time to a moment specified by the application.
theTrackDisplayManager->displayTime(getPlaybackTime());
Conclusion
This short blog has shown you how you can easily and intuitively add the display of tracked objects, dynamic features and sensor feeds to your mapping application using Envitia’s MapLink Pro Tracks SDK. You can use the Tracks SDK in a variety of use cases including the tracking of emergency vehicles in a command and control system, showing the location of an unmanned drone in Beyond Visual Line of Sight (BVLOS) applications or displaying the current attributes of your Internet of Things (IoT) sensor. You can show the historical location of tracked objects, either through the display of breadcrumbs or through playback capabilities.
To find out more about the SDK’s capabilities, take a look at the API documentation here and you can find the Tracks SDK Developer Guide here.