Skip to content

Commit

Permalink
Show alternatives in history replay
Browse files Browse the repository at this point in the history
  • Loading branch information
kmadsen committed Jul 1, 2020
1 parent 8278540 commit 4384ff3
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.mapbox.navigation.base.internal.extensions.applyDefaultParams
import com.mapbox.navigation.base.internal.extensions.coordinates
import com.mapbox.navigation.core.MapboxNavigation
import com.mapbox.navigation.core.directions.session.RoutesRequestCallback
import com.mapbox.navigation.core.fasterroute.FasterRouteObserver
import com.mapbox.navigation.core.replay.MapboxReplayer
import com.mapbox.navigation.core.replay.ReplayLocationEngine
import com.mapbox.navigation.core.replay.history.CustomEventMapper
Expand Down Expand Up @@ -171,6 +172,13 @@ class ReplayHistoryActivity : AppCompatActivity() {
}
})

mapboxNavigation.attachFasterRouteObserver(object : FasterRouteObserver {
override fun onFasterRoute(currentRoute: DirectionsRoute, alternatives: List<DirectionsRoute>, isAlternativeFaster: Boolean) {
navigationContext?.navigationMapboxMap?.drawRoutes(alternatives)
navigationContext?.mapboxNavigation?.setRoutes(alternatives)
}
})

