Skip to content

Commit ea08447

Browse files
dzinadgithub-actions[bot]
authored andcommitted
NAVAND-5371: use reversed geometry
GitOrigin-RevId: 8549ad1cda32d7433e23e1877305656914006a6e
1 parent 92147e5 commit ea08447

File tree

18 files changed

+1447
-1269
lines changed

18 files changed

+1447
-1269
lines changed

changelog/unreleased/bugfixes/9717.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fixed an issue where the closer part of route line might have been overlapped by a farther part in case they covered the same space within a single leg (e. g. U-turns on narrow roads).

instrumentation-tests/src/androidTest/java/com/mapbox/navigation/instrumentation_tests/ui/routeline/RouteLineLayersTest.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,9 +628,14 @@ class RouteLineLayersTest : BaseTest<BasicNavigationViewActivity>(
628628
)
629629
assertNotNull(property.value.contents)
630630
assertTrue(property.value.contents is ArrayList<*>)
631-
// the alternative route overlaps primary on ~92%
631+
// the alternative route overlaps primary on ~92% + use reverse geometry - reverse the offset
632632
assertEquals(
633-
0.9263153441670023,
633+
0.07368465583,
634+
((property.value.contents as ArrayList<*>)[0] as Value).contents as Double,
635+
0.0000000001,
636+
)
637+
assertEquals(
638+
1.0,
634639
((property.value.contents as ArrayList<*>)[1] as Value).contents as Double,
635640
0.0000000001,
636641
)

instrumentation-tests/src/androidTest/java/com/mapbox/navigation/instrumentation_tests/ui/routeline/SetRouteOrderTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class SetRouteOrderTest : BaseTest<BasicNavigationViewActivity>(
111111
assertNotNull(property.value.contents)
112112
assertTrue(property.value.contents is ArrayList<*>)
113113
assertEquals(
114-
9,
114+
7,
115115
(property.value.contents as ArrayList<*>).size,
116116
)
117117
myResourceIdler.decrement()
@@ -166,7 +166,7 @@ class SetRouteOrderTest : BaseTest<BasicNavigationViewActivity>(
166166
assertNotNull(property.value.contents)
167167
assertTrue(property.value.contents is ArrayList<*>)
168168
assertEquals(
169-
9,
169+
7,
170170
(property.value.contents as ArrayList<*>).size,
171171
)
172172
myResourceIdler.decrement()

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

Lines changed: 122 additions & 105 deletions
Large diffs are not rendered by default.

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,27 @@ private fun RouteLineExpressionEventData.toHolder(): RouteLineValueCommandHolder
175175
)
176176
}
177177

