Custom destination marker
Enhance the visual representation of destination markers and provide users with real-time ETA information.
This example shows:
-
How to Custom destination marker
-
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:
-
mapView: A NavigationMapView object that displays the map.
-
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:
-
viewDidLoad(): This method is called when the view controller is loaded. In this method, the map view is created and configured.
-
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.
-
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.
-
addNewDestinationcon(): This method adds a new destination annotation to the map.
-
requestRoutes(): This method requests routes between the user's current location and the custom destination marker.
-
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.
-
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:
-
CustomDestinationMarkerController: NGLMapViewDelegate
-
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.