Rich Information For User Position
This tutorial shows how to get rich user position information.
Get started
Rich user position information is detected along the most possible path (MPP).
In user position information, you will get things including current road, nearby road, intersections, admin and timezone.
User position listener
Make a customized position listener to handle user position updates.
| class PositionObserver : public tn::drive::api::PositionEventListener
{
public:
void onPositionIndicatorUpdated(const tn::drive::models::v1::Indicator& indicator) override
{
// vehicle is on road if matched road is available
if (indicator.matched_road.has_value())
{
const auto currentStreetName = parseRoadName(indicator.matched_road->road_name);
const auto houseNumber = indicator.matched_road->house_number;
// generate the shield icon via the context of current matched road
if (indicator.shield_info.has_value())
{
const auto icon = navigationService->renderIcon(60, 48, indicator.shield_info->shield_icon_context);
}
}
// vehicle is off road if the nearby road information is available
// NOTICE: the nearby road information not available does not mean vehicle is on road
if (indicator.nearby_road.has_value())
{
const auto nearbyRoadName = parseRoadName(indicator.nearby_road->name);
// the crow fly distance from current vehicle location to the nearby road
const auto distanceToVehicle = indicator.nearby_road->distance;
}
// regional info at the vehicle location
if (indicator.regional.has_value())
{
const auto urban = indicator.regional->urban;
const auto admin = indicator.regional->admin_info;
const auto utcOffset = indicator.regional->time_zone.UTC_offset;
const auto dstOffset = indicator.regional->time_zone.DST_offset;
// calculate local time for user position according to UTC and DST offset
}
// ahead intersection when vehicle is on road
if (indicator.ahead_intersection.has_value())
{
// location of the intersection
const auto location = indicator.ahead_intersection->location;
// road names of the cross roads
const auto crossRoadNames = pickCrossRoadNames(indicator.ahead_intersection->cross_roads);
// distance along the road from current vehicle location to intersection location
const auto distanceToVehicle = indicator.ahead_intersection->distance;
}
// behind intersection when vehicle is on road
if (indicator.behind_intersection.has_value())
{
// ...
}
}
// omit other methods
};
std::vector<std::string> pickCrossRoadNames(const std::vector<tn::mapcontent::models::v1::NameString>& cross_roads)
{
std::vector<std::string> names;
uint32_t count = 0;
for (const auto& cross_road : cross_roads)
{
const auto name = parseRoadName(cross_road);
names.push_back(name);
count++;
if (count >= 2)
{
// pick two cross road names at most
break;
}
}
return names;
}
|
Refer to parse name string for road names for parseRoadName
implementation.
Register the listener after creation of navigation service.
| const auto listener = tn::make_shared<PositionObserver>();
navigationService->addPositionEventListener(listener);
|
Unregister it when not needed.
| navigationService->removePositionEventListener(listener);
|