playReplay.setOnClickListener {
mapboxReplayer.play()
mapboxNavigation.startTripSession()
Expand Down Expand Up @@ -235,7 +243,7 @@ class ReplayHistoryActivity : AppCompatActivity() {
override fun onRoutesReady(routes: List<DirectionsRoute>) {
MapboxLogger.d(Message("route request success $routes"))
if (routes.isNotEmpty()) {
navigationContext?.navigationMapboxMap?.drawRoute(routes[0])
navigationContext?.navigationMapboxMap?.drawRoutes(routes)
navigationContext?.startNavigation()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal class FasterRouteController(
) {

private val fasterRouteTimer = MapboxTimer()
private val fasterRouteDetector = FasterRouteDetector()
private val fasterRouteDetector = FasterRouteDetector(RouteComparator())
private var fasterRouteObserver: FasterRouteObserver? = null

fun attach(fasterRouteObserver: FasterRouteObserver) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ package com.mapbox.navigation.core.fasterroute
import com.mapbox.api.directions.v5.models.DirectionsRoute
import com.mapbox.navigation.base.trip.model.RouteProgress

internal class FasterRouteDetector {
fun isRouteFaster(newRoute: DirectionsRoute, routeProgress: RouteProgress): Boolean {
val newRouteDuration = newRoute.duration() ?: return false
internal class FasterRouteDetector(
private val routeComparator: RouteComparator
) {

fun isRouteFaster(alternativeRoute: DirectionsRoute, routeProgress: RouteProgress): Boolean {
val alternativeDuration = alternativeRoute.duration() ?: return false
val weightedDuration = routeProgress.durationRemaining * PERCENTAGE_THRESHOLD
return newRouteDuration < weightedDuration
val isNewRouteFaster = alternativeDuration < weightedDuration
return isNewRouteFaster && routeComparator.isNewRoute(routeProgress, alternativeRoute)
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.mapbox.navigation.core.fasterroute

import com.mapbox.api.directions.v5.models.DirectionsRoute
import com.mapbox.navigation.base.trip.model.RouteProgress

/**
* Compares if an alternative route is different from the current route.
*/
internal class RouteComparator {

/**
* @param routeProgress current route progress
* @param alternativeRoute suggested new route
*
* @return true when the alternative route has different
* geometry from the current route progress
*/
fun isNewRoute(routeProgress: RouteProgress, alternativeRoute: DirectionsRoute): Boolean {
val currentGeometry = routeProgress.route.geometry() ?: ""
val alternativeGeometry = (alternativeRoute.geometry() ?: "").ifEmpty {
return false
}

return isNewRoute(currentGeometry, alternativeGeometry)
}

private fun isNewRoute(currentGeometry: String, alternativeGeometry: String): Boolean {
return currentGeometry != alternativeGeometry
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ import org.junit.Test

class FasterRouteDetectorTest {

private val fasterRouteDetector = FasterRouteDetector()
private val routeComparator: RouteComparator = mockk {
every { isNewRoute(any(), any()) } returns true
}
private val fasterRouteDetector = FasterRouteDetector(routeComparator)

@Test
fun shouldDetectWhenRouteIsFaster() {
every { routeComparator.isNewRoute(any(), any()) } returns true
val newRoute: DirectionsRoute = mockk()
every { newRoute.duration() } returns 402.6
val routeProgress: RouteProgress = mockk()
Expand All @@ -24,6 +28,19 @@ class FasterRouteDetectorTest {
assertTrue(isFasterRoute)
}

@Test
fun shouldDetectWhenRouteIsFasterOnlyIfDifferent() {
every { routeComparator.isNewRoute(any(), any()) } returns false
val newRoute: DirectionsRoute = mockk()
every { newRoute.duration() } returns 402.6
val routeProgress: RouteProgress = mockk()
every { routeProgress.durationRemaining } returns 797.447

val isFasterRoute = fasterRouteDetector.isRouteFaster(newRoute, routeProgress)

assertFalse(isFasterRoute)
}

@Test
fun shouldDetectWhenRouteIsSlower() {
val newRoute: DirectionsRoute = mockk()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.mapbox.navigation.core.fasterroute

import com.mapbox.api.directions.v5.models.DirectionsRoute
import com.mapbox.navigation.base.trip.model.RouteProgress
import io.mockk.every
import io.mockk.mockk
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import org.junit.Test

class RouteComparatorTest {

private val routeComparator = RouteComparator()

@Test
fun `route with different geometry is new`() {
val currentRoute = """indacAcvqniGkFBmJB{FJ_JrEqBbAoRvEwJdBmC\sJb@eEDkEI_Mc@oIUsEF_FTgFt@qHjBmFjB}ItEqItAkE~BeW`NcEbCsNjIcCaFq@wA"""
val alternative = """{{dacAiaqniGdAlIjA^vC\nD?GwX\sFgH?oJ?yF\_JtEqBz@qRtEuJxBoC?uJ|@_E?mE?aM}@oI?sE?}E^cF\yHxBkFzA_JrEmIzAmExBcWfNeExCoNnHgCuEu@yA"""
val routeProgress: RouteProgress = mockk {
every { route } returns mockk {
every { geometry() } returns currentRoute
}
}
val directionsRoute: DirectionsRoute = mockk {
every { geometry() } returns alternative
}

val isNewRoute = routeComparator.isNewRoute(routeProgress, directionsRoute)

assertTrue(isNewRoute)
}

@Test
fun `route with same geometry is not new`() {
val currentRoute = """indacAcvqniGkFBmJB{FJ_JrEqBbAoRvEwJdBmC\sJb@eEDkEI_Mc@oIUsEF_FTgFt@qHjBmFjB}ItEqItAkE~BeW`NcEbCsNjIcCaFq@wA"""
val alternative = """indacAcvqniGkFBmJB{FJ_JrEqBbAoRvEwJdBmC\sJb@eEDkEI_Mc@oIUsEF_FTgFt@qHjBmFjB}ItEqItAkE~BeW`NcEbCsNjIcCaFq@wA"""
val routeProgress: RouteProgress = mockk {
every { route } returns mockk {
every { geometry() } returns currentRoute
}
}
val directionsRoute: DirectionsRoute = mockk {
every { geometry() } returns alternative
}

val isNewRoute = routeComparator.isNewRoute(routeProgress, directionsRoute)

assertFalse(isNewRoute)
}

@Test
fun `alternative is not new when alternative is empty`() {
val currentGeometry = """indacAcvqniGkFBmJB{FJ_JrEqBbAoRvEwJdBmC\sJb@eEDkEI_Mc@oIUsEF_FTgFt@qHjBmFjB}ItEqItAkE~BeW`NcEbCsNjIcCaFq@wA"""
val alternativeGeometry = ""
val routeProgress: RouteProgress = mockk {
every { route } returns mockk {
every { geometry() } returns currentGeometry
}
}
val directionsRoute: DirectionsRoute = mockk {
every { geometry() } returns alternativeGeometry
}

val isNewRoute = routeComparator.isNewRoute(routeProgress, directionsRoute)

assertFalse(isNewRoute)
}

@Test
fun `routes with same beginning and end, can still be different`() {
val currentGeometry = """e|h~bAslcjiGvBab@tHe}AnEs~@AqdAB{d@EsQCii@Ie\EeUFoh@Reg@nHwEbUsNjUuM`ZiQ|McI`e@eZbf@yX|[wRdCyAfYcQpYwPlVcOvn@y^nUqKfPwFnLeDvW{Hd^sKhr@kTzk@yd@jMuK|IqC`PrgAhM|u@nInm@pB`KnCjMbFzS`EtOrIl_@`T|{@rChMzL`i@jGbX|CzMtd@bjBbEfPdU~}@pFdTjAxDzH~XjGrSdOlc@xTvs@tUzt@jKl_@hP`d@bM``@tQ`h@vVlu@dYlw@pLl]nNrd@lApEtCdIpXpv@|AtExUpt@bXps@`Stk@lDfKlSbl@rv@~{BdD~HdIdMnOpQ|e@la@tt@|m@nEpDlItBxYhVlJ~H|P|L`LhI~SdL~FnBbXjElYbFlW`G|f@|Hpt@|J|Fm^vJs`@|Swk@jPee@j@_BpA{BrEaIfHcM~]vS`EbB"""
val alternativeGeometry = """e|h~bAslcjiGvBab@tHe}AnEs~@AqdAB{d@EsQCii@Ie\EeUh`@}@ta@_@x\mAlE~YjA`IpAxGvCzSxG`c@lJjn@~AxKZvIIvDfYzSpAdAbHvFlLnEnJHvJEXtKnBdh@mCxV\~H|Jv`@zc@uKtZoIz]aKva@kKj]mIzOyDf_@mJvNcEbOqD`SmF~XiH\bOj@jXZnIX`Lt@jMt@fLnAlPn@bJ|BfS`Pg@nFOpDUde@iFbOk@fq@}BrRL|SCfBWfa@wU|[eR\SrOaJpJkFxTvs@tUzt@jKl_@hP`d@bM``@tQ`h@vVlu@dYlw@pLl]nNrd@lApEtCdIpXpv@|AtExUpt@bXps@`Stk@lDfKlSbl@rv@~{BdD~HdIdMnOpQ|e@la@tt@|m@nEpDlItBxYhVlJ~H|P|L`LhI~SdL~FnBbXjElYbFlW`G|f@|Hpt@|J|Fm^vJs`@|Swk@jPee@j@_BpA{BrEaIfHcM~]vS`EbB"""
val routeProgress: RouteProgress = mockk {
every { route } returns mockk {
every { geometry() } returns currentGeometry
}
}
val directionsRoute: DirectionsRoute = mockk {
every { geometry() } returns alternativeGeometry
}

val isNewRoute = routeComparator.isNewRoute(routeProgress, directionsRoute)

assertTrue(isNewRoute)
}
}

0 comments on commit 4384ff3

Please sign in to comment.