Skip to content

Commit 44a0db8

Browse files
committed
NAVAND-1073: fix geometry leg index calculation
1 parent 80444d9 commit 44a0db8

File tree

4 files changed

+255
-91
lines changed

4 files changed

+255
-91
lines changed

instrumentation-tests/src/androidTest/java/com/mapbox/navigation/instrumentation_tests/core/RouteRefreshTest.kt

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.mapbox.api.directions.v5.models.DirectionsResponse
99
import com.mapbox.api.directions.v5.models.Incident
1010
import com.mapbox.api.directions.v5.models.RouteOptions
1111
import com.mapbox.geojson.Point
12+
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
1213
import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
1314
import com.mapbox.navigation.base.options.NavigationOptions
1415
import com.mapbox.navigation.base.options.RoutingTilesOptions
@@ -59,6 +60,7 @@ import java.net.URI
5960
import java.util.concurrent.TimeUnit
6061
import kotlin.math.absoluteValue
6162

63+
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
6264
class RouteRefreshTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java) {
6365

6466
@get:Rule
@@ -528,6 +530,73 @@ class RouteRefreshTest : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.ja
528530
assertEquals(187.126, refreshedRoutes[1].getSumOfDurationAnnotationsFromLeg(0), 0.0001)
529531
}
530532

