From 8985c19b7d95a735dea1e10d5d9e452ae43c73ff Mon Sep 17 00:00:00 2001 From: VysotskiVadim Date: Fri, 4 Nov 2022 09:36:50 +0100 Subject: [PATCH 01/13] implemented experimental route preview --- CHANGELOG.md | 18 + .../examples/core/MapboxNavigationActivity.kt | 79 +++- .../res/layout/layout_activity_navigation.xml | 15 +- .../core/RoutesPreviewTest.kt | 192 +++++++++ .../utils/coroutines/Adapters.kt | 17 + libnavigation-core/api/current.txt | 43 ++ .../navigation/core/MapboxNavigation.kt | 74 ++++ .../core/NavigationComponentProvider.kt | 10 + .../core/preview/NativeRoutesDataParser.kt | 18 + .../navigation/core/preview/RoutesPreview.kt | 74 ++++ .../core/preview/RoutesPreviewController.kt | 148 +++++++ .../core/preview/RoutesPreviewExtra.kt | 34 ++ .../core/preview/RoutesPreviewObserver.kt | 64 +++ .../RouteAlternativesController.kt | 2 +- .../core/preview/RouteDataParserStub.kt | 28 ++ .../preview/RoutePreviewControllerFactory.kt | 18 + .../preview/RoutesPreviewControllerTest.kt | 404 ++++++++++++++++++ 17 files changed, 1224 insertions(+), 14 deletions(-) create mode 100644 instrumentation-tests/src/androidTest/java/com/mapbox/navigation/instrumentation_tests/core/RoutesPreviewTest.kt create mode 100644 libnavigation-core/src/main/java/com/mapbox/navigation/core/preview/NativeRoutesDataParser.kt create mode 100644 libnavigation-core/src/main/java/com/mapbox/navigation/core/preview/RoutesPreview.kt create mode 100644 libnavigation-core/src/main/java/com/mapbox/navigation/core/preview/RoutesPreviewController.kt create mode 100644 libnavigation-core/src/main/java/com/mapbox/navigation/core/preview/RoutesPreviewExtra.kt create mode 100644 libnavigation-core/src/main/java/com/mapbox/navigation/core/preview/RoutesPreviewObserver.kt create mode 100644 libnavigation-core/src/test/java/com/mapbox/navigation/core/preview/RouteDataParserStub.kt create mode 100644 libnavigation-core/src/test/java/com/mapbox/navigation/core/preview/RoutePreviewControllerFactory.kt create mode 100644 libnavigation-core/src/test/java/com/mapbox/navigation/core/preview/RoutesPreviewControllerTest.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index b54e049f7c5..aaec3cfddc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,24 @@ Mapbox welcomes participation and contributions from everyone. ## Unreleased #### Features +- Added `ComponentInstaller` for the `TripProgressComponent` that offers simplified integration of the `MapboxTripProgressView` and `MapboxTripProgressApi`. [#6513](https://github.com/mapbox/mapbox-navigation-android/pull/6513) +- Introduced new `ViewOptionsCustomization` options that allows showing/hiding of various `NavigationView` subviews. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showManeuver` can be used to show/hide the maneuver view. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showSpeedLimit` can be used to show/hide the speed limit view. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showRoadName` can be used to show/hide the road name view. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showActionButtons` can be used to show/hide action buttons layout. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showCompassActionButton` can be used to show/hide compass action button. The default is `false`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showCameraModeActionButton` can be used to show/hide toggle camera mode action button. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showToggleAudioActionButton` can be used to show/hide toggle voice instructions action button. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showRecenterActionButton` can be used to show/hide re-center camera action button. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showTripProgress` can be used to show/hide info panel's trip progress view. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showRoutePreviewButton` can be used to show/hide info panel's show route preview button. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showStartNavigationButton` can be used to show/hide info panel's start navigation button. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) + - `ViewOptionsCustomization.showEndNavigationButton` can be used to show/hide info panel's end navigation button. The default is `true`. [#6506](https://github.com/mapbox/mapbox-navigation-android/pull/6506) +- Introduced `ViewOptionsCustomization.showPoiName` and `ViewOptionsCustomization.showArrivalText` that allows showing/hiding of the POI and arrival text view. [#6515](https://github.com/mapbox/mapbox-navigation-android/pull/6515) +- Introduced `ViewBinderCustomization.infoPanelPoiNameBinder` and `ViewBinderCustomization.infoPanelArrivalTextBinder` that allows injection of custom Info Panel POI and arrival text view into `NavigationView`. [#6515](https://github.com/mapbox/mapbox-navigation-android/pull/6515) +- Added `LocationMatcherResult#inTunnel` which indicates if a current matched location is in a tunnel. [#6548](https://github.com/mapbox/mapbox-navigation-android/pull/6548) +- Added experimental routes preview state, see `MapboxNavigaton#setRoutesPreview`, `MapboxNavigaton#changeRoutesPreviewPrimaryRoute`, `MapboxNavigaton#registerRoutesPreviewObserver`, `MapboxNavigaton#getRoutesPreview`. [#6495](https://github.com/mapbox/mapbox-navigation-android/pull/6495) #### Bug fixes and improvements ## Mapbox Navigation SDK 2.10.0-alpha.2 - 04 November, 2022 diff --git a/examples/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt b/examples/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt index 84ea81b9275..34d028e77d9 100644 --- a/examples/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt +++ b/examples/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt @@ -5,11 +5,13 @@ import android.content.res.Configuration import android.content.res.Resources import android.location.Location import android.os.Bundle +import android.view.View import android.view.View.INVISIBLE import android.view.View.VISIBLE import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat +import androidx.lifecycle.lifecycleScope import com.mapbox.api.directions.v5.models.RouteOptions import com.mapbox.bindgen.Expected import com.mapbox.geojson.Point @@ -19,8 +21,10 @@ import com.mapbox.maps.MapboxMap import com.mapbox.maps.Style.Companion.MAPBOX_STREETS import com.mapbox.maps.plugin.LocationPuck2D import com.mapbox.maps.plugin.animation.camera +import com.mapbox.maps.plugin.gestures.OnMapClickListener import com.mapbox.maps.plugin.gestures.gestures import com.mapbox.maps.plugin.locationcomponent.location +import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI import com.mapbox.navigation.base.TimeFormat import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions import com.mapbox.navigation.base.extensions.applyLanguageAndVoiceUnitOptions @@ -35,6 +39,7 @@ import com.mapbox.navigation.core.MapboxNavigation import com.mapbox.navigation.core.MapboxNavigationProvider import com.mapbox.navigation.core.directions.session.RoutesObserver import com.mapbox.navigation.core.formatter.MapboxDistanceFormatter +import com.mapbox.navigation.core.preview.RoutesPreviewObserver import com.mapbox.navigation.core.trip.session.LocationMatcherResult import com.mapbox.navigation.core.trip.session.LocationObserver import com.mapbox.navigation.core.trip.session.NavigationSessionStateObserver @@ -52,11 +57,10 @@ import com.mapbox.navigation.ui.maps.location.NavigationLocationProvider import com.mapbox.navigation.ui.maps.route.arrow.api.MapboxRouteArrowApi import com.mapbox.navigation.ui.maps.route.arrow.api.MapboxRouteArrowView import com.mapbox.navigation.ui.maps.route.arrow.model.RouteArrowOptions -import com.mapbox.navigation.ui.maps.route.line.MapboxRouteLineApiExtensions.setRoutes +import com.mapbox.navigation.ui.maps.route.line.MapboxRouteLineApiExtensions.findClosestRoute import com.mapbox.navigation.ui.maps.route.line.api.MapboxRouteLineApi import com.mapbox.navigation.ui.maps.route.line.api.MapboxRouteLineView import com.mapbox.navigation.ui.maps.route.line.model.MapboxRouteLineOptions -import com.mapbox.navigation.ui.maps.route.line.model.RouteLine import com.mapbox.navigation.ui.tripprogress.api.MapboxTripProgressApi import com.mapbox.navigation.ui.tripprogress.model.DistanceRemainingFormatter import com.mapbox.navigation.ui.tripprogress.model.EstimatedTimeToArrivalFormatter @@ -70,11 +74,10 @@ import com.mapbox.navigation.ui.voice.model.SpeechError import com.mapbox.navigation.ui.voice.model.SpeechValue import com.mapbox.navigation.ui.voice.model.SpeechVolume import com.mapbox.navigation.utils.internal.logD -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.util.Locale +@OptIn(ExperimentalPreviewMapboxNavigationAPI::class) class MapboxNavigationActivity : AppCompatActivity() { /* ----- Layout binding reference ----- */ @@ -229,18 +232,17 @@ class MapboxNavigationActivity : AppCompatActivity() { } private val routesObserver = RoutesObserver { result -> - if (result.routes.isNotEmpty()) { + if (result.navigationRoutes.isNotEmpty()) { // generate route geometries asynchronously and render them - CoroutineScope(Dispatchers.Main).launch { - val result = routeLineAPI.setRoutes( - listOf(RouteLine(result.routes.first(), null)) - ) + routeLineAPI.setNavigationRoutes( + result.navigationRoutes, + mapboxNavigation.getAlternativeMetadataFor(result.navigationRoutes) + ) { val style = mapboxMap.getStyle() if (style != null) { - routeLineView.renderRouteDrawData(style, result) + routeLineView.renderRouteDrawData(style, it) } } - // update the camera position to account for the new route viewportDataSource.onRouteChanged(result.routes.first()) viewportDataSource.evaluate() @@ -263,11 +265,48 @@ class MapboxNavigationActivity : AppCompatActivity() { } } + private val routesPreviewObserver = RoutesPreviewObserver { update -> + val routePreview = update.routesPreview + if (routePreview != null) { + routeLineAPI.setNavigationRoutes( + routePreview.routesList, + routePreview.alternativesMetadata + ) { + val style = mapboxMap.getStyle() + if (style != null) { + routeLineView.renderRouteDrawData(style, it) + } + } + // update the camera position to account for the new route + viewportDataSource.onRouteChanged(routePreview.primaryRoute) + viewportDataSource.evaluate() + } + } + private val navigationSessionStateObserver = NavigationSessionStateObserver { logD("NavigationSessionState=$it", LOG_CATEGORY) logD("sessionId=${mapboxNavigation.getNavigationSessionState().sessionId}", LOG_CATEGORY) } + private val routeClickPadding = com.mapbox.android.gestures.Utils.dpToPx(30f) + + private val previewMapClickListener = OnMapClickListener { + lifecycleScope.launch { + mapboxNavigation.getRoutesPreview() ?: return@launch + val result = routeLineAPI.findClosestRoute( + it, + binding.mapView.getMapboxMap(), + routeClickPadding + ) + + val routeFound = result.value?.navigationRoute + if (routeFound != null && routeFound != routeLineAPI.getPrimaryNavigationRoute()) { + mapboxNavigation.changeRoutesPreviewPrimaryRoute(routeFound) + } + } + false + } + @SuppressLint("MissingPermission") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -401,6 +440,7 @@ class MapboxNavigationActivity : AppCompatActivity() { findRoute(point) true } + binding.mapView.gestures.addOnMapClickListener(previewMapClickListener) } // initialize view interactions @@ -438,6 +478,7 @@ class MapboxNavigationActivity : AppCompatActivity() { mapboxNavigation.registerRouteProgressObserver(routeProgressObserver) mapboxNavigation.registerLocationObserver(locationObserver) mapboxNavigation.registerVoiceInstructionsObserver(voiceInstructionsObserver) + mapboxNavigation.registerRoutesPreviewObserver(routesPreviewObserver) } override fun onStop() { @@ -447,6 +488,7 @@ class MapboxNavigationActivity : AppCompatActivity() { mapboxNavigation.unregisterRouteProgressObserver(routeProgressObserver) mapboxNavigation.unregisterLocationObserver(locationObserver) mapboxNavigation.unregisterVoiceInstructionsObserver(voiceInstructionsObserver) + mapboxNavigation.unregisterRoutesPreviewObserver(routesPreviewObserver) } override fun onDestroy() { @@ -468,6 +510,7 @@ class MapboxNavigationActivity : AppCompatActivity() { RouteOptions.builder() .applyDefaultNavigationOptions() .applyLanguageAndVoiceUnitOptions(this) + .alternatives(true) .coordinatesList(listOf(origin, destination)) .layersList(listOf(mapboxNavigation.getZLevel(), null)) .build(), @@ -476,7 +519,7 @@ class MapboxNavigationActivity : AppCompatActivity() { routes: List, routerOrigin: RouterOrigin ) { - setRouteAndStartNavigation(routes) + setRoutesPreview(routes) } override fun onFailure( @@ -493,6 +536,18 @@ class MapboxNavigationActivity : AppCompatActivity() { ) } + private fun setRoutesPreview(routes: List) { + binding.navigateButton.apply { + visibility = View.VISIBLE + setOnClickListener { + visibility = View.GONE + setRouteAndStartNavigation(mapboxNavigation.getRoutesPreview()!!.routesList) + mapboxNavigation.setRoutesPreview(emptyList()) + } + } + mapboxNavigation.setRoutesPreview(routes) + } + private fun setRouteAndStartNavigation(route: List) { // set route mapboxNavigation.setNavigationRoutes(route) diff --git a/examples/src/main/res/layout/layout_activity_navigation.xml b/examples/src/main/res/layout/layout_activity_navigation.xml index 1a6f38c5d9e..85d34baa5bf 100644 --- a/examples/src/main/res/layout/layout_activity_navigation.xml +++ b/examples/src/main/res/layout/layout_activity_navigation.xml @@ -2,7 +2,9 @@ + android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools" + > +