iOS Native - Navigation information
Navigation information
The NavigationInfo
struct contains all information about the user's progress along the itinerary, including the current leg and step information. This object allows you to get distance and time measurements, previous and next steps, and more.
The NavigationInfoHandler
helps to get updated information about the user’s progress along the itinerary on request by providing an updated NavigationInfo
struct.
Navigation information is calculated according to CoreConstants.userLocationProjectionOnItineraryEnabled
constant.
If this constant is enabled, the origin and user projection distances will not be included in the total navigation distance, since these parts are not visible to the user.
If this constant is disabled, the origin and user projection distance will be included in the total navigation distance, since these parts are visible to the user. Thus, in this case, the total itinerary distance is not equal to the distance traveled + distance remaining.
Below are code samples showing how to get NavigationInfo
using only WemapCoreSDK
or WemapMapSDK
.
WemapCoreSDK
import RxCocoa
import RxSwift
import UIKit
import WemapCoreSDK
class ViewController: UIViewController {
private let disposeBag = DisposeBag()
private let service = ServiceFactory.getItineraryService()
private let infoHandler = ManagerFactory.getNavigationInfoHandler()
private var itinerary: Itinerary?
override func viewDidLoad() {
super.viewDidLoad()
computeItineraries()
}
private func computeItineraries() {
let origin = Coordinate(latitude: 43.610628, longitude: 3.876654)
let destination = Coordinate(latitude: 43.609011, longitude: 3.917091)
let parameters = ItineraryParameters(origin: origin, destination: destination, travelMode: .bike(preference: .safest))
service
.itineraries(parameters: parameters)
.subscribe(
onSuccess: { [unowned self] response in
debugPrint("response - \(response)")
setItinerary(response.itineraries.first!)
}, onFailure: {
debugPrint("error - \($0)")
}
)
.disposed(by: disposeBag)
}
private func setItinerary(_ itinerary: Itinerary) {
self.itinerary = itinerary
infoHandler.itinerary = itinerary
// request for an update of the navigation information with a certain time interval
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5)) { [unowned self] in
getNavigationInfo(.init(latitude: 43.610107, longitude: 3.891805))
}
}
private func getNavigationInfo(_ userPosition: Coordinate) {
let info = infoHandler.getNavigationInfo(userPosition: userPosition)
debugPrint("navigation info - \(String(describing: info))")
}
}
WemapMapSDK
In WemapMapSDK
this logic is controlled by MapNavigationManaging
protocol, which you can access directly from the map using mapView.navigationManager
as shown below.
NavigationManager
observes the user’s progress along the itinerary and constantly calls NavigationManagerDelegate.navigationManager(_: NavigationManager, didUpdateNavigationInfo info: NavigationInfo)
method with the updated NavigationInfo
struct.
You can set NavigationInfo
update time interval using mapView.navigationManager.infoUpdatesTimeInterval = .seconds(2)
.
import MapLibre
import RxSwift
import UIKit
import WemapCoreSDK
import WemapMapSDK
class NavigationInfoViewController: UIViewController {
private var mapView: MapView!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
WemapMap.shared
.getMapData(mapID: 19158, token: "GUHTU6TYAWWQHUSR5Z5JZNMXX")
.subscribe(onSuccess: { [self] mapData in
mapView = MapView(frame: view.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.mapDelegate = self
mapView.mapData = mapData
view.addSubview(mapView)
}, onFailure: {
debugPrint("Failed to get map data with error - \($0)")
})
.disposed(by: disposeBag)
}
private func startNavigation() {
let origin = Coordinate(latitude: 43.610628, longitude: 3.876654)
let destination = Coordinate(latitude: 43.609011, longitude: 3.917091)
mapView.navigationManager
.startNavigation(origin: origin, destination: destination)
.subscribe(
onSuccess: { _ in
debugPrint("Successfully started navigation from: \(origin) to: \(destination)")
},
onFailure: { error in
debugPrint("Failed to start navigation from \(origin) to: \(destination) with error: \(error)")
}
).disposed(by: disposeBag)
}
}
extension NavigationInfoViewController: MapViewDelegate {
func mapViewLoaded(_ mapView: MapView, style _: MLNStyle, data _: MapData) {
mapView.navigationManager.delegate = self
mapView.navigationManager.infoUpdatesTimeInterval = .seconds(2) // default is .seconds(1)
mapView.userTrackingMode = .follow
startNavigation()
}
}
extension NavigationInfoViewController: NavigationManagerDelegate {
func navigationManager(_: NavigationManager, didUpdateNavigationInfo info: NavigationInfo) {
debugPrint("Navigation info updated - \(info)")
}
}
Examples
You can find additional examples for the WemapSDKs on GitHub. Clone the repository and run the example application following the instructions in the README.