178+
// deprecated
178179
"line-trim-end" -> {
180+
RouteLineValueCommandHolder(
181+
LightRouteLineValueProvider { value!! },
182+
object : RouteLineCommandApplier<StylePropertyValue>() {
183+
override fun applyCommand(
184+
style: Style,
185+
layerId: String,
186+
command: StylePropertyValue,
187+
) {
188+
style.setStyleLayerProperty(layerId, getProperty(), command.value)
189+
}
190+
191+
override fun getProperty(): String {
192+
return "line-trim-end"
193+
}
194+
},
195+
)
196+
}
197+
198+
"line-trim-start" -> {
179199
RouteLineValueCommandHolder(
180200
LightRouteLineValueProvider { value!! },
181201
LineTrimCommandApplier(),

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineApi.kt

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,6 @@ class MapboxRouteLineApi @VisibleForTesting internal constructor(
753753
val routeLineData =
754754
if (routeLineOptions.styleInactiveRouteLegsIndependently) {
755755
getPrimaryRouteLineDynamicData(
756-
calculationsScope = calculationsScope,
757756
routeLineOptions = routeLineOptions,
758757
routeLineExpressionData =
759758
routeLineActiveLegExpressionData(activeLegIndex),
@@ -1015,7 +1014,7 @@ class MapboxRouteLineApi @VisibleForTesting internal constructor(
10151014
featuresData: List<RouteFeatureData>,
10161015
): Expected<RouteNotFound, ClosestRouteValue> {
10171016
val routesAndFeatures = featuresData.toList()
1018-
val features = routesAndFeatures.map { it.featureCollection }
1017+
val features = routesAndFeatures.map { it.reversedFeatureCollection }
10191018

10201019
val primaryRouteLineLayers = ifNonNull(mapboxMap.getStyle()) { style ->
10211020
MapboxRouteLineUtils.getLayerIdsForPrimaryRoute(
@@ -1154,7 +1153,7 @@ class MapboxRouteLineApi @VisibleForTesting internal constructor(
11541153
featureDataProvider()
11551154
}
11561155
val routeFeatureDataResult = routeFeatureDataDef.await()
1157-
if (routeFeatureDataResult.count { it.lineString.coordinates().size < 2 } > 0) {
1156+
if (routeFeatureDataResult.count { it.coordinatesCount < 2 } > 0) {
11581157
return ExpectedFactory.createError(
11591158
RouteLineError(
11601159
"The route geometry contained less than two coordinates. " +
@@ -1248,11 +1247,11 @@ class MapboxRouteLineApi @VisibleForTesting internal constructor(
12481247
null
12491248
}
12501249

1251-
val primaryRouteSource = primaryRoute.featureCollection
1250+
val primaryRouteSource = primaryRoute.reversedFeatureCollection
12521251
val alternativeRoute1FeatureCollection =
1253-
alternativeRoute1?.featureCollection
1252+
alternativeRoute1?.reversedFeatureCollection
12541253
?: FeatureCollection.fromFeatures(listOf())
1255-
val alternativeRoute2FeatureCollection = alternativeRoute2?.featureCollection
1254+
val alternativeRoute2FeatureCollection = alternativeRoute2?.reversedFeatureCollection
12561255
?: FeatureCollection.fromFeatures(listOf())
12571256
val wayPointsFeatureCollection = wayPointsFeatureCollectionDef.await()
12581257

@@ -1280,34 +1279,22 @@ class MapboxRouteLineApi @VisibleForTesting internal constructor(
12801279

12811280
val alternateRoute1TrailExpressionCommandHolder = RouteLineValueCommandHolder(
12821281
LightRouteLineValueProvider {
1283-
MapboxRouteLineUtils.getRouteLineExpression(
1284-
alternative1PercentageTraveled,
1285-
Color.TRANSPARENT,
1286-
Color.TRANSPARENT,
1287-
)
1282+
getSingleColorExpression(Color.TRANSPARENT)
12881283
},
12891284
LineGradientCommandApplier(),
12901285
)
12911286

12921287
val alternateRoute1TrailCasingExpressionCommandHolder = RouteLineValueCommandHolder(
12931288
LightRouteLineValueProvider {
1294-
MapboxRouteLineUtils.getRouteLineExpression(
1295-
alternative1PercentageTraveled,
1296-
Color.TRANSPARENT,
1297-
Color.TRANSPARENT,
1298-
)
1289+
getSingleColorExpression(Color.TRANSPARENT)
12991290
},
13001291
LineGradientCommandApplier(),
13011292
)
13021293

13031294
val alternateRoute1RestrictedSectionsExpressionCommandHolder =
13041295
RouteLineValueCommandHolder(
13051296
LightRouteLineValueProvider {
1306-
MapboxRouteLineUtils.getRouteLineExpression(
1307-
alternative1PercentageTraveled,
1308-
Color.TRANSPARENT,
1309-
Color.TRANSPARENT,
1310-
)
1297+
getSingleColorExpression(Color.TRANSPARENT)
13111298
},
13121299
LineGradientCommandApplier(),
13131300
)
@@ -1343,34 +1330,22 @@ class MapboxRouteLineApi @VisibleForTesting internal constructor(
13431330

13441331
val alternateRoute2TrailExpressionCommandHolder = RouteLineValueCommandHolder(
13451332
LightRouteLineValueProvider {
1346-
MapboxRouteLineUtils.getRouteLineExpression(
1347-
alternative2PercentageTraveled,
1348-
Color.TRANSPARENT,
1349-
Color.TRANSPARENT,
1350-
)
1333+
getSingleColorExpression(Color.TRANSPARENT)
13511334
},
13521335
LineGradientCommandApplier(),
13531336
)
13541337

13551338
val alternateRoute2TrailCasingExpressionCommandHolder = RouteLineValueCommandHolder(
13561339
LightRouteLineValueProvider {
1357-
MapboxRouteLineUtils.getRouteLineExpression(
1358-
alternative2PercentageTraveled,
1359-
Color.TRANSPARENT,
1360-
Color.TRANSPARENT,
1361-
)
1340+
getSingleColorExpression(Color.TRANSPARENT)
13621341
},
13631342
LineGradientCommandApplier(),
13641343
)
13651344

13661345
val alternateRoute2RestrictedSectionsExpressionCommandHolder =
13671346
RouteLineValueCommandHolder(
13681347
LightRouteLineValueProvider {
1369-
MapboxRouteLineUtils.getRouteLineExpression(
1370-
alternative2PercentageTraveled,
1371-
Color.TRANSPARENT,
1372-
Color.TRANSPARENT,
1373-
)
1348+
getSingleColorExpression(Color.TRANSPARENT)
13741349
},
13751350
LineGradientCommandApplier(),
13761351
)
@@ -1391,11 +1366,7 @@ class MapboxRouteLineApi @VisibleForTesting internal constructor(
13911366
legIndex,
13921367
)
13931368
} else {
1394-
val exp = MapboxRouteLineUtils.getRouteLineExpression(
1395-
1.0,
1396-
Color.TRANSPARENT,
1397-
Color.TRANSPARENT,
1398-
)
1369+
val exp = getSingleColorExpression(Color.TRANSPARENT)
13991370
RouteLineDynamicData(
14001371
baseExpressionCommandHolder = RouteLineValueCommandHolder(
14011372
LightRouteLineValueProvider { exp },
@@ -1435,7 +1406,6 @@ class MapboxRouteLineApi @VisibleForTesting internal constructor(
14351406
primaryRouteLineData = RouteLineData(
14361407
primaryRouteSource,
14371408
getPrimaryRouteLineDynamicData(
1438-
calculationsScope = calculationsScope,
14391409
routeLineOptions = routeLineOptions,
14401410
routeLineExpressionData = routeLineActiveLegExpressionData(legIndex),
14411411
restrictedExpressionData = restrictedExpressionData,

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineView.kt

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.mapbox.geojson.FeatureCollection
1010
import com.mapbox.maps.LayerPosition
1111
import com.mapbox.maps.MapboxMap
1212
import com.mapbox.maps.Style
13+
import com.mapbox.maps.extension.style.expressions.dsl.generated.literal
1314
import com.mapbox.maps.extension.style.layers.Layer
1415
import com.mapbox.maps.extension.style.layers.getLayer
1516
import com.mapbox.maps.extension.style.layers.properties.generated.Visibility
@@ -441,22 +442,22 @@ class MapboxRouteLineView @VisibleForTesting internal constructor(
441442
else -> {
442443
val maskingTrimCommands = if (index == 0) {
443444
listOf(
444-
createTrimEndCommand(
445+
createTrimOffsetCommand(
445446
routeSetValue.routeLineMaskingLayerDynamicData,
446447
MASKING_LAYER_CASING,
447448
style,
448449
),
449-
createTrimEndCommand(
450+
createTrimOffsetCommand(
450451
routeSetValue.routeLineMaskingLayerDynamicData,
451452
MASKING_LAYER_MAIN,
452453
style,
453454
),
454-
createTrimEndCommand(
455+
createTrimOffsetCommand(
455456
routeSetValue.routeLineMaskingLayerDynamicData,
456457
MASKING_LAYER_TRAFFIC,
457458
style,
458459
),
459-
createTrimEndCommand(
460+
createTrimOffsetCommand(
460461
routeSetValue.routeLineMaskingLayerDynamicData,
461462
MASKING_LAYER_RESTRICTED,
462463
style,
@@ -465,7 +466,7 @@ class MapboxRouteLineView @VisibleForTesting internal constructor(
465466
} else {
466467
listOf()
467468
}
468-
getTrimEndCommands(
469+
getTrimOffsetCommands(
469470
style,
470471
sourceKeyFeaturePair.first,
471472
routeLineData,
@@ -1079,14 +1080,14 @@ class MapboxRouteLineView @VisibleForTesting internal constructor(
10791080
}
10801081
}
10811082

1082-
private fun updateTrimEnd(
1083+
private fun updateTrimOffset(
10831084
layerId: String,
10841085
value: Value?,
10851086
): (Style) -> Unit = { style: Style ->
10861087
ifNonNull(value) { expression ->
10871088
style.setStyleLayerProperty(
10881089
layerId,
1089-
"line-trim-end",
1090+
"line-trim-offset",
10901091
expression,
10911092
)
10921093
}
@@ -1127,7 +1128,7 @@ class MapboxRouteLineView @VisibleForTesting internal constructor(
11271128
}
11281129
}
11291130

1130-
private fun getTrimEndCommands(
1131+
private fun getTrimOffsetCommands(
11311132
style: Style,
11321133
routeLineSourceKey: RouteLineSourceKey?,
11331134
routeLineData: RouteLineData,
@@ -1136,20 +1137,20 @@ class MapboxRouteLineView @VisibleForTesting internal constructor(
11361137
val trailLayerIds = trailCasingLayerIds.plus(trailLayerIds)
11371138
return sourceLayerMap[routeLineSourceKey]?.filter { !trailLayerIds.contains(it) }
11381139
?.map {
1139-
createTrimEndCommand(routeLineData.dynamicData, it, style)
1140+
createTrimOffsetCommand(routeLineData.dynamicData, it, style)
11401141
} ?: listOf()
11411142
}
11421143

1143-
private fun createTrimEndCommand(
1144+
private fun createTrimOffsetCommand(
11441145
dynamicData: RouteLineDynamicData?,
11451146
layerId: String,
11461147
style: Style,
11471148
): () -> Unit {
11481149
val value = ifNonNull(dynamicData, dynamicData?.trimOffset?.offset) { _, offset ->
1149-
Value.valueOf(offset)
1150+
literal(listOf(1.0 - offset, 1.0))
11501151
}
11511152

1152-
return { updateTrimEnd(layerId, value)(style) }
1153+
return { updateTrimOffset(layerId, value)(style) }
11531154
}
11541155

11551156
private suspend fun getGradientUpdateCommands(

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/RouteLineCommandApplier.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,6 @@ internal class LineTrimCommandApplier : RouteLineCommandApplier<StylePropertyVal
6161
}
6262

6363
override fun getProperty(): String {
64-
return "line-trim-end"
64+
return "line-trim-start"
6565
}
6666
}

ui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/VanishingRouteLine.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ internal class VanishingRouteLine() {
129129
offset: Double,
130130
): VanishingRouteLineExpressions {
131131
vanishPointOffset = offset
132-
val value = StylePropertyValue(Value.valueOf(offset), StylePropertyValueKind.CONSTANT)
132+
// Use reversed geometry, that's why 1.0 - offset is used here.
133+
val value = StylePropertyValue(
134+
Value(1.0 - offset),
135+
StylePropertyValueKind.CONSTANT,
136+
)
133137
val trafficLineExpressionCommandHolder = RouteLineValueCommandHolder(
134138
LightRouteLineValueProvider { value },
135139
LineTrimCommandApplier(),
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
package com.mapbox.navigation.ui.maps.route.line.model
22

33
import com.mapbox.geojson.FeatureCollection
4-
import com.mapbox.geojson.LineString
54
import com.mapbox.navigation.base.route.NavigationRoute
65

76
/**
87
* An association between a DirectionsRoute, FeatureCollection
98
* and LineString.
109
*
1110
* @param route a DirectionsRoute
12-
* @param featureCollection a FeatureCollection created using the route
13-
* @param lineString a LineString derived from the route's geometry.
11+
* @param reversedFeatureCollection a FeatureCollection created using the route, reversed (ready to be rendered)
12+
* @param coordinatesCount number of coordinates in geometry
1413
*/
15-
internal data class RouteFeatureData constructor(
14+
internal data class RouteFeatureData(
1615
val route: NavigationRoute,
17-
val featureCollection: FeatureCollection,
18-
val lineString: LineString,
16+
val reversedFeatureCollection: FeatureCollection,
17+
val coordinatesCount: Int,
1918
)

0 commit comments

Comments
 (0)