Umbau
This commit is contained in:
@@ -236,7 +236,7 @@ class MainActivity : ComponentActivity() {
|
||||
if (isNavigating()) {
|
||||
updateLocation(currentLocation, navigationViewModel)
|
||||
stepData.value = currentStep()
|
||||
if (route.currentManeuverIndex + 1 <= route.maneuvers.size) {
|
||||
if (route.currentStep + 1 <= legs.steps.size) {
|
||||
nextStepData.value = nextStep()
|
||||
}
|
||||
if (routeState.maneuverType == 39
|
||||
@@ -302,20 +302,21 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
fun simulate() = GlobalScope.async {
|
||||
for ((_, loc) in routeModel.route.waypoints.withIndex()) {
|
||||
if (routeModel.isNavigating()) {
|
||||
mock.setMockLocation(loc[1], loc[0])
|
||||
delay(500L) //
|
||||
for ((index, step) in routeModel.legs.steps.withIndex()) {
|
||||
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||
mock.setMockLocation(waypoint[1], waypoint[0])
|
||||
delay(1000L) //
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
for ((index, loc) in routeModel.route.waypoints.withIndex()) {
|
||||
if (index > 300) {
|
||||
routeModel.updateLocation(location(loc[0], loc[1]), navigationViewModel)
|
||||
for ((index, step) in routeModel.legs.steps.withIndex()) {
|
||||
println("${step.maneuver.waypoints.size}")
|
||||
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||
routeModel.updateLocation(location(waypoint[0], waypoint[1]), navigationViewModel)
|
||||
routeModel.currentStep()
|
||||
if (routeModel.route.currentManeuverIndex + 1 <= routeModel.route.maneuvers.size) {
|
||||
if (index + 1 <= routeModel.legs.steps.size) {
|
||||
nextStepData.value = routeModel.nextStep()
|
||||
}
|
||||
println(routeModel.routeState.maneuverType)
|
||||
|
||||
@@ -300,7 +300,7 @@ class SurfaceRenderer(
|
||||
with(routeModel) {
|
||||
routeData.value = route.routeGeoJson
|
||||
centerLocation = route.centerLocation
|
||||
previewDistance = route.distance
|
||||
previewDistance = route.summary!!.distance
|
||||
}
|
||||
updateCameraPosition(
|
||||
0.0,
|
||||
|
||||
@@ -196,7 +196,7 @@ fun DrawNavigationImages(
|
||||
|
||||
@Composable
|
||||
fun NavigationImage(padding: PaddingValues, width: Int, height: Int) {
|
||||
val imageSize = (height / 6)
|
||||
val imageSize = (height / 8)
|
||||
val color = remember { NavigationColor }
|
||||
Box(contentAlignment = Alignment.Center, modifier = Modifier.padding(padding)) {
|
||||
Canvas(
|
||||
|
||||
@@ -89,7 +89,7 @@ class RoutePreviewScreen(
|
||||
)
|
||||
.build()
|
||||
|
||||
val message = if (routeModel.isNavigating() && routeModel.route.waypoints.isNotEmpty()) {
|
||||
val message = if (routeModel.isNavigating() && routeModel.route.waypoints!!.isNotEmpty()) {
|
||||
createRouteText()
|
||||
} else {
|
||||
CarText.Builder("Wait")
|
||||
@@ -173,8 +173,8 @@ class RoutePreviewScreen(
|
||||
.build()
|
||||
|
||||
private fun createRouteText(): CarText {
|
||||
val time = routeModel.route.summary.time
|
||||
val length = BigDecimal(routeModel.route.distance).setScale(1, RoundingMode.HALF_EVEN)
|
||||
val time = routeModel.route.summary!!.duration
|
||||
val length = BigDecimal(routeModel.route.summary!!.distance).setScale(1, RoundingMode.HALF_EVEN)
|
||||
val firstRoute = SpannableString(" \u00b7 $length km")
|
||||
firstRoute.setSpan(
|
||||
DurationSpan.create(time.toLong()), 0, 1, 0
|
||||
|
||||
@@ -40,7 +40,7 @@ abstract class NavigationRepository {
|
||||
val route = getRoute(currentLocation, location, searchFilter)
|
||||
val routeModel = RouteModel()
|
||||
routeModel.startNavigation(route)
|
||||
return routeModel.route.distance
|
||||
return routeModel.route.summary!!.distance
|
||||
}
|
||||
|
||||
fun searchPlaces(search: String, location: Location) : String {
|
||||
|
||||
@@ -2,125 +2,91 @@ package com.kouros.navigation.data
|
||||
|
||||
import android.location.Location
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.kouros.navigation.data.valhalla.Maneuvers
|
||||
import com.kouros.navigation.data.valhalla.Summary
|
||||
import com.kouros.navigation.data.valhalla.Trip
|
||||
import com.kouros.navigation.data.valhalla.ValhallaJson
|
||||
import com.kouros.navigation.data.route.Leg
|
||||
import com.kouros.navigation.data.route.Step
|
||||
import com.kouros.navigation.data.route.Summary
|
||||
import com.kouros.navigation.data.valhalla.ValhallaResponse
|
||||
import com.kouros.navigation.data.valhalla.ValhallaRoute
|
||||
import com.kouros.navigation.utils.GeoUtils.createCenterLocation
|
||||
import com.kouros.navigation.utils.GeoUtils.createLineStringCollection
|
||||
import com.kouros.navigation.utils.GeoUtils.decodePolyline
|
||||
import com.kouros.navigation.utils.location
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import org.maplibre.geojson.Point
|
||||
|
||||
|
||||
data class Route(
|
||||
/**
|
||||
* A Leg is a route between only two waypoints.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
val maneuvers: List<Maneuvers>,
|
||||
|
||||
/**
|
||||
* The distance traveled from origin to destination.
|
||||
*
|
||||
* @return a double number with unit meters
|
||||
* @since 1.0.0
|
||||
*/
|
||||
val distance: Double,
|
||||
|
||||
/**
|
||||
* List of [List<Double>] objects. Each `waypoint` is an input coordinate
|
||||
* snapped to the road and path network. The `waypoint` appear in the list in the order of
|
||||
* the input coordinates.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
val waypoints: List<List<Double>>,
|
||||
|
||||
/**
|
||||
* List of [List<Point>] objects. Each `Point` is an input coordinate
|
||||
* snapped to the road and path network. The `waypoint` appear in the list in the order of
|
||||
* the input coordinates.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
val pointLocations: List<Point>,
|
||||
|
||||
val summary: Summary,
|
||||
|
||||
val trip: Trip,
|
||||
|
||||
val time: Double,
|
||||
|
||||
val routeGeoJson: String,
|
||||
|
||||
val currentManeuverIndex : Int,
|
||||
|
||||
val centerLocation: Location
|
||||
|
||||
val routeEngine: Int,
|
||||
val summary: Summary?,
|
||||
val legs: List<Leg>?,
|
||||
val routeGeoJson: String = "",
|
||||
val centerLocation : Location = location(0.0, 0.0),
|
||||
var currentStep : Int = 0,
|
||||
val waypoints: List<List<Double>>?,
|
||||
) {
|
||||
|
||||
class Builder {
|
||||
private lateinit var maneuvers: List<Maneuvers>
|
||||
private var distance: Double = 0.0
|
||||
private var time: Double = 0.0
|
||||
private lateinit var waypoints: List<List<Double>>
|
||||
private lateinit var pointLocations: List<Point>
|
||||
private lateinit var summary: Summary
|
||||
private lateinit var trip: Trip
|
||||
private var routeGeoJson = ""
|
||||
private var centerLocation = location(0.0, 0.0)
|
||||
data class Builder (
|
||||
|
||||
var routeEngine : Int = 0,
|
||||
var summary: Summary? = null,
|
||||
var legs: List<Leg>? = null,
|
||||
var routeGeoJson: String = "",
|
||||
var centerLocation: Location = location(0.0, 0.0),
|
||||
var waypoints : List<List<Double>>? = null,) {
|
||||
|
||||
fun routeType (routeEngine: Int) = apply {this.routeEngine = routeEngine }
|
||||
fun summary(summary: Summary) = apply { this.summary = summary }
|
||||
fun legs(legs: List<Leg>) = apply { this.legs = legs }
|
||||
fun routeGeoJson(routeGeoJson: String) = apply {
|
||||
this.routeGeoJson = routeGeoJson
|
||||
centerLocation = createCenterLocation(routeGeoJson)
|
||||
}
|
||||
fun waypoints(waypoints: List<List<Double>>) = apply { this.waypoints = waypoints }
|
||||
fun route(route: String) = apply {
|
||||
if (route.isNotEmpty() && route != "[]") {
|
||||
val gson = GsonBuilder().serializeNulls().create()
|
||||
val routeJson = gson.fromJson(route, ValhallaJson::class.java)
|
||||
trip = routeJson.trip
|
||||
val jsonObject: Map<String, JsonElement> = Json.parseToJsonElement(route).jsonObject
|
||||
val routeJson =
|
||||
gson.fromJson(jsonObject["trip"].toString(), ValhallaResponse::class.java)
|
||||
ValhallaRoute().mapJsonToValhalla(routeJson, this)
|
||||
}
|
||||
}
|
||||
|
||||
fun build(): Route {
|
||||
maneuvers = trip.legs[0].maneuvers
|
||||
summary = trip.summary
|
||||
distance = summary.length
|
||||
time = summary.time
|
||||
waypoints = decodePolyline(trip.legs[0].shape)
|
||||
val points = mutableListOf<Point>()
|
||||
for (loc in waypoints) {
|
||||
val point = Point.fromLngLat(loc[0], loc[1])
|
||||
points.add(point)
|
||||
}
|
||||
pointLocations = points
|
||||
routeGeoJson = createLineStringCollection( waypoints)
|
||||
centerLocation = createCenterLocation(routeGeoJson)
|
||||
return Route(
|
||||
maneuvers,
|
||||
distance,
|
||||
waypoints,
|
||||
pointLocations,
|
||||
summary,
|
||||
trip,
|
||||
time,
|
||||
routeGeoJson,
|
||||
0,
|
||||
centerLocation
|
||||
routeEngine = this.routeEngine,
|
||||
summary = this.summary,
|
||||
legs = this.legs,
|
||||
waypoints = this.waypoints,
|
||||
routeGeoJson = this.routeGeoJson,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun maneuverLocations(): List<Point> {
|
||||
return pointLocations
|
||||
val step = currentStep()
|
||||
val waypoints = step.maneuver.waypoints
|
||||
val points = mutableListOf<Point>()
|
||||
for (loc in waypoints) {
|
||||
val point = Point.fromLngLat(loc[0], loc[1])
|
||||
points.add(point)
|
||||
}
|
||||
return points
|
||||
}
|
||||
|
||||
fun currentManeuver(): Maneuvers {
|
||||
return maneuvers[currentManeuverIndex]
|
||||
fun currentStep(): Step {
|
||||
if (legs != null) {
|
||||
return legs.first().steps[currentStep]
|
||||
} else {
|
||||
throw IndexOutOfBoundsException("No legs available.")
|
||||
}
|
||||
}
|
||||
|
||||
fun nextManeuver(): Maneuvers {
|
||||
val nextIndex = currentManeuverIndex + 1
|
||||
return if (nextIndex < maneuvers.size) {
|
||||
maneuvers[nextIndex]
|
||||
fun nextStep(): Step {
|
||||
val nextIndex = currentStep + 1
|
||||
return if (nextIndex < legs!!.first().steps.size) {
|
||||
legs.first().steps[currentStep + 1]
|
||||
} else {
|
||||
throw IndexOutOfBoundsException("No next maneuver available.")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.kouros.navigation.data.route
|
||||
|
||||
data class Leg(
|
||||
var steps : List<Step> = arrayListOf()
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.kouros.navigation.data.route
|
||||
|
||||
data class Maneuver(
|
||||
val bearingBefore : Int = 0,
|
||||
val bearingAfter : Int = 0,
|
||||
val type: Int = 0,
|
||||
val waypoints: List<List<Double>>,
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.kouros.navigation.data.route
|
||||
|
||||
class Step(
|
||||
var index : Int = 0,
|
||||
var waypointIndex : Int = 0,
|
||||
val maneuver: Maneuver,
|
||||
val duration: Double = 0.0,
|
||||
val distance: Double = 0.0,
|
||||
val name : String = "",
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.kouros.navigation.data.route
|
||||
|
||||
data class Summary(
|
||||
var duration : Double = 0.0,
|
||||
var distance : Double = 0.0,
|
||||
)
|
||||
@@ -2,7 +2,6 @@ package com.kouros.navigation.data.valhalla
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.JsonIgnoreUnknownKeys
|
||||
|
||||
|
||||
@@ -11,7 +10,7 @@ import kotlinx.serialization.json.JsonIgnoreUnknownKeys
|
||||
data class Legs (
|
||||
|
||||
@SerializedName("maneuvers" ) var maneuvers : ArrayList<Maneuvers> = arrayListOf(),
|
||||
@SerializedName("summary" ) var summary : Summary = Summary(),
|
||||
@SerializedName("summary" ) var summaryValhalla : SummaryValhalla = SummaryValhalla(),
|
||||
@SerializedName("shape" ) var shape : String = ""
|
||||
|
||||
)
|
||||
@@ -2,13 +2,12 @@ package com.kouros.navigation.data.valhalla
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.JsonIgnoreUnknownKeys
|
||||
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@JsonIgnoreUnknownKeys
|
||||
data class Summary (
|
||||
data class SummaryValhalla (
|
||||
|
||||
@SerializedName("has_time_restrictions" ) var hasTimeRestrictions : Boolean = false,
|
||||
@SerializedName("has_toll" ) var hasToll : Boolean = false,
|
||||
@@ -2,7 +2,6 @@ package com.kouros.navigation.data.valhalla
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.JsonIgnoreUnknownKeys
|
||||
|
||||
|
||||
@@ -12,7 +11,7 @@ data class Trip (
|
||||
|
||||
@SerializedName("locations" ) var locations : ArrayList<Locations> = arrayListOf(),
|
||||
@SerializedName("legs" ) var legs : ArrayList<Legs> = arrayListOf(),
|
||||
@SerializedName("summary" ) var summary : Summary = Summary(),
|
||||
@SerializedName("summary" ) var summaryValhalla : SummaryValhalla = SummaryValhalla(),
|
||||
@SerializedName("status_message" ) var statusMessage : String = "",
|
||||
@SerializedName("status" ) var status : Int = 0,
|
||||
@SerializedName("units" ) var units : String = "",
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.kouros.navigation.data.valhalla
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.JsonIgnoreUnknownKeys
|
||||
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@JsonIgnoreUnknownKeys
|
||||
data class ValhallaResponse(
|
||||
|
||||
@SerializedName("locations") var locations: ArrayList<Locations> = arrayListOf(),
|
||||
@SerializedName("legs") var legs: ArrayList<Legs> = arrayListOf(),
|
||||
@SerializedName("summary") var summaryValhalla: SummaryValhalla = SummaryValhalla(),
|
||||
@SerializedName("status_message") var statusMessage: String = "",
|
||||
@SerializedName("status") var status: Int = 0,
|
||||
@SerializedName("units") var units: String = "",
|
||||
@SerializedName("language") var language: String = "",
|
||||
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.kouros.navigation.data.valhalla
|
||||
|
||||
import com.kouros.navigation.data.Route
|
||||
import com.kouros.navigation.data.route.Leg
|
||||
import com.kouros.navigation.data.route.Maneuver
|
||||
import com.kouros.navigation.data.route.Step
|
||||
import com.kouros.navigation.data.route.Summary
|
||||
import com.kouros.navigation.utils.GeoUtils.createLineStringCollection
|
||||
import com.kouros.navigation.utils.GeoUtils.decodePolyline
|
||||
|
||||
class ValhallaRoute {
|
||||
|
||||
fun mapJsonToValhalla(routeJson: ValhallaResponse, builder: Route.Builder) {
|
||||
val waypoints = decodePolyline(routeJson.legs[0].shape)
|
||||
val summary = Summary()
|
||||
summary.distance = routeJson.summaryValhalla.length
|
||||
summary.duration = routeJson.summaryValhalla.time
|
||||
val steps = mutableListOf<Step>()
|
||||
var stepIndex = 0
|
||||
routeJson.legs[0].maneuvers.forEach {
|
||||
val maneuver = Maneuver(
|
||||
bearingBefore = 0,
|
||||
bearingAfter = it.bearingAfter,
|
||||
type = it.type,
|
||||
waypoints =waypoints.subList(it.beginShapeIndex, it.endShapeIndex+1)
|
||||
)
|
||||
var name = ""
|
||||
if (it.streetNames != null && it.streetNames.isNotEmpty()) {
|
||||
name = it.streetNames[0]
|
||||
}
|
||||
val step = Step( index = stepIndex, name = name, distance = it.length, duration = it.time, maneuver = maneuver)
|
||||
steps.add(step)
|
||||
stepIndex += 1
|
||||
}
|
||||
val leg = Leg(steps)
|
||||
builder
|
||||
.routeType(1)
|
||||
.summary(summary)
|
||||
.routeGeoJson(createLineStringCollection(waypoints))
|
||||
.legs(listOf(leg))
|
||||
.waypoints(waypoints)
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.kouros.navigation.data.ManeuverType
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.data.Route
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.data.route.Leg
|
||||
import com.kouros.navigation.utils.location
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -24,15 +25,10 @@ open class RouteModel() {
|
||||
val destination: Place = Place(),
|
||||
val arrived: Boolean = false,
|
||||
val maneuverType: Int = 0,
|
||||
var currentShapeIndex: Int = 0,
|
||||
var distanceToStepEnd: Float = 0F,
|
||||
var beginIndex: Int = 0,
|
||||
var endIndex: Int = 0,
|
||||
val travelMessage: String = "",
|
||||
// max speed for street (maneuver)
|
||||
val lastSpeedIndex: Int = 0,
|
||||
val maxSpeed: Int = 0,
|
||||
|
||||
)
|
||||
|
||||
var routeState = RouteState()
|
||||
@@ -43,6 +39,10 @@ open class RouteModel() {
|
||||
routeState = routeState.copy(route = value)
|
||||
}
|
||||
|
||||
|
||||
val legs: Leg
|
||||
get() = routeState.route!!.legs!!.first()
|
||||
|
||||
fun startNavigation(routeString: String) {
|
||||
val newRoute = Route.Builder()
|
||||
.route(routeString)
|
||||
@@ -59,40 +59,39 @@ open class RouteModel() {
|
||||
isNavigating = false,
|
||||
arrived = false,
|
||||
maneuverType = 0,
|
||||
currentShapeIndex = 0,
|
||||
distanceToStepEnd = 0F,
|
||||
beginIndex = 0,
|
||||
endIndex = 0
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
fun updateLocation(location: Location, viewModel: ViewModel) {
|
||||
var nearestDistance = 100000.0f
|
||||
var newShapeIndex = -1
|
||||
// find nearest waypoint and current shape index
|
||||
// start search at last shape index
|
||||
for (i in routeState.currentShapeIndex..<route.waypoints.size) {
|
||||
val waypoint = route.waypoints[i]
|
||||
val distance = location.distanceTo(location(waypoint[0], waypoint[1]))
|
||||
if (distance < nearestDistance) {
|
||||
nearestDistance = distance
|
||||
newShapeIndex = i
|
||||
}
|
||||
}
|
||||
// find maneuver
|
||||
// calculate distance to step end
|
||||
findManeuver(newShapeIndex)
|
||||
|
||||
findStep(location)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
updateSpeedLimit(location, viewModel)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findStep(location: Location) {
|
||||
var nearestDistance = 100000.0f
|
||||
for ((index, step) in legs.steps.withIndex()) {
|
||||
if (index >= route.currentStep && nearestDistance > 0) {
|
||||
for ((wayIndex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||
if (wayIndex >= step.waypointIndex) {
|
||||
val distance = location.distanceTo(location(waypoint[0], waypoint[1]))
|
||||
if (distance < nearestDistance) {
|
||||
nearestDistance = distance
|
||||
route.currentStep = step.index
|
||||
step.waypointIndex = wayIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSpeedLimit(location: Location, viewModel: ViewModel) {
|
||||
// speed limit for each maneuver index
|
||||
if (routeState.lastSpeedIndex < route.currentManeuverIndex) {
|
||||
routeState = routeState.copy(lastSpeedIndex = route.currentManeuverIndex)
|
||||
if (routeState.lastSpeedIndex < route.currentStep) {
|
||||
routeState = routeState.copy(lastSpeedIndex = route.currentStep)
|
||||
val elements = viewModel.getMaxSpeed(location)
|
||||
elements.forEach {
|
||||
if (it.tags.name != null && it.tags.maxspeed != null) {
|
||||
@@ -103,52 +102,30 @@ open class RouteModel() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun findManeuver(newShapeIndex: Int) {
|
||||
for (i in route.currentManeuverIndex..<route.maneuvers.size) {
|
||||
val maneuver = route.maneuvers[i]
|
||||
if (maneuver.beginShapeIndex <= newShapeIndex && maneuver.endShapeIndex >= newShapeIndex) {
|
||||
route = route.copy(currentManeuverIndex = i)
|
||||
routeState.apply {
|
||||
currentShapeIndex = newShapeIndex
|
||||
beginIndex = maneuver.beginShapeIndex
|
||||
endIndex = maneuver.endShapeIndex
|
||||
distanceToStepEnd = 0F
|
||||
// calculate shape distance to step end
|
||||
for (j in newShapeIndex + 1..maneuver.endShapeIndex) {
|
||||
val loc1 = location(route!!.waypoints[j - 1][0], route.waypoints[j - 1][1])
|
||||
val loc2 = location(route.waypoints[j][0], route.waypoints[j][1])
|
||||
distanceToStepEnd += loc1.distanceTo(loc2)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun currentStep(): StepData {
|
||||
val currentManeuver = route.currentManeuver()
|
||||
val currentStep = route.currentStep()
|
||||
// Determine if we should display the current or the next maneuver
|
||||
val distanceToNextStep = leftStepDistance()
|
||||
val isNearNextManeuver = distanceToNextStep in 0.0..NEXT_STEP_THRESHOLD
|
||||
val shouldAdvance =
|
||||
isNearNextManeuver && route.currentManeuverIndex < (route.maneuvers.size)
|
||||
isNearNextManeuver && route.currentStep < (route.legs!!.first().steps.size)
|
||||
|
||||
// Determine the maneuver type and corresponding icon
|
||||
var maneuverType = if (hasArrived(currentManeuver.type)) {
|
||||
currentManeuver.type
|
||||
var maneuverType = if (hasArrived(currentStep.maneuver.type)) {
|
||||
currentStep.maneuver.type
|
||||
} else {
|
||||
ManeuverType.None.value
|
||||
}
|
||||
// Get the single, correct maneuver for this state
|
||||
val relevantManeuver = if (shouldAdvance) {
|
||||
route.nextManeuver() // This advances the route's state
|
||||
route.nextStep() // This advances the route's state
|
||||
} else {
|
||||
route.currentManeuver()
|
||||
route.currentStep()
|
||||
}
|
||||
// Safely get the street name from the maneuver
|
||||
val streetName = relevantManeuver.streetNames?.firstOrNull() ?: ""
|
||||
val streetName = relevantManeuver.name
|
||||
if (shouldAdvance) {
|
||||
maneuverType = relevantManeuver.type
|
||||
maneuverType = relevantManeuver.maneuver.type
|
||||
}
|
||||
val maneuverIconPair = maneuverIcon(maneuverType)
|
||||
routeState = routeState.copy(maneuverType = maneuverIconPair.first)
|
||||
@@ -165,8 +142,8 @@ open class RouteModel() {
|
||||
|
||||
|
||||
fun nextStep(): StepData {
|
||||
val maneuver = route.nextManeuver()
|
||||
val maneuverType = maneuver.type
|
||||
val step = route.nextStep()
|
||||
val maneuverType = step.maneuver.type
|
||||
val distanceLeft = leftStepDistance()
|
||||
var text = ""
|
||||
|
||||
@@ -175,8 +152,8 @@ open class RouteModel() {
|
||||
}
|
||||
|
||||
else -> {
|
||||
if (maneuver.streetNames != null && maneuver.streetNames.isNotEmpty()) {
|
||||
text = maneuver.streetNames[0]
|
||||
if (step.name.isNotEmpty()) {
|
||||
text = step.name
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,18 +172,16 @@ open class RouteModel() {
|
||||
|
||||
fun travelLeftTime(): Double {
|
||||
var timeLeft = 0.0
|
||||
for (i in route.currentManeuverIndex + 1..<route.maneuvers.size) {
|
||||
val maneuver = route.maneuvers[i]
|
||||
timeLeft += maneuver.time
|
||||
for (i in route.currentStep + 1..<legs.steps.size) {
|
||||
val step = legs.steps[i]
|
||||
timeLeft += step.duration
|
||||
}
|
||||
if (routeState.endIndex > 0) {
|
||||
val maneuver = route.currentManeuver()
|
||||
val curTime = maneuver.time
|
||||
val step = route.nextStep()
|
||||
val curTime = step.duration
|
||||
val percent =
|
||||
100 * (routeState.endIndex - routeState.currentShapeIndex) / (routeState.endIndex - routeState.beginIndex)
|
||||
100 * (step.maneuver.waypoints.size - step.waypointIndex) / (step.maneuver.waypoints.size)
|
||||
val time = curTime * percent / 100
|
||||
timeLeft += time
|
||||
}
|
||||
return timeLeft
|
||||
}
|
||||
|
||||
@@ -221,11 +196,11 @@ open class RouteModel() {
|
||||
|
||||
/** Returns the current [Step] left distance in m. */
|
||||
fun leftStepDistance(): Double {
|
||||
val maneuver = route.currentManeuver()
|
||||
var leftDistance = maneuver.length
|
||||
if (routeState.endIndex > 0) {
|
||||
leftDistance = (routeState.distanceToStepEnd / 1000).toDouble()
|
||||
}
|
||||
val step = route.currentStep()
|
||||
var leftDistance = step.distance
|
||||
val percent =
|
||||
100 * (step.maneuver.waypoints.size - step.waypointIndex) / (step.maneuver.waypoints.size)
|
||||
leftDistance = leftDistance * percent / 100
|
||||
// The remaining distance to the step, rounded to the nearest 10 units.
|
||||
return (leftDistance * 1000 / 10.0).roundToInt() * 10.0
|
||||
|
||||
@@ -234,18 +209,17 @@ open class RouteModel() {
|
||||
/** Returns the left distance in km. */
|
||||
fun travelLeftDistance(): Double {
|
||||
var leftDistance = 0.0
|
||||
for (i in route.currentManeuverIndex + 1..<route.maneuvers.size) {
|
||||
val maneuver = route.maneuvers[i]
|
||||
leftDistance += maneuver.length
|
||||
for (i in route.currentStep + 1..<legs.steps.size) {
|
||||
val step = route.legs!![0].steps[i]
|
||||
leftDistance += step.distance
|
||||
}
|
||||
if (routeState.endIndex > 0) {
|
||||
val maneuver = route.currentManeuver()
|
||||
val curDistance = maneuver.length
|
||||
|
||||
val step = route.currentStep()
|
||||
val curDistance = step.distance
|
||||
val percent =
|
||||
100 * (routeState.endIndex - routeState.currentShapeIndex) / (routeState.endIndex - routeState.beginIndex)
|
||||
100 * (step.maneuver.waypoints.size - step.waypointIndex) / (step.maneuver.waypoints.size)
|
||||
val time = curDistance * percent / 100
|
||||
leftDistance += time
|
||||
}
|
||||
return leftDistance
|
||||
}
|
||||
|
||||
@@ -311,7 +285,6 @@ open class RouteModel() {
|
||||
currentTurnIcon = R.drawable.ic_roundabout_ccw
|
||||
}
|
||||
}
|
||||
//routeState.maneuverType = type
|
||||
return Pair(type, currentTurnIcon)
|
||||
}
|
||||
|
||||
@@ -321,7 +294,6 @@ open class RouteModel() {
|
||||
|
||||
|
||||
fun hasArrived(type: Int): Boolean {
|
||||
// return leftStepDistance() < DESTINATION_ARRIVAL_DISTANCE && type == ManeuverType.DestinationRight.value
|
||||
return type == ManeuverType.DestinationRight.value
|
||||
|| type == ManeuverType.Destination.value
|
||||
|| type == ManeuverType.DestinationLeft.value
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M190,840L160,810L480,80L800,810L770,840L480,708L190,840Z"/>
|
||||
android:pathData="M190,840L160,810L480,80L800,810L770,840L480,708L190,840ZM258,742L480,644L702,742L480,228L258,742ZM480,644L480,644L480,644L480,644Z"/>
|
||||
</vector>
|
||||
|
||||
Reference in New Issue
Block a user