Introduction

Map Driving Extension

The TomTomOnlineSDKMapsDriving

Map and route matching

This module is built on top of the Maps SDK for iOS and contains logic and helpful utils that can be used in more complex scenarios, like driving or cycling.

To use this library, add the following dependency to the Podfile file:

pod 'TomTomOnlineSDKMapsDriving'

Map and route matching

Map matching snaps an inaccurate GPS probe to the road network obtained from map tiles, so roads are represented by collections of coordinates. Route matching is a special case of map matching which snaps an inaccurate GPS probe to the given route. The reference route is represented by a collection of coordinates. The route can be calculated using the Routing API or provided manually.

Sample use case: You have a speed radar application that is used when driving. To have a proper user experience, you want to match GPS positions with the road data obtained from map tiles.

Sample use case: You want to match/place the chevron with the the right road.

Sample use case: A user plans and displays a route on the map in your app. The vehicle position is being matched along the planned route.

To create map matcher instance and register for updates:

SWIFT
OBJECTIVEC
matcher = TTMatcher(matchDataSet: mapView)
matcher.delegate = self
self.matcher = [[TTMatcher alloc] initWithMatchDataSet:self.mapView];
self.matcher.delegate = self;

To update map matcher with a new GPS position:

SWIFT
OBJECTIVEC
matcher.setMatcherLocation(location)
[self.source updateLocationWithLocation:location];

To process map matcher results:

