Skip to content

Commit 22a771d

Browse files
committed
implemented experimental route preview
1 parent adb715c commit 22a771d

File tree

17 files changed

+1207
-14
lines changed

17 files changed

+1207
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Mapbox welcomes participation and contributions from everyone.
2121
- 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)
2222
- 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)
2323
- Added `LocationMatcherResult#inTunnel` which indicates if a current matched location is in a tunnel. [#6548](https://github.com/mapbox/mapbox-navigation-android/pull/6548)
24+
- Added experimental routes preview state, see `MapboxNavigaton#setRoutesPreview`, `MapboxNavigaton#changeRoutesPreviewPrimaryRoute`, `MapboxNavigaton#registerRoutesPreviewObserver`, `MapboxNavigaton#getRoutesPreview`. [#6495](https://github.com/mapbox/mapbox-navigation-android/pull/6495)
2425
#### Bug fixes and improvements
2526
- :warning: Removed `MapboxMapScalebarParams` and replaced `ViewStyleCustomization.mapScalebarParams` by `ViewOptionsCustomization.showMapScalebar` [#6523](https://github.com/mapbox/mapbox-navigation-android/pull/6523)
2627
- Refactored `ScalebarComponent` to use `ViewOptionsCustomization.distanceFormatterOptions` to change between imperial and metric based unit. [#6523](https://github.com/mapbox/mapbox-navigation-android/pull/6523)

examples/src/main/java/com/mapbox/navigation/examples/core/MapboxNavigationActivity.kt

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import android.content.res.Configuration
55
import android.content.res.Resources
66
import android.location.Location
77
import android.os.Bundle
8+
import android.view.View
89
import android.view.View.INVISIBLE
910
import android.view.View.VISIBLE
1011
import android.widget.Toast
1112
import androidx.appcompat.app.AppCompatActivity
1213
import androidx.core.content.ContextCompat
14+
import androidx.lifecycle.lifecycleScope
1315
import com.mapbox.api.directions.v5.models.RouteOptions
1416
import com.mapbox.bindgen.Expected
1517
import com.mapbox.geojson.Point
@@ -19,8 +21,10 @@ import com.mapbox.maps.MapboxMap
1921
import com.mapbox.maps.Style.Companion.MAPBOX_STREETS
2022
import com.mapbox.maps.plugin.LocationPuck2D
2123
import com.mapbox.maps.plugin.animation.camera
24+
import com.mapbox.maps.plugin.gestures.OnMapClickListener
2225
import com.mapbox.maps.plugin.gestures.gestures
2326
import com.mapbox.maps.plugin.locationcomponent.location
27+
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
2428
import com.mapbox.navigation.base.TimeFormat
2529
import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
2630
import com.mapbox.navigation.base.extensions.applyLanguageAndVoiceUnitOptions
@@ -35,6 +39,7 @@ import com.mapbox.navigation.core.MapboxNavigation
3539
import com.mapbox.navigation.core.MapboxNavigationProvider
3640
import com.mapbox.navigation.core.directions.session.RoutesObserver
3741
import com.mapbox.navigation.core.formatter.MapboxDistanceFormatter
42+
import com.mapbox.navigation.core.preview.RoutesPreviewObserver
3843
import com.mapbox.navigation.core.trip.session.LocationMatcherResult
3944
import com.mapbox.navigation.core.trip.session.LocationObserver
4045
import com.mapbox.navigation.core.trip.session.NavigationSessionStateObserver
@@ -52,11 +57,10 @@ import com.mapbox.navigation.ui.maps.location.NavigationLocationProvider
5257
import com.mapbox.navigation.ui.maps.route.arrow.api.MapboxRouteArrowApi
5358
import com.mapbox.navigation.ui.maps.route.arrow.api.MapboxRouteArrowView
5459
import com.mapbox.navigation.ui.maps.route.arrow.model.RouteArrowOptions
55-
import com.mapbox.navigation.ui.maps.route.line.MapboxRouteLineApiExtensions.setRoutes
60+
import com.mapbox.navigation.ui.maps.route.line.MapboxRouteLineApiExtensions.findClosestRoute
5661
import com.mapbox.navigation.ui.maps.route.line.api.MapboxRouteLineApi
5762
import com.mapbox.navigation.ui.maps.route.line.api.MapboxRouteLineView
5863
import com.mapbox.navigation.ui.maps.route.line.model.MapboxRouteLineOptions
59-
import com.mapbox.navigation.ui.maps.route.line.model.RouteLine
6064
import com.mapbox.navigation.ui.tripprogress.api.MapboxTripProgressApi
6165
import com.mapbox.navigation.ui.tripprogress.model.DistanceRemainingFormatter
6266
import com.mapbox.navigation.ui.tripprogress.model.EstimatedTimeToArrivalFormatter
@@ -70,11 +74,10 @@ import com.mapbox.navigation.ui.voice.model.SpeechError
7074
import com.mapbox.navigation.ui.voice.model.SpeechValue
7175
import com.mapbox.navigation.ui.voice.model.SpeechVolume
7276
import com.mapbox.navigation.utils.internal.logD
73-
import kotlinx.coroutines.CoroutineScope
74-
import kotlinx.coroutines.Dispatchers
7577
import kotlinx.coroutines.launch
7678
import java.util.Locale
7779

80+
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
7881
class MapboxNavigationActivity : AppCompatActivity() {
7982

8083
/* ----- Layout binding reference ----- */
@@ -229,18 +232,17 @@ class MapboxNavigationActivity : AppCompatActivity() {
229232
}
230233

231234
private val routesObserver = RoutesObserver { result ->
232-
if (result.routes.isNotEmpty()) {
235+
if (result.navigationRoutes.isNotEmpty()) {
233236
// generate route geometries asynchronously and render them
234-
CoroutineScope(Dispatchers.Main).launch {
235-
val result = routeLineAPI.setRoutes(
236-
listOf(RouteLine(result.routes.first(), null))
237-
)
237+
routeLineAPI.setNavigationRoutes(
238+
result.navigationRoutes,
239+
mapboxNavigation.getAlternativeMetadataFor(result.navigationRoutes)
240+
) {
238241
val style = mapboxMap.getStyle()
239242
if (style != null) {
240-
routeLineView.renderRouteDrawData(style, result)
243+
routeLineView.renderRouteDrawData(style, it)
241244
}
242245
}
243-
244246
// update the camera position to account for the new route
245247
viewportDataSource.onRouteChanged(result.routes.first())
246248
viewportDataSource.evaluate()
@@ -263,11 +265,48 @@ class MapboxNavigationActivity : AppCompatActivity() {
263265
}
264266
}
265267

268+
private val routesPreviewObserver = RoutesPreviewObserver { update ->
269+
val routePreview = update.routesPreview
270+
if (routePreview != null) {
271+
routeLineAPI.setNavigationRoutes(
272+
routePreview.routesList,
273+
routePreview.alternativesMetadata
274+
) {
275+
val style = mapboxMap.getStyle()
276+
if (style != null) {
277+
routeLineView.renderRouteDrawData(style, it)
278+
}
279+
}
280+
// update the camera position to account for the new route
281+
viewportDataSource.onRouteChanged(routePreview.primaryRoute)
282+
viewportDataSource.evaluate()
283+
}
284+
}
285+
266286
private val navigationSessionStateObserver = NavigationSessionStateObserver {
267287
logD("NavigationSessionState=$it", LOG_CATEGORY)
268288
logD("sessionId=${mapboxNavigation.getNavigationSessionState().sessionId}", LOG_CATEGORY)
269289
}
270290

291+
private val routeClickPadding = com.mapbox.android.gestures.Utils.dpToPx(30f)
292+
293+
private val previewMapClickListener = OnMapClickListener {
294+
lifecycleScope.launch {
295+
mapboxNavigation.getRoutesPreview() ?: return@launch
296+
val result = routeLineAPI.findClosestRoute(
297+
it,
298+
binding.mapView.getMapboxMap(),
299+
routeClickPadding
300+
)
301+
302+
val routeFound = result.value?.navigationRoute
303+
if (routeFound != null && routeFound != routeLineAPI.getPrimaryNavigationRoute()) {
304+
mapboxNavigation.changeRoutesPreviewPrimaryRoute(routeFound)
305+
}
306+
}
307+
false
308+
}
309+
271310
@SuppressLint("MissingPermission")
272311
override fun onCreate(savedInstanceState: Bundle?) {
273312
super.onCreate(savedInstanceState)
@@ -401,6 +440,7 @@ class MapboxNavigationActivity : AppCompatActivity() {
401440
findRoute(point)
402441
true
403442
}
443+
binding.mapView.gestures.addOnMapClickListener(previewMapClickListener)
404444
}
405445

406446
// initialize view interactions
@@ -438,6 +478,7 @@ class MapboxNavigationActivity : AppCompatActivity() {
438478
mapboxNavigation.registerRouteProgressObserver(routeProgressObserver)
439479
mapboxNavigation.registerLocationObserver(locationObserver)
440480
mapboxNavigation.registerVoiceInstructionsObserver(voiceInstructionsObserver)
481+
mapboxNavigation.registerRoutesPreviewObserver(routesPreviewObserver)
441482
}
442483

443484
override fun onStop() {
@@ -447,6 +488,7 @@ class MapboxNavigationActivity : AppCompatActivity() {
447488
mapboxNavigation.unregisterRouteProgressObserver(routeProgressObserver)
448489
mapboxNavigation.unregisterLocationObserver(locationObserver)
449490
mapboxNavigation.unregisterVoiceInstructionsObserver(voiceInstructionsObserver)
491+
mapboxNavigation.unregisterRoutesPreviewObserver(routesPreviewObserver)
450492
}
451493

452494
override fun onDestroy() {
@@ -468,6 +510,7 @@ class MapboxNavigationActivity : AppCompatActivity() {
468510
RouteOptions.builder()
469511
.applyDefaultNavigationOptions()
470512
.applyLanguageAndVoiceUnitOptions(this)
513+
.alternatives(true)
471514
.coordinatesList(listOf(origin, destination))
472515
.layersList(listOf(mapboxNavigation.getZLevel(), null))
473516
.build(),
@@ -476,7 +519,7 @@ class MapboxNavigationActivity : AppCompatActivity() {
476519
routes: List<NavigationRoute>,
477520
routerOrigin: RouterOrigin
478521
) {
479-
setRouteAndStartNavigation(routes)
522+
setRoutesPreview(routes)
480523
}
481524

482525
override fun onFailure(
@@ -493,6 +536,18 @@ class MapboxNavigationActivity : AppCompatActivity() {
493536
)
494537
}
495538

539+
private fun setRoutesPreview(routes: List<NavigationRoute>) {
540+
binding.navigateButton.apply {
541+
visibility = View.VISIBLE
542+
setOnClickListener {
543+
visibility = View.GONE
544+
setRouteAndStartNavigation(mapboxNavigation.getRoutesPreview()!!.routesList)
545+
mapboxNavigation.setRoutesPreview(emptyList())
546+
}
547+
}
548+
mapboxNavigation.setRoutesPreview(routes)
549+
}
550+
496551
private fun setRouteAndStartNavigation(route: List<NavigationRoute>) {
497552
// set route
498553
mapboxNavigation.setNavigationRoutes(route)

examples/src/main/res/layout/layout_activity_navigation.xml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:app="http://schemas.android.com/apk/res-auto"
44
android:layout_width="match_parent"
5-
android:layout_height="match_parent">
5+
android:layout_height="match_parent"
6+
xmlns:tools="http://schemas.android.com/tools"
7+
>
68

79
<com.mapbox.maps.MapView
810
android:id="@+id/mapView"
@@ -77,4 +79,15 @@
7779
app:layout_constraintEnd_toEndOf="parent"
7880
app:layout_constraintTop_toBottomOf="@id/routeOverview" />
7981

82+
<Button
83+
android:id="@+id/navigateButton"
84+
android:layout_width="0dp"
85+
android:layout_height="wrap_content"
86+
app:layout_constraintEnd_toEndOf="parent"
87+
app:layout_constraintStart_toStartOf="parent"
88+
app:layout_constraintBottom_toBottomOf="parent"
89+
android:visibility="gone"
90+
tools:visibility="visible"
91+
android:text="Navigate"/>
92+
8093
</androidx.constraintlayout.widget.ConstraintLayout>

0 commit comments

Comments
 (0)