Skip to content

Commit eefc831

Browse files
committed
NAVAND-552: calculate the number of instructions to download
1 parent 67b9efc commit eefc831

File tree

4 files changed

+916
-0
lines changed

4 files changed

+916
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.mapbox.navigation.ui.voice.api
2+
3+
import com.mapbox.api.directions.v5.models.DirectionsRoute
4+
import com.mapbox.api.directions.v5.models.VoiceInstructions
5+
6+
internal data class RouteProgressData(
7+
val route: DirectionsRoute,
8+
val legIndex: Int,
9+
val stepIndex: Int,
10+
val stepDurationRemaining: Double,
11+
val stepDistanceRemaining: Double,
12+
)
13+
14+
internal interface NextVoiceInstructionsProvider {
15+
16+
fun getNextVoiceInstructions(progress: RouteProgressData): List<VoiceInstructions>
17+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package com.mapbox.navigation.ui.voice.api
2+
3+
import com.mapbox.api.directions.v5.models.LegStep
4+
import com.mapbox.api.directions.v5.models.RouteLeg
5+
import com.mapbox.api.directions.v5.models.VoiceInstructions
6+
import com.mapbox.navigation.utils.internal.logW
7+
8+
internal class TimeBasedNextVoiceInstructionsProvider(
9+
private val observableTimeSeconds: Int,
10+
) : NextVoiceInstructionsProvider {
11+
12+
override fun getNextVoiceInstructions(progress: RouteProgressData): List<VoiceInstructions> {
13+
val legs = progress.route.legs() ?: return emptyList<VoiceInstructions>().also {
14+
logW(
15+
"Route does not contain legs, progress=$progress",
16+
LOG_CATEGORY
17+
)
18+
}
19+
var legSteps = legs.getOrNull(progress.legIndex)?.steps()
20+
var currentStep = legSteps
21+
?.getOrNull(progress.stepIndex)
22+
?: return emptyList<VoiceInstructions>().also {
23+
logW(
24+
"Route does not contain valid step, progress=$progress",
25+
LOG_CATEGORY
26+
)
27+
}
28+
29+
val voiceInstructions = mutableListOf<VoiceInstructions>()
30+
fillCurrentStepVoiceInstructions(
31+
currentStep,
32+
progress.stepDistanceRemaining,
33+
voiceInstructions
34+
)
35+
var cumulatedTime = progress.stepDurationRemaining
36+
37+
// fill next steps
38+
var currentStepIndex = progress.stepIndex
39+
var currentLegIndex = progress.legIndex
40+
while (cumulatedTime < observableTimeSeconds) {
41+
if (isLastStep(currentStepIndex, legSteps)) {
42+
currentStepIndex = 0
43+
if (isLastLeg(currentLegIndex, legs)) {
44+
break
45+
} else {
46+
legSteps = legs[currentLegIndex + 1].steps()
47+
currentLegIndex++
48+
if (legSteps.isNullOrEmpty()) {
49+
continue
50+
} else {
51+
currentStep = legSteps.first()
52+
}
53+
}
54+
} else {
55+
currentStep = legSteps!![currentStepIndex + 1]
56+
currentStepIndex++
57+
}
58+
currentStep.voiceInstructions()?.let { voiceInstructions.addAll(it) }
59+
cumulatedTime += currentStep.duration()
60+
}
61+
return voiceInstructions
62+
}
63+
64+
private fun fillCurrentStepVoiceInstructions(
65+
currentStep: LegStep,
66+
stepDistanceRemaining: Double,
67+
voiceInstructions: MutableList<VoiceInstructions>
68+
) {
69+
val currentStepInstructions = currentStep.voiceInstructions()?.filter { instruction ->
70+
val distanceAlongGeometry = instruction.distanceAlongGeometry()
71+
distanceAlongGeometry != null &&
72+
distanceAlongGeometry <= stepDistanceRemaining
73+
}
74+
if (currentStepInstructions != null) {
75+
voiceInstructions.addAll(currentStepInstructions)
76+
}
77+
}
78+
79+
private fun isLastStep(currentStepIndex: Int, legSteps: List<LegStep>?): Boolean {
80+
return currentStepIndex + 1 >= (legSteps?.size ?: 0)
81+
}
82+
83+
private fun isLastLeg(currentLegIndex: Int, legs: List<RouteLeg>): Boolean {
84+
return currentLegIndex + 1 >= legs.size
85+
}
86+
87+
private companion object {
88+
private const val LOG_CATEGORY = "TimeBasedNextVoiceInstructionsProvider"
89+
}
90+
}

0 commit comments

Comments
 (0)