In this page

Custom navigation camera

这篇文档目前尚未提供译文,将以原文展示。

Optimize navigation experience by adjusting MapView camera based on requested route, ensuring clear visibility and focus on route.

This example shows:

  1. How to fit the mapview camera according to the requested route info

For all code examples, refer to Navigation Code Examples

CustomCameraController view source

1import UIKit
2import NbmapNavigation
3import NbmapCoreNavigation
4import NbmapDirections
5import Nbmap
6
7class CustomCameraController: UIViewController, NGLMapViewDelegate, NavigationViewControllerDelegate {
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       didSet {
20           guard let routes = routes,
21                 let current = routes.first
22           else {
23               mapView?.removeRoutes()
24               mapView?.removeRouteDurationSymbol()
25               if let annotation = mapView?.annotations?.last {
26                   mapView?.removeAnnotation(annotation)
27               }
28               return
29              
30           }
31          
32           mapView?.showRoutes(routes)
33           mapView?.showWaypoints(current)
34           mapView?.showRouteDurationSymbol(routes)
35          
36           fitCameraWithRoutes(routes: routes)
37       }
38   }
39  
40   var startButton = UIButton()
41  
42   var trackingImage = UIImageView()
43  
44   override func viewDidLoad() {
45       super.viewDidLoad()
46      
47       self.mapView = NavigationMapView(frame: view.bounds)
48      
49       mapView?.userTrackingMode = .followWithHeading
50      
51       let singleTap = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress(tap:)))
52       mapView?.gestureRecognizers?.filter({ $0 is UILongPressGestureRecognizer }).forEach(singleTap.require(toFail:))
53       mapView?.addGestureRecognizer(singleTap)
54       mapView?.delegate = self
55      
56       setupStartButton()
57       setupLocationTrackingButton()
58   }
59  
60   func setupStartButton() {
61       startButton.setTitle("Start", for: .normal)
62       startButton.layer.cornerRadius = 5
63       startButton.contentEdgeInsets = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
64       startButton.backgroundColor = .blue
65      
66       startButton.addTarget(self, action: #selector(tappedButton), for: .touchUpInside)
67       view.addSubview(startButton)
68       startButton.translatesAutoresizingMaskIntoConstraints = false
69       startButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -50).isActive = true
70       startButton.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
71       startButton.titleLabel?.font = UIFont.systemFont(ofSize: 25)
72   }
73  
74   func setupLocationTrackingButton(){
75       trackingImage.isUserInteractionEnabled = true
76       trackingImage.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(trackingClick)))
77       trackingImage.image = UIImage(named: "my_location")
78       view.addSubview(trackingImage)
79       startButton.translatesAutoresizingMaskIntoConstraints = false
80       startButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -50).isActive = true
81       startButton.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor,constant: 16).isActive = true
82   }
83  
84   @objc func didLongPress(tap: UILongPressGestureRecognizer) {
85       guard let mapView = mapView, tap.state == .began else {
86           return
87       }
88       let coordinates = mapView.convert(tap.location(in: mapView), toCoordinateFrom: mapView)
89       let destination = Waypoint(coordinate: coordinates, name: "\(coordinates.latitude),\(coordinates.longitude)")
90      
91       guard let currentLocation =  mapView.userLocation?.coordinate else { return}
92       let currentWayPoint = Waypoint.init(coordinate: currentLocation, name: "My Location")
93      
94       requestRoutes(origin: currentWayPoint, destination: destination)
95   }
96  
97  
98   @objc func tappedButton(sender: UIButton) {
99       guard let routes = self.routes else {
100           return
101       }
102       var engineConfig = NavigationEngineConfig()
103       // Config mininum and maxnum camera zoom
104       engineConfig.minNavigationCameraZoom = 16
105       engineConfig.maxNavigationCameraZoom = 18
106       let navigationService = NBNavigationService(routes: routes, routeIndex: 0,navigationEngConfig: engineConfig)
107      
108       let navigationOptions = NavigationOptions(navigationService: navigationService)
109       let navigationViewController = NavigationViewController(for: routes,navigationOptions: navigationOptions)
110       navigationViewController.modalPresentationStyle = .fullScreen
111      
112       navigationViewController.delegate = self
113      
114       // Start navigation
115       present(navigationViewController, animated: true, completion: nil)
116   }
117  
118   @objc func trackingClick() {
119       guard let location = mapView?.userLocation else {
120           return
121       }
122       guard let newCamera = mapView?.camera else {
123           return
124       }
125       newCamera.centerCoordinate = location.coordinate
126       newCamera.viewingDistance = 1000
127       mapView?.setCamera(newCamera, animated: true)
128   }
129  
130   func fitCameraWithRoutes(routes: [Route]) {
131       guard let mapView = mapView else {
132           return
133       }
134      
135       var coordinates: [CLLocationCoordinate2D] = []
136       routes.forEach({route in
137           coordinates.append(contentsOf: route.coordinates!)
138       })
139       let polyLine = NGLPolyline(coordinates: coordinates, count: UInt(coordinates.count))
140       let camera = mapView.cameraThatFitsShape(polyLine, direction: mapView.camera.heading, edgePadding: UIEdgeInsets(top: view.safeAreaInsets.top, left: view.safeAreaInsets.left, bottom: view.safeAreaInsets.bottom, right: view.safeAreaInsets.right))
141       mapView.setCamera(camera, animated: true)
142   }
143  
144   func requestRoutes(origin: Waypoint, destination: Waypoint){
145       let options = NavigationRouteOptions(origin: origin, destination: destination)
146      
147       Directions.shared.calculate(options) { [weak self] routes, error in
148           guard let weakSelf = self else {
149               return
150           }
151           guard error == nil else {
152               print(error!)
153               return
154           }
155          
156           guard let routes = routes else { return }
157           weakSelf.routes = routes
158       }
159   }  
160}

This class is a view controller that allows users to add a custom destination marker to a map and then navigate to that destination. 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.

  3. startButton: A UIButton object that is used to start navigation.

  4. trackingImage: A UIImageView object that is used to show the current location of the user.

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. tappedButton(): 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. trackingClick(): This method is called when the user taps the "My Location" button. In this method, the map view is centered on the user's current location.

  5. fitCameraWithRoutes(): This method fits the camera to the routes on the map.

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

The code you provided also has two extensions:

  1. CustomCameraController: NGLMapViewDelegate

  2. CustomCameraController: NavigationViewControllerDelegate

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

ios-sdk-7
没找到你要找的内容?