533+
@Test
534+
fun route_refresh_updates_annotations_for_new_alternative_with_more_legs() =
535+
sdkTest {
536+
setupMockRequestHandlers(
537+
multilegCoordinates,
538+
R.raw.route_response_single_route_multileg,
539+
R.raw.route_response_single_route_multileg_refreshed,
540+
"route_response_single_route_multileg",
541+
acceptedGeometryIndex = 70
542+
)
543+
mockWebServerRule.requestHandlers.add(
544+
FailByRequestMockRequestHandler(
545+
MockDirectionsRefreshHandler(
546+
"route_response_single_route_multileg_alternative",
547+
readRawFileText(
548+
activity,
549+
R.raw.route_response_single_route_multileg_alternative_refreshed
550+
),
551+
acceptedGeometryIndex = 11
552+
)
553+
)
554+
)
555+
val routeOptions = generateRouteOptions(multilegCoordinates)
556+
val alternativeRoutes = mapboxNavigation.requestRoutes(routeOptions)
557+
.getSuccessfulResultOrThrowException()
558+
.routes
559+
// alternative which was requested on the second leg of the original route,
560+
// so the alternative has only one leg while the original route has two
561+
val primaryRoute = alternativeForMultileg(activity).toNavigationRoutes().first()
562+
563+
// corresponds to currentRouteGeometryIndex = 70 for alternative route and 11 for the primary route
564+
mockLocationUpdatesRule.pushLocationUpdate(
565+
mockLocationUpdatesRule.generateLocationUpdate {
566+
latitude = 38.581798
567+
longitude = -121.476146
568+
}
569+
)
570+
571+
mapboxNavigation.setNavigationRoutes(listOf(primaryRoute) + alternativeRoutes, initialLegIndex = 0)
572+
mapboxNavigation.startTripSession()
573+
574+
mapboxNavigation.routeProgressUpdates()
575+
.filter {
576+
it.currentRouteGeometryIndex == 11
577+
}
578+
.first()
579+
580+
val refreshedRoutes = mapboxNavigation.routesUpdates()
581+
.filter {
582+
it.reason == ROUTES_UPDATE_REASON_REFRESH
583+
}
584+
.first()
585+
.navigationRoutes
586+
587+
assertEquals(
588+
alternativeRoutes[0].getSumOfDurationAnnotationsFromLeg(0),
589+
refreshedRoutes[1].getSumOfDurationAnnotationsFromLeg(0),
590+
0.0001
591+
)
592+
593+
assertEquals(201.673, alternativeRoutes[0].getSumOfDurationAnnotationsFromLeg(1), 0.0001)
594+
assertEquals(202.881, refreshedRoutes[1].getSumOfDurationAnnotationsFromLeg(1), 0.0001)
595+
596+
assertEquals(194.3, primaryRoute.getSumOfDurationAnnotationsFromLeg(0), 0.0001)
597+
assertEquals(187.126, refreshedRoutes[0].getSumOfDurationAnnotationsFromLeg(0), 0.0001)
598+
}
599+
531600
@Test
532601
fun expect_route_refresh_to_update_annotations_incidents_and_closures_for_truncated_next_leg() =
533602
sdkTest {

libnavigation-core/src/main/java/com/mapbox/navigation/core/routealternatives/AlternativeRouteProgressDataProvider.kt

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package com.mapbox.navigation.core.routealternatives
22

3+
import com.mapbox.navigation.base.route.NavigationRoute
4+
import com.mapbox.navigation.base.utils.DecodeUtils.stepsGeometryToPoints
35
import com.mapbox.navigation.core.RouteProgressData
6+
import com.mapbox.navigation.utils.internal.ThreadController
7+
import kotlinx.coroutines.Dispatchers
8+
import kotlinx.coroutines.withContext
49

510
internal object AlternativeRouteProgressDataProvider {
611

7-
fun getRouteProgressData(
12+
suspend fun getRouteProgressData(
813
primaryRouteProgressData: RouteProgressData,
914
alternativeMetadata: AlternativeRouteMetadata
1015
): RouteProgressData {
@@ -22,16 +27,30 @@ internal object AlternativeRouteProgressDataProvider {
2227
primaryFork.geometryIndexInRoute - alternativeFork.geometryIndexInRoute
2328
routeGeometryIndex =
2429
primaryRouteProgressData.routeGeometryIndex - routeGeometryIndexDiff
25-
val legGeometryIndexDiff =
26-
primaryFork.geometryIndexInLeg - alternativeFork.geometryIndexInLeg
27-
legGeometryIndex = primaryRouteProgressData.legGeometryIndex?.let {
28-
it - legGeometryIndexDiff
29-
}
30+
legGeometryIndex = routeGeometryIndex -
31+
prevLegsGeometryIndicesCount(alternativeMetadata.navigationRoute, legIndex)
3032
} else {
3133
legIndex = alternativeFork.legIndex
3234
routeGeometryIndex = alternativeFork.geometryIndexInRoute
3335
legGeometryIndex = alternativeFork.geometryIndexInLeg
3436
}
3537
return RouteProgressData(legIndex, routeGeometryIndex, legGeometryIndex)
3638
}
39+
40+
private suspend fun prevLegsGeometryIndicesCount(route: NavigationRoute, currentLegIndex: Int): Int {
41+
return withContext(ThreadController.DefaultDispatcher) {
42+
var result = 0
43+
val stepsGeometries by lazy { route.directionsRoute.stepsGeometryToPoints() }
44+
for (legIndex in 0 until currentLegIndex) {
45+
val legGeometries = stepsGeometries.getOrNull(legIndex)
46+
if (legGeometries != null) {
47+
// remove step duplicates (the last point in prev step is the same as the first point in the current step)
48+
result += legGeometries.sumOf { it.size } - legGeometries.size + 1
49+
}
50+
}
51+
// remove leg duplicates (the last point of the last step of prev leg is the same as the first point of the first step in the current leg)
52+
result -= currentLegIndex
53+
result
54+
}
55+
}
3756
}

libnavigation-core/src/test/java/com/mapbox/navigation/core/RoutesProgressDataProviderTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,13 @@ class RoutesProgressDataProviderTest {
7373
every {
7474
alternativeMetadataProvider.getMetadataFor(alternativeRoute2)
7575
} returns alternativeMetadata2
76-
every {
76+
coEvery {
7777
AlternativeRouteProgressDataProvider.getRouteProgressData(
7878
primaryRouteProgressData,
7979
alternativeMetadata1
8080
)
8181
} returns alternativeRoute1ProgressData
82-
every {
82+
coEvery {
8383
AlternativeRouteProgressDataProvider.getRouteProgressData(
8484
primaryRouteProgressData,
8585
alternativeMetadata2
@@ -116,7 +116,7 @@ class RoutesProgressDataProviderTest {
116116
every {
117117
alternativeMetadataProvider.getMetadataFor(alternativeRoute2)
118118
} returns alternativeMetadata2
119-
every {
119+
coEvery {
120120
AlternativeRouteProgressDataProvider.getRouteProgressData(
121121
primaryRouteProgressData,
122122
alternativeMetadata2

0 commit comments

Comments
 (0)