SWIFT
OBJECTIVEC
public func matcherResultMatchedLocation(_ matched: TTMatcherLocation, withOriginalLocation original: TTMatcherLocation, isMatched: Bool) {
- (void)matcherResultMatchedLocation:(TTMatcherLocation *)matched withOriginalLocation:(TTMatcherLocation *)original isMatched:(BOOL)isMatched {

Grey chevron - position is matched to the map

Blue chevron - position is not matched to the map

To create a route matcher instance and register for updates:

SWIFT
OBJECTIVEC
matcher = TTMatcher(matchDataSet: plannedRoute)
matcher?.delegate = self
self.matcher = [[TTMatcher alloc] initWithMatchDataSet:plannedRoute];
self.matcher.delegate = self;

Follow the chevron

Allow your users to follow their changing positions on the map e.g., when driving. When a new location is set, the animation moves the chevron to the new position.

Sample use case 1: You want to show your user position when driving.

Custom chevron indicator

You can set a custom icon for the chevron indicator.

To create a custom chevron:

SWIFT
OBJECTIVEC
let animation = TTChevronAnimationOptionsBuilder.create(withAnimatedCornerRounding: false).build()
chevron = TTChevronObject(normalImage: TTChevronObject.defaultNormalImage(), withDimmedImage: TTChevronObject.defaultDimmedImage(), with: animation)
TTChevronAnimationOptions *animation = [[TTChevronAnimationOptionsBuilder createWithAnimatedCornerRounding:true] build];
self.chevron = [[TTChevronObject alloc] initWithNormalImage:[TTChevronObject defaultNormalImage] withDimmedImage:[TTChevronObject defaultDimmedImage] withChevronAnimationOptions:animation];

Chevron tracking mode

Additionally, it is possible to track the chevron. It means that the camera/map and the chevron move when a new location is received so that the map is always centered on the chevron with the bearing of the drive. In the tracking mode, rotate and pan gestures are blocked. The user can only change the zoom level, while the map camera is automatically adjusted to follow the chevron.

To start tracking a selected chevron:

SWIFT
OBJECTIVEC
mapView.trackingManager.start(chevron)
[self.mapView.trackingManager startTrackingObject:self.chevron];

To stop tracking a selected chevron:

SWIFT
OBJECTIVEC
mapView.trackingManager.stop(chevron!)
[self.mapView.trackingManager stopTrackingObject:self.chevron];

To add route to the chevron source:

SWIFT
OBJECTIVEC
1let mapRoute = TTMapRoute(coordinatesData: plannedRoute,
2 with: TTMapRouteStyle.defaultActive(),
3 imageStart: TTMapRoute.defaultImageDeparture(),
4 imageEnd: TTMapRoute.defaultImageDestination())
5source = MapFollowTheChevronSource(trackingManager: mapView.trackingManager, routeManager: mapView.routeManager, trackingObject: chevron, route: mapRoute)
6source?.activate()
1TTMapRoute *mapRoute = [TTMapRoute routeWithCoordinatesData:result.routes.firstObject withRouteStyle:TTMapRouteStyle.defaultActiveStyle imageStart:TTMapRoute.defaultImageDeparture imageEnd:TTMapRoute.defaultImageDestination];
2self.source = [[MapFollowTheChevronSource alloc] initWithTrackingManager:self.mapView.trackingManager routeManager:self.mapView.routeManager trackingObject:self.chevron route:mapRoute];
3[self.source activate];

To set the chevron position on the screen:

SWIFT
OBJECTIVEC
mapView.trackingManager.setTrackingScreenCoordinates(CGPoint(x: 200, y: 500))
[self.mapView.trackingManager setTrackingScreenCoordinates:CGPointMake(200, 500)];

Chevron overview

Chevron tracking

Zooming the route

Zooming in and out are used to navigate through map areas that are too large or too small to be conveniently displayed within a single window. While following the chevron, zooming alters the map scale because it changes the proportion of the workspace shown in each window.

Sample use case: You are a taxi driver navigating through the city of Łódź, and thanks to the zoom level adjusted to the velocity of your car you see a convenient map area for you to move.

Use the following code snippets to try this in your app:

SWIFT
OBJECTIVEC
1func updateZoomLevelBaseOnNewLocation(_ location: CLLocation) {
2 guard updateZoom else { return }
3 var zoom: Double
4 switch location.speed {
5 case SMALL_SPEED_RANGE_IN_KMH:
6 zoom = SMALL_SPEED_ZOOM_LEVEL
7 case MEDIUM_SPEED_RANGE_IN_KMH:
8 zoom = MEDIUM_SPEED_ZOOM_LEVEL
9 case GREATER_SPEED_RANGE_IN_KMH:
10 zoom = GREATER_SPEED_ZOOM_LEVEL
11 case BIG_SPEED_RANGE_IN_KMH:
12 zoom = BIG_SPEED_ZOOM_LEVEL
13 default:
14 zoom = HUGE_SPEED_ZOOM_LEVEL
15 }
16 guard mapView.zoom() != zoom else { return }
17 let cameraPostion = TTCameraPositionBuilder.create(withCameraPosition: mapView.cameraPosition().cameraPosition).withZoom(zoom).withAnimationDuration(Int32(ZOOM_CHANGE_ANIMATION_MILLIS)).build()
18 mapView.setCameraPosition(cameraPostion)
19}
1- (void)updateZoomLevelBaseOnNewLocation:(CLLocation *)location {
2 if (!_updateZoom) {
3 return;
4 }
5 double zoom;
6 if (location.speed < SMALL_SPEED_RANGE_END_IN_KMH) {
7 zoom = SMALL_SPEED_ZOOM_LEVEL;
8 } else if (location.speed < MEDIUM_SPEED_RANGE_END_IN_KMH) {
9 zoom = MEDIUM_SPEED_ZOOM_LEVEL;
10 } else if (location.speed < GREATER_SPEED_RANGE_END_IN_KMH) {
11 zoom = GREATER_SPEED_ZOOM_LEVEL;
12 } else if (location.speed < BIG_SPEED_RANGE_END_IN_KMH) {
13 zoom = BIG_SPEED_ZOOM_LEVEL;
14 } else {
15 zoom = HUGE_SPEED_ZOOM_LEVEL;
16 }
17 TTCameraPosition *cameraPosition = [[[[TTCameraPositionBuilder createWithCameraPosition:self.mapView.cameraPosition.cameraPosition] withZoom:zoom] withAnimationDuration:ZOOM_CHANGE_ANIMATION_MILLIS] build];
18 [self.mapView setCameraPosition:cameraPosition];
19}

Lookup for the constants used in the sample code:

SWIFT
OBJECTIVEC
1let ZOOM_CHANGE_ANIMATION_MILLIS = 300
2let SMALL_SPEED_ZOOM_LEVEL = 19.0
3let MEDIUM_SPEED_ZOOM_LEVEL = 18.0
4let GREATER_SPEED_ZOOM_LEVEL = 17.0
5let BIG_SPEED_ZOOM_LEVEL = 16.0
6let HUGE_SPEED_ZOOM_LEVEL = 14.0
7let SMALL_SPEED_RANGE_IN_KMH = 0.0 ..< 10.0
8let MEDIUM_SPEED_RANGE_IN_KMH = 10.0 ..< 20.0
9let GREATER_SPEED_RANGE_IN_KMH = 20.0 ..< 40.0
10let BIG_SPEED_RANGE_IN_KMH = 40.0 ..< 70.0
11let HUGE_SPEED_RANGE_IN_KMH = 70.0 ..< 120.0
1#define ZOOM_CHANGE_ANIMATION_MILLIS 300
2#define SMALL_SPEED_ZOOM_LEVEL 19.0
3#define MEDIUM_SPEED_ZOOM_LEVEL 18.0
4#define GREATER_SPEED_ZOOM_LEVEL 17.0
5#define BIG_SPEED_ZOOM_LEVEL 16.0
6#define HUGE_SPEED_ZOOM_LEVEL 14.0
7#define SMALL_SPEED_RANGE_END_IN_KMH 10.0
8#define MEDIUM_SPEED_RANGE_END_IN_KMH 20.0
9#define GREATER_SPEED_RANGE_END_IN_KMH 40.0
10#define BIG_SPEED_RANGE_END_IN_KMH 70.0
11#define HUGE_SPEED_RANGE_END_IN_KMH 120.0

Screen shots presenting how the programmatic zooming functionality works:

image

Zooming route

Api Reference

API reference for Driving (APIDocDriving_2.4.714.zip)

Progress along the route

Allow your users to visually distinguish the part of the route that has already been traveled. When a new location is set, the specified route style layer is drawn up to the desired location.

Sample use case: You want to show your user the part of the route that has already been traveled.

Use the following code snippet to create your route progress style:

let style = TTMapRouteStyleLayerBuilder().withColor(UIColor(red: 255 / 255, green: 153 / 255, blue: 0, alpha: 1.0)).build()

Use the following code snippet to activate showing the route progress layer on top of a route:

routeManager.activateProgress(alongTheRoute: route, withStyling: style)

Use the following code snippet to update the already traveled part of the route:

self.routeManager.updateProgress(alongTheRoute: self.mapRoute, with: location)

Screen shots presenting how progress along the route works: