Skip to content

Commit fcb5e56

Browse files
committed
- Added Waypoints to NavigationRoute; - RouteOptionsUpdater refactored;
1 parent c4b39fa commit fcb5e56

File tree

20 files changed

+870
-305
lines changed

20 files changed

+870
-305
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.mapbox.navigation.instrumentation_tests.core
2+
3+
import android.location.Location
4+
import com.mapbox.api.directions.v5.models.DirectionsResponse
5+
import com.mapbox.api.directions.v5.models.DirectionsRoute
6+
import com.mapbox.api.directions.v5.models.RouteOptions
7+
import com.mapbox.geojson.Point
8+
import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
9+
import com.mapbox.navigation.base.internal.route.createNavigationRoutes
10+
import com.mapbox.navigation.base.internal.utils._waypoints
11+
import com.mapbox.navigation.base.route.NavigationRoute
12+
import com.mapbox.navigation.base.route.RouterOrigin
13+
import com.mapbox.navigation.instrumentation_tests.R
14+
import com.mapbox.navigation.instrumentation_tests.activity.EmptyTestActivity
15+
import com.mapbox.navigation.instrumentation_tests.utils.readRawFileText
16+
import com.mapbox.navigation.testing.ui.BaseTest
17+
import junit.framework.Assert.assertTrue
18+
import org.junit.Test
19+
20+
class NavigationRouteTests : BaseTest<EmptyTestActivity>(EmptyTestActivity::class.java) {
21+
22+
override fun setupMockLocation(): Location = mockLocationUpdatesRule.generateLocationUpdate {
23+
latitude = 0.0
24+
longitude = 0.0
25+
}
26+
27+
@Test
28+
fun mapDirectionsResponseToNavigationRoutes() {
29+
val jsonResponse = readRawFileText(activity, R.raw.route_response_dc_very_short)
30+
31+
val navRoutes = NavigationRoute.create(
32+
DirectionsResponse.fromJson(jsonResponse),
33+
provideRouteOptions(),
34+
RouterOrigin.Onboard
35+
)
36+
37+
assertTrue(navRoutes.isNotEmpty())
38+
navRoutes.forEach {
39+
assertTrue(it._waypoints().isNotEmpty())
40+
}
41+
}
42+
43+
@Test
44+
fun mapDirectionsRoutesToNavigationRoutes() {
45+
val directionsRoute = DirectionsRoute.fromJson(readRawFileText(activity, R.raw.short_route))
46+
47+
val navRoutes = createNavigationRoutes(
48+
listOf(directionsRoute),
49+
provideRouteOptions(),
50+
RouterOrigin.Onboard,
51+
)
52+
53+
assertTrue(navRoutes.isNotEmpty())
54+
}
55+
56+
private fun provideRouteOptions(): RouteOptions =
57+
RouteOptions.builder().applyDefaultNavigationOptions()
58+
.coordinatesList(
59+
listOf(
60+
Point.fromLngLat(1.1, 2.2),
61+
Point.fromLngLat(3.3, 4.4),
62+
)
63+
)
64+
.build()
65+
}

libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/NativeRouteParserWrapper.kt

+17
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ interface SDKRouteParser {
1212
request: String,
1313
routerOrigin: RouterOrigin,
1414
): Expected<String, List<RouteInterface>>
15+
16+
fun parseDirectionsRoutes(
17+
directionsRoutes: String,
18+
request: String,
19+
routerOrigin: RouterOrigin,
20+
): Expected<String, List<RouteInterface>>
1521
}
1622

