Skip to content

Commit 50cf093

Browse files
stanis-kgithub-actions[bot]
authored andcommitted
Use the geometry index to calculate the vanishing route. Fix missed index bug in RouteLineGranularDistances builder. (#9510)
* Get rid of findClosestRouteLineDistanceIndexToPoint. Use geo index instead * Add changelog * Ktlint fix * Use RD data from NavNative as source of geometry of granular distances * Remove logic of filtering duplicates step points * Add MapboxRdRouteDataAccessor proxy for dealing in unit tests * Fix SDKRouteParser mocking * Fix tests * Use NN geometry as source of routeDistances list. Fix test. * Fix ktlint * Fix test * Fix ktlint * Add debug logging for test * Revert "Add debug logging for test" This reverts commit 71bd03c231ad59700fdd0e2152796043346c3183. * Fix test * Write better docs. * Remove usage of RdRouteDataInterface * Add nnGeometryCompleteDistance and nnGeometryRouteDistances to RouteLineGranularDistances * Add RestrictTo to NavigationRoute.nativeGeometry * Don't use nn geometry, use complete geometry from json instead * Fix how legArray for RouteLineGranularDistances calculated * Format ktlint GitOrigin-RevId: 38fb39fc0a331a947dad8b3473f5bdaf32498254
1 parent 6e7063c commit 50cf093

File tree

12 files changed

+50
-2435
lines changed

12 files changed

+50
-2435
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix when already passed part of route appears behind CCP

libtesting-navigation-base/src/main/java/com/mapbox/navigation/testing/NativeRouteParserRule.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import com.mapbox.navigation.base.internal.SDKRouteParser
55
import com.mapbox.navigation.testing.factories.TestSDKRouteParser
66
import io.mockk.every
77
import io.mockk.mockkObject
8+
import io.mockk.mockkStatic
9+
import io.mockk.unmockkObject
810
import org.junit.rules.TestRule
911
import org.junit.runner.Description
1012
import org.junit.runners.model.Statement
@@ -14,9 +16,13 @@ class NativeRouteParserRule : TestRule {
1416
return object : Statement() {
1517
@SuppressLint("VisibleForTests")
1618
override fun evaluate() {
17-
mockkObject(SDKRouteParser) {
18-
every { SDKRouteParser.default } returns TestSDKRouteParser()
19+
mockkObject(SDKRouteParser)
20+
every { SDKRouteParser.default } returns TestSDKRouteParser()
21+
22+
try {
1923
base.evaluate()
24+
} finally {
25+
unmockkObject(SDKRouteParser)
2026
}
2127
}
2228
}

libtesting-navigation-base/src/main/java/com/mapbox/navigation/testing/factories/NavigationRouteFactory.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.mapbox.navigation.base.route.NavigationRoute
1717
import com.mapbox.navigation.base.route.ResponseOriginAPI
1818
import com.mapbox.navigation.base.route.ResponseOriginAPI.Companion.DIRECTIONS_API
1919
import com.mapbox.navigation.base.route.RouterOrigin
20+
import com.mapbox.navigation.base.utils.DecodeUtils.completeGeometryToPoints
2021
import com.mapbox.navigator.RouteInfo
2122
import com.mapbox.navigator.RouteInterface
2223
import com.mapbox.navigator.Waypoint
@@ -130,7 +131,8 @@ fun createRouteInterfacesFromDirectionRequestResponse(
130131
waypoints = nativeWaypointsMapper(
131132
responseModel.waypoints() ?: directionsRoute.waypoints() ?: emptyList(),
132133
directionsRoute.routeOptions()
133-
)
134+
),
135+
routeGeometry = directionsRoute.completeGeometryToPoints(),
134136
)
135137
}
136138
}

