In this page

Custom destination marker

Enhance the visual representation of destination markers and provide users with real-time ETA information.

This example shows:

  1. How to Custom destination marker

  2. How to show route ETA on top of route line on map

For all code examples, refer to Navigation Code Examples

CustomDestinationMarkerController view source

1import UIKit
2import NbmapNavigation
3import NbmapCoreNavigation
4import NbmapDirections
5import Nbmap
6
7class CustomDestinationMarkerController: UIViewController {
8  
9   var mapView: NavigationMapView? {
10       didSet {
11           oldValue?.removeFromSuperview()
12           if let mapView = mapView {
13               view.insertSubview(mapView, at: 0)
14           }
15       }
16   }
17  
18   var routes : [Route]?
19  
20   override func viewDidLoad() {
21       super.viewDidLoad()
22      
23       self.mapView = NavigationMapView(frame: view.bounds)
24      
25       mapView?.userTrackingMode = .followWithHeading
26      
27       let singleTap = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress(tap:)))
28       mapView?.gestureRecognizers?.filter({ $0 is UILongPressGestureRecognizer }).forEach(singleTap.require(toFail:))
29       mapView?.addGestureRecognizer(singleTap)
30       mapView?.delegate = self
31      
32   }
33  
34   @objc func didLongPress(tap: UILongPressGestureRecognizer) {
35       guard let mapView = mapView, tap.state == .began else {
36           return
37       }
38       let coordinates = mapView.convert(tap.location(in: mapView), toCoordinateFrom: mapView)
39       // Note: The destination name can be modified. The value is used in the top banner when arriving at a destination.
40       let destination = Waypoint(coordinate: coordinates, name: "\(coordinates.latitude),\(coordinates.longitude)")
41       addNewDestinationcon(coordinates: coordinates)
42      
43       guard let currentLocation =  mapView.userLocation?.coordinate else { return}
44       let currentWayPoint = Waypoint.init(coordinate: currentLocation, name: "My Location")
45      
46       requestRoutes(origin: currentWayPoint, destination: destination)
47   }
48  
49   @IBAction func startNavigation(_ sender: Any) {
50       guard let routes = self.routes else {
51           return
52       }
53       let navigationService = NBNavigationService(routes: routes, routeIndex: 0)
54      
55       let navigationOptions = NavigationOptions(navigationService: navigationService)
56      
57       let navigationViewController = NavigationViewController(for: routes,navigationOptions: navigationOptions)
58       navigationViewController.modalPresentationStyle = .fullScreen
59      
60       navigationViewController.delegate = self
61      
62       present(navigationViewController, animated: true, completion: nil)
63      
64   }
65  
66   func addNewDestinationcon(coordinates: CLLocationCoordinate2D){
67       guard let mapView = mapView else {
68           return
69       }
70      
71       if let annotation = mapView.annotations?.last {
72           mapView.removeAnnotation(annotation)
73       }
74      
75       let annotation = NGLPointAnnotation()
76       annotation.coordinate = coordinates
77       mapView.addAnnotation(annotation)
78   }
79  
80   func requestRoutes(origin: Waypoint, destination: Waypoint){
81      
82       let options = RouteOptions.init(origin: origin, destination: destination)
83       // Includes alternative routes in the response
84       options.includesAlternativeRoutes = true
85      
86       // Set the measurement format system
87       options.distanceMeasurementSystem = MeasurementSystem.metric
88      
89       Directions.shared.calculate(options) { [weak self] routes, error in
90           guard let weakSelf = self else {
91               return
92           }
93           guard error == nil else {
94               print(error!)
95               return
96           }
97          
98           guard let routes = routes else { return }
99          
100          
101           // Process or display routes information.For example,display the routes,waypoints and duration symbol on the map
102           weakSelf.mapView?.showRoutes(routes)
103           weakSelf.mapView?.showRouteDurationSymbol(routes)
104          
105           guard let current = routes.first else { return }
106           weakSelf.mapView?.showWaypoints(current)
107           weakSelf.routes = routes
108       }
109   }
110  
111}
112
113extension CustomDestinationMarkerController : NGLMapViewDelegate {
114  
115   func mapView(_ mapView: NGLMapView, imageFor annotation: NGLAnnotation) -> NGLAnnotationImage? {
116       let image = UIImage(named: "marker", in: .main, compatibleWith: nil)!.withRenderingMode(.alwaysOriginal)
117       return NGLAnnotationImage(image: image, reuseIdentifier: "destination_icon_identifier")
118   }
119}
120
121extension CustomDestinationMarkerController : NavigationViewControllerDelegate {
122  
123   func navigationViewController(_ navigationViewController: NavigationViewController, imageFor annotation: NGLAnnotation) -> NGLAnnotationImage? {
124       let image = UIImage(named: "marker", in: .main, compatibleWith: nil)!.withRenderingMode(.alwaysOriginal)
125       return NGLAnnotationImage(image: image, reuseIdentifier: "destination_icon_identifier")
126   }
127}
128

The class CustomDestinationMarkerController is a view controller that allows users to add a custom destination marker to a map. The class has the following properties:

  1. mapView: A NavigationMapView object that displays the map.

  2. routes: An array of Route objects that represent the routes between the user's current location and the custom destination marker.

The class has the following methods:

  1. viewDidLoad(): This method is called when the view controller is loaded. In this method, the map view is created and configured.

  2. didLongPress(): This method is called when the user long-presses on the map. In this method, a custom destination marker is added to the map at the location of the long press.

  3. startNavigation(): This method is called when the user taps the "Start Navigation" button. In this method, a navigation controller is created and presented to the user. The navigation controller uses the routes property to display the route between the user's current location and the custom destination marker.

  4. addNewDestinationcon(): This method adds a new destination annotation to the map.

  5. requestRoutes(): This method requests routes between the user's current location and the custom destination marker.

  6. mapView(_:imageFor:): This method is called by the map view to get an image for an annotation. In this method, a custom image is returned for the destination annotation.

  7. navigationViewController(_:imageFor:): This method is called by the navigation controller to get an image for an annotation. In this method, a custom image is returned for the destination annotation.

The code also has two extensions:

  1. CustomDestinationMarkerController: NGLMapViewDelegate

  2. CustomDestinationMarkerController: NavigationViewControllerDelegate

These extensions conform the CustomDestinationMarkerController class to the NGLMapViewDelegate and NavigationViewControllerDelegate protocols. These protocols allow the CustomDestinationMarkerController class to respond to events from the map view and the navigation controller.

DIDN'T FIND WHAT YOU LOOKING FOR?