This commit is contained in:
Dimitris
2026-01-06 08:25:27 +01:00
parent fdf2ee9f48
commit 7efa2685be
24 changed files with 226 additions and 88 deletions

View File

@@ -47,7 +47,6 @@ import com.kouros.navigation.model.BaseStyleModel
import com.kouros.navigation.model.MockLocation import com.kouros.navigation.model.MockLocation
import com.kouros.navigation.model.RouteModel import com.kouros.navigation.model.RouteModel
import com.kouros.navigation.ui.theme.NavigationTheme import com.kouros.navigation.ui.theme.NavigationTheme
import com.kouros.navigation.utils.GeoUtils.snapLocation
import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue
import com.kouros.navigation.utils.bearing import com.kouros.navigation.utils.bearing
import com.kouros.navigation.utils.calculateZoom import com.kouros.navigation.utils.calculateZoom
@@ -62,7 +61,6 @@ import org.maplibre.compose.location.Location
import org.maplibre.compose.location.rememberDefaultLocationProvider import org.maplibre.compose.location.rememberDefaultLocationProvider
import org.maplibre.compose.location.rememberUserLocationState import org.maplibre.compose.location.rememberUserLocationState
import org.maplibre.compose.style.BaseStyle import org.maplibre.compose.style.BaseStyle
import org.maplibre.geojson.Point
import org.maplibre.spatialk.geojson.Position import org.maplibre.spatialk.geojson.Position
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
@@ -222,6 +220,7 @@ class MainActivity : ComponentActivity() {
SearchSheet(applicationContext, navigationViewModel, lastLocation) { closeSheet() } SearchSheet(applicationContext, navigationViewModel, lastLocation) { closeSheet() }
} else { } else {
NavigationSheet( NavigationSheet(
applicationContext,
routeModel, step!!, nextStep!!, routeModel, step!!, nextStep!!,
{ stopNavigation { closeSheet() } }, { stopNavigation { closeSheet() } },
{ simulateNavigation() } { simulateNavigation() }
@@ -274,7 +273,7 @@ class MainActivity : ComponentActivity() {
closeSheet() closeSheet()
routeModel.stopNavigation() routeModel.stopNavigation()
routeData.value = "" routeData.value = ""
stepData.value = StepData("", 0.0, 0, 0, 0, 0.0) stepData.value = StepData("", 0.0, 0, 0,0, 0.0)
} }
fun simulateNavigation() { fun simulateNavigation() {
@@ -310,8 +309,11 @@ class MainActivity : ComponentActivity() {
if (routeModel.isNavigating()) { if (routeModel.isNavigating()) {
for ((index, waypoint) in routeModel.route.waypoints!!.withIndex()) { for ((index, waypoint) in routeModel.route.waypoints!!.withIndex()) {
var deviation = 0.0 var deviation = 0.0
mock.setMockLocation(waypoint[1] + deviation, waypoint[0]) //if (index in 0..350 ) {
delay(500L) // mock.setMockLocation(waypoint[1] + deviation, waypoint[0])
delay(500L) //
// }
} }
} }
} }

View File

@@ -1,20 +1,20 @@
import android.content.Context
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.kouros.data.R import com.kouros.data.R
import com.kouros.navigation.data.Constants.NEXT_STEP_THRESHOLD
import com.kouros.navigation.data.StepData import com.kouros.navigation.data.StepData
import com.kouros.navigation.model.RouteModel import com.kouros.navigation.model.RouteModel
import com.kouros.navigation.utils.formatDateTime import com.kouros.navigation.utils.formatDateTime
@@ -23,6 +23,7 @@ import com.kouros.navigation.utils.round
@Composable @Composable
fun NavigationSheet( fun NavigationSheet(
applicationContext: Context,
routeModel: RouteModel, routeModel: RouteModel,
step: StepData, step: StepData,
nextStep: StepData, nextStep: StepData,
@@ -30,6 +31,14 @@ fun NavigationSheet(
simulateNavigation: () -> Unit, simulateNavigation: () -> Unit,
) { ) {
val distance = step.leftDistance.round(1) val distance = step.leftDistance.round(1)
step.lane.forEach {
if (it.indications.isNotEmpty()) {
routeModel.createLaneIcon(applicationContext, step)
}
}
Column { Column {
FlowRow(horizontalArrangement = Arrangement.SpaceEvenly) { FlowRow(horizontalArrangement = Arrangement.SpaceEvenly) {
Text(formatDateTime(step.arrivalTime), fontSize = 22.sp) Text(formatDateTime(step.arrivalTime), fontSize = 22.sp)

View File

@@ -55,9 +55,9 @@ class NavigationSession : Session(), NavigationScreen.Listener {
var mLocationListener: LocationListenerCompat = LocationListenerCompat { location: Location? -> var mLocationListener: LocationListenerCompat = LocationListenerCompat { location: Location? ->
val routingEngine = getIntKeyValue(carContext, ROUTING_ENGINE) val routingEngine = getIntKeyValue(carContext, ROUTING_ENGINE)
if (routingEngine == RouteEngine.VALHALLA.ordinal) { // if (routingEngine == RouteEngine.VALHALLA.ordinal) {
updateLocation(location!!) updateLocation(location!!)
} // }
} }
private val mLifeCycleObserver: LifecycleObserver = object : DefaultLifecycleObserver { private val mLifeCycleObserver: LifecycleObserver = object : DefaultLifecycleObserver {
@@ -97,7 +97,9 @@ class NavigationSession : Session(), NavigationScreen.Listener {
OnCarDataAvailableListener { data -> OnCarDataAvailableListener { data ->
if (data.location.status == CarValue.STATUS_SUCCESS) { if (data.location.status == CarValue.STATUS_SUCCESS) {
val location = data.location.value val location = data.location.value
surfaceRenderer.updateCarLocation(location!!) if (location != null) {
updateLocation(location)
}
} }
} }

View File

@@ -36,9 +36,12 @@ import androidx.car.app.navigation.model.Step
import androidx.car.app.navigation.model.TravelEstimate import androidx.car.app.navigation.model.TravelEstimate
import androidx.core.graphics.drawable.IconCompat import androidx.core.graphics.drawable.IconCompat
import com.kouros.data.R import com.kouros.data.R
import com.kouros.navigation.data.StepData
import com.kouros.navigation.model.RouteModel import com.kouros.navigation.model.RouteModel
import java.util.Collections
import java.util.TimeZone import java.util.TimeZone
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.text.trim
/** A class that provides models for the routing demos. */ /** A class that provides models for the routing demos. */
class RouteCarModel() : RouteModel() { class RouteCarModel() : RouteModel() {
@@ -48,23 +51,16 @@ class RouteCarModel() : RouteModel() {
val stepData = currentStep() val stepData = currentStep()
val currentStepCueWithImage: SpannableString = val currentStepCueWithImage: SpannableString =
createString(stepData.instruction) createString(stepData.instruction)
val straightNormal =
Lane.Builder()
.addDirection(LaneDirection.create(LaneDirection.SHAPE_STRAIGHT, false))
.build()
val step = val step =
Step.Builder(currentStepCueWithImage) Step.Builder(currentStepCueWithImage)
.setManeuver( .setManeuver(
Maneuver.Builder(stepData.maneuverType) Maneuver.Builder(stepData.currentManeuverType)
.setIcon(createCarIcon(carContext, stepData.icon)) .setIcon(createCarIcon(carContext, stepData.icon))
.build() .build()
) )
.setRoad(routeState.destination.street!!) .setRoad(routeState.destination.street!!)
stepData.lane.forEach { if (stepData.lane.isNotEmpty()) {
if (it.indications.isNotEmpty() ) { addLanes(carContext, step, stepData)
step.setLanesImage(createCarIcon(createLaneIcon(carContext, stepData)))
step.addLane(straightNormal)
}
} }
return step.build() return step.build()
} }
@@ -77,7 +73,7 @@ class RouteCarModel() : RouteModel() {
val step = val step =
Step.Builder(currentStepCueWithImage) Step.Builder(currentStepCueWithImage)
.setManeuver( .setManeuver(
Maneuver.Builder(stepData.maneuverType) Maneuver.Builder(stepData.currentManeuverType)
.setIcon(createCarIcon(carContext, stepData.icon)) .setIcon(createCarIcon(carContext, stepData.icon))
.build() .build()
) )
@@ -121,6 +117,90 @@ class RouteCarModel() : RouteModel() {
return travelBuilder.build() return travelBuilder.build()
} }
fun addLanes(carContext: CarContext, step: Step.Builder, stepData: StepData) {
var laneImageAdded = false
stepData.lane.forEach {
if (it.indications.isNotEmpty() && it.valid) {
Collections.sort<String>(it.indications)
var direction = ""
it.indications.forEach { it2 ->
direction = if (direction.isEmpty()) {
it2.trim()
} else {
"${direction}_${it2.trim()}"
}
}
val laneDirection = when (direction) {
"left_straight" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_TURN_NORMAL_LEFT -> LaneDirection.SHAPE_NORMAL_LEFT
Maneuver.TYPE_STRAIGHT -> LaneDirection.SHAPE_STRAIGHT
else
-> LaneDirection.SHAPE_UNKNOWN
}
}
"left" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_TURN_NORMAL_LEFT -> LaneDirection.SHAPE_NORMAL_LEFT
else
-> LaneDirection.SHAPE_UNKNOWN
}
}
"straight" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_STRAIGHT -> LaneDirection.SHAPE_STRAIGHT
else
-> LaneDirection.SHAPE_UNKNOWN
}
}
"right" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_TURN_NORMAL_RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT
else
-> LaneDirection.SHAPE_UNKNOWN
}
}
"right_straight" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_TURN_NORMAL_RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT
Maneuver.TYPE_STRAIGHT -> LaneDirection.SHAPE_STRAIGHT
else
-> LaneDirection.SHAPE_UNKNOWN
}
}
"left_slight" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_TURN_SLIGHT_LEFT -> LaneDirection.SHAPE_SLIGHT_LEFT
else
-> LaneDirection.SHAPE_UNKNOWN
}
}
"right_slight" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_TURN_SLIGHT_RIGHT-> LaneDirection.SHAPE_NORMAL_RIGHT
else
-> LaneDirection.SHAPE_UNKNOWN
}
}
else -> {
LaneDirection.SHAPE_UNKNOWN
}
}
if (laneDirection != LaneDirection.SHAPE_UNKNOWN) {
if (!laneImageAdded) {
step.setLanesImage(createCarIcon(createLaneIcon(carContext, stepData)))
laneImageAdded = true
}
val laneType =
Lane.Builder()
.addDirection(LaneDirection.create(laneDirection, false))
.build()
step.addLane(laneType)
}
}
}
}
fun createString( fun createString(
text: String text: String
): SpannableString { ): SpannableString {

View File

@@ -20,6 +20,7 @@ import android.location.Location
import android.location.LocationManager import android.location.LocationManager
import android.net.Uri import android.net.Uri
import com.kouros.navigation.data.route.Lane import com.kouros.navigation.data.route.Lane
import com.kouros.navigation.utils.location
import io.objectbox.annotation.Entity import io.objectbox.annotation.Entity
import io.objectbox.annotation.Id import io.objectbox.annotation.Id
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@@ -58,7 +59,7 @@ data class StepData (
var leftStepDistance: Double, var leftStepDistance: Double,
var maneuverType: Int, var currentManeuverType: Int,
var icon: Int, var icon: Int,
@@ -66,7 +67,7 @@ data class StepData (
var leftDistance: Double, var leftDistance: Double,
var lane: List<Lane> = listOf(Lane(valid = false, indications = emptyList())), var lane: List<Lane> = listOf(Lane(location(0.0, 0.0), valid = false, indications = emptyList())),
) )
@@ -176,7 +177,7 @@ object Constants {
const val ROUTING_ENGINE = "RoutingEngine" const val ROUTING_ENGINE = "RoutingEngine"
const val NEXT_STEP_THRESHOLD = 100.0 const val NEXT_STEP_THRESHOLD = 120.0
const val MAXIMAL_SNAP_CORRECTION = 50.0 const val MAXIMAL_SNAP_CORRECTION = 50.0

View File

@@ -30,7 +30,9 @@ import kotlinx.serialization.json.Json
abstract class NavigationRepository { abstract class NavigationRepository {
private val nominatimUrl = "https://nominatim.openstreetmap.org/" //private val nominatimUrl = "https://nominatim.openstreetmap.org/"
private val nominatimUrl = "https://kouros-online.de/nominatim/"
abstract fun getRoute(currentLocation: Location, location: Location, searchFilter: SearchFilter): String abstract fun getRoute(currentLocation: Location, location: Location, searchFilter: SearchFilter): String

View File

@@ -9,6 +9,7 @@ import com.kouros.navigation.data.route.Step
import com.kouros.navigation.data.route.Summary import com.kouros.navigation.data.route.Summary
import com.kouros.navigation.utils.GeoUtils.createLineStringCollection import com.kouros.navigation.utils.GeoUtils.createLineStringCollection
import com.kouros.navigation.utils.GeoUtils.decodePolyline import com.kouros.navigation.utils.GeoUtils.decodePolyline
import com.kouros.navigation.utils.location
class OsrmRoute { class OsrmRoute {
@@ -34,8 +35,14 @@ class OsrmRoute {
if (it2.location[0] != 0.0) { if (it2.location[0] != 0.0) {
val lanes = mutableListOf<Lane>() val lanes = mutableListOf<Lane>()
it2.lanes.forEach { it3 -> it2.lanes.forEach { it3 ->
val lane = Lane(it3.valid, it3.indications) if (it3.indications.isNotEmpty() && it3.indications.first() != "none") {
lanes.add(lane) val lane = Lane(
location(it2.location[0], it2.location[1]),
it3.valid,
it3.indications
)
lanes.add(lane)
}
} }
intersections.add(Intersection(it2.location, lanes)) intersections.add(Intersection(it2.location, lanes))
} }

View File

@@ -1,6 +1,9 @@
package com.kouros.navigation.data.route package com.kouros.navigation.data.route
import android.location.Location
data class Lane ( data class Lane (
val location: Location,
val valid: Boolean, val valid: Boolean,
var indications: List<String>, var indications: List<String>,
) )

View File

@@ -28,6 +28,7 @@ import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import java.util.Collections
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt import kotlin.math.roundToInt
@@ -44,7 +45,7 @@ open class RouteModel() {
val maxSpeed: Int = 0, val maxSpeed: Int = 0,
val location: Location = location(0.0, 0.0), val location: Location = location(0.0, 0.0),
val lastLocation: Location = location(0.0, 0.0), val lastLocation: Location = location(0.0, 0.0),
val bearing : Float = 0F val bearing: Float = 0F
) )
var routeState = RouteState() var routeState = RouteState()
@@ -104,7 +105,8 @@ open class RouteModel() {
step.waypointIndex = wayIndex step.waypointIndex = wayIndex
step.wayPointLocation = location(waypoint[0], waypoint[1]) step.wayPointLocation = location(waypoint[0], waypoint[1])
val bearing = routeState.lastLocation.bearingTo(location) val bearing = routeState.lastLocation.bearingTo(location)
this.routeState = routeState.copy(lastLocation = location, bearing = bearing) this.routeState =
routeState.copy(lastLocation = location, bearing = bearing)
} }
} }
if (nearestDistance == 0F) { if (nearestDistance == 0F) {
@@ -174,15 +176,15 @@ open class RouteModel() {
if (shouldAdvance) { if (shouldAdvance) {
maneuverType = relevantStep.maneuver.type maneuverType = relevantStep.maneuver.type
} }
val maneuverIconPair = maneuverIcon(maneuverType) val maneuverIcon = maneuverIcon(maneuverType)
routeState = routeState.copy(maneuverType = maneuverIconPair.first) routeState = routeState.copy(maneuverType = maneuverType)
// Construct and return the final StepData object // Construct and return the final StepData object
val intersection = currentIntersection(routeState.location) val intersection = currentIntersection(routeState.location)
return StepData( return StepData(
streetName, streetName,
distanceToNextStep, distanceToNextStep,
maneuverIconPair.first, maneuverType,
maneuverIconPair.second, maneuverIcon,
arrivalTime(), arrivalTime(),
travelLeftDistance(), travelLeftDistance(),
intersection.lane intersection.lane
@@ -206,13 +208,13 @@ open class RouteModel() {
} }
} }
val routing: (Pair<Int, Int>) = maneuverIcon(maneuverType) val maneuverIcon = maneuverIcon(maneuverType)
// Construct and return the final StepData object // Construct and return the final StepData object
return StepData( return StepData(
text, text,
distanceLeft, distanceLeft,
routing.first, maneuverType,
routing.second, maneuverIcon,
arrivalTime(), arrivalTime(),
travelLeftDistance() travelLeftDistance()
) )
@@ -247,13 +249,15 @@ open class RouteModel() {
/** Returns the current [Step] left distance in m. */ /** Returns the current [Step] left distance in m. */
fun leftStepDistance(): Double { fun leftStepDistance(): Double {
val step = route.currentStep() val step = route.currentStep()
var leftDistance = step.distance var leftDistance = 0.0
val percent = for (i in step.waypointIndex..<step.maneuver.waypoints.size - 1) {
100 * (step.maneuver.waypoints.size - step.waypointIndex) / (step.maneuver.waypoints.size) val loc1 = location(step.maneuver.waypoints[i][0], step.maneuver.waypoints[i][1])
leftDistance = leftDistance * percent / 100 val loc2 =
// The remaining distance to the step, rounded to the nearest 10 units. location(step.maneuver.waypoints[i + 1][0], step.maneuver.waypoints[i + 1][1])
return (leftDistance * 1000 / 10.0).roundToInt() * 10.0 val distance = loc1.distanceTo(loc2)
leftDistance += distance
}
return (leftDistance / 10.0).roundToInt() * 10.0
} }
/** Returns the left distance in km. */ /** Returns the left distance in km. */
@@ -263,17 +267,11 @@ open class RouteModel() {
val step = route.legs!![0].steps[i] val step = route.legs!![0].steps[i]
leftDistance += step.distance leftDistance += step.distance
} }
leftDistance += leftStepDistance() / 1000
val step = route.currentStep()
val curDistance = step.distance
val percent =
100 * (step.maneuver.waypoints.size - step.waypointIndex) / (step.maneuver.waypoints.size)
val distance = curDistance * percent / 100
leftDistance += distance
return leftDistance return leftDistance
} }
fun maneuverIcon(routeManeuverType: Int): (Pair<Int, Int>) { fun maneuverIcon(routeManeuverType: Int): Int {
var currentTurnIcon = R.drawable.ic_turn_name_change var currentTurnIcon = R.drawable.ic_turn_name_change
when (routeManeuverType) { when (routeManeuverType) {
Maneuver.TYPE_STRAIGHT -> { Maneuver.TYPE_STRAIGHT -> {
@@ -304,9 +302,11 @@ open class RouteModel() {
Maneuver.TYPE_KEEP_RIGHT -> { Maneuver.TYPE_KEEP_RIGHT -> {
currentTurnIcon = R.drawable.ic_turn_name_change currentTurnIcon = R.drawable.ic_turn_name_change
} }
Maneuver.TYPE_KEEP_LEFT -> { Maneuver.TYPE_KEEP_LEFT -> {
currentTurnIcon = R.drawable.ic_turn_name_change currentTurnIcon = R.drawable.ic_turn_name_change
} }
Maneuver.TYPE_ROUNDABOUT_ENTER_CCW -> { Maneuver.TYPE_ROUNDABOUT_ENTER_CCW -> {
currentTurnIcon = R.drawable.ic_roundabout_ccw currentTurnIcon = R.drawable.ic_roundabout_ccw
} }
@@ -316,7 +316,7 @@ open class RouteModel() {
currentTurnIcon = R.drawable.ic_roundabout_ccw currentTurnIcon = R.drawable.ic_roundabout_ccw
} }
} }
return Pair(routeManeuverType, currentTurnIcon) return currentTurnIcon
} }
fun isNavigating(): Boolean { fun isNavigating(): Boolean {
@@ -333,31 +333,30 @@ open class RouteModel() {
fun createLaneIcon(context: Context, stepData: StepData): IconCompat { fun createLaneIcon(context: Context, stepData: StepData): IconCompat {
val bitmaps = mutableListOf<Bitmap>() val bitmaps = mutableListOf<Bitmap>()
stepData.lane.forEach { stepData.lane.forEach {
if (it.indications.isNotEmpty()) { if (it.indications.isNotEmpty() && it.valid) {
it.indications.forEach { it2 -> Collections.sort<String>(it.indications)
val resource = laneToResource(it2, it, stepData) val resource = laneToResource(it.indications, stepData)
if (it2 != "none") { if (resource.isNotEmpty()) {
println("Direction $resource") val id = resourceId(resource);
if (resource.isNotEmpty()) { val bitMap = BitmapFactory.decodeResource(context.resources, id)
val id = resourceId( resource); bitmaps.add(bitMap)
val bitMap = BitmapFactory.decodeResource(context.resources, id)
bitmaps.add(bitMap)
}
}
} }
} }
} }
return IconCompat.createWithBitmap(overlay(bitmaps = bitmaps)) return if (bitmaps.isEmpty()) {
IconCompat.createWithResource(context, R.drawable.ic_close_white_24dp)
} else {
IconCompat.createWithBitmap(overlay(bitmaps = bitmaps))
}
} }
fun overlay(bitmaps: List<Bitmap>): Bitmap { fun overlay(bitmaps: List<Bitmap>): Bitmap {
val matrix = Matrix() val matrix = Matrix()
if (bitmaps.size == 1) { if (bitmaps.size == 1) {
return bitmaps.first() return bitmaps.first()
} }
val bmOverlay = createBitmap( val bmOverlay = createBitmap(
bitmaps.first().getWidth() * bitmaps.size, bitmaps.first().getWidth() * (bitmaps.size) ,
bitmaps.first().getHeight(), bitmaps.first().getHeight(),
bitmaps.first().getConfig()!! bitmaps.first().getConfig()!!
) )
@@ -366,7 +365,7 @@ open class RouteModel() {
var i = 0 var i = 0
bitmaps.forEach { bitmaps.forEach {
if (i > 0) { if (i > 0) {
matrix.setTranslate(i * 40F, 0F) matrix.setTranslate(i * 45F, 0F)
canvas.drawBitmap(it, matrix, null) canvas.drawBitmap(it, matrix, null)
} }
i++ i++
@@ -374,33 +373,66 @@ open class RouteModel() {
return bmOverlay return bmOverlay
} }
private fun laneToResource(direction: String, lane: Lane, stepData: StepData): String { private fun laneToResource(directions: List<String>, stepData: StepData): String {
println("Maneuver ${stepData.maneuverType}") var direction = ""
return when (val direction = direction.replace(" ", "_")) { directions.forEach {
"left" -> if (stepData.maneuverType == Maneuver.TYPE_TURN_NORMAL_LEFT) "${direction}_valid" else "${direction}_not_valid" direction = if (direction.isEmpty()) {
"right" -> if (stepData.maneuverType == Maneuver.TYPE_TURN_NORMAL_RIGHT) "${direction}_valid" else "${direction}_not_valid" it.trim()
"straight" -> if (stepData.maneuverType == Maneuver.TYPE_STRAIGHT) "${direction}_valid" else "${direction}_not_valid" } else {
"slight_right" -> if (stepData.maneuverType == Maneuver.TYPE_TURN_SLIGHT_RIGHT) "${direction}_valid" else "${direction}_not_valid" "${direction}_${it.trim()}"
"slight_left" -> if (stepData.maneuverType == Maneuver.TYPE_TURN_SLIGHT_LEFT) "${direction}_valid" else "${direction}_not_valid" }
else -> {""} }
return when (direction) {
"left_straight" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_TURN_NORMAL_LEFT -> "left_o_straight_x"
Maneuver.TYPE_STRAIGHT -> "left_x_straight_o"
else
-> "left_x_straight_x"
}
}
"right_straight" -> {
when (stepData.currentManeuverType) {
Maneuver.TYPE_TURN_NORMAL_RIGHT -> "right_x_straight_x"
Maneuver.TYPE_STRAIGHT -> "right_x_straight_o"
Maneuver.TYPE_TURN_SLIGHT_RIGHT -> "right_o_straight_o"
else
-> "right_x_straight_x"
}
}
"left" -> if (stepData.currentManeuverType == Maneuver.TYPE_TURN_NORMAL_LEFT) "${direction}_o" else "${direction}_x"
"straight" -> if (stepData.currentManeuverType == Maneuver.TYPE_STRAIGHT) "${direction}_o" else "${direction}_x"
"right_slight" -> if (stepData.currentManeuverType == Maneuver.TYPE_TURN_SLIGHT_RIGHT) "${direction}_o" else "${direction}_x"
"left_slight" -> if (stepData.currentManeuverType == Maneuver.TYPE_TURN_SLIGHT_LEFT) "${direction}_o" else "${direction}_x"
else -> {
""
}
} }
} }
fun resourceId( fun resourceId(
variableName: String, variableName: String,
): Int { ): Int {
return when(variableName) { return when (variableName) {
"left_not_valid" -> R.drawable.left_not_valid "left_x" -> R.drawable.left_x
"left_valid" -> R.drawable.left_valid "left_o" -> R.drawable.left_o
"left_valid_right_not_valid" -> R.drawable.left_valid_right_not_valid "left_o_right_x" -> R.drawable.left_o_right_x
"right_not_valid" -> R.drawable.right_not_valid "right_x" -> R.drawable.right_x
"right_valid" -> R.drawable.right_valid "right_o" -> R.drawable.right_o
"slight_right_not_valid" -> R.drawable.slight_right_not_valid "slight_right_x" -> R.drawable.slight_right_x
"slight_right_valid" -> R.drawable.slight_right_valid "slight_right_o" -> R.drawable.slight_right_o
"straight_not_valid" -> R.drawable.straight_not_valid "straight_x" -> R.drawable.straight_x
"straight_not_valid_right_valid" -> R.drawable.straight_not_valid_right_valid "right_o_straight_x" -> R.drawable.right_o_straight_x
"straight_valid" -> R.drawable.straight_valid "right_x_straight_x" -> R.drawable.right_x_straight_x
else -> {R.drawable.ic_close_white_24dp} "right_x_straight_o" -> R.drawable.right_x_straight_x
"straight_o" -> R.drawable.straight_o
"left_o_straight_x" -> R.drawable.left_o_straight_x
"left_x_straight_o" -> R.drawable.left_x_straight_o
else -> {
R.drawable.ic_close_white_24dp
}
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 914 B

After

Width:  |  Height:  |  Size: 914 B

View File

Before

Width:  |  Height:  |  Size: 883 B

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 888 B

After

Width:  |  Height:  |  Size: 888 B

View File

Before

Width:  |  Height:  |  Size: 895 B

After

Width:  |  Height:  |  Size: 895 B

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 888 B

After

Width:  |  Height:  |  Size: 888 B

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 723 B

After

Width:  |  Height:  |  Size: 723 B

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB