Navigation information
Track the user's progress along an itinerary.
Overview
WemapCoreSDK/NavigationInfo contains everything about the user's progress along an itinerary — current leg and
step, distances and times, previous/next steps, and more. WemapCoreSDK/NavigationInfoHandler produces an
updated WemapCoreSDK/NavigationInfo on request.
Navigation information depends on WemapCoreSDK/SessionConfig/userLocationProjectionOnItineraryEnabled:
- Enabled — the origin and user-projection distances are not included in the total, since those parts aren't visible to the user.
- Disabled — they are included (so the total itinerary distance won't equal distance-travelled + distance-remaining).
WemapCoreSDK
Compute an itinerary with session.itineraryProvider, hand it to
session.navigationInfoHandler, then request info for a user position. WemapCoreSDK/NavigationInfoHandler
holds its itinerary weakly, so keep a strong reference to the itinerary you assign:
final class ViewController: UIViewController {
private var session: CoreSession!
private var itinerary: Itinerary? // retained; the handler holds it weakly
private func computeItinerary() async throws {
let origin = Coordinate(coordinate2D: .init(latitude: 43.610628, longitude: 3.876654))
let destination = Coordinate(coordinate2D: .init(latitude: 43.609011, longitude: 3.917091))
let itineraries = try await session.itineraryProvider.itineraries(
origin: origin, destination: destination, travelMode: .bike(preference: .safest)
)
setItinerary(itineraries.first!)
}
private func setItinerary(_ itinerary: Itinerary) {
self.itinerary = itinerary
session.navigationInfoHandler.itinerary = itinerary
let userPosition = Coordinate(coordinate2D: .init(latitude: 43.610107, longitude: 3.891805))
let info = session.navigationInfoHandler.getNavigationInfo(userPosition: userPosition)
print("navigation info: \(String(describing: info))")
}
}
WemapMapSDK
WemapMapSDK/MapNavigationManaging (via mapView.navigationManager) observes the user's progress and emits an
updated WemapCoreSDK/NavigationInfo on its navigationInfoUpdates stream. Set the cadence with
navigationInfoUpdatesInterval:
final class NavigationInfoViewController: UIViewController {
private var mapView: MapView!
private var observationTasks: [Task<Void, Never>] = []
func setUp() async throws {
let session = try await MapSession(mapID: 19158, token: "YOUR_TOKEN")
mapView = MapView(frame: view.bounds, session: session)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(mapView)
_ = try await mapView.awaitLoaded()
observeNavigationInfo(mapView)
}
private func observeNavigationInfo(_ mapView: MapView) {
mapView.navigationManager.navigationInfoUpdatesInterval = .seconds(2) // default is .seconds(1)
mapView.userTrackingMode = .follow
let updates = mapView.navigationManager.navigationInfoUpdates
observationTasks = [
Task { [weak self] in
for await info in updates {
guard self != nil else {
return
}
print("Navigation info updated: \(info)")
}
}
]
Task { try await startNavigation() }
}
private func startNavigation() async throws {
let origin = Coordinate(coordinate2D: .init(latitude: 43.610628, longitude: 3.876654))
let destination = Coordinate(coordinate2D: .init(latitude: 43.609011, longitude: 3.917091))
_ = try await mapView.navigationManager.startNavigation(origin: origin, destination: destination)
}
}