Skip to content

Commit 1266395

Browse files
dzinadgithub-actions[bot]
authored andcommitted
NAVAND-5544: calculate current alternative step correctly
GitOrigin-RevId: bc67630f6717c0aae603bcc63c5320d6895681bf
1 parent 26cb478 commit 1266395

11 files changed

Lines changed: 555 additions & 127 deletions

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/camera/data/MapboxNavigationViewportDataSource.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -492,10 +492,7 @@ class MapboxNavigationViewportDataSource private constructor(
492492
postManeuverFramingPoints,
493493
)
494494

495-
overviewViewportDataSource.onRouteProgressChanged(
496-
routeProgress,
497-
pointsToFrameOnCurrentStep,
498-
)
495+
overviewViewportDataSource.onRouteProgressChanged(routeProgress)
499496
} ?: run {
500497
logE(
501498
"You're calling #onRouteProgressChanged with empty leg or step progress.",

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/camera/transition/DefaultSimplifiedUpdateFrameTransitionProvider.kt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,21 @@ internal class DefaultSimplifiedUpdateFrameTransitionProvider(
1515
private val cameraPlugin: CameraAnimationsPlugin,
1616
) : SimplifiedUpdateFrameTransitionProvider {
1717

18-
override fun updateFrame(
18+
override fun updateFollowingFrame(
19+
cameraOptions: CameraOptions,
20+
transitionOptions: NavigationCameraTransitionOptions,
21+
): List<ValueAnimator> {
22+
return updateFrame(cameraOptions, transitionOptions)
23+
}
24+
25+
override fun updateOverviewFrame(
26+
cameraOptions: CameraOptions,
27+
transitionOptions: NavigationCameraTransitionOptions,
28+
): List<ValueAnimator> {
29+
return updateFrame(cameraOptions, transitionOptions)
30+
}
31+
32+
fun updateFrame(
1933
cameraOptions: CameraOptions,
2034
transitionOptions: NavigationCameraTransitionOptions,
2135
): List<ValueAnimator> {

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/camera/transition/SimplifiedFrameAnimatorsCreator.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ internal class SimplifiedFrameAnimatorsCreator(
3636
): MapboxAnimatorSet {
3737
return SimplifiedAnimatorSet(
3838
cameraAnimationsPlugin,
39-
simplifiedUpdateFrameTransition.updateFrame(cameraOptions, transitionOptions),
39+
simplifiedUpdateFrameTransition.updateFollowingFrame(cameraOptions, transitionOptions),
4040
)
4141
}
4242

@@ -46,7 +46,7 @@ internal class SimplifiedFrameAnimatorsCreator(
4646
): MapboxAnimatorSet {
4747
return SimplifiedAnimatorSet(
4848
cameraAnimationsPlugin,
49-
simplifiedUpdateFrameTransition.updateFrame(cameraOptions, transitionOptions),
49+
simplifiedUpdateFrameTransition.updateOverviewFrame(cameraOptions, transitionOptions),
5050
)
5151
}
5252
}

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/internal/camera/OverviewViewportDataSource.kt

Lines changed: 90 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.mapbox.navigation.ui.maps.internal.camera
22

33
import androidx.annotation.RestrictTo
4+
import androidx.annotation.VisibleForTesting
45
import com.mapbox.common.location.Location
56
import com.mapbox.geojson.Point
67
import com.mapbox.maps.CameraOptions
@@ -14,6 +15,7 @@ import com.mapbox.navigation.base.internal.utils.areSameRoutes
1415
import com.mapbox.navigation.base.internal.utils.isSameRoute
1516
import com.mapbox.navigation.base.route.NavigationRoute
1617
import com.mapbox.navigation.base.trip.model.RouteProgress
18+
import com.mapbox.navigation.base.utils.DecodeUtils.stepGeometryToPoints
1719
import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSource.Companion.BEARING_NORTH
1820
import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSource.Companion.EMPTY_EDGE_INSETS
1921
import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSource.Companion.NULL_ISLAND_POINT
@@ -29,12 +31,29 @@ import com.mapbox.navigation.utils.internal.logW
2931
import com.mapbox.navigation.utils.internal.toPoint
3032
import kotlin.math.min
3133

34+
private data class RouteIndices(
35+
val legIndex: Int,
36+
val stepIndex: Int,
37+
val legGeometryIndex: Int,
38+
)
39+
40+
private data class CachedRemainingPoints(
41+
val indices: RouteIndices,
42+
val remainingPointsOnCurrentStep: List<Point>,
43+
)
44+
3245
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
33-
class OverviewViewportDataSource(
46+
class OverviewViewportDataSource @VisibleForTesting internal constructor(
3447
private val mapboxMap: MapboxMap,
3548
internalOptions: InternalViewportDataSourceOptions,
49+
private val indicesConverter: RoutesIndicesConverter,
3650
) {
3751

52+
constructor(
53+
mapboxMap: MapboxMap,
54+
internalOptions: InternalViewportDataSourceOptions,
55+
) : this(mapboxMap, internalOptions, RoutesIndicesConverter())
56+
3857
internal var internalOptions = internalOptions
3958
set(value) {
4059
if (field != value) {
@@ -47,10 +66,10 @@ class OverviewViewportDataSource(
4766

4867
private var navigationRoutes: List<NavigationRoute> = emptyList()
4968
private var routeProgress: RouteProgress? = null
50-
private var pointsToFrameOnCurrentStep: List<Point> = emptyList()
5169
private var simplifiedCompleteRoutesPoints: List<List<List<List<Point>>>> = emptyList()
5270
private var simplifiedRemainingPointsOnRoutes: List<Point> = emptyList()
5371
private var targetLocation: Location? = null
72+
private var cachedRemainingPoints: MutableMap<String, CachedRemainingPoints> = hashMapOf()
5473

5574
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
5675
var debugger: MapboxNavigationViewportDataSourceDebugger? = null
@@ -85,7 +104,7 @@ class OverviewViewportDataSource(
85104

86105
private fun reevaluate() {
87106
calculateRouteData(navigationRoutes)
88-
routeProgress?.let { onRouteProgressChanged(it, pointsToFrameOnCurrentStep) }
107+
routeProgress?.let { onRouteProgressChanged(it) }
89108
evaluate()
90109
}
91110

@@ -101,15 +120,22 @@ class OverviewViewportDataSource(
101120
if (routes.isEmpty()) {
102121
clearRouteData()
103122
} else {
104-
val completeRoutePoints = routes
123+
val completeRoutesPoints = routes
105124
.mapIndexedNotNull { index, route ->
106125
if (index == 0 || internalOptions.overviewAlternatives) {
107126
processRoutePoints(route.directionsRoute)
108127
} else {
109128
null
110129
}
111130
}
112-
simplifiedCompleteRoutesPoints = completeRoutePoints.map {
131+
indicesConverter.onRoutesChanged(
132+
if (internalOptions.overviewAlternatives) {
133+
routes
134+
} else {
135+
routes.take(1)
136+
},
137+
)
138+
simplifiedCompleteRoutesPoints = completeRoutesPoints.map {
113139
simplifyCompleteRoutePoints(
114140
options.overviewFrameOptions.geometrySimplification.enabled,
115141
options.overviewFrameOptions.geometrySimplification.simplificationFactor,
@@ -124,6 +150,7 @@ class OverviewViewportDataSource(
124150

125151
fun clearRouteData() {
126152
this.navigationRoutes = emptyList()
153+
indicesConverter.onRoutesChanged(emptyList())
127154
runIfActive {
128155
simplifiedCompleteRoutesPoints = emptyList()
129156
simplifiedRemainingPointsOnRoutes = emptyList()
@@ -132,7 +159,7 @@ class OverviewViewportDataSource(
132159

133160
fun clearProgressData() {
134161
this.routeProgress = null
135-
pointsToFrameOnCurrentStep = emptyList()
162+
cachedRemainingPoints = hashMapOf()
136163
runIfActive {
137164
simplifiedRemainingPointsOnRoutes = simplifiedCompleteRoutesPoints
138165
.flatten().flatten().flatten()
@@ -141,10 +168,8 @@ class OverviewViewportDataSource(
141168

142169
fun onRouteProgressChanged(
143170
routeProgress: RouteProgress,
144-
pointsToFrameOnCurrentStep: List<Point>,
145171
) {
146172
this.routeProgress = routeProgress
147-
this.pointsToFrameOnCurrentStep = pointsToFrameOnCurrentStep
148173
val currentRoute = this.navigationRoutes.firstOrNull()
149174
if (currentRoute == null) {
150175
return
@@ -158,37 +183,71 @@ class OverviewViewportDataSource(
158183
routeProgress.currentLegProgress,
159184
routeProgress.currentLegProgress?.currentStepProgress,
160185
) { currentLegProgress, currentStepProgress ->
161-
val primaryPoints = getRemainingPointsOnRoute(
162-
simplifiedCompleteRoutesPoints.first(),
163-
pointsToFrameOnCurrentStep,
164-
internalOptions.overviewMode,
165-
currentLegProgress.legIndex,
166-
currentStepProgress.stepIndex,
167-
)
168-
val alternativePoints = if (internalOptions.overviewAlternatives) {
169-
navigationRoutes.drop(1).mapIndexedNotNull { index, route ->
170-
val alternativeIndices = routeProgress
171-
.internalAlternativeRouteIndices()[route.id]
172-
if (alternativeIndices == null) {
186+
simplifiedRemainingPointsOnRoutes =
187+
navigationRoutes.mapIndexedNotNull { index, route ->
188+
if (index > 0 && !internalOptions.overviewAlternatives) {
173189
null
174190
} else {
175-
getRemainingPointsOnRoute(
176-
simplifiedCompleteRoutesPoints[index + 1],
177-
emptyList(), // already overviewed by primary route
178-
internalOptions.overviewMode,
179-
alternativeIndices.legIndex,
180-
alternativeIndices.stepIndex,
181-
)
191+
val indices = if (index == 0) {
192+
RouteIndices(
193+
currentLegProgress.legIndex,
194+
currentStepProgress.stepIndex,
195+
currentLegProgress.geometryIndex,
196+
)
197+
} else {
198+
routeProgress.internalAlternativeRouteIndices()[route.id]?.let {
199+
RouteIndices(it.legIndex, it.stepIndex, it.legGeometryIndex)
200+
}
201+
}
202+
if (indices == null) {
203+
null
204+
} else {
205+
if (indices != cachedRemainingPoints[route.id]?.indices) {
206+
val stepGeometryIndex = indicesConverter.convert(
207+
route.id,
208+
indices.legIndex,
209+
indices.stepIndex,
210+
indices.legGeometryIndex,
211+
)
212+
if (stepGeometryIndex != null) {
213+
cachedRemainingPoints[route.id] = getCachedRemainingPoints(
214+
route,
215+
indices,
216+
stepGeometryIndex,
217+
)
218+
}
219+
}
220+
getRemainingPointsOnRoute(
221+
simplifiedCompleteRoutesPoints[index],
222+
cachedRemainingPoints[route.id]?.remainingPointsOnCurrentStep
223+
.orEmpty(),
224+
internalOptions.overviewMode,
225+
indices.legIndex,
226+
indices.stepIndex,
227+
)
228+
}
182229
}
183230
}.flatten()
184-
} else {
185-
emptyList()
186-
}
187-
simplifiedRemainingPointsOnRoutes = primaryPoints + alternativePoints
188231
}
189232
}
190233
}
191234

235+
private fun getCachedRemainingPoints(
236+
route: NavigationRoute,
237+
indices: RouteIndices,
238+
stepGeometryIndex: Int,
239+
): CachedRemainingPoints {
240+
val remainingPointsOnCurrentStep = route.directionsRoute.legs()
241+
?.getOrNull(indices.legIndex)
242+
?.steps()
243+
?.getOrNull(indices.stepIndex)?.let {
244+
route.directionsRoute.stepGeometryToPoints(it)
245+
}
246+
?.drop(stepGeometryIndex)
247+
.orEmpty()
248+
return CachedRemainingPoints(indices, remainingPointsOnCurrentStep)
249+
}
250+
192251
fun onLocationChanged(location: Location) {
193252
this.targetLocation = location
194253
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.mapbox.navigation.ui.maps.internal.camera
2+
3+
import com.mapbox.api.directions.v5.models.DirectionsRoute
4+
import com.mapbox.navigation.base.route.NavigationRoute
5+
import com.mapbox.navigation.base.utils.DecodeUtils.stepGeometryToPoints
6+
7+
internal class RoutesIndicesConverter {
8+
9+
// key - route id, each element in a value list is a lambda that converts shapeIndex
10+
// (leg geometry index) to step geometry index for a set leg index and step index
11+
// Example: indicesConverter["routeId2"][1][4](15) means:
12+
// "for alternative with id 'routeId2', for leg #1 for step#15
13+
// convert legGeometryIndex=15, result is current step geometry index"
14+
private var lambdasMap: MutableMap<String, List<List<(Int) -> Int?>>> = hashMapOf()
15+
16+
fun onRoutesChanged(routes: List<NavigationRoute>) {
17+
lambdasMap = hashMapOf()
18+
routes.forEachIndexed { index, route ->
19+
lambdasMap[routes[index].id] = processIndices(
20+
route.directionsRoute,
21+
)
22+
}
23+
}
24+
25+
fun convert(id: String, legIndex: Int, stepIndex: Int, legGeometryIndex: Int): Int? {
26+
return lambdasMap[id]
27+
?.getOrNull(legIndex)
28+
?.getOrNull(stepIndex)
29+
?.invoke(legGeometryIndex)
30+
}
31+
32+
private fun processIndices(directionsRoute: DirectionsRoute): List<List<(Int) -> Int?>> {
33+
return directionsRoute.legs()?.map { leg ->
34+
var prevPointsCount = 0
35+
leg.steps()?.map { step ->
36+
val prevPointsCountSnapshot = prevPointsCount
37+
val stepSize = directionsRoute.stepGeometryToPoints(step).size
38+
val lambda = { shapeIndex: Int ->
39+
val result = shapeIndex - prevPointsCountSnapshot
40+
if (result in 0 until stepSize) result else null
41+
}
42+
prevPointsCount += stepSize - 1
43+
lambda
44+
}.orEmpty()
45+
}.orEmpty()
46+
}
47+
}

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/internal/camera/SimplifiedUpdateFrameTransitionProvider.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ import com.mapbox.navigation.ui.maps.camera.transition.NavigationCameraTransitio
88
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
99
interface SimplifiedUpdateFrameTransitionProvider {
1010

11-
fun updateFrame(
11+
fun updateFollowingFrame(
12+
cameraOptions: CameraOptions,
13+
transitionOptions: NavigationCameraTransitionOptions,
14+
): List<ValueAnimator>
15+
16+
fun updateOverviewFrame(
1217
cameraOptions: CameraOptions,
1318
transitionOptions: NavigationCameraTransitionOptions,
1419
): List<ValueAnimator>

ui-maps/src/test/java/com/mapbox/navigation/ui/maps/camera/data/MapboxNavigationViewportDataSourceTest.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ class MapboxNavigationViewportDataSourceTest {
224224
every {
225225
getRemainingPointsOnRoute(
226226
completeRoutePoints,
227-
pointsToFrameOnCurrentStep,
227+
any(),
228228
any(),
229229
any(),
230230
any(),
@@ -381,7 +381,7 @@ class MapboxNavigationViewportDataSourceTest {
381381
viewportDataSource.onRouteProgressChanged(routeProgress)
382382

383383
verify(exactly = 0) {
384-
overviewViewportDataSource.onRouteProgressChanged(any(), any())
384+
overviewViewportDataSource.onRouteProgressChanged(any())
385385
}
386386
}
387387

@@ -409,7 +409,7 @@ class MapboxNavigationViewportDataSourceTest {
409409
unmockkStatic("com.mapbox.navigation.base.internal.utils.DirectionsRouteEx")
410410

411411
verify(exactly = 0) {
412-
overviewViewportDataSource.onRouteProgressChanged(any(), any())
412+
overviewViewportDataSource.onRouteProgressChanged(any())
413413
}
414414
}
415415

@@ -432,7 +432,7 @@ class MapboxNavigationViewportDataSourceTest {
432432
viewportDataSource.onRouteProgressChanged(routeProgress)
433433

434434
verify(exactly = 0) {
435-
overviewViewportDataSource.onRouteProgressChanged(any(), any())
435+
overviewViewportDataSource.onRouteProgressChanged(any())
436436
}
437437
}
438438

@@ -467,7 +467,6 @@ class MapboxNavigationViewportDataSourceTest {
467467
verify {
468468
overviewViewportDataSource.onRouteProgressChanged(
469469
routeProgress,
470-
pointsToFrameOnCurrentStep,
471470
)
472471
}
473472
}

0 commit comments

Comments
 (0)