Skip to content

Commit 97f962d

Browse files
authored
Update the mapSDK puck in NavigationMapView with location course for bearing (#3123)
1 parent e566afc commit 97f962d

File tree

6 files changed

+38
-76
lines changed

6 files changed

+38
-76
lines changed

Example/ViewController+FreeDrive.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ extension ViewController {
4343

4444
if let location = notification.userInfo?[PassiveLocationManager.NotificationUserInfoKey.locationKey] as? CLLocation {
4545
trackStyledFeature.lineString.coordinates.append(contentsOf: [location.coordinate])
46-
navigationMapView.moveUserLocation(to: location)
4746
}
4847

4948
if let rawLocation = notification.userInfo?[PassiveLocationManager.NotificationUserInfoKey.rawLocationKey] as? CLLocation {

Sources/MapboxNavigation/CarPlayManager.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ public class CarPlayManager: NSObject {
228228
let route = navigationService.route
229229
let routeOptions = navigationService.routeProgress.routeOptions
230230

231+
// Stop the background `PassiveLocationProvider` sending location and heading update `mapView` before turn-by-turn navigation session starts.
232+
navigationMapView?.mapView.location.locationProvider.stopUpdatingLocation()
233+
navigationMapView?.mapView.location.locationProvider.stopUpdatingHeading()
234+
231235
var trip = CPTrip(routes: [route], routeOptions: routeOptions, waypoints: routeOptions.waypoints)
232236
trip = delegate?.carPlayManager(self, willPreview: trip) ?? trip
233237

Sources/MapboxNavigation/NavigationMapView+VanishingRouteLine.swift

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ extension NavigationMapView {
151151
*/
152152
func updateTraveledRouteLine(_ coordinate: CLLocationCoordinate2D?) {
153153
guard let granularDistances = routeLineGranularDistances,let index = routeRemainingDistancesIndex, let location = coordinate else { return }
154+
guard index < granularDistances.distanceArray.endIndex else { return }
154155
let traveledIndex = granularDistances.distanceArray[index]
155156
let upcomingPoint = traveledIndex.point
156157

@@ -205,27 +206,8 @@ extension NavigationMapView {
205206

206207
let congestionSegments = routeProgress.route.congestionFeatures(legIndex: currentLegIndex, roadClassesWithOverriddenCongestionLevels: roadClassesWithOverriddenCongestionLevels)
207208

208-
switch userLocationStyle {
209-
210-
case .courseView:
211-
let startDate = Date()
212-
vanishingRouteLineUpdateTimer = Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true, block: { timer in
213-
let timePassedInMilliseconds = Date().timeIntervalSince(startDate) * 1000
214-
// In case if the time was already in the last interval - invalidate the timer and wait for the next routeProgress update.
215-
if timePassedInMilliseconds >= 980 {
216-
timer.invalidate()
217-
return
218-
}
219-
220-
let newFractionTraveled = self.preFractionTraveled + traveledDifference * timePassedInMilliseconds.truncatingRemainder(dividingBy: 1000) / 1000
221-
self.updateRouteLine(congestionSegments:congestionSegments, layerIdentifier: mainRouteLayerIdentifier, fractionTraveledUpdate: newFractionTraveled)
222-
self.updateRouteLine(layerIdentifier: mainRouteCasingLayerIdentifier, fractionTraveledUpdate: newFractionTraveled)
223-
})
224-
225-
default:
226-
self.updateRouteLine(congestionSegments:congestionSegments, layerIdentifier: mainRouteLayerIdentifier, fractionTraveledUpdate: fractionTraveled)
227-
self.updateRouteLine(layerIdentifier: mainRouteCasingLayerIdentifier, fractionTraveledUpdate: fractionTraveled)
228-
}
209+
updateRouteLine(congestionSegments:congestionSegments, layerIdentifier: mainRouteLayerIdentifier, fractionTraveledUpdate: fractionTraveled)
210+
updateRouteLine(layerIdentifier: mainRouteCasingLayerIdentifier, fractionTraveledUpdate: fractionTraveled)
229211
}
230212

231213
func updateRouteLine(congestionSegments: [Turf.Feature]? = nil, layerIdentifier: String, fractionTraveledUpdate: Double) {

Sources/MapboxNavigation/NavigationMapView.swift

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ open class NavigationMapView: UIView {
177177
/**
178178
Specifies how the map displays the user’s current location, including the appearance and underlying implementation.
179179

180-
By default, this property is set to `UserLocationStyle.courseView`.
180+
By default, this property is set to `UserLocationStyle.courseView`, the bearing source is location course.
181181
*/
182182
public var userLocationStyle: UserLocationStyle = .courseView(UserPuckCourseView(frame: CGRect(origin: .zero, size: 75.0))) {
183183
didSet {
@@ -262,6 +262,7 @@ open class NavigationMapView: UIView {
262262
self.mapView.location.options.puckType = .puck3D(configuration)
263263
}
264264
}
265+
mapView.location.options.puckBearingSource = .course
265266
}
266267

267268
deinit {
@@ -330,9 +331,12 @@ open class NavigationMapView: UIView {
330331
mapView.mapboxMap.onEvery(.renderFrameFinished) { [weak self] _ in
331332
guard let self = self,
332333
let location = self.mostRecentUserCourseViewLocation else { return }
333-
switch self.userLocationStyle {
334-
case .courseView: self.moveUserLocation(to: location)
335-
default: break
334+
self.moveUserLocation(to: location)
335+
336+
if self.simulatesLocation {
337+
if let locationProvider = self.mapView.location.locationProvider {
338+
self.mapView.location.locationProvider(locationProvider, didUpdateLocations: [location])
339+
}
336340
}
337341
}
338342

@@ -463,49 +467,8 @@ open class NavigationMapView: UIView {
463467
direction: cameraOptions.bearing!,
464468
animated: animated,
465469
navigationCameraState: navigationCamera.state)
466-
case .puck2D(configuration: _):
467-
if simulatesLocation {
468-
if !(mapView.location.locationProvider is PassiveLocationProvider) {
469-
mapView.location.locationProvider.stopUpdatingLocation()
470-
}
471-
if mapView.mapboxMap.style.layerExists(withId: NavigationMapView.LayerIdentifier.puck2DLayer) {
472-
let newLocation: [Double] = [
473-
location.coordinate.latitude,
474-
location.coordinate.longitude,
475-
location.altitude
476-
]
477-
do {
478-
try mapView.mapboxMap.style.setLayerProperties(for: NavigationMapView.LayerIdentifier.puck2DLayer,
479-
properties: [
480-
"location": newLocation,
481-
"bearing": location.course
482-
])
483-
} catch {
484-
print("Failed to perform operation while updating 2D puck bearing arrow with error: \(error.localizedDescription).")
485-
}
486-
}
487-
}
488-
case .puck3D(configuration: let configuration):
489-
if simulatesLocation {
490-
if !(mapView.location.locationProvider is PassiveLocationProvider) {
491-
mapView.location.locationProvider.stopUpdatingLocation()
492-
}
493-
if mapView.mapboxMap.style.sourceExists(withId: NavigationMapView.SourceIdentifier.puck3DSource) {
494-
var model = configuration.model
495-
model.position = [location.coordinate.longitude, location.coordinate.latitude]
496-
if var orientation = model.orientation,
497-
orientation.count > 2 {
498-
orientation[2] = orientation[2] + location.course
499-
model.orientation = orientation
500-
}
501-
502-
let modelSourceCode = [NavigationMapView.ModelKeyIdentifier.modelSouce: model]
503-
if let data = try? JSONEncoder().encode(modelSourceCode),
504-
let jsonDictionary = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
505-
try? mapView.mapboxMap.style.setSourceProperty(for: NavigationMapView.SourceIdentifier.puck3DSource, property: "models", value: jsonDictionary)
506-
}
507-
}
508-
}
470+
471+
default: break
509472
}
510473
}
511474

Sources/MapboxNavigation/NavigationViewController.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ open class NavigationViewController: UIViewController, NavigationStatusPresenter
195195
}
196196
set {
197197
navigationMapView?.routeLineTracksTraversal = newValue
198+
routeOverlayController?.routeLineTracksTraversal = newValue
198199
}
199200
}
200201

@@ -836,19 +837,22 @@ extension NavigationViewController: NavigationServiceDelegate {
836837
for component in navigationComponents {
837838
component.navigationService(service, didBeginSimulating: progress, becauseOf: reason)
838839
}
840+
let simulatedLocationProvider = NavigationLocationProvider(locationManager: SimulatedLocationManager(routeProgress: progress))
841+
navigationMapView?.mapView.location.overrideLocationProvider(with: simulatedLocationProvider)
839842
}
840843

841844
public func navigationService(_ service: NavigationService, willEndSimulating progress: RouteProgress, becauseOf reason: SimulationIntent) {
842845
for component in navigationComponents {
843846
component.navigationService(service, willEndSimulating: progress, becauseOf: reason)
844847
}
845-
navigationMapView?.simulatesLocation = true
848+
navigationMapView?.simulatesLocation = false
846849
}
847850

848851
public func navigationService(_ service: NavigationService, didEndSimulating progress: RouteProgress, becauseOf reason: SimulationIntent) {
849852
for component in navigationComponents {
850853
component.navigationService(service, didEndSimulating: progress, becauseOf: reason)
851854
}
855+
navigationMapView?.mapView.location.overrideLocationProvider(with: AppleLocationProvider())
852856
}
853857

854858
private func checkTunnelState(at location: CLLocation, along progress: RouteProgress) {

Sources/MapboxNavigation/RouteLineController.swift

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import MapboxDirections
22
import MapboxCoreNavigation
3+
import MapboxMaps
34
import CoreLocation
45
import UIKit
56

67
extension NavigationMapView {
78
/// A component meant to assist displaying route line and related items like arrows, waypoints, annotations and other.
8-
class RouteOverlayController: NavigationComponent, NavigationComponentDelegate {
9+
class RouteOverlayController: NavigationComponent, NavigationComponentDelegate, LocationConsumer {
910

1011
// MARK: - Properties
1112

@@ -20,12 +21,17 @@ extension NavigationMapView {
2021
navigationViewData.router
2122
}
2223

23-
fileprivate var routeLineTracksTraversal: Bool {
24+
fileprivate var routeProgress: RouteProgress?
25+
26+
var routeLineTracksTraversal: Bool {
2427
get {
2528
navigationMapView.routeLineTracksTraversal
2629
}
2730
set {
2831
navigationMapView.routeLineTracksTraversal = newValue
32+
if newValue {
33+
navigationMapView.mapView.location.addLocationConsumer(newConsumer: self)
34+
}
2935
}
3036
}
3137

@@ -59,6 +65,12 @@ extension NavigationMapView {
5965
}
6066
}
6167

68+
internal func locationUpdate(newLocation: Location) {
69+
guard routeLineTracksTraversal, let progress = routeProgress else { return }
70+
navigationMapView.updateTraveledRouteLine(newLocation.coordinate)
71+
navigationMapView.updateRoute(progress)
72+
}
73+
6274
private func updateMapOverlays(for routeProgress: RouteProgress) {
6375
if routeProgress.currentLegProgress.followOnStep != nil {
6476
navigationMapView.addArrow(route: routeProgress.route,
@@ -75,8 +87,7 @@ extension NavigationMapView {
7587
navigationMapView.show([routeProgress.route], legIndex: routeProgress.legIndex)
7688
if routeLineTracksTraversal {
7789
navigationMapView.updateUpcomingRoutePointIndex(routeProgress: routeProgress)
78-
navigationMapView.updateTraveledRouteLine(router.location?.coordinate)
79-
navigationMapView.updateRoute(routeProgress)
90+
self.routeProgress = routeProgress
8091
}
8192
}
8293

@@ -121,8 +132,7 @@ extension NavigationMapView {
121132

122133
if routeLineTracksTraversal {
123134
navigationMapView.updateUpcomingRoutePointIndex(routeProgress: progress)
124-
navigationMapView.updateTraveledRouteLine(location.coordinate)
125-
navigationMapView.updateRoute(progress)
135+
routeProgress = progress
126136
}
127137
}
128138

0 commit comments

Comments
 (0)