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

For all code examples, refer to Navigation Code Examples

CustomLocationSourceViewController view source

1
import UIKit
2
import NbmapNavigation
3
import NbmapCoreNavigation
4
import NbmapDirections
5
import Nbmap
6
7
class CustomLocationSourceViewController: UIViewController, NGLMapViewDelegate {
8
9
var navigationMapView: NavigationMapView? {
10
didSet {
11
oldValue?.removeFromSuperview()
12
if let navigationMapView = navigationMapView {
13
view.insertSubview(navigationMapView, at: 0)
14
}
15
}
16
}
17
18
var routes : [Route]? {
19
didSet {
20
guard routes != nil else{
21
startButton.isEnabled = false
22
return
23
}
24
startButton.isEnabled = true
25
}
26
}
27
28
var currentRouteIndex = 0
29
30
var startButton = UIButton()
31
32
override func viewDidLoad() {
33
super.viewDidLoad()
34
35
navigationMapView = NavigationMapView(frame: view.bounds)
36
37
navigationMapView?.locationManager = CustomMapLocationManager()
38
39
navigationMapView?.userTrackingMode = .followWithHeading
40
41
let singleTap = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress(tap:)))
42
navigationMapView?.gestureRecognizers?.filter({ $0 is UILongPressGestureRecognizer }).forEach(singleTap.require(toFail:))
43
navigationMapView?.addGestureRecognizer(singleTap)
44
45
setupStartButton()
46
47
self.view.setNeedsLayout()
48
49
}
50
51
func setupStartButton() {
52
startButton.setTitle("Start", for: .normal)
53
startButton.layer.cornerRadius = 5
54
startButton.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
55
startButton.backgroundColor = .blue
56
57
startButton.addTarget(self, action: #selector(tappedButton), for: .touchUpInside)
58
view.addSubview(startButton)
59
startButton.translatesAutoresizingMaskIntoConstraints = false
60
startButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -50).isActive = true
61
startButton.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
62
startButton.titleLabel?.font = UIFont.systemFont(ofSize: 25)
63
}
64
65
@objc func tappedButton(sender: UIButton) {
66
guard let routes = self.routes else {
67
return
68
}
69
let navigationService = NBNavigationService(routes: routes, routeIndex: currentRouteIndex,locationSource: CustomNavigationLocationManager())
70
let navigationOptions = NavigationOptions(navigationService: navigationService)
71
72
let navigationViewController = NavigationViewController(for: routes,navigationOptions: navigationOptions)
73
navigationViewController.modalPresentationStyle = .fullScreen
74
75
present(navigationViewController, animated: true, completion: nil)
76
}
77
78
@objc func didLongPress(tap: UILongPressGestureRecognizer) {
79
guard let navigationMapView = navigationMapView, tap.state == .began else {
80
return
81
}
82
let 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.
84
let destination = Waypoint(coordinate: coordinates, name: "\(coordinates.latitude),\(coordinates.longitude)")
85
addNewDestinationcon(coordinates: coordinates)
86
87
guard let currentLocation = navigationMapView.userLocation?.coordinate else { return}
88
let currentWayPoint = Waypoint.init(coordinate: currentLocation, name: "My Location")
89
90
requestRoutes(origin: currentWayPoint, destination: destination)
91
}
92
93
94
func addNewDestinationcon(coordinates: CLLocationCoordinate2D){
95
guard let mapView = navigationMapView else {
96
return
97
}
98
99
if let annotation = mapView.annotations?.last {
100
mapView.removeAnnotation(annotation)
101
}
102
103
let annotation = NGLPointAnnotation()
104
annotation.coordinate = coordinates
105
mapView.addAnnotation(annotation)
106
}
107
108
func requestRoutes(origin: Waypoint, destination: Waypoint){
109
110
let options = NavigationRouteOptions(origin: origin, destination: destination)
111
112
Directions.shared.calculate(options) { [weak self] routes, error in
113
guard let weakSelf = self else {
114
return
115
}
116
guard error == nil else {
117
print(error!)
118
return
119
}
120
121
guard let routes = routes else { return }
122
123
124
// Process or display routes information.For example,display the routes,waypoints and duration symbol on the map
125
weakSelf.navigationMapView?.showRoutes(routes)
126
weakSelf.navigationMapView?.showRouteDurationSymbol(routes)
127
128
guard let current = routes.first else { return }
129
weakSelf.navigationMapView?.showWaypoints(current)
130
weakSelf.routes = routes
131
}
132
}
133
}
134
135
136
CustomMapViewLocationManager View source
137
import Nbmap
138
import CoreLocation
139
class CustomMapViewLocationManager: NSObject,NGLLocationManager {
140
141
var delegate: NGLLocationManagerDelegate? {
142
didSet {
143
locationManager.delegate = self
144
}
145
}
146
147
// Replace with your own location manager
148
private let locationManager = CLLocationManager()
149
150
var headingOrientation: CLDeviceOrientation {
151
get {
152
return locationManager.headingOrientation
153
}
154
set {
155
locationManager.headingOrientation = newValue
156
}
157
}
158
159
var desiredAccuracy: CLLocationAccuracy {
160
get {
161
return locationManager.desiredAccuracy
162
}
163
set {
164
locationManager.desiredAccuracy = newValue
165
}
166
}
167
168
var authorizationStatus: CLAuthorizationStatus {
169
if #available(iOS 14.0, *) {
170
return locationManager.authorizationStatus
171
} else {
172
return CLLocationManager.authorizationStatus()
173
}
174
}
175
176
var activityType: CLActivityType {
177
get {
178
return locationManager.activityType
179
}
180
set {
181
locationManager.activityType = newValue
182
}
183
}
184
185
@available(iOS 14.0, *)
186
var accuracyAuthorization: CLAccuracyAuthorization {
187
return locationManager.accuracyAuthorization
188
}
189
190
@available(iOS 14.0, *)
191
func requestTemporaryFullAccuracyAuthorization(withPurposeKey purposeKey: String) {
192
locationManager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: purposeKey)
193
}
194
195
func dismissHeadingCalibrationDisplay() {
196
locationManager.dismissHeadingCalibrationDisplay()
197
}
198
199
func requestAlwaysAuthorization() {
200
locationManager.requestAlwaysAuthorization()
201
}
202
203
func requestWhenInUseAuthorization() {
204
locationManager.requestWhenInUseAuthorization()
205
}
206
207
func startUpdatingHeading() {
208
locationManager.startUpdatingHeading()
209
}
210
211
func startUpdatingLocation() {
212
locationManager.startUpdatingLocation()
213
}
214
215
func stopUpdatingHeading() {
216
locationManager.stopUpdatingHeading()
217
}
218
219
func stopUpdatingLocation() {
220
locationManager.stopUpdatingLocation()
221
}
222
223
deinit {
224
locationManager.stopUpdatingLocation()
225
locationManager.stopUpdatingHeading()
226
locationManager.delegate = nil
227
delegate = nil
228
}
229
230
}
231
// MARK: - CLLocationManagerDelegate , Please replace with your location data source delegate
232
extension CustomMapLocationManager : CLLocationManagerDelegate {
233
234
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
235
delegate?.locationManager(self, didUpdate: locations)
236
}
237
238
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
239
delegate?.locationManager(self, didUpdate: newHeading)
240
}
241
242
func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool {
243
return delegate?.locationManagerShouldDisplayHeadingCalibration(self) ?? false
244
}
245
246
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
247
delegate?.locationManager(self, didFailWithError: error)
248
}
249
250
@available(iOS 14.0, *)
251
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
252
delegate?.locationManagerDidChangeAuthorization(self)
253
}
254
}
255
256
257
CustomNavigationLocationManager view source
258
import NbmapCoreNavigation
259
import CoreLocation
260
class CustomNavigationLocationManager : NavigationLocationManager {
261
262
override var delegate: CLLocationManagerDelegate? {
263
didSet {
264
locationManager.delegate = self
265
}
266
}
267
268
// Replace with your own location manager
269
private let locationManager = CLLocationManager()
270
271
override var headingOrientation: CLDeviceOrientation {
272
get {
273
return locationManager.headingOrientation
274
}
275
set {
276
locationManager.headingOrientation = newValue
277
}
278
}
279
280
override var desiredAccuracy: CLLocationAccuracy {
281
get {
282
return locationManager.desiredAccuracy
283
}
284
set {
285
locationManager.desiredAccuracy = newValue
286
}
287
}
288
289
override var authorizationStatus: CLAuthorizationStatus {
290
if #available(iOS 14.0, *) {
291
return locationManager.authorizationStatus
292
} else {
293
return CLLocationManager.authorizationStatus()
294
}
295
}
296
297
override var activityType: CLActivityType {
298
get {
299
return locationManager.activityType
300
}
301
set {
302
locationManager.activityType = newValue
303
}
304
}
305
306
@available(iOS 14.0, *)
307
override var accuracyAuthorization: CLAccuracyAuthorization {
308
return locationManager.accuracyAuthorization
309
}
310
311
@available(iOS 14.0, *)
312
override func requestTemporaryFullAccuracyAuthorization(withPurposeKey purposeKey: String) {
313
locationManager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: purposeKey)
314
}
315
316
override func dismissHeadingCalibrationDisplay() {
317
locationManager.dismissHeadingCalibrationDisplay()
318
}
319
320
override func requestAlwaysAuthorization() {
321
locationManager.requestAlwaysAuthorization()
322
}
323
324
override func requestWhenInUseAuthorization() {
325
locationManager.requestWhenInUseAuthorization()
326
}
327
328
override func startUpdatingHeading() {
329
locationManager.startUpdatingHeading()
330
}
331
332
override func startUpdatingLocation() {
333
locationManager.startUpdatingLocation()
334
}
335
336
override func stopUpdatingHeading() {
337
locationManager.stopUpdatingHeading()
338
}
339
340
override func stopUpdatingLocation() {
341
locationManager.stopUpdatingLocation()
342
}
343
344
deinit {
345
locationManager.stopUpdatingLocation()
346
locationManager.stopUpdatingHeading()
347
locationManager.delegate = nil
348
delegate = nil
349
}
350
351
}
352
// MARK: - CLLocationManagerDelegate
353
extension CustomNavigationLocationManager : CLLocationManagerDelegate {
354
355
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
356
delegate?.locationManager!(self, didUpdateLocations: locations)
357
}
358
359
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
360
delegate?.locationManager!(self, didUpdateHeading: newHeading)
361
}
362
363
func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool {
364
return delegate?.locationManagerShouldDisplayHeadingCalibration!(self) ?? false
365
}
366
367
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
368
delegate?.locationManager!(self, didFailWithError: error)
369
}
370
371
@available(iOS 14.0, *)
372
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
373
delegate?.locationManagerDidChangeAuthorization!(self)
374
}
375
}
376

© 2024 NextBillion.ai all rights reserved.