1723
object NativeRouteParserWrapper : SDKRouteParser {
@@ -25,4 +31,15 @@ object NativeRouteParserWrapper : SDKRouteParser {
2531
request,
2632
routerOrigin.mapToNativeRouteOrigin()
2733
)
34+
35+
override fun parseDirectionsRoutes(
36+
directionsRoutes: String,
37+
request: String,
38+
routerOrigin: RouterOrigin,
39+
): Expected<String, List<RouteInterface>> =
40+
RouteParser.parseDirectionsRoutes(
41+
directionsRoutes,
42+
request,
43+
routerOrigin.mapToNativeRouteOrigin()
44+
)
2845
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
@file:JvmName("WaypointEx")
2+
3+
package com.mapbox.navigation.base.internal.extensions
4+
5+
import com.mapbox.api.directions.v5.models.DirectionsRoute
6+
import com.mapbox.navigation.base.internal.route.Waypoint
7+
import com.mapbox.navigation.base.trip.model.RouteProgress
8+
9+
/**
10+
* Return waypoints that are requested explicitly
11+
*/
12+
fun List<Waypoint>.requestedWaypoints(): List<Waypoint> =
13+
this.filter { it.type != Waypoint.EV_CHARGING }
14+
15+
/**
16+
* Return waypoints that tracking in [RouteProgress.currentLegProgress]#legIndex and based on
17+
* [DirectionsRoute.legs] index
18+
*/
19+
fun List<Waypoint>.legsWaypoints(): List<Waypoint> =
20+
this.filter { it.type != Waypoint.SILENT }
21+
22+
/**
23+
* Return the index of **next requested** coordinate.
24+
*
25+
* For instance, EV waypoints are not requested explicitly, so they are not taken into account.
26+
*/
27+
fun indexOfNextRequestedCoordinate(
28+
waypoints: List<Waypoint>,
29+
remainingWaypoints: Int,
30+
): Int? {
31+
if (remainingWaypoints > waypoints.size) {
32+
return null
33+
}
34+
val nextRequestedWaypoint = waypoints
35+
.subList(waypoints.size - remainingWaypoints, waypoints.size)
36+
.requestedWaypoints()
37+
.firstOrNull()
38+
?: return null
39+
40+
return waypoints
41+
.requestedWaypoints()
42+
.indexOf(nextRequestedWaypoint)
43+
}

libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/route/NavigationRouteEx.kt

+15
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.mapbox.api.directions.v5.models.LegAnnotation
1212
import com.mapbox.api.directions.v5.models.LegStep
1313
import com.mapbox.api.directions.v5.models.RouteLeg
1414
import com.mapbox.api.directions.v5.models.RouteOptions
15+
import com.mapbox.navigation.base.internal.NativeRouteParserWrapper
1516
import com.mapbox.navigation.base.internal.SDKRouteParser
1617
import com.mapbox.navigation.base.route.NavigationRoute
1718
import com.mapbox.navigation.base.route.toNavigationRoute
@@ -149,6 +150,20 @@ fun createNavigationRoutes(
149150
): List<NavigationRoute> =
150151
NavigationRoute.create(directionsResponse, routeOptions, routeParser, routerOrigin)
151152

153+
@VisibleForTesting
154+
fun createNavigationRoutes(
155+
directionsRoutes: List<DirectionsRoute>,
156+
routeOptions: RouteOptions,
157+
routerOrigin: com.mapbox.navigation.base.route.RouterOrigin,
158+
routeParser: SDKRouteParser = NativeRouteParserWrapper
159+
): List<NavigationRoute> =
160+
NavigationRoute.create(
161+
directionsRoutes,
162+
routeOptions,
163+
routerOrigin,
164+
routeParser,
165+
)
166+
152167
/**
153168
* Internal API to create a new [NavigationRoute] from a native peer.
154169
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.mapbox.navigation.base.internal.route
2+
3+
import androidx.annotation.IntDef
4+
import com.mapbox.geojson.Point
5+
6+
data class Waypoint(
7+
val location: Point,
8+
@Type val type: Int,
9+
val name: String,
10+
val target: Point?,
11+
) {
12+
companion object {
13+
const val REGULAR = 1
14+
const val SILENT = 2
15+
const val EV_CHARGING = 3
16+
}
17+
18+
@Target(
19+
AnnotationTarget.PROPERTY,
20+
AnnotationTarget.VALUE_PARAMETER,
21+
AnnotationTarget.FUNCTION,
22+
AnnotationTarget.TYPE
23+
)
24+
@Retention(AnnotationRetention.BINARY)
25+
@IntDef(REGULAR, SILENT, EV_CHARGING)
26+
annotation class Type
27+
}

libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/utils/DirectionsRouteEx.kt

+19
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package com.mapbox.navigation.base.internal.utils
44

55
import com.mapbox.api.directions.v5.models.DirectionsRoute
66
import com.mapbox.api.directions.v5.models.LegStep
7+
import com.mapbox.navigation.base.internal.route.Waypoint
78
import com.mapbox.navigation.base.utils.ifNonNull
89

910
/**
@@ -36,3 +37,21 @@ private fun DirectionsRoute.stepsNamesAsString(): String? =
3637
?.joinToString { leg ->
3738
leg.steps()?.joinToString { step -> step.name() ?: "" } ?: ""
3839
}
40+
41+
internal fun List<com.mapbox.navigator.Waypoint>.mapToSkd(): List<Waypoint> =
42+
map { nativeWaypoint ->
43+
Waypoint(
44+
location = nativeWaypoint.location,
45+
type = nativeWaypoint.type.mapToSdk(),
46+
name = nativeWaypoint.name,
47+
target = nativeWaypoint.target,
48+
)
49+
}
50+
51+
@Waypoint.Type
52+
private fun com.mapbox.navigator.WaypointType.mapToSdk(): Int =
53+
when (this) {
54+
com.mapbox.navigator.WaypointType.REGULAR -> Waypoint.REGULAR
55+
com.mapbox.navigator.WaypointType.SILENT -> Waypoint.SILENT
56+
com.mapbox.navigator.WaypointType.EV_CHARGING -> Waypoint.EV_CHARGING
57+
}

libnavigation-base/src/main/java/com/mapbox/navigation/base/internal/utils/RouterEx.kt

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.mapbox.navigation.base.internal.utils
22

3+
import com.mapbox.navigation.base.internal.route.Waypoint
4+
import com.mapbox.navigation.base.route.NavigationRoute
35
import com.mapbox.navigator.RouterOrigin
46

57
fun RouterOrigin.mapToSdkRouteOrigin(): com.mapbox.navigation.base.route.RouterOrigin =
@@ -15,3 +17,5 @@ fun com.mapbox.navigation.base.route.RouterOrigin.mapToNativeRouteOrigin(): Rout
1517
com.mapbox.navigation.base.route.RouterOrigin.Onboard -> RouterOrigin.ONBOARD
1618
is com.mapbox.navigation.base.route.RouterOrigin.Custom -> RouterOrigin.CUSTOM
1719
}
20+
21+
fun NavigationRoute._waypoints(): List<Waypoint> = waypoints

libnavigation-base/src/main/java/com/mapbox/navigation/base/route/NavigationRoute.kt

+49
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ import com.mapbox.navigation.base.internal.NativeRouteParserWrapper
1717
import com.mapbox.navigation.base.internal.SDKRouteParser
1818
import com.mapbox.navigation.base.internal.factory.RoadObjectFactory.toUpcomingRoadObjects
1919
import com.mapbox.navigation.base.internal.route.RouteCompatibilityCache
20+
import com.mapbox.navigation.base.internal.route.Waypoint
21+
import com.mapbox.navigation.base.internal.route.toNavigationRoute
2022
import com.mapbox.navigation.base.internal.utils.DirectionsRouteMissingConditionsCheck
2123
import com.mapbox.navigation.base.internal.utils.mapToSdkRouteOrigin
24+
import com.mapbox.navigation.base.internal.utils.mapToSkd
2225
import com.mapbox.navigation.base.trip.model.roadobject.UpcomingRoadObject
2326
import com.mapbox.navigation.utils.internal.ThreadController
2427
import com.mapbox.navigation.utils.internal.logD
@@ -27,6 +30,7 @@ import com.mapbox.navigation.utils.internal.logI
2730
import com.mapbox.navigator.RouteInterface
2831
import kotlinx.coroutines.async
2932
import kotlinx.coroutines.coroutineScope
33+
import org.json.JSONArray
3034
import java.net.URL
3135

3236
/**
@@ -203,6 +207,36 @@ class NavigationRoute internal constructor(
203207
}
204208
}
205209

210+
internal fun create(
211+
directionsRoutes: List<DirectionsRoute>,
212+
routeOptions: RouteOptions,
213+
routerOrigin: RouterOrigin,
214+
routeParser: SDKRouteParser = NativeRouteParserWrapper
215+
): List<NavigationRoute> {
216+
val directionsRoutesJson = JSONArray(directionsRoutes.map { it.toJson() }).toString()
217+
return create(
218+
directionsRoutesJson,
219+
routeOptions.toUrl("").toString(),
220+
routerOrigin,
221+
routeParser
222+
)
223+
}
224+
225+
private fun create(
226+
directionsRoutesJson: String,
227+
routeOptionsUrlString: String,
228+
routerOrigin: RouterOrigin,
229+
routeParser: SDKRouteParser = NativeRouteParserWrapper
230+
): List<NavigationRoute> {
231+
return routeParser.parseDirectionsRoutes(
232+
directionsRoutesJson,
233+
routeOptionsUrlString,
234+
routerOrigin
235+
).run {
236+
create(this)
237+
}
238+
}
239+
206240
internal fun create(
207241
directionsResponse: DirectionsResponse,
208242
routeOptions: RouteOptions,
@@ -255,6 +289,19 @@ class NavigationRoute internal constructor(
255289
)
256290
}.cache()
257291
}
292+
293+
private fun create(
294+
expected: Expected<String, List<RouteInterface>>
295+
): List<NavigationRoute> {
296+
return expected.fold({ error ->
297+
logE("NavigationRoute", "Failed to parse a route. Reason: $error")
298+
listOf()
299+
}, { value ->
300+
value
301+
}).map { routeInterface ->
302+
routeInterface.toNavigationRoute()
303+
}.cache()
304+
}
258305
}
259306

260307
/**
@@ -293,6 +340,8 @@ class NavigationRoute internal constructor(
293340
*/
294341
val upcomingRoadObjects = nativeRoute.routeInfo.alerts.toUpcomingRoadObjects()
295342

343+
internal val waypoints: List<Waypoint> by lazy { nativeRoute.waypoints.mapToSkd() }
344+
296345
/**
297346
* Indicates whether some other object is "equal to" this one.
298347
*

0 commit comments

Comments
 (0)