diff --git a/changelog/unreleased/bugfixes/6793.md b/changelog/unreleased/bugfixes/6793.md new file mode 100644 index 00000000000..44a42aaa261 --- /dev/null +++ b/changelog/unreleased/bugfixes/6793.md @@ -0,0 +1 @@ +- :warning: If you're recreating the `MapboxRouteLineView` instance, for example to change the `MapboxRouteLineOptions`, make sure that your first interaction restores the state and re-applies the options by calling `MapboxRouteLineApi.getRouteDrawData` and passing the result to `MapboxRouteLineView.renderRouteDrawData`. This is a necessary change to fix an issue where `MapboxRouteLineOptions` provided in a new instance of `MapboxRouteLineView` were ignored if the style object used with `render` functions already had route line layers initialized. \ No newline at end of file diff --git a/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtils.kt b/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtils.kt index a27aff9a266..4dfbb29a1b0 100644 --- a/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtils.kt +++ b/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtils.kt @@ -1751,4 +1751,31 @@ internal object MapboxRouteLineUtils { .iconIgnorePlacement(true) .iconKeepUpright(true) } + + internal fun removeLayersAndSources(style: Style) { + style.removeStyleSource(RouteLayerConstants.LAYER_GROUP_1_SOURCE_ID) + style.removeStyleSource(RouteLayerConstants.LAYER_GROUP_2_SOURCE_ID) + style.removeStyleSource(RouteLayerConstants.LAYER_GROUP_3_SOURCE_ID) + style.removeStyleSource(RouteLayerConstants.WAYPOINT_SOURCE_ID) + style.removeStyleLayer(RouteLayerConstants.TOP_LEVEL_ROUTE_LINE_LAYER_ID) + style.removeStyleLayer(RouteLayerConstants.BOTTOM_LEVEL_ROUTE_LINE_LAYER_ID) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_1_TRAIL_CASING) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_1_TRAIL) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_1_CASING) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_1_MAIN) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_1_TRAFFIC) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_1_RESTRICTED) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_2_TRAIL_CASING) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_2_TRAIL) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_2_CASING) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_2_MAIN) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_2_TRAFFIC) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_2_RESTRICTED) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_3_TRAIL_CASING) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_3_TRAIL) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_3_CASING) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_3_MAIN) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_3_TRAFFIC) + style.removeStyleLayer(RouteLayerConstants.LAYER_GROUP_3_RESTRICTED) + } } diff --git a/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineView.kt b/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineView.kt index 3d1fcf50f1a..a14e0e5a12e 100644 --- a/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineView.kt +++ b/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineView.kt @@ -18,6 +18,7 @@ import com.mapbox.navigation.ui.maps.internal.route.line.MapboxRouteLineUtils.ge import com.mapbox.navigation.ui.maps.internal.route.line.MapboxRouteLineUtils.layerGroup1SourceLayerIds import com.mapbox.navigation.ui.maps.internal.route.line.MapboxRouteLineUtils.layerGroup2SourceLayerIds import com.mapbox.navigation.ui.maps.internal.route.line.MapboxRouteLineUtils.layerGroup3SourceLayerIds +import com.mapbox.navigation.ui.maps.internal.route.line.MapboxRouteLineUtils.layersAreInitialized import com.mapbox.navigation.ui.maps.internal.route.line.MapboxRouteLineUtils.sourceLayerMap import com.mapbox.navigation.ui.maps.route.RouteLayerConstants import com.mapbox.navigation.ui.maps.route.RouteLayerConstants.LAYER_GROUP_1_CASING @@ -73,11 +74,17 @@ import org.jetbrains.annotations.TestOnly * Many of the method calls execute tasks on a background thread. A cancel method is provided * in this class which will cancel the background tasks. * + * If you're recreating the [MapboxRouteLineView] instance, for example to change the + * [MapboxRouteLineOptions], make sure that your first interaction restores the state and re-applies + * the options by calling [MapboxRouteLineApi.getRouteDrawData] and passing the result to [MapboxRouteLineView.renderRouteDrawData]. + * * @param options resource options used rendering the route line on the map */ @UiThread class MapboxRouteLineView(options: MapboxRouteLineOptions) { + private var rebuildLayersOnFirstRender: Boolean = true + private companion object { private const val TAG = "MbxRouteLineView" } @@ -88,7 +95,8 @@ class MapboxRouteLineView(options: MapboxRouteLineOptions) { var options: MapboxRouteLineOptions = options @Deprecated( message = "Avoid using this setter as it will not correctly " + - "re-apply all mutated parameters." + "re-apply all mutated parameters. " + + "Recreate the instance and provide options via constructor instead." ) set @@ -149,7 +157,7 @@ class MapboxRouteLineView(options: MapboxRouteLineOptions) { * @param style a valid [Style] instance */ fun initializeLayers(style: Style) { - MapboxRouteLineUtils.initializeLayers(style, options) + rebuildSourcesAndLayersIfNeeded(style) } /** @@ -159,7 +167,7 @@ class MapboxRouteLineView(options: MapboxRouteLineOptions) { * @param routeDrawData a [Expected] */ fun renderRouteDrawData(style: Style, routeDrawData: Expected) { - MapboxRouteLineUtils.initializeLayers(style, options) + rebuildSourcesAndLayersIfNeeded(style) jobControl.scope.launch(Dispatchers.Main) { mutex.withLock { val primaryRouteTrafficVisibility = getTrafficVisibility(style) @@ -234,7 +242,9 @@ class MapboxRouteLineView(options: MapboxRouteLineOptions) { sourceLayerMap ) } - } else { {} } + } else { + {} + } listOf(layerMoveCommand).plus(trimOffsetCommands).plus(gradientCommands) } ?: listOf() } @@ -332,7 +342,7 @@ class MapboxRouteLineView(options: MapboxRouteLineOptions) { style: Style, clearRouteLineValue: Expected ) { - MapboxRouteLineUtils.initializeLayers(style, options) + rebuildSourcesAndLayersIfNeeded(style) jobControl.scope.launch(Dispatchers.Main) { mutex.withLock { clearRouteLineValue.onValue { value -> @@ -837,7 +847,8 @@ class MapboxRouteLineView(options: MapboxRouteLineOptions) { } else -> null } - } else -> { + } + else -> { when (it) { in casingLayerIds -> { options.resourceProvider.alternativeRouteCasingLineScaleExpression @@ -862,4 +873,33 @@ class MapboxRouteLineView(options: MapboxRouteLineOptions) { } } } + + private fun rebuildSourcesAndLayersIfNeeded(style: Style) { + if (rebuildLayersOnFirstRender || !layersAreInitialized(style, options)) { + rebuildLayersOnFirstRender = false + resetLayers(style) + } + } + + private fun resetLayers(style: Style) { + sourceToFeatureMap.clear() + sourceToFeatureMap[MapboxRouteLineUtils.layerGroup1SourceKey] = RouteLineFeatureId(null) + sourceToFeatureMap[MapboxRouteLineUtils.layerGroup2SourceKey] = RouteLineFeatureId(null) + sourceToFeatureMap[MapboxRouteLineUtils.layerGroup3SourceKey] = RouteLineFeatureId(null) + primaryRouteLineLayerGroup = setOf() + listOf( + RouteLayerConstants.LAYER_GROUP_1_SOURCE_ID, + RouteLayerConstants.LAYER_GROUP_2_SOURCE_ID, + RouteLayerConstants.LAYER_GROUP_3_SOURCE_ID, + RouteLayerConstants.WAYPOINT_SOURCE_ID + ).forEach { + updateSource( + style, + it, + FeatureCollection.fromFeatures(listOf()) + ) + } + MapboxRouteLineUtils.removeLayersAndSources(style) + MapboxRouteLineUtils.initializeLayers(style, options) + } } diff --git a/libnavui-maps/src/test/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtilsTest.kt b/libnavui-maps/src/test/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtilsTest.kt index c58892e4512..91bb6db4510 100644 --- a/libnavui-maps/src/test/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtilsTest.kt +++ b/libnavui-maps/src/test/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtilsTest.kt @@ -2028,6 +2028,41 @@ class MapboxRouteLineUtilsTest { assertFalse(result) } + @Test + fun removeLayersAndSources() { + val style = mockk