Mapbox-navigation-android: KotlinNullPointerException inside ReplayRouteDriver - trying to setup mapboxReplayer

Created on 19 Aug 2020  路  5Comments  路  Source: mapbox/mapbox-navigation-android

Android API: 929 / Android 10
Mapbox Navigation SDK version:
implementation 'com.mapbox.navigation:ui-v1:1.0.0-SNAPSHOT'
implementation 'com.mapbox.navigation:core:1.0.0-rc.4'

Steps to trigger behavior

  1. Call ReplayRouteMapper.mapDirectionsRouteLegAnnotation() with a route
  2. ???
  3. KotlinNullPointerException at ReplayRouteDriver.driveRouteLeg().

Expected behavior

No exception

Actual behavior

Exception thrown. I tried to enable a custom replayer so that I can simulate driving while sitting at home. Code is below the exception.

kotlin.KotlinNullPointerException
        at com.mapbox.navigation.core.replay.route.ReplayRouteDriver.driveRouteLeg(ReplayRouteDriver.kt:71)
        at com.mapbox.navigation.core.replay.route.ReplayRouteMapper.mapRouteLegAnnotation(ReplayRouteMapper.kt:101)
        at com.mapbox.navigation.core.replay.route.ReplayRouteMapper.mapDirectionsRouteLegAnnotation(ReplayRouteMapper.kt:88)
        at xyz.removed.package.name.presentation.activities.MapBoxNavigationActivity$routesRequestCallback$1.onRoutesReady(MapBoxNavigationActivity.kt:108)
        at com.mapbox.navigation.core.directions.session.MapboxDirectionsSession$requestRoutes$1.onResponse(MapboxDirectionsSession.kt:79)
        at com.mapbox.navigation.route.hybrid.internal.MapboxHybridRouter$RouterHandler.onResponse(MapboxHybridRouter.kt:91)
        at com.mapbox.navigation.route.offboard.internal.MapboxOffboardRouter$getRoute$1.onResponse(MapboxOffboardRouter.kt:68)
// MapboxNavigationActivity.kt
    private val mapboxReplayer by lazy { MapboxReplayer() }

    private val routesRequestCallback = object : RoutesRequestCallback {
        override fun onRoutesReady(routes: List<DirectionsRoute>) {
            mapboxNavigation.setRoutes(routes)
            navigationMapRoute.addRoutes(routes)

            val mapper = ReplayRouteMapper()
            val firstRoute = routes.firstOrNull() ?: return
            val eventList = mapper.mapDirectionsRouteLegAnnotation(firstRoute)

            mapboxReplayer.pushEvents(eventList)
        }
      // ...
    }

    private fun setupLocationTracking(style: Style) {
        // ...
        val locationEngine = if (debug) {
            ReplayLocationEngine(mapboxReplayer)
        } else {
            mapboxNavigation.navigationOptions.locationEngine
        }

        val locationComponentActivationOptions = LocationComponentActivationOptions
                .builder(this, style)
                .locationEngine(locationEngine)
                // ...
                .build()
        mapboxMap.locationComponent.activateLocationComponent(locationComponentActivationOptions)
        mapboxMap.locationComponent.isLocationComponentEnabled = true
        mapboxMap.locationComponent.renderMode = GPS
    }
bug

All 5 comments

cc @kmadsen

Thanks for reporting @carstenhag! The ReplayRouteMapper.mapDirectionsRouteLegAnnotation() function has not been used much, it simulates the route using the directions api traffic conditions.

The other ways you can simulate a route, are by mapping the route using ReplayRouteMapper().mapGeometry(). You can also register a ReplayRouteObserver which will work when you set routes through MapboxNavigation.setRoutes

The latter simulators can be customized with their own speed profiles based on route geometry https://github.com/mapbox/mapbox-navigation-android/blob/384a25d5e1a409d6316fe3a1dfd9f4c9747ea81a/libnavigation-core/src/main/java/com/mapbox/navigation/core/replay/route/ReplayRouteOptions.kt#L9-L13

Also, will dig into mapDirectionsRouteLegAnnotation issue soon

@carstenhag here is where the exception is happening. We need the speed from the directions response in order to create a simulation speed
https://github.com/mapbox/mapbox-navigation-android/blob/285adbbdd0ae59e0de5c4507893e1f4e52f708f5/libnavigation-core/src/main/java/com/mapbox/navigation/core/replay/route/ReplayRouteDriver.kt#L71

Can you make sure to add DrivingCriteria.PROFILE_DRIVING_TRAFFIC to your directions request?

  RouteOptions.builder().applyDefaultParams()
                        .accessToken(Utils.getMapboxAccessToken(applicationContext))
                        .coordinates(originLocation.toPoint(), null, latLng.toPoint())
                        .profile(DirectionsCriteria.PROFILE_DRIVING_TRAFFIC)
                        .build(),

EDIT: actually I'm noticing the speed is null even with the criteria added 馃

Thanks, works with the below code now 馃憤 馃拑

        override fun onRoutesReady(routes: List<DirectionsRoute>) {
            mapboxNavigation.setRoutes(routes)
            navigationMapRoute.addRoutes(routes)

            val mapper = ReplayRouteMapper()
            val firstRouteGeometry = routes.firstOrNull()?.geometry() ?: return

            mapboxReplayer.apply {
                clearEvents()
                pushEvents(mapper.mapGeometry(firstRouteGeometry))
                playbackSpeed(10.0)
                play()
            }
        }

Found issues with mapDirectionsRouteLegAnnotation while investigating this.

The NPE will be fixed with better error messaging. But that function doesn't work very well, but will track it here
https://github.com/mapbox/mapbox-navigation-android/issues/3476

Was this page helpful?
0 / 5 - 0 ratings