Custom Location Source
Customize the location data source for NavigationMapView
and Navigation
. Obtain location data from user tap actions on the map.
This example shows how to customize your location data source for NavigationMapView
and Navigation
-
Custom your location data source for
NavigationMapView
, the location data value is from the user tap action on the map -
Custom your location data source for
Navigation
![documentation image](https://static.nextbillion.io/docs-next/docs/navigation/ios/custom-location-source.webp)
For all code examples, refer to Navigation Code Examples
CustomLocationSourceViewController view source
1import UIKit2import NbmapNavigation3import NbmapCoreNavigation4import NbmapDirections5import Nbmap67class CustomLocationSourceViewController: UIViewController, NGLMapViewDelegate {89var navigationMapView: NavigationMapView? {10didSet {11oldValue?.removeFromSuperview()12if let navigationMapView = navigationMapView {13view.insertSubview(navigationMapView, at: 0)14}15}16}1718var routes : [Route]? {19didSet {20guard routes != nil else{21startButton.isEnabled = false22return23}24startButton.isEnabled = true25}26}2728var currentRouteIndex = 02930var startButton = UIButton()3132override func viewDidLoad() {33super.viewDidLoad()3435navigationMapView = NavigationMapView(frame: view.bounds)3637navigationMapView?.locationManager = CustomMapLocationManager()3839navigationMapView?.userTrackingMode = .followWithHeading4041let singleTap = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress(tap:)))42navigationMapView?.gestureRecognizers?.filter({ $0 is UILongPressGestureRecognizer }).forEach(singleTap.require(toFail:))43navigationMapView?.addGestureRecognizer(singleTap)4445setupStartButton()4647self.view.setNeedsLayout()4849}5051func setupStartButton() {52startButton.setTitle("Start", for: .normal)53startButton.layer.cornerRadius = 554startButton.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)55startButton.backgroundColor = .blue5657startButton.addTarget(self, action: #selector(tappedButton), for: .touchUpInside)58view.addSubview(startButton)59startButton.translatesAutoresizingMaskIntoConstraints = false60startButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -50).isActive = true61startButton.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true62startButton.titleLabel?.font = UIFont.systemFont(ofSize: 25)63}6465@objc func tappedButton(sender: UIButton) {66guard let routes = self.routes else {67return68}69let navigationService = NBNavigationService(routes: routes, routeIndex: currentRouteIndex,locationSource: CustomNavigationLocationManager())70let navigationOptions = NavigationOptions(navigationService: navigationService)7172let navigationViewController = NavigationViewController(for: routes,navigationOptions: navigationOptions)73navigationViewController.modalPresentationStyle = .fullScreen7475present(navigationViewController, animated: true, completion: nil)76}7778@objc func didLongPress(tap: UILongPressGestureRecognizer) {79guard let navigationMapView = navigationMapView, tap.state == .began else {80return81}82let coordinates = navigationMapView.convert(tap.location(in: navigationMapView), toCoordinateFrom: navigationMapView)83// Note: The destination name can be modified. The value is used in the top banner when arriving at a destination.84let destination = Waypoint(coordinate: coordinates, name: "\(coordinates.latitude),\(coordinates.longitude)")85addNewDestinationcon(coordinates: coordinates)8687guard let currentLocation = navigationMapView.userLocation?.coordinate else { return}88let currentWayPoint = Waypoint.init(coordinate: currentLocation, name: "My Location")8990requestRoutes(origin: currentWayPoint, destination: destination)91}929394func addNewDestinationcon(coordinates: CLLocationCoordinate2D){95guard let mapView = navigationMapView else {96return97}9899if let annotation = mapView.annotations?.last {100mapView.removeAnnotation(annotation)101}102103let annotation = NGLPointAnnotation()104annotation.coordinate = coordinates105mapView.addAnnotation(annotation)106}107108func requestRoutes(origin: Waypoint, destination: Waypoint){109110let options = NavigationRouteOptions(origin: origin, destination: destination)111112Directions.shared.calculate(options) { [weak self] routes, error in113guard let weakSelf = self else {114return115}116guard error == nil else {117print(error!)118return119}120121guard let routes = routes else { return }122123124// Process or display routes information.For example,display the routes,waypoints and duration symbol on the map125weakSelf.navigationMapView?.showRoutes(routes)126weakSelf.navigationMapView?.showRouteDurationSymbol(routes)127128guard let current = routes.first else { return }129weakSelf.navigationMapView?.showWaypoints(current)130weakSelf.routes = routes131}132}133}134135136CustomMapViewLocationManager View source137import Nbmap138import CoreLocation139class CustomMapViewLocationManager: NSObject,NGLLocationManager {140141var delegate: NGLLocationManagerDelegate? {142didSet {143locationManager.delegate = self144}145}146147// Replace with your own location manager148private let locationManager = CLLocationManager()149150var headingOrientation: CLDeviceOrientation {151get {152return locationManager.headingOrientation153}154set {155locationManager.headingOrientation = newValue156}157}158159var desiredAccuracy: CLLocationAccuracy {160get {161return locationManager.desiredAccuracy162}163set {164locationManager.desiredAccuracy = newValue165}166}167168var authorizationStatus: CLAuthorizationStatus {169if #available(iOS 14.0, *) {170return locationManager.authorizationStatus171} else {172return CLLocationManager.authorizationStatus()173}174}175176var activityType: CLActivityType {177get {178return locationManager.activityType179}180set {181locationManager.activityType = newValue182}183}184185@available(iOS 14.0, *)186var accuracyAuthorization: CLAccuracyAuthorization {187return locationManager.accuracyAuthorization188}189190@available(iOS 14.0, *)191func requestTemporaryFullAccuracyAuthorization(withPurposeKey purposeKey: String) {192locationManager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: purposeKey)193}194195func dismissHeadingCalibrationDisplay() {196locationManager.dismissHeadingCalibrationDisplay()197}198199func requestAlwaysAuthorization() {200locationManager.requestAlwaysAuthorization()201}202203func requestWhenInUseAuthorization() {204locationManager.requestWhenInUseAuthorization()205}206207func startUpdatingHeading() {208locationManager.startUpdatingHeading()209}210211func startUpdatingLocation() {212locationManager.startUpdatingLocation()213}214215func stopUpdatingHeading() {216locationManager.stopUpdatingHeading()217}218219func stopUpdatingLocation() {220locationManager.stopUpdatingLocation()221}222223deinit {224locationManager.stopUpdatingLocation()225locationManager.stopUpdatingHeading()226locationManager.delegate = nil227delegate = nil228}229230}231// MARK: - CLLocationManagerDelegate , Please replace with your location data source delegate232extension CustomMapLocationManager : CLLocationManagerDelegate {233234func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {235delegate?.locationManager(self, didUpdate: locations)236}237238func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {239delegate?.locationManager(self, didUpdate: newHeading)240}241242func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool {243return delegate?.locationManagerShouldDisplayHeadingCalibration(self) ?? false244}245246func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {247delegate?.locationManager(self, didFailWithError: error)248}249250@available(iOS 14.0, *)251func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {252delegate?.locationManagerDidChangeAuthorization(self)253}254}255256257CustomNavigationLocationManager view source258import NbmapCoreNavigation259import CoreLocation260class CustomNavigationLocationManager : NavigationLocationManager {261262override var delegate: CLLocationManagerDelegate? {263didSet {264locationManager.delegate = self265}266}267268// Replace with your own location manager269private let locationManager = CLLocationManager()270271override var headingOrientation: CLDeviceOrientation {272get {273return locationManager.headingOrientation274}275set {276locationManager.headingOrientation = newValue277}278}279280override var desiredAccuracy: CLLocationAccuracy {281get {282return locationManager.desiredAccuracy283}284set {285locationManager.desiredAccuracy = newValue286}287}288289override var authorizationStatus: CLAuthorizationStatus {290if #available(iOS 14.0, *) {291return locationManager.authorizationStatus292} else {293return CLLocationManager.authorizationStatus()294}295}296297override var activityType: CLActivityType {298get {299return locationManager.activityType300}301set {302locationManager.activityType = newValue303}304}305306@available(iOS 14.0, *)307override var accuracyAuthorization: CLAccuracyAuthorization {308return locationManager.accuracyAuthorization309}310311@available(iOS 14.0, *)312override func requestTemporaryFullAccuracyAuthorization(withPurposeKey purposeKey: String) {313locationManager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: purposeKey)314}315316override func dismissHeadingCalibrationDisplay() {317locationManager.dismissHeadingCalibrationDisplay()318}319320override func requestAlwaysAuthorization() {321locationManager.requestAlwaysAuthorization()322}323324override func requestWhenInUseAuthorization() {325locationManager.requestWhenInUseAuthorization()326}327328override func startUpdatingHeading() {329locationManager.startUpdatingHeading()330}331332override func startUpdatingLocation() {333locationManager.startUpdatingLocation()334}335336override func stopUpdatingHeading() {337locationManager.stopUpdatingHeading()338}339340override func stopUpdatingLocation() {341locationManager.stopUpdatingLocation()342}343344deinit {345locationManager.stopUpdatingLocation()346locationManager.stopUpdatingHeading()347locationManager.delegate = nil348delegate = nil349}350351}352// MARK: - CLLocationManagerDelegate353extension CustomNavigationLocationManager : CLLocationManagerDelegate {354355func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {356delegate?.locationManager!(self, didUpdateLocations: locations)357}358359func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {360delegate?.locationManager!(self, didUpdateHeading: newHeading)361}362363func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool {364return delegate?.locationManagerShouldDisplayHeadingCalibration!(self) ?? false365}366367func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {368delegate?.locationManager!(self, didFailWithError: error)369}370371@available(iOS 14.0, *)372func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {373delegate?.locationManagerDidChangeAuthorization!(self)374}375}376