Routes

A route is a sequence of coordinates on the map. It represents the path the user must follow to get from point A to point B. The route may contain intermediate via points.

But the route contains more information than just the directions. For example, there are road warnings, the distance, and the estimated arrival time.

In MapKit SDK, the route is represented by the MMKDrivingRoute class. Here are its main functions.

Metadata

MMKDrivingRouteMetadata contains the route description, parameters, characteristics, distance, and estimated arrival time.

To get the metadata, use the MMKDrivingRoute.metadata method.

Route URI

URI is the route's string ID.

To get the route URI, use the MMKDrivingRouteMetadata.uri method.

Position

The route may contain information about the current user position. It shows how much of the route has been completed during guidance.

To get the current position, use the MMKDrivingRoute.position method.

Warnings and events

Road events provide information about traffic events along the route. To get information about road events along the route, use the MMKDrivingRoute.events method.

Route warnings contain information about objects along the route. The objects include traffic lights (MMKDrivingRoute.trafficLights), railway crossings (MMKDrivingRoute.railwayCrossings), and speed bumps (MMKDrivingRoute.speedBumps). Learn more in the MMKDrivingRoute API.

Traffic jams on the route

Using the MMKDrivingRoute.jamSegments you can get information about traffic congestion on the route. This method returns a list of MMKJamSegment objects. Each element of the list describes the state of congestion of the road and the average speed of movement along it on the corresponding segment of the route. The segment with the number N corresponds to the section of the route that is located between N and N + 1 points of the route geometry, which can be obtained by calling MMKDrivingRoute.geometry.

Subscribe to updates

Some route data may change during the route life cycle. With MapKit SDK, you can track route data changes using the MMKDrivingConditionsListener interface.

Calculation of progress along the route

The progress along the route is the fraction of the original route that was completed.

Below is a code snippet for calculating this value:

func routeProgress(route: MMKDrivingRoute) -> Double {
    let startPosition = MMKPolylinePosition(segmentIndex: .zero, segmentPosition: .zero)
    let distanceFull = route.metadataAt(with: startPosition).weight.distance.value
    let distanceLeft = route.metadata.weight.distance.value
    return 1.0 - distanceLeft / distanceFull
}

To calculate the proportion of the route traveled, you need to calculate the total and the distance traveled of the route, and then divide one value by another.

Distance between route points

To calculate the distance between any two route points, use the MMKPolylineUtils methods. Follow these steps:

  1. Create a MMKPolylineIndex object that's linked to your route using MMKPolylineUtils.createPolylineIndex(with:).

  2. Use the MMKPolylineIndex.closestPolylinePosition(with:priority:maxLocationBias:) method to get the route points MMKPolylinePosition.

  3. Calculate the distance between two route points using MMKPolylineUtils.distanceBetweenPolylinePositions(with:from:to:).

Here's an example of how to calculate the distance between two arbitrary route points:

func distanceBetweenPointsOnRoute(route: MMKDrivingRoute, first: MMKPoint, second: MMKPoint) -> Double {
    let polylineIndex = MMKPolylineUtils.createPolylineIndex(with: route.geometry)
    let firstPosition = polylineIndex.closestPolylinePosition(
        with: first,
        priority: .closestToRawPoint,
        maxLocationBias: 1.0
    )!
    let secondPosition = polylineIndex.closestPolylinePosition(
        with: second,
        priority: .closestToRawPoint,
        maxLocationBias: 1.0
    )!
    return Double(
        MMKPolylineUtils.distanceBetweenPolylinePositions(
            with: route.geometry,
            from: firstPosition,
            to: secondPosition
        )
    )
}

Time between route points

Let's look at the algorithm for calculating the travel time from the current route point to an arbitrary later route point.

  1. We need to calculate the distance between the current and next route points. To do so, we can use the algorithm from the previous step.

  2. Using the MMKRoutePosition.advance(withDistance:) method, calculate MMKRoutePosition for the second point.

  3. Using the MMKRoutePosition.timeToFinish() method, find the travel time difference between the current and next points.

Here's an example of how to calculate the travel time from the current route point to another arbitrary route point:

func timeTravelToPoint(route: MMKDrivingRoute, point: MMKPoint) -> Double {
    let currentPosition = route.routePosition
    let distance = distanceBetweenPointsOnRoute(
        route: route,
        first: currentPosition.point,
        second: point
    )
    let targetPosition = currentPosition.advance(withDistance: distance)
    return targetPosition.timeToFinish() - currentPosition.timeToFinish()
}

To calculate the travel time between any two route points, use the difference between the results of calculating their timeTravelToPoint.