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

documentation image

For all code examples, refer to Navigation Code Examples

CustomDestinationMarkerController view source

1
import UIKit
2
import NbmapNavigation
3
import NbmapCoreNavigation
4
import NbmapDirections
5
import Nbmap
6
7
class 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
113
extension 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
121
extension 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.

© 2024 NextBillion.ai all rights reserved.