libtesting-thirdparty/src/main/java/com/mapbox/navigation/testing/factories/NativeFactories.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ fun createRouteInterface(
205205
waypoints: List<Waypoint> = emptyList(),
206206
expirationTimeMs: Long? = null,
207207
lastRefreshTimestamp: Date? = null,
208-
routeGeometry: List<Point> = emptyList(),
208+
routeGeometry: List<Point>,
209209
): RouteInterface = object : RouteInterface {
210210

211211
override fun getRouteId() = "$responseUuid#$routeIndex"

navigation/src/test/java/com/mapbox/navigation/core/routealternatives/RouteAlternativesControllerTest.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import com.mapbox.navigation.base.route.NavigationRoute
99
import com.mapbox.navigation.base.route.RouteAlternativesOptions
1010
import com.mapbox.navigation.base.route.RouterOrigin
1111
import com.mapbox.navigation.base.trip.model.RouteProgress
12+
import com.mapbox.navigation.base.utils.DecodeUtils.completeGeometryToPoints
1213
import com.mapbox.navigation.core.directions.session.DirectionsSession
1314
import com.mapbox.navigation.core.directions.session.findRoute
1415
import com.mapbox.navigation.core.trip.session.TripSession
@@ -213,6 +214,7 @@ class RouteAlternativesControllerTest {
213214
routes = listOf(createDirectionsRoute(refreshTtl = 5)),
214215
).toJson(),
215216
responseUUID = "test",
217+
routeGeometry = emptyList(),
216218
)
217219
nativeObserver.captured.onRouteAlternativesUpdated(
218220
testOnlinePrimaryRoute,
@@ -258,6 +260,7 @@ class RouteAlternativesControllerTest {
258260
routes = listOf(createDirectionsRoute(refreshTtl = null)),
259261
).toJson(),
260262
responseUUID = "test",
263+
routeGeometry = emptyList(),
261264
)
262265
nativeObserver.captured.onRouteAlternativesUpdated(
263266
testOnlinePrimaryRoute,
@@ -1315,6 +1318,7 @@ class RouteAlternativesControllerTest {
13151318
routerOrigin = routerOrigin,
13161319
responseUUID = response.uuid()!!,
13171320
routeIndex = routeIndex,
1321+
routeGeometry = response.routes()[0].completeGeometryToPoints(),
13181322
)
13191323

13201324
return mockk {

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtils.kt

Lines changed: 5 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ import com.mapbox.navigation.ui.utils.internal.ifNonNull
7070
import com.mapbox.navigation.utils.internal.logE
7171
import com.mapbox.navigation.utils.internal.logW
7272
import com.mapbox.turf.TurfConstants
73-
import com.mapbox.turf.TurfMeasurement
7473
import com.mapbox.turf.TurfMisc
7574
import kotlinx.coroutines.CoroutineScope
7675
import kotlin.math.abs
@@ -1043,19 +1042,11 @@ internal object MapboxRouteLineUtils {
10431042
stepsArray.forEachIndexed { legIndex, stepDistances ->
10441043
val legArray = mutableListOf<RouteLineDistancesIndex>()
10451044
stepDistances.forEachIndexed { stepIndex, distances ->
1046-
val squashed = if (distances.size == 2) {
1047-
// step with 2 coordinate might have duplicated values
1048-
distances.toSet().toTypedArray()
1049-
} else {
1050-
distances
1051-
}
10521045
legArray.addAll(
1053-
if (stepIndex != 0) {
1054-
// removing duplicate points for adjacent steps
1055-
// Array#copyOfRange is significantly faster than Collection#drop
1056-
squashed.copyOfRange(1, squashed.size)
1057-
} else {
1058-
squashed
1046+
when (stepIndex) {
1047+
0 -> distances
1048+
stepDistances.lastIndex -> emptyArray()
1049+
else -> distances.copyOfRange(1, distances.size)
10591050
} as Array<RouteLineDistancesIndex>,
10601051
)
10611052
}
@@ -1074,7 +1065,7 @@ internal object MapboxRouteLineUtils {
10741065
}
10751066

10761067
return RouteLineGranularDistances(
1077-
distance,
1068+
completeDistance = distance,
10781069
routeDistances = routeArray.toTypedArray(),
10791070
legsDistances = legsArray.toTypedArray(),
10801071
stepsDistances = stepsArray as Array<Array<Array<RouteLineDistancesIndex>>>,
@@ -1196,94 +1187,6 @@ internal object MapboxRouteLineUtils {
11961187
).getNumberProperty("dist")?.toDouble() ?: 0.0
11971188
}
11981189

1199-
/**
1200-
* Searches for the closest [RouteLineDistanceIndex] to the point
1201-
* that the point hasn't passed along the route.
1202-
*
1203-
* For example if point is between index 2 and 3 of [RouteLineGranularDistances]
1204-
* and closest to 2 but has already past the [RouteLineGranularDistances] at index
1205-
* 2 along the route, the [RouteLineGranularDistances] at index 3 will be returned.
1206-
*/
1207-
/*
1208-
Prior to this the RouteProgress.currentRouteGeometryIndex was used
1209-
to find the closest RouteLineGranularDistances to a point but there
1210-
are cases where nav. native can emit values in non-consecutive order.
1211-
Meaning values emitted can resemble 7-8-9-8-9-10. This would result
1212-
in trim-offset values that would jump in value then decrement in value.
1213-
The code below should resolve this issue by returning the same RouteLineGranularDistances
1214-
index even in cases where the upcomingIndex parameter has incremented
1215-
"erroneously".
1216-
1217-
In order to determine which RouteLineDistanceIndex to return the bearing of the
1218-
two RouteLineDistanceIndexes the point is between are compared to the bearing
1219-
of the point to the preliminary RouteLineDistanceIndex. If the point hasn't passed
1220-
the preliminary RouteLineDistanceIndex it should have a similar bearing.
1221-
*/
1222-
internal fun findClosestRouteLineDistanceIndexToPoint(
1223-
point: Point,
1224-
granularDistances: RouteLineGranularDistances,
1225-
upcomingIndex: Int,
1226-
): Int {
1227-
val closest = getClosestRoutLineDistanceIndex(point, granularDistances, upcomingIndex)
1228-
if (closest.first == 0) {
1229-
return 1
1230-
}
1231-
1232-
val baseBearing = TurfMeasurement.bearing(
1233-
granularDistances.routeDistances[closest.first - 1].point,
1234-
granularDistances.routeDistances[closest.first].point,
1235-
)
1236-
val closesPointBearing = TurfMeasurement.bearing(
1237-
point,
1238-
granularDistances.routeDistances[closest.first].point,
1239-
)
1240-
return if (isWithin30Degrees(baseBearing, closesPointBearing)) {
1241-
closest.first
1242-
} else {
1243-
if (closest.first < granularDistances.routeDistances.lastIndex) {
1244-
closest.first + 1
1245-
} else {
1246-
closest.first
1247-
}
1248-
}
1249-
}
1250-
1251-
private fun getClosestRoutLineDistanceIndex(
1252-
point: Point,
1253-
granularDistances: RouteLineGranularDistances,
1254-
upcomingIndex: Int,
1255-
): Pair<Int, Double> {
1256-
val pointIndex = max(upcomingIndex - 10, 0)
1257-
val initialDistance = TurfMeasurement.distance(
1258-
granularDistances.routeDistances[pointIndex].point,
1259-
point,
1260-
TurfConstants.UNIT_METERS,
1261-
)
1262-
var closest = Pair(pointIndex, initialDistance)
1263-
for (i in pointIndex..upcomingIndex) {
1264-
val distance = TurfMeasurement.distance(
1265-
granularDistances.routeDistances[i].point,
1266-
point,
1267-
TurfConstants.UNIT_METERS,
1268-
)
1269-
if (distance < closest.second) {
1270-
closest = Pair(i, distance)
1271-
}
1272-
}
1273-
return closest
1274-
}
1275-
1276-
/*
1277-
Determines if two bearings have a range of 30 degrees or less.
1278-
*/
1279-
private fun isWithin30Degrees(bearing1: Double, bearing2: Double): Boolean {
1280-
val normalizedBearing1 = bearing1 % 360
1281-
val normalizedBearing2 = bearing2 % 360
1282-
val difference = abs(normalizedBearing1 - normalizedBearing2)
1283-
1284-
return difference <= 30
1285-
}
1286-
12871190
internal fun buildScalingExpression(scalingValues: List<RouteLineScaleValue>): Expression {
12881191
val expressionBuilder = Expression.ExpressionBuilder("interpolate")
12891192
expressionBuilder.addArgument(Expression.exponential { literal(1.5) })

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/VanishingRouteLine.kt

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,22 +59,24 @@ internal class VanishingRouteLine() {
5959
internal fun getOffset(
6060
point: Point,
6161
granularDistances: RouteLineGranularDistances,
62-
index: Int,
62+
upcomingGeoIndex: Int,
6363
): Double? {
64-
val upcomingIndex = granularDistances.routeDistances.getOrNull(index)
65-
if (upcomingIndex == null) {
64+
val upcomingDistance = granularDistances.routeDistances.getOrNull(
65+
upcomingGeoIndex,
66+
)
67+
if (upcomingDistance == null) {
6668
logD(
6769
"Upcoming route line index is null.",
6870
"VanishingRouteLine",
6971
)
7072
return null
7173
}
7274

73-
if (index > 0) {
75+
if (upcomingGeoIndex > 0) {
7476
val distanceToLine = MapboxRouteLineUtils.findDistanceToNearestPointOnCurrentLine(
7577
point,
7678
granularDistances,
77-
index,
79+
upcomingGeoIndex,
7880
)
7981
if (
8082
distanceToLine >
@@ -83,20 +85,13 @@ internal class VanishingRouteLine() {
8385
return null
8486
}
8587
}
86-
87-
val closestIndex = MapboxRouteLineUtils.findClosestRouteLineDistanceIndexToPoint(
88-
point,
89-
granularDistances,
90-
index,
91-
)
92-
9388
/**
9489
* Take the remaining distance from the upcoming point on the route and extends it
9590
* by the exact position of the puck.
9691
*/
97-
val remainingDistance = granularDistances.routeDistances[closestIndex].distanceRemaining +
92+
val remainingDistance = upcomingDistance.distanceRemaining +
9893
MapboxRouteLineUtils.calculateDistance(
99-
granularDistances.routeDistances[closestIndex].point,
94+
upcomingDistance.point,
10095
point,
10196
)
10297

ui-maps/src/test/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtilsTest.kt

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ import com.mapbox.navigation.ui.maps.route.line.model.SegmentColorType
8585
import com.mapbox.navigation.ui.maps.testing.TestingUtil.loadNavigationRoute
8686
import com.mapbox.navigation.ui.maps.util.CacheResultUtils
8787
import com.mapbox.navigation.ui.maps.util.StyleManager
88-
import com.mapbox.turf.TurfConstants
89-
import com.mapbox.turf.TurfMeasurement
9088
import io.mockk.every
9189
import io.mockk.mockk
9290
import io.mockk.mockkStatic
@@ -2795,46 +2793,4 @@ class MapboxRouteLineUtilsTest {
27952793
MapboxRouteLineUtils.getRouteColorTypeForCongestion("aaa", false),
27962794
)
27972795
}
2798-
2799-
@Test
2800-
fun findClosestRouteLineDistanceIndexToPoint() {
2801-
val route = loadNavigationRoute("customer_test_route.json")
2802-
val granularDistances = MapboxRouteLineUtils.granularDistancesProvider(route)!!
2803-
val point = Point.fromLngLat(11.590394230334425, 48.166546952177086)
2804-
val index1 = MapboxRouteLineUtils.findClosestRouteLineDistanceIndexToPoint(
2805-
point,
2806-
granularDistances,
2807-
8,
2808-
)
2809-
val index2 = MapboxRouteLineUtils.findClosestRouteLineDistanceIndexToPoint(
2810-
point,
2811-
granularDistances,
2812-
9,
2813-
)
2814-
2815-
assertEquals(index1, index2)
2816-
}
2817-
2818-
@Test
2819-
fun findClosestRouteLineDistanceIndexToPoint_whenPointBeyondLastGranularDistancePoint() {
2820-
val route = loadNavigationRoute("short_route.json")
2821-
val granularDistances = MapboxRouteLineUtils.granularDistancesProvider(route)!!
2822-
val bearing = TurfMeasurement.bearing(
2823-
granularDistances.routeDistances[granularDistances.routeDistances.lastIndex - 1].point,
2824-
granularDistances.routeDistances[granularDistances.routeDistances.lastIndex].point,
2825-
)
2826-
val point = TurfMeasurement.destination(
2827-
granularDistances.routeDistances[granularDistances.routeDistances.lastIndex].point,
2828-
1.0,
2829-
bearing,
2830-
TurfConstants.UNIT_METERS,
2831-
)
2832-
val index = MapboxRouteLineUtils.findClosestRouteLineDistanceIndexToPoint(
2833-
point,
2834-
granularDistances,
2835-
granularDistances.routeDistances.lastIndex,
2836-
)
2837-
2838-
assertEquals(index, 4)
2839-
}
28402796
}

0 commit comments

Comments
 (0)