Skip to content

Commit 893a152

Browse files
kriedvolkdmitri
authored andcommitted
Use full struct NavigationProgress in Viewport state (#10608)
1 parent 7739d89 commit 893a152

File tree

8 files changed

+245
-125
lines changed

8 files changed

+245
-125
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@
44

55
### API Deprecations
66

7+
* `ViewportState.routeProgress` is deprecated and is always `nil` now. Use `ViewportState.navigationProgress` instead.
78
* `ViewportState.heading` is deprecated and is always `nil` now. Use `ViewportState.navigationHeading` instead.
89
* `ViewportState.location` is deprecated in favor of `ViewportState.navigationLocation` instead.
9-
* `ViewportState.init(location:routeProgress:viewportPadding:heading:)` is deprecated in favor of `ViewportState.init(navigationLocation:routeProgress:viewportPadding:navigationHeading:)`.
10+
* `ViewportState.init(location:routeProgress:viewportPadding:heading:)` is deprecated in favor of `ViewportState.init(navigationLocation:navigationProgress:viewportPadding:navigationHeading:)`.
11+
12+
### Navigation Camera
13+
14+
* When implementing a custom `ViewportDataSource` for the navigation camera, migrate to `viewportState.navigationProgress` for tracking active guidance progress.
1015

1116
### Other changes
1217

13-
* Fixed a possible race condition in `NavigationCamera` state `CLHeading` updates.
18+
* Fixed a possible race condition in `NavigationCamera` state updates.
1419
* Fixed memory leaks caused by `Task.detached` usage in `NavigationController`.
1520
* Fixed memory leaks in `NWPathMonitor` caused by a non-stopped monitor.
1621
* Removed excessive `Sendable` conformance for types from Turf and Maps.

Examples/AdditionalExamples/Examples/NavigationCamera/CustomViewportDataSource.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class CustomViewportDataSource: ViewportDataSource {
6868
pitch: 0.0
6969
)
7070

71-
if let shape = state.routeProgress?.route.shape, let cameraOptions = try? mapView.mapboxMap.camera(
71+
if let shape = state.navigationProgress?.route.shape, let cameraOptions = try? mapView.mapboxMap.camera(
7272
for: shape.coordinates.compactMap { $0 },
7373
camera: initialCameraOptions,
7474
coordinatesPadding: UIEdgeInsets(

Sources/MapboxNavigationCore/Map/Camera/NavigationCamera.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class NavigationCamera {
1616
var cameraState: NavigationCameraState = .idle
1717
var location: NavigationLocation?
1818
var navigationHeading: NavigationHeading?
19-
var routeProgress: RouteProgress?
19+
var navigationProgress: NavigationProgress?
2020
var viewportPadding: UIEdgeInsets = .zero
2121
}
2222

@@ -92,7 +92,7 @@ public class NavigationCamera {
9292
self.viewportDataSource.update(
9393
using: ViewportState(
9494
navigationLocation: location,
95-
routeProgress: newState.routeProgress,
95+
navigationProgress: newState.navigationProgress,
9696
viewportPadding: viewportPadding,
9797
navigationHeading: newState.navigationHeading
9898
)
@@ -143,7 +143,7 @@ public class NavigationCamera {
143143
routeProgress
144144
.receive(on: DispatchQueue.main)
145145
.sink { [weak self] in
146-
self?.state.routeProgress = $0
146+
self?.state.navigationProgress = $0.map(NavigationProgress.init)
147147
}.store(in: &lifetimeSubscriptions)
148148
}
149149

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import CoreLocation
2+
import MapboxDirections
3+
4+
/// ``NavigationProgress`` stores the user’s progress along a route.
5+
public struct NavigationProgress: RouteProgressRepresentable, Equatable, Sendable {
6+
/// Returns the current main `Route`.
7+
public let route: Route
8+
/// Returns the id of the current main `Route`.
9+
public let routeId: RouteId
10+
11+
/// Returns the progress along the current ``RouteLeg``.
12+
public let currentLegProgress: RouteLegProgress
13+
/// Total distance traveled by user along all legs.
14+
public let distanceTraveled: CLLocationDistance
15+
/// Number between 0 and 1 representing how far along the `Route` the user has traveled.
16+
public let fractionTraveled: Double
17+
/// Total seconds remaining on all legs.
18+
public let durationRemaining: TimeInterval
19+
/// Total distance remaining in meters along route.
20+
public let distanceRemaining: CLLocationDistance
21+
/// Index representing current ``RouteLeg``.
22+
public let legIndex: Int
23+
/// Index relative to route shape, representing the point the user is currently located at.
24+
public let shapeIndex: Int
25+
/// The waypoints of the route.
26+
public let waypoints: [Waypoint]
27+
28+
/// Initializes a new ``NavigationProgress``.
29+
/// - Parameters:
30+
/// - route: The current main `Route`.
31+
/// - routeId: The id of the current main `Route`.
32+
/// - currentLegProgress: The progress along the current ``RouteLeg``.
33+
/// - distanceTraveled: Total distance traveled by user along all legs.
34+
/// - fractionTraveled: Number between 0 and 1 representing how far along the `Route` the user has traveled.
35+
/// - durationRemaining: Total seconds remaining on all legs.
36+
/// - distanceRemaining: Total distance remaining in meters along route.
37+
/// - legIndex: Index representing current ``RouteLeg``.
38+
/// - shapeIndex: Index relative to route shape, representing the point the user is currently located at.
39+
/// - waypoints: The waypoints of the route.
40+
public init(
41+
route: Route,
42+
routeId: RouteId,
43+
currentLegProgress: RouteLegProgress,
44+
distanceTraveled: CLLocationDistance,
45+
fractionTraveled: Double,
46+
durationRemaining: TimeInterval,
47+
distanceRemaining: CLLocationDistance,
48+
legIndex: Int,
49+
shapeIndex: Int,
50+
waypoints: [Waypoint]
51+
) {
52+
self.route = route
53+
self.routeId = routeId
54+
self.currentLegProgress = currentLegProgress
55+
self.distanceTraveled = distanceTraveled
56+
self.fractionTraveled = fractionTraveled
57+
self.durationRemaining = durationRemaining
58+
self.distanceRemaining = distanceRemaining
59+
self.legIndex = legIndex
60+
self.shapeIndex = shapeIndex
61+
self.waypoints = waypoints
62+
}
63+
}
64+
65+
extension NavigationProgress {
66+
init(_ routeProgress: RouteProgress) {
67+
self.route = routeProgress.route
68+
self.routeId = routeProgress.navigationRoutes.mainRoute.routeId
69+
self.currentLegProgress = routeProgress.currentLegProgress
70+
self.distanceTraveled = routeProgress.distanceTraveled
71+
self.fractionTraveled = routeProgress.fractionTraveled
72+
self.distanceRemaining = routeProgress.distanceRemaining
73+
self.durationRemaining = routeProgress.durationRemaining
74+
self.legIndex = routeProgress.legIndex
75+
self.shapeIndex = routeProgress.shapeIndex
76+
self.waypoints = routeProgress.waypoints
77+
}
78+
}

Sources/MapboxNavigationCore/Map/Camera/ViewportDataSource/CommonViewportDataSource.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class CommonViewportDataSource {
7878
let parameters = provider.parameters(
7979
with: viewportState.navigationLocation,
8080
navigationHeading: viewportState.navigationHeading,
81-
routeProgress: viewportState.routeProgress,
81+
navigationProgress: viewportState.navigationProgress,
8282
viewportPadding: viewportState.viewportPadding,
8383
options: options
8484
)

Sources/MapboxNavigationCore/Map/Camera/ViewportDataSource/ViewportDataSource.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public struct ViewportState: Equatable, Sendable {
88
/// The current location of the user.
99
public let navigationLocation: NavigationLocation
1010
/// The navigation route progress.
11-
public let routeProgress: RouteProgress?
11+
public let navigationProgress: NavigationProgress?
1212
/// The padding applied to the viewport.
1313
public let viewportPadding: UIEdgeInsets
1414
/// The current user heading.
@@ -17,17 +17,17 @@ public struct ViewportState: Equatable, Sendable {
1717
/// Initializes a new ``ViewportState`` instance.
1818
/// - Parameters:
1919
/// - navigationLocation: The current location of the user.
20-
/// - routeProgress: The navigation route progress. Pass `nil` in case of no active navigation at the moment.
20+
/// - navigationProgress: The navigation route progress. Pass `nil` in case of no active navigation at the moment.
2121
/// - viewportPadding: The padding applied to the viewport.
2222
/// - navigationHeading: The current user heading.
2323
public init(
2424
navigationLocation: NavigationLocation,
25-
routeProgress: RouteProgress?,
25+
navigationProgress: NavigationProgress?,
2626
viewportPadding: UIEdgeInsets,
2727
navigationHeading: NavigationHeading?
2828
) {
2929
self.navigationLocation = navigationLocation
30-
self.routeProgress = routeProgress
30+
self.navigationProgress = navigationProgress
3131
self.viewportPadding = viewportPadding
3232
self.navigationHeading = navigationHeading
3333
}
@@ -41,7 +41,7 @@ public struct ViewportState: Equatable, Sendable {
4141
@available(
4242
*,
4343
deprecated,
44-
message: "Use `init(navigationLocation:routeProgress:viewportPadding:navigationHeading:)` instead"
44+
message: "Use `init(navigationLocation:navigationProgress:viewportPadding:navigationHeading:)` instead"
4545
)
4646
public init(
4747
location: CLLocation,
@@ -50,7 +50,7 @@ public struct ViewportState: Equatable, Sendable {
5050
heading: CLHeading?
5151
) {
5252
self.navigationLocation = NavigationLocation(location)
53-
self.routeProgress = routeProgress
53+
self.navigationProgress = routeProgress.map(NavigationProgress.init)
5454
self.viewportPadding = viewportPadding
5555
self.navigationHeading = heading.map(NavigationHeading.init)
5656
}
@@ -66,6 +66,10 @@ extension ViewportState {
6666
public var location: CLLocation {
6767
navigationLocation.clLocation
6868
}
69+
70+
/// The navigation route progress. Use ``navigationProgress`` instead. Always returns `nil`.
71+
@available(*, deprecated, message: "Use `navigationProgress` instead")
72+
public var routeProgress: RouteProgress? { return nil }
6973
}
7074

7175
/// The protocol, which is used to fill and store ``NavigationCameraOptions`` which will be used by ``NavigationCamera``

Sources/MapboxNavigationCore/Map/Camera/ViewportParametersProvider.swift

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ struct ViewportParametersProvider: Sendable {
77
func parameters(
88
with navigationLocation: NavigationLocation?,
99
navigationHeading: NavigationHeading?,
10-
routeProgress: RouteProgress?,
10+
navigationProgress: NavigationProgress?,
1111
viewportPadding: UIEdgeInsets,
1212
options: NavigationViewportDataSourceOptions
1313
) -> ViewportDataSourceState {
14-
if let routeProgress {
14+
if let navigationProgress {
1515
let intersectionDensity = options.followingCameraOptions.intersectionDensity
16-
let stepIndex = routeProgress.currentLegProgress.stepIndex
17-
let nextStepIndex = min(stepIndex + 1, routeProgress.currentLeg.steps.count - 1)
16+
let stepIndex = navigationProgress.currentLegProgress.stepIndex
17+
let nextStepIndex = min(stepIndex + 1, navigationProgress.currentLeg.steps.count - 1)
1818

19-
var remainingCoordinatesOnRoute = routeProgress.currentLegProgress.currentStepProgress
19+
var remainingCoordinatesOnRoute = navigationProgress.currentLegProgress.currentStepProgress
2020
.remainingStepCoordinates()
21-
routeProgress.currentLeg.steps[nextStepIndex...]
21+
navigationProgress.currentLeg.steps[nextStepIndex...]
2222
.lazy
2323
.compactMap { $0.shape?.coordinates }
2424
.forEach { stepCoordinates in
@@ -30,15 +30,19 @@ struct ViewportParametersProvider: Sendable {
3030
navigationHeading: navigationHeading,
3131
navigationState: .active(
3232
.init(
33-
coordinatesToManeuver: routeProgress.currentLegProgress.currentStepProgress
33+
coordinatesToManeuver: navigationProgress.currentLegProgress.currentStepProgress
3434
.remainingStepCoordinates(),
35-
lookaheadDistance: lookaheadDistance(routeProgress, intersectionDensity: intersectionDensity),
36-
currentLegStepIndex: routeProgress.currentLegProgress.stepIndex,
37-
currentLegSteps: routeProgress.currentLeg.steps,
38-
isRouteComplete: routeProgress.routeIsComplete == true,
35+
lookaheadDistance: lookaheadDistance(
36+
navigationProgress,
37+
intersectionDensity: intersectionDensity
38+
),
39+
currentLegStepIndex: navigationProgress.currentLegProgress.stepIndex,
40+
currentLegSteps: navigationProgress.currentLeg.steps,
41+
isRouteComplete: navigationProgress.routeIsComplete == true,
3942
remainingCoordinatesOnRoute: remainingCoordinatesOnRoute,
40-
transportType: routeProgress.currentLegProgress.currentStep.transportType,
41-
distanceRemainingOnStep: routeProgress.currentLegProgress.currentStepProgress.distanceRemaining
43+
transportType: navigationProgress.currentLegProgress.currentStep.transportType,
44+
distanceRemainingOnStep: navigationProgress.currentLegProgress.currentStepProgress
45+
.distanceRemaining
4246
)
4347
),
4448
viewportPadding: viewportPadding
@@ -60,10 +64,10 @@ struct ViewportParametersProvider: Sendable {
6064
/// - intersectionDensity: Lookahead distance
6165
/// - Returns: The lookahead distance.
6266
private func lookaheadDistance(
63-
_ routeProgress: RouteProgress,
67+
_ navigationProgress: NavigationProgress,
6468
intersectionDensity: IntersectionDensity
6569
) -> CLLocationDistance {
66-
let averageIntersectionDistances = routeProgress.route.legs.map { leg -> [CLLocationDistance] in
70+
let averageIntersectionDistances = navigationProgress.route.legs.map { leg -> [CLLocationDistance] in
6771
return leg.steps.map { step -> CLLocationDistance in
6872
if let firstStepCoordinate = step.shape?.coordinates.first,
6973
let lastStepCoordinate = step.shape?.coordinates.last
@@ -90,8 +94,8 @@ struct ViewportParametersProvider: Sendable {
9094

9195
let averageDistanceMultiplier = intersectionDensity.enabled ? intersectionDensity
9296
.averageDistanceMultiplier : 1.0
93-
let currentRouteLegIndex = routeProgress.legIndex
94-
let currentRouteStepIndex = routeProgress.currentLegProgress.stepIndex
97+
let currentRouteLegIndex = navigationProgress.legIndex
98+
let currentRouteStepIndex = navigationProgress.currentLegProgress.stepIndex
9599
let lookaheadDistance = averageIntersectionDistances[currentRouteLegIndex][currentRouteStepIndex] *
96100
averageDistanceMultiplier
97101

0 commit comments

Comments
 (0)