@@ -22,7 +22,7 @@ import com.mapbox.navigation.ui.maps.route.line.model.RouteLineExpressionProvide
2222import com.mapbox.navigation.ui.maps.route.line.model.RouteLineUpdateValue
2323import com.mapbox.navigation.ui.maps.route.line.model.RouteSetValue
2424import com.mapbox.navigation.utils.internal.InternalJobControlFactory
25- import kotlinx.coroutines.CoroutineScope
25+ import com.mapbox.navigation.utils.internal.ifNonNull
2626import kotlinx.coroutines.Dispatchers
2727import kotlinx.coroutines.async
2828import kotlinx.coroutines.cancelChildren
@@ -83,87 +83,137 @@ class MapboxRouteLineView(var options: MapboxRouteLineOptions) {
8383 Log .e(TAG , error.errorMessage)
8484 },
8585 { value ->
86+ val baseExpressionDeferred = jobControl.scope.async {
87+ value.primaryRouteLineData
88+ .dynamicData
89+ .baseExpressionProvider
90+ .generateExpression()
91+ }
92+ val casingExpressionDeferred = jobControl.scope.async {
93+ value.primaryRouteLineData
94+ .dynamicData
95+ .casingExpressionProvider
96+ .generateExpression()
97+ }
98+ val trafficExpressionDeferred = jobControl.scope.async {
99+ value.primaryRouteLineData
100+ .dynamicData
101+ .trafficExpressionProvider
102+ ?.generateExpression()
103+ }
104+ val restrictedSectionExpressionDeferred = jobControl.scope.async {
105+ value.primaryRouteLineData
106+ .dynamicData
107+ .restrictedSectionExpressionProvider
108+ ?.generateExpression()
109+ }
110+ val alternativeRouteLinesData1Deferred = jobControl.scope.async {
111+ value.alternativeRouteLinesData[0 ]
112+ .dynamicData
113+ .trafficExpressionProvider
114+ ?.generateExpression()
115+ }
116+ val alternativeRouteLinesData2Deferred = jobControl.scope.async {
117+ value.alternativeRouteLinesData[1 ]
118+ .dynamicData
119+ .trafficExpressionProvider
120+ ?.generateExpression()
121+ }
122+
86123 jobControl.scope.launch(Dispatchers .Main ) {
87124 mutex.withLock {
125+ // The gradients are set to transparent first so that when the route line
126+ // layer sources are updated they don't initially reflect the wrong traffic
127+ // gradient. The gradients are set on the layers not the feature collections.
128+ // The set gradient call is asynchronous in the Maps SDK but the update source
129+ // is not. Setting the gradients to transparent means the traffic isn't
130+ // visible with the layer sources are updated. The traffic is calculated and
131+ // applied later.
88132 updateLineGradient(
89133 style,
90134 RouteLayerConstants .PRIMARY_ROUTE_TRAFFIC_LAYER_ID ,
91135 Expression .color(Color .TRANSPARENT )
92136 )
137+
93138 updateLineGradient(
94139 style,
95140 RouteLayerConstants .ALTERNATIVE_ROUTE1_TRAFFIC_LAYER_ID ,
96141 Expression .color(Color .TRANSPARENT )
97142 )
143+
98144 updateLineGradient(
99145 style,
100146 RouteLayerConstants .ALTERNATIVE_ROUTE2_TRAFFIC_LAYER_ID ,
101147 Expression .color(Color .TRANSPARENT )
102148 )
149+
103150 updateLineGradient(
104151 style,
105152 RouteLayerConstants .RESTRICTED_ROAD_LAYER_ID ,
106153 Expression .color(Color .TRANSPARENT )
107154 )
108155
109- value.primaryRouteLineData.also {
110- updateSource(
111- style,
112- RouteLayerConstants .PRIMARY_ROUTE_SOURCE_ID ,
113- it.featureCollection
114- )
115- updateLineGradientAsync(
116- jobControl.scope,
117- style,
118- RouteLayerConstants .PRIMARY_ROUTE_LAYER_ID ,
119- it.dynamicData.baseExpressionProvider
120- )
121- updateLineGradientAsync(
122- jobControl.scope,
123- style,
124- RouteLayerConstants .PRIMARY_ROUTE_CASING_LAYER_ID ,
125- it.dynamicData.casingExpressionProvider
126- )
127- updateLineGradientAsync(
128- jobControl.scope,
156+ updateSource(
157+ style,
158+ RouteLayerConstants .PRIMARY_ROUTE_SOURCE_ID ,
159+ value.primaryRouteLineData.featureCollection
160+ )
161+
162+ updateSource(
163+ style,
164+ RouteLayerConstants .ALTERNATIVE_ROUTE1_SOURCE_ID ,
165+ value.alternativeRouteLinesData[0 ].featureCollection
166+ )
167+
168+ updateSource(
169+ style,
170+ RouteLayerConstants .ALTERNATIVE_ROUTE2_SOURCE_ID ,
171+ value.alternativeRouteLinesData[1 ].featureCollection
172+ )
173+
174+ updateLineGradient(
175+ style,
176+ RouteLayerConstants .PRIMARY_ROUTE_LAYER_ID ,
177+ baseExpressionDeferred.await()
178+ )
179+
180+ updateLineGradient(
181+ style,
182+ RouteLayerConstants .PRIMARY_ROUTE_CASING_LAYER_ID ,
183+ casingExpressionDeferred.await()
184+ )
185+
186+ ifNonNull(trafficExpressionDeferred.await()) {
187+ updateLineGradient(
129188 style,
130189 RouteLayerConstants .PRIMARY_ROUTE_TRAFFIC_LAYER_ID ,
131- it.dynamicData.trafficExpressionProvider
190+ it
132191 )
133- updateLineGradientAsync(
134- jobControl.scope,
192+ }
193+
194+ ifNonNull(restrictedSectionExpressionDeferred.await()) {
195+ updateLineGradient(
135196 style,
136197 RouteLayerConstants .RESTRICTED_ROAD_LAYER_ID ,
137- it.dynamicData.restrictedSectionExpressionProvider
198+ it
138199 )
139200 }
201+
140202 // SBNOTE: In the future let's find a better way to
141203 // match the items in the list with the alt. route layer ID's.
142- value.alternativeRouteLinesData[0 ].also {
143- updateSource(
144- style,
145- RouteLayerConstants .ALTERNATIVE_ROUTE1_SOURCE_ID ,
146- it.featureCollection
147- )
148- updateLineGradientAsync(
149- jobControl.scope,
204+ ifNonNull(alternativeRouteLinesData1Deferred.await()) {
205+ updateLineGradient(
150206 style,
151207 RouteLayerConstants .ALTERNATIVE_ROUTE1_TRAFFIC_LAYER_ID ,
152- it.dynamicData.trafficExpressionProvider
208+ it
153209 )
154210 }
155211
156- value.alternativeRouteLinesData[1 ].also {
157- updateSource(
158- style,
159- RouteLayerConstants .ALTERNATIVE_ROUTE2_SOURCE_ID ,
160- it.featureCollection
161- )
162- updateLineGradientAsync(
163- jobControl.scope,
212+ ifNonNull(alternativeRouteLinesData2Deferred.await()) {
213+ updateLineGradient(
164214 style,
165215 RouteLayerConstants .ALTERNATIVE_ROUTE2_TRAFFIC_LAYER_ID ,
166- it.dynamicData.trafficExpressionProvider
216+ it
167217 )
168218 }
169219
@@ -516,26 +566,6 @@ class MapboxRouteLineView(var options: MapboxRouteLineOptions) {
516566 }
517567 }
518568
519- private suspend fun updateLineGradientAsync (
520- coroutineScope : CoroutineScope ,
521- style : Style ,
522- layerId : String ,
523- expressionProvider : RouteLineExpressionProvider ?
524- ) {
525- if (expressionProvider != null ) {
526- val gradientExpression = coroutineScope.async {
527- expressionProvider.generateExpression()
528- }
529- gradientExpression.await().apply {
530- updateLineGradient(
531- style,
532- layerId,
533- this
534- )
535- }
536- }
537- }
538-
539569 private fun updateLineGradient (
540570 style : Style ,
541571 layerId : String ,
0 commit comments