Skip to content

Commit f144870

Browse files
author
Seth Bourget
committed
Added feature to mask the primary route line in order to give the appearance the active leg is above the inactive legs for multi-leg routes.
1 parent a3da3ba commit f144870

25 files changed

+2279
-175
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Mapbox welcomes participation and contributions from everyone.
1010
- Fixed approaches list update in `RouteOptionsUpdater`(uses for reroute). It was putting to the origin approach corresponding approach from legacy approach list. [#6540](https://github.com/mapbox/mapbox-navigation-android/pull/6540)
1111
- Updated the `MapboxRestAreaApi` logic to load a SAPA map only if the upcoming rest stop is at the current step of the route leg. [#6695](https://github.com/mapbox/mapbox-navigation-android/pull/6695)
1212
- Fixed an issue where `MapboxRerouteController` could deliver a delayed interruption state notifications. Now, the interruption state is always delivered synchronously, as soon as it's available. [#6718](https://github.com/mapbox/mapbox-navigation-android/pull/6718)
13+
- Modified the route line implementation so that for multi-leg routes the active route appears above inactive route legs. [#6742](https://github.com/mapbox/mapbox-navigation-android/pull/6742)
1314

1415
## Mapbox Navigation SDK 2.9.5 - 13 December, 2022
1516
### Changelog

libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/internal/route/line/MapboxRouteLineUtils.kt

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ internal object MapboxRouteLineUtils {
9393
val layerGroup2SourceKey = RouteLineSourceKey(RouteLayerConstants.LAYER_GROUP_2_SOURCE_ID)
9494
val layerGroup3SourceKey = RouteLineSourceKey(RouteLayerConstants.LAYER_GROUP_3_SOURCE_ID)
9595

96+
// ordering is important
9697
val layerGroup1SourceLayerIds = setOf(
9798
RouteLayerConstants.LAYER_GROUP_1_TRAIL_CASING,
9899
RouteLayerConstants.LAYER_GROUP_1_TRAIL,
@@ -101,6 +102,8 @@ internal object MapboxRouteLineUtils {
101102
RouteLayerConstants.LAYER_GROUP_1_TRAFFIC,
102103
RouteLayerConstants.LAYER_GROUP_1_RESTRICTED
103104
)
105+
106+
// ordering is important
104107
val layerGroup2SourceLayerIds = setOf(
105108
RouteLayerConstants.LAYER_GROUP_2_TRAIL_CASING,
106109
RouteLayerConstants.LAYER_GROUP_2_TRAIL,
@@ -109,6 +112,8 @@ internal object MapboxRouteLineUtils {
109112
RouteLayerConstants.LAYER_GROUP_2_TRAFFIC,
110113
RouteLayerConstants.LAYER_GROUP_2_RESTRICTED
111114
)
115+
116+
// ordering is important
112117
val layerGroup3SourceLayerIds = setOf(
113118
RouteLayerConstants.LAYER_GROUP_3_TRAIL_CASING,
114119
RouteLayerConstants.LAYER_GROUP_3_TRAIL,
@@ -118,6 +123,15 @@ internal object MapboxRouteLineUtils {
118123
RouteLayerConstants.LAYER_GROUP_3_RESTRICTED
119124
)
120125

126+
// ordering is important
127+
val maskingLayerIds = setOf(
128+
RouteLayerConstants.MASKING_LAYER_TRAIL_CASING,
129+
RouteLayerConstants.MASKING_LAYER_TRAIL,
130+
RouteLayerConstants.MASKING_LAYER_CASING,
131+
RouteLayerConstants.MASKING_LAYER_MAIN,
132+
RouteLayerConstants.MASKING_LAYER_TRAFFIC
133+
)
134+
121135
val sourceLayerMap = mapOf<RouteLineSourceKey, Set<String>>(
122136
Pair(layerGroup1SourceKey, layerGroup1SourceLayerIds),
123137
Pair(layerGroup2SourceKey, layerGroup2SourceLayerIds),
@@ -524,8 +538,7 @@ internal object MapboxRouteLineUtils {
524538

525539
/**
526540
* Extracts data from the [DirectionsRoute] and removes items that are deemed duplicates based
527-
* on factors such as traffic congestion and/or road class. The results are cached for
528-
* performance reasons.
541+
* on factors such as traffic congestion and/or road class.
529542
*/
530543
internal val extractRouteDataWithTrafficAndRoadClassDeDuped: (
531544
route: NavigationRoute,
@@ -1353,6 +1366,68 @@ internal object MapboxRouteLineUtils {
13531366
style.addPersistentLayer(this, LayerPosition(null, belowLayerIdToUse, null))
13541367
}
13551368
}
1369+
1370+
if (!style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_TRAIL_CASING)) {
1371+
LineLayer(
1372+
RouteLayerConstants.MASKING_LAYER_TRAIL_CASING,
1373+
RouteLayerConstants.LAYER_GROUP_1_SOURCE_ID
1374+
)
1375+
.lineCap(LineCap.ROUND)
1376+
.lineJoin(LineJoin.ROUND)
1377+
.lineWidth(options.resourceProvider.routeCasingLineScaleExpression)
1378+
.lineColor(Color.GRAY).apply {
1379+
style.addPersistentLayer(this, LayerPosition(null, belowLayerIdToUse, null))
1380+
}
1381+
}
1382+
if (!style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_TRAIL)) {
1383+
LineLayer(
1384+
RouteLayerConstants.MASKING_LAYER_TRAIL,
1385+
RouteLayerConstants.LAYER_GROUP_1_SOURCE_ID
1386+
)
1387+
.lineCap(LineCap.ROUND)
1388+
.lineJoin(LineJoin.ROUND)
1389+
.lineWidth(options.resourceProvider.routeLineScaleExpression)
1390+
.lineColor(Color.GRAY).apply {
1391+
style.addPersistentLayer(this, LayerPosition(null, belowLayerIdToUse, null))
1392+
}
1393+
}
1394+
if (!style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_CASING)) {
1395+
LineLayer(
1396+
RouteLayerConstants.MASKING_LAYER_CASING,
1397+
RouteLayerConstants.LAYER_GROUP_1_SOURCE_ID
1398+
)
1399+
.lineCap(LineCap.ROUND)
1400+
.lineJoin(LineJoin.ROUND)
1401+
.lineWidth(options.resourceProvider.routeCasingLineScaleExpression)
1402+
.lineColor(Color.GRAY).apply {
1403+
style.addPersistentLayer(this, LayerPosition(null, belowLayerIdToUse, null))
1404+
}
1405+
}
1406+
if (!style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_MAIN)) {
1407+
LineLayer(
1408+
RouteLayerConstants.MASKING_LAYER_MAIN,
1409+
RouteLayerConstants.LAYER_GROUP_1_SOURCE_ID
1410+
)
1411+
.lineCap(LineCap.ROUND)
1412+
.lineJoin(LineJoin.ROUND)
1413+
.lineWidth(options.resourceProvider.routeLineScaleExpression)
1414+
.lineColor(Color.GRAY).apply {
1415+
style.addPersistentLayer(this, LayerPosition(null, belowLayerIdToUse, null))
1416+
}
1417+
}
1418+
if (!style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_TRAFFIC)) {
1419+
LineLayer(
1420+
RouteLayerConstants.MASKING_LAYER_TRAFFIC,
1421+
RouteLayerConstants.LAYER_GROUP_1_SOURCE_ID
1422+
)
1423+
.lineCap(LineCap.ROUND)
1424+
.lineJoin(LineJoin.ROUND)
1425+
.lineWidth(options.resourceProvider.routeTrafficLineScaleExpression)
1426+
.lineColor(Color.GRAY).apply {
1427+
style.addPersistentLayer(this, LayerPosition(null, belowLayerIdToUse, null))
1428+
}
1429+
}
1430+
13561431
if (options.displayRestrictedRoadSections) {
13571432
if (!style.styleLayerExists(RouteLayerConstants.LAYER_GROUP_1_RESTRICTED)) {
13581433
LineLayer(
@@ -1413,6 +1488,11 @@ internal object MapboxRouteLineUtils {
14131488
style.styleLayerExists(RouteLayerConstants.LAYER_GROUP_3_CASING) &&
14141489
style.styleLayerExists(RouteLayerConstants.LAYER_GROUP_3_MAIN) &&
14151490
style.styleLayerExists(RouteLayerConstants.LAYER_GROUP_3_TRAFFIC) &&
1491+
style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_TRAIL_CASING) &&
1492+
style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_TRAIL) &&
1493+
style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_CASING) &&
1494+
style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_MAIN) &&
1495+
style.styleLayerExists(RouteLayerConstants.MASKING_LAYER_TRAFFIC) &&
14161496
if (options.displayRestrictedRoadSections) {
14171497
style.styleLayerExists(RouteLayerConstants.LAYER_GROUP_1_RESTRICTED) &&
14181498
style.styleLayerExists(RouteLayerConstants.LAYER_GROUP_2_RESTRICTED) &&

libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/RouteLayerConstants.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,24 @@ object RouteLayerConstants {
206206
internal const val LAYER_GROUP_3_MAIN = "mapbox-layerGroup-3-main"
207207
internal const val LAYER_GROUP_3_TRAFFIC = "mapbox-layerGroup-3-traffic"
208208
internal const val LAYER_GROUP_3_RESTRICTED = "mapbox-layerGroup-3-restricted"
209+
210+
/*
211+
When a line on the map overlaps itself it appears as though the later part of the line
212+
is on top of the earlier part of the line. For multi-leg routes this gives the appearance
213+
the inactive leg(s) appearing on top of the active leg. Customer feedback indicated this
214+
was unsatisfactory. The masking layers were created to address this issue and give the
215+
opposite of the default appearance. The end result is the active route leg appears
216+
above inactive leg(s) when a route overlaps itself.
217+
218+
The masking layers share the same source as the primary route line. They are placed above
219+
the primary route line layers except for the restricted line which appears above all other
220+
primary route layers. The implementation will set the inactive route legs to transparent
221+
so the primary route line layers are visible. The active leg section of the masking layers
222+
are opaque thus masking the the primary route line layers beneath.
223+
*/
224+
internal const val MASKING_LAYER_TRAIL_CASING = "mapbox-masking-layer-trailCasing"
225+
internal const val MASKING_LAYER_TRAIL = "mapbox-masking-layer-trail"
226+
internal const val MASKING_LAYER_CASING = "mapbox-masking-layer-casing"
227+
internal const val MASKING_LAYER_MAIN = "mapbox-masking-layer-main"
228+
internal const val MASKING_LAYER_TRAFFIC = "mapbox-masking-layer-traffic"
209229
}

0 commit comments

Comments
 (0)