Stopover and Legs
This commit is contained in:
@@ -2,11 +2,11 @@ package com.kouros.navigation.data
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val NavigationColorLight = Color(0xFF066462)
|
||||
val NavigationColorLight = Color(0xFF17A119)
|
||||
|
||||
val NavigationColorDark = Color(0xFF10DED9)
|
||||
val NavigationColorDark = Color(0xFF4EDE10)
|
||||
|
||||
val RouteColor = Color(0xFF7B06E1)
|
||||
val RouteColor = Color(0xFF05692D)
|
||||
|
||||
val SpeedColor = Color(0xFF262525)
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ data class Place(
|
||||
var lastDate: Long = 0,
|
||||
var routeIndex: Int = 0,
|
||||
var route: String = "",
|
||||
var stopOver: Boolean = false,
|
||||
)
|
||||
|
||||
data class ContactData(
|
||||
|
||||
@@ -20,7 +20,7 @@ abstract class NavigationRepository {
|
||||
abstract fun getRoute(
|
||||
context: Context,
|
||||
currentLocation: Location,
|
||||
destination: Location,
|
||||
location: List<Location>,
|
||||
carOrientation: Float,
|
||||
searchFilter: SearchFilter
|
||||
): String
|
||||
|
||||
@@ -58,6 +58,8 @@ class DataStoreManager(private val context: Context) {
|
||||
|
||||
val ENGINE_TYPE = intPreferencesKey("EngineType")
|
||||
|
||||
val ALTERNATIVE_ROUTES = booleanPreferencesKey("AlternativeRoutes")
|
||||
|
||||
}
|
||||
|
||||
// Read values
|
||||
@@ -145,6 +147,11 @@ class DataStoreManager(private val context: Context) {
|
||||
?: EngineType.COMBUSTION.ordinal
|
||||
}
|
||||
|
||||
val alternativeRoutesFlow: Flow<Boolean> =
|
||||
context.dataStore.data.map { preferences ->
|
||||
preferences[PreferencesKeys.ALTERNATIVE_ROUTES] == true
|
||||
}
|
||||
|
||||
// Save values
|
||||
suspend fun setShow3D(enabled: Boolean) {
|
||||
context.dataStore.edit { preferences ->
|
||||
@@ -235,4 +242,11 @@ class DataStoreManager(private val context: Context) {
|
||||
prefs[PreferencesKeys.ENGINE_TYPE] = mode
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setAlternativeRoutes(enabled: Boolean) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.ALTERNATIVE_ROUTES] = enabled
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class OsrmRepository : NavigationRepository() {
|
||||
override fun getRoute(
|
||||
context: Context,
|
||||
currentLocation: Location,
|
||||
location: Location,
|
||||
location: List<Location>,
|
||||
carOrientation: Float,
|
||||
searchFilter: SearchFilter
|
||||
): String {
|
||||
@@ -28,7 +28,7 @@ class OsrmRepository : NavigationRepository() {
|
||||
if (searchFilter.avoidFerry) {
|
||||
exclude = "$exclude&exclude=ferry"
|
||||
}
|
||||
val routeLocation = "${currentLocation.longitude},${currentLocation.latitude};${location.longitude},${location.latitude}?steps=true&alternatives=false"
|
||||
val routeLocation = "${currentLocation.longitude},${currentLocation.latitude};${location.first().longitude},${location.first().latitude}?steps=true&alternatives=false"
|
||||
return fetchUrl(routeUrl + routeLocation + exclude, true)
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ class OsrmRoute {
|
||||
steps.add(step)
|
||||
stepIndex += 1
|
||||
}
|
||||
legs.add(Leg(steps))
|
||||
legs.add(Leg(steps, summary))
|
||||
}
|
||||
val routeGeoJson = createLineStringCollection(waypoints)
|
||||
val centerLocation = createCenterLocation(createLineStringCollection(waypoints))
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package com.kouros.navigation.data.route
|
||||
|
||||
import android.location.Location
|
||||
import com.kouros.navigation.utils.location
|
||||
|
||||
data class Leg(
|
||||
var steps : List<Step> = arrayListOf(),
|
||||
val summary: Summary,
|
||||
)
|
||||
|
||||
@@ -13,3 +13,57 @@ data class Maneuver(
|
||||
val message: String = "",
|
||||
val pointIndex : Int = 0,
|
||||
)
|
||||
|
||||
enum class ManeuverType {
|
||||
TYPE_UNKNOWN,
|
||||
TYPE_DEPART,
|
||||
TYPE_NAME_CHANGE,
|
||||
TYPE_KEEP_LEFT,
|
||||
TYPE_KEEP_RIGHT,
|
||||
TYPE_TURN_SLIGHT_LEFT,
|
||||
TYPE_TURN_SLIGHT_RIGHT,
|
||||
TYPE_TURN_NORMAL_LEFT,
|
||||
TYPE_TURN_NORMAL_RIGHT,
|
||||
TYPE_TURN_SHARP_LEFT,
|
||||
TYPE_TURN_SHARP_RIGHT,
|
||||
TYPE_U_TURN_LEFT,
|
||||
TYPE_U_TURN_RIGHT,
|
||||
TYPE_ON_RAMP_SLIGHT_LEFT,
|
||||
TYPE_ON_RAMP_SLIGHT_RIGHT,
|
||||
TYPE_ON_RAMP_NORMAL_LEFT,
|
||||
TYPE_ON_RAMP_NORMAL_RIGHT,
|
||||
TYPE_ON_RAMP_SHARP_LEFT,
|
||||
TYPE_ON_RAMP_SHARP_RIGHT,
|
||||
TYPE_ON_RAMP_U_TURN_LEFT,
|
||||
TYPE_ON_RAMP_U_TURN_RIGHT,
|
||||
TYPE_OFF_RAMP_SLIGHT_LEFT,
|
||||
TYPE_OFF_RAMP_SLIGHT_RIGHT,
|
||||
TYPE_OFF_RAMP_NORMAL_LEFT,
|
||||
TYPE_OFF_RAMP_NORMAL_RIGHT,
|
||||
TYPE_FORK_LEFT,
|
||||
TYPE_FORK_RIGHT,
|
||||
TYPE_MERGE_LEFT,
|
||||
TYPE_MERGE_RIGHT,
|
||||
TYPE_MERGE_SIDE_UNSPECIFIED,
|
||||
TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW,
|
||||
TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW_WITH_ANGLE,
|
||||
TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW,
|
||||
TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW_WITH_ANGLE,
|
||||
TYPE_STRAIGHT,
|
||||
TYPE_FERRY_BOAT,
|
||||
TYPE_FERRY_TRAIN,
|
||||
TYPE_DESTINATION,
|
||||
TYPE_DESTINATION_STRAIGHT,
|
||||
TYPE_DESTINATION_LEFT,
|
||||
TYPE_DESTINATION_RIGHT,
|
||||
TYPE_ROUNDABOUT_ENTER_CW,
|
||||
TYPE_ROUNDABOUT_EXIT_CW,
|
||||
TYPE_ROUNDABOUT_ENTER_CCW,
|
||||
TYPE_ROUNDABOUT_EXIT_CCW,
|
||||
TYPE_FERRY_BOAT_LEFT,
|
||||
TYPE_FERRY_BOAT_RIGHT,
|
||||
TYPE_FERRY_TRAIN_LEFT,
|
||||
TYPE_FERRY_TRAIN_RIGHT,
|
||||
TYPE_WAYPOINT_RIGHT,
|
||||
TYPE_WAYPOINT_LEFT
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@ private const val tomtomFields =
|
||||
|
||||
val useLocal = BuildConfig.DEBUG
|
||||
|
||||
val useLocalTraffic = BuildConfig.DEBUG
|
||||
val useLocalTraffic = BuildConfig.DEBUG
|
||||
|
||||
|
||||
class TomTomRepository : NavigationRepository() {
|
||||
override fun getRoute(
|
||||
context: Context,
|
||||
currentLocation: Location,
|
||||
location: Location,
|
||||
location: List<Location>,
|
||||
carOrientation: Float,
|
||||
searchFilter: SearchFilter
|
||||
): String {
|
||||
@@ -55,17 +55,34 @@ class TomTomRepository : NavigationRepository() {
|
||||
engineType = "electric"
|
||||
}
|
||||
val repository = getSettingsRepository(context)
|
||||
val tomtomApiKey = runBlocking { repository.tomTomApiKeyFlow.first() }
|
||||
val tomtomApiKey = runBlocking {
|
||||
repository.tomTomApiKeyFlow.first()
|
||||
}
|
||||
val alternativeRoutes = runBlocking {
|
||||
repository.alternativeRoutesFlow.first()
|
||||
}
|
||||
val altRoutes = if (alternativeRoutes) {
|
||||
"&maxAlternatives=2"
|
||||
} else {
|
||||
"&maxAlternatives=0"
|
||||
}
|
||||
val currentLocale = Locale.getDefault()
|
||||
val language = currentLocale.language + "-" + currentLocale.country
|
||||
var loc = ""
|
||||
location.forEach {
|
||||
loc += if (loc.isEmpty()) {
|
||||
"${it.latitude},${it.longitude}"
|
||||
} else {
|
||||
":${it.latitude},${it.longitude}"
|
||||
}
|
||||
}
|
||||
val url =
|
||||
routeUrl + "${currentLocation.latitude},${currentLocation.longitude}:${location.latitude},${location.longitude}" +
|
||||
routeUrl + "${currentLocation.latitude},${currentLocation.longitude}:$loc" +
|
||||
"/json?sectionType=traffic&report=effectiveSettings&routeType=eco" +
|
||||
"&traffic=true&avoid=unpavedRoads&travelMode=car" +
|
||||
"&vehicleMaxSpeed=120&vehicleCommercial=false" +
|
||||
"&instructionsType=text&language=$language§ionType=lanes" +
|
||||
"&routeRepresentation=encodedPolyline" +
|
||||
"&maxAlternatives=2" +
|
||||
"&routeRepresentation=encodedPolyline$altRoutes" +
|
||||
"&vehicleEngineType=$engineType$filter&key=$tomtomApiKey"
|
||||
return fetchUrl(
|
||||
url,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.kouros.navigation.data.tomtom
|
||||
|
||||
|
||||
import com.kouros.navigation.data.Route
|
||||
import com.kouros.navigation.data.RouteEngine
|
||||
import com.kouros.navigation.data.route.Intersection
|
||||
import com.kouros.navigation.data.route.Lane
|
||||
import com.kouros.navigation.data.route.Leg
|
||||
import com.kouros.navigation.data.route.ManeuverType
|
||||
import com.kouros.navigation.data.route.Routes
|
||||
import com.kouros.navigation.data.route.Step
|
||||
import com.kouros.navigation.data.route.Summary
|
||||
import com.kouros.navigation.utils.GeoUtils.createCenterLocation
|
||||
@@ -17,12 +20,12 @@ import com.kouros.navigation.data.route.Maneuver as RouteManeuver
|
||||
class TomTomRoute {
|
||||
|
||||
fun mapToRoute(routeJson: TomTomResponse, builder: Route.Builder) {
|
||||
val routes = mutableListOf<com.kouros.navigation.data.route.Routes>()
|
||||
val routes = mutableListOf<Routes>()
|
||||
routeJson.routes.forEach { route ->
|
||||
val waypoints = mutableListOf<List<Double>>()
|
||||
val points = mutableListOf<List<Double>>()
|
||||
val legs = mutableListOf<Leg>()
|
||||
var stepIndex = 0
|
||||
var points = listOf<List<Double>>()
|
||||
val summary = Summary(
|
||||
route.summary.travelTimeInSeconds.toDouble(),
|
||||
route.summary.lengthInMeters.toDouble(),
|
||||
@@ -30,89 +33,98 @@ class TomTomRoute {
|
||||
route.summary.trafficLengthInMeters.toDouble()
|
||||
)
|
||||
route.legs.forEach { leg ->
|
||||
points = decodePolyline(leg.encodedPolyline, leg.encodedPolylinePrecision)
|
||||
waypoints.addAll(points)
|
||||
val p = decodePolyline(leg.encodedPolyline, leg.encodedPolylinePrecision)
|
||||
points.addAll(p)
|
||||
waypoints.addAll(p)
|
||||
}
|
||||
var stepDistance = 0.0
|
||||
var stepDuration = 0.0
|
||||
val steps = mutableListOf<Step>()
|
||||
var lastPointIndex = 0
|
||||
for (index in 1..<route.guidance.instructions.size) {
|
||||
val lastInstruction = route.guidance.instructions[index - 1]
|
||||
val instruction = route.guidance.instructions[index]
|
||||
val street = lastInstruction.street ?: ""
|
||||
val maneuverStreet = instruction.street ?: ""
|
||||
val maneuver = RouteManeuver(
|
||||
bearingBefore = 0,
|
||||
bearingAfter = 0,
|
||||
type = convertType(instruction.maneuver),
|
||||
waypoints = points.subList(
|
||||
lastPointIndex,
|
||||
instruction.pointIndex + 1,
|
||||
),
|
||||
exit = exitNumber(instruction),
|
||||
location = location(
|
||||
instruction.point.longitude, instruction.point.latitude
|
||||
),
|
||||
street = maneuverStreet,
|
||||
message = instruction.message,
|
||||
pointIndex = instruction.pointIndex
|
||||
route.legs.forEach { leg ->
|
||||
var stepDistance = 0.0
|
||||
var stepDuration = 0.0
|
||||
val steps = mutableListOf<Step>()
|
||||
val summary = Summary(
|
||||
leg.summary.travelTimeInSeconds.toDouble(),
|
||||
leg.summary.lengthInMeters.toDouble(),
|
||||
leg.summary.trafficDelayInSeconds.toDouble(),
|
||||
leg.summary.trafficLengthInMeters.toDouble()
|
||||
)
|
||||
var lastPointIndex = 0
|
||||
for (index in 1..<route.guidance.instructions.size) {
|
||||
val lastInstruction = route.guidance.instructions[index - 1]
|
||||
val instruction = route.guidance.instructions[index]
|
||||
val street = lastInstruction.street ?: ""
|
||||
val maneuverStreet = instruction.street ?: ""
|
||||
val maneuver = RouteManeuver(
|
||||
bearingBefore = 0,
|
||||
bearingAfter = 0,
|
||||
type = convertType(instruction.maneuver),
|
||||
waypoints = points.subList(
|
||||
lastPointIndex,
|
||||
instruction.pointIndex + 1,
|
||||
),
|
||||
exit = exitNumber(instruction),
|
||||
location = location(
|
||||
instruction.point.longitude, instruction.point.latitude
|
||||
),
|
||||
street = maneuverStreet,
|
||||
message = instruction.message,
|
||||
pointIndex = instruction.pointIndex
|
||||
)
|
||||
|
||||
lastPointIndex = instruction.pointIndex
|
||||
val intersections = mutableListOf<Intersection>()
|
||||
route.sections?.forEach { section ->
|
||||
if (section.sectionType == "LANES" && section.startPointIndex <= lastPointIndex
|
||||
&& section.endPointIndex >= lastPointIndex
|
||||
) {
|
||||
val lanes = mutableListOf<Lane>()
|
||||
var startIndex = 0
|
||||
var lastLane: Lane? = null
|
||||
section.lanes?.forEach { itLane ->
|
||||
val lane = Lane(
|
||||
location = location(
|
||||
waypoints[section.startPointIndex][0],
|
||||
waypoints[section.startPointIndex][1]
|
||||
),
|
||||
valid = itLane.directions.first() == itLane.follow,
|
||||
indications = itLane.directions,
|
||||
startIndex = startIndex,
|
||||
endIndex = section.endPointIndex
|
||||
)
|
||||
startIndex = section.startPointIndex
|
||||
if (lastLane == null
|
||||
|| (!(lastLane.valid && lane.valid
|
||||
&& lastLane.indications == lane.indications))
|
||||
) {
|
||||
lanes.add(lane)
|
||||
lastPointIndex = instruction.pointIndex
|
||||
val intersections = mutableListOf<Intersection>()
|
||||
route.sections?.forEach { section ->
|
||||
if (section.sectionType == "LANES" && section.startPointIndex <= lastPointIndex
|
||||
&& section.endPointIndex >= lastPointIndex
|
||||
) {
|
||||
val lanes = mutableListOf<Lane>()
|
||||
var startIndex = 0
|
||||
var lastLane: Lane? = null
|
||||
section.lanes?.forEach { itLane ->
|
||||
val lane = Lane(
|
||||
location = location(
|
||||
waypoints[section.startPointIndex][0],
|
||||
waypoints[section.startPointIndex][1]
|
||||
),
|
||||
valid = itLane.directions.first() == itLane.follow,
|
||||
indications = itLane.directions,
|
||||
startIndex = startIndex,
|
||||
endIndex = section.endPointIndex
|
||||
)
|
||||
startIndex = section.startPointIndex
|
||||
if (lastLane == null
|
||||
|| (!(lastLane.valid && lane.valid
|
||||
&& lastLane.indications == lane.indications))
|
||||
) {
|
||||
lanes.add(lane)
|
||||
}
|
||||
lastLane = lane
|
||||
}
|
||||
lastLane = lane
|
||||
intersections.add(Intersection(waypoints[startIndex], lanes))
|
||||
}
|
||||
intersections.add(Intersection(waypoints[startIndex], lanes))
|
||||
}
|
||||
stepDistance =
|
||||
route.guidance.instructions[index].routeOffsetInMeters - stepDistance
|
||||
stepDuration =
|
||||
route.guidance.instructions[index].travelTimeInSeconds - stepDuration
|
||||
val step = Step(
|
||||
index = stepIndex,
|
||||
street = street,
|
||||
distance = stepDistance,
|
||||
duration = stepDuration,
|
||||
maneuver = maneuver,
|
||||
intersection = intersections,
|
||||
countryCode = lastInstruction.countryCode
|
||||
)
|
||||
stepDistance = route.guidance.instructions[index].routeOffsetInMeters.toDouble()
|
||||
stepDuration = route.guidance.instructions[index].travelTimeInSeconds.toDouble()
|
||||
steps.add(step)
|
||||
stepIndex += 1
|
||||
}
|
||||
stepDistance =
|
||||
route.guidance.instructions[index].routeOffsetInMeters - stepDistance
|
||||
stepDuration =
|
||||
route.guidance.instructions[index].travelTimeInSeconds - stepDuration
|
||||
val step = Step(
|
||||
index = stepIndex,
|
||||
street = street,
|
||||
distance = stepDistance,
|
||||
duration = stepDuration,
|
||||
maneuver = maneuver,
|
||||
intersection = intersections,
|
||||
countryCode = lastInstruction.countryCode
|
||||
)
|
||||
stepDistance = route.guidance.instructions[index].routeOffsetInMeters.toDouble()
|
||||
stepDuration = route.guidance.instructions[index].travelTimeInSeconds.toDouble()
|
||||
steps.add(step)
|
||||
stepIndex += 1
|
||||
legs.add(Leg(steps, summary))
|
||||
}
|
||||
legs.add(Leg(steps))
|
||||
val routeGeoJson = createLineStringCollection(waypoints)
|
||||
val centerLocation = createCenterLocation(createLineStringCollection(waypoints))
|
||||
val newRoute = com.kouros.navigation.data.route.Routes(
|
||||
val newRoute = Routes(
|
||||
legs,
|
||||
summary,
|
||||
routeGeoJson,
|
||||
@@ -130,75 +142,79 @@ class TomTomRoute {
|
||||
var newType = 0
|
||||
when (type) {
|
||||
"DEPART" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_DEPART
|
||||
newType = ManeuverType.TYPE_DEPART.ordinal
|
||||
}
|
||||
|
||||
"ARRIVE" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_DESTINATION
|
||||
newType = ManeuverType.TYPE_DESTINATION.ordinal
|
||||
}
|
||||
|
||||
|
||||
"ARRIVE_LEFT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_DESTINATION_LEFT
|
||||
newType = ManeuverType.TYPE_DESTINATION_LEFT.ordinal
|
||||
}
|
||||
|
||||
"ARRIVE_RIGHT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_DESTINATION_RIGHT
|
||||
newType = ManeuverType.TYPE_DESTINATION_RIGHT.ordinal
|
||||
}
|
||||
|
||||
"STRAIGHT", "FOLLOW" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_STRAIGHT
|
||||
newType = ManeuverType.TYPE_STRAIGHT.ordinal
|
||||
}
|
||||
|
||||
"KEEP_RIGHT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_KEEP_RIGHT
|
||||
newType = ManeuverType.TYPE_KEEP_RIGHT.ordinal
|
||||
}
|
||||
|
||||
"BEAR_RIGHT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||
newType = ManeuverType.TYPE_TURN_SLIGHT_RIGHT.ordinal
|
||||
}
|
||||
|
||||
"BEAR_LEFT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT
|
||||
newType = ManeuverType.TYPE_TURN_SLIGHT_LEFT.ordinal
|
||||
}
|
||||
|
||||
"KEEP_LEFT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_KEEP_LEFT
|
||||
newType = ManeuverType.TYPE_KEEP_LEFT.ordinal
|
||||
}
|
||||
|
||||
"TURN_LEFT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||
newType = ManeuverType.TYPE_TURN_NORMAL_LEFT.ordinal
|
||||
}
|
||||
|
||||
"TURN_RIGHT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_RIGHT
|
||||
newType = ManeuverType.TYPE_TURN_NORMAL_RIGHT.ordinal
|
||||
}
|
||||
|
||||
"SHARP_LEFT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SHARP_LEFT
|
||||
newType = ManeuverType.TYPE_TURN_SHARP_LEFT.ordinal
|
||||
}
|
||||
|
||||
"SHARP_RIGHT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SHARP_RIGHT
|
||||
newType = ManeuverType.TYPE_TURN_SHARP_RIGHT.ordinal
|
||||
}
|
||||
|
||||
"ROUNDABOUT_RIGHT", "ROUNDABOUT_CROSS" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_CCW
|
||||
newType = ManeuverType.TYPE_ROUNDABOUT_ENTER_CCW.ordinal
|
||||
}
|
||||
|
||||
"ROUNDABOUT_LEFT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_CW
|
||||
newType = ManeuverType.TYPE_ROUNDABOUT_ENTER_CW.ordinal
|
||||
}
|
||||
|
||||
"MAKE_UTURN" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_U_TURN_LEFT
|
||||
"MAKE_UTURN", "TRY_MAKE_UTURN" -> {
|
||||
newType = ManeuverType.TYPE_U_TURN_LEFT.ordinal
|
||||
}
|
||||
|
||||
"ENTER_MOTORWAY" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_MERGE_LEFT
|
||||
newType = ManeuverType.TYPE_MERGE_LEFT.ordinal
|
||||
}
|
||||
|
||||
"TAKE_EXIT" -> {
|
||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||
newType = ManeuverType.TYPE_TURN_SLIGHT_RIGHT.ordinal
|
||||
}
|
||||
"WAYPOINT_RIGHT" -> {
|
||||
newType = ManeuverType.TYPE_WAYPOINT_RIGHT.ordinal
|
||||
}
|
||||
}
|
||||
return newType
|
||||
|
||||
@@ -16,7 +16,7 @@ class ValhallaRepository : NavigationRepository() {
|
||||
override fun getRoute(
|
||||
context: Context,
|
||||
currentLocation: Location,
|
||||
location: Location,
|
||||
location: List<Location>,
|
||||
carOrientation: Float,
|
||||
searchFilter: SearchFilter
|
||||
): String {
|
||||
@@ -35,7 +35,7 @@ class ValhallaRepository : NavigationRepository() {
|
||||
lon = currentLocation.longitude,
|
||||
searchFilter = exclude
|
||||
),
|
||||
Locations(lat = location.latitude, lon = location.longitude, searchFilter = exclude)
|
||||
Locations(lat = location.first().latitude, lon = location.first().longitude, searchFilter = exclude)
|
||||
)
|
||||
val valhallaLocation = ValhallaLocation(
|
||||
locations = vLocation,
|
||||
|
||||
@@ -6,15 +6,12 @@ import android.graphics.BitmapFactory
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.Paint
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.car.app.model.CarIcon
|
||||
import androidx.car.app.navigation.model.LaneDirection
|
||||
import androidx.car.app.navigation.model.Maneuver
|
||||
import androidx.core.graphics.createBitmap
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.data.StepData
|
||||
import java.util.Collections
|
||||
import com.kouros.navigation.data.route.ManeuverType
|
||||
import java.util.Locale
|
||||
|
||||
class IconMapper {
|
||||
@@ -22,62 +19,66 @@ class IconMapper {
|
||||
fun maneuverIcon(routeManeuverType: Int): Int {
|
||||
var currentTurnIcon = R.drawable.ic_turn_name_change
|
||||
when (routeManeuverType) {
|
||||
Maneuver.TYPE_STRAIGHT -> {
|
||||
ManeuverType.TYPE_STRAIGHT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_name_change
|
||||
}
|
||||
|
||||
Maneuver.TYPE_DESTINATION,
|
||||
Maneuver.TYPE_DESTINATION_RIGHT,
|
||||
Maneuver.TYPE_DESTINATION_LEFT,
|
||||
Maneuver.TYPE_DESTINATION_STRAIGHT
|
||||
ManeuverType.TYPE_DESTINATION.ordinal,
|
||||
ManeuverType.TYPE_DESTINATION_RIGHT.ordinal,
|
||||
ManeuverType.TYPE_DESTINATION_LEFT.ordinal,
|
||||
ManeuverType.TYPE_DESTINATION_STRAIGHT.ordinal
|
||||
-> {
|
||||
currentTurnIcon = R.drawable.ic_turn_destination
|
||||
}
|
||||
|
||||
Maneuver.TYPE_TURN_NORMAL_RIGHT -> {
|
||||
ManeuverType.TYPE_TURN_NORMAL_RIGHT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_normal_right
|
||||
}
|
||||
|
||||
Maneuver.TYPE_TURN_NORMAL_LEFT -> {
|
||||
ManeuverType.TYPE_TURN_NORMAL_LEFT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_normal_left
|
||||
}
|
||||
|
||||
Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT -> {
|
||||
ManeuverType.TYPE_OFF_RAMP_SLIGHT_RIGHT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_slight_right
|
||||
}
|
||||
|
||||
Maneuver.TYPE_TURN_SLIGHT_RIGHT -> {
|
||||
ManeuverType.TYPE_TURN_SLIGHT_RIGHT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_slight_right
|
||||
}
|
||||
|
||||
Maneuver.TYPE_KEEP_RIGHT -> {
|
||||
ManeuverType.TYPE_KEEP_RIGHT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_name_change
|
||||
}
|
||||
|
||||
Maneuver.TYPE_KEEP_LEFT -> {
|
||||
ManeuverType.TYPE_KEEP_LEFT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_name_change
|
||||
}
|
||||
|
||||
Maneuver.TYPE_ROUNDABOUT_ENTER_CCW -> {
|
||||
ManeuverType.TYPE_ROUNDABOUT_ENTER_CCW.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_roundabout_ccw
|
||||
}
|
||||
|
||||
Maneuver.TYPE_ROUNDABOUT_EXIT_CCW -> {
|
||||
ManeuverType.TYPE_ROUNDABOUT_EXIT_CCW.ordinal -> {
|
||||
|
||||
currentTurnIcon = R.drawable.ic_roundabout_ccw
|
||||
}
|
||||
|
||||
Maneuver.TYPE_U_TURN_LEFT -> {
|
||||
ManeuverType.TYPE_U_TURN_LEFT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_u_turn_left
|
||||
}
|
||||
|
||||
Maneuver.TYPE_U_TURN_RIGHT -> {
|
||||
ManeuverType.TYPE_U_TURN_RIGHT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_u_turn_right
|
||||
}
|
||||
|
||||
Maneuver.TYPE_MERGE_LEFT -> {
|
||||
ManeuverType.TYPE_MERGE_LEFT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_merge_symmetrical
|
||||
}
|
||||
|
||||
ManeuverType.TYPE_WAYPOINT_RIGHT.ordinal -> {
|
||||
currentTurnIcon = R.drawable.ic_turn_destination
|
||||
}
|
||||
}
|
||||
return currentTurnIcon
|
||||
}
|
||||
@@ -86,8 +87,8 @@ class IconMapper {
|
||||
val laneDirection = when (direction.lowercase(Locale.getDefault())) {
|
||||
"left_straight" -> {
|
||||
when (stepData.currentManeuverType) {
|
||||
Maneuver.TYPE_TURN_NORMAL_LEFT -> LaneDirection.SHAPE_NORMAL_LEFT
|
||||
Maneuver.TYPE_STRAIGHT -> LaneDirection.SHAPE_STRAIGHT
|
||||
ManeuverType.TYPE_TURN_NORMAL_LEFT.ordinal -> LaneDirection.SHAPE_NORMAL_LEFT
|
||||
ManeuverType.TYPE_STRAIGHT.ordinal -> LaneDirection.SHAPE_STRAIGHT
|
||||
else
|
||||
-> LaneDirection.SHAPE_UNKNOWN
|
||||
}
|
||||
@@ -95,7 +96,7 @@ class IconMapper {
|
||||
|
||||
"left" -> {
|
||||
when (stepData.currentManeuverType) {
|
||||
Maneuver.TYPE_TURN_NORMAL_LEFT -> LaneDirection.SHAPE_NORMAL_LEFT
|
||||
ManeuverType.TYPE_TURN_NORMAL_LEFT.ordinal -> LaneDirection.SHAPE_NORMAL_LEFT
|
||||
else
|
||||
-> LaneDirection.SHAPE_UNKNOWN
|
||||
}
|
||||
@@ -103,9 +104,9 @@ class IconMapper {
|
||||
|
||||
"straight" -> {
|
||||
when (stepData.currentManeuverType) {
|
||||
Maneuver.TYPE_STRAIGHT -> LaneDirection.SHAPE_STRAIGHT
|
||||
Maneuver.TYPE_KEEP_LEFT -> LaneDirection.SHAPE_STRAIGHT
|
||||
Maneuver.TYPE_KEEP_RIGHT -> LaneDirection.SHAPE_STRAIGHT
|
||||
ManeuverType.TYPE_STRAIGHT.ordinal -> LaneDirection.SHAPE_STRAIGHT
|
||||
ManeuverType.TYPE_KEEP_LEFT.ordinal -> LaneDirection.SHAPE_STRAIGHT
|
||||
ManeuverType.TYPE_KEEP_RIGHT.ordinal -> LaneDirection.SHAPE_STRAIGHT
|
||||
else
|
||||
-> LaneDirection.SHAPE_UNKNOWN
|
||||
}
|
||||
@@ -113,7 +114,7 @@ class IconMapper {
|
||||
|
||||
"right" -> {
|
||||
when (stepData.currentManeuverType) {
|
||||
Maneuver.TYPE_TURN_NORMAL_RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT
|
||||
ManeuverType.TYPE_TURN_NORMAL_RIGHT.ordinal -> LaneDirection.SHAPE_NORMAL_RIGHT
|
||||
else
|
||||
-> LaneDirection.SHAPE_UNKNOWN
|
||||
}
|
||||
@@ -121,8 +122,8 @@ class IconMapper {
|
||||
|
||||
"right_straight" -> {
|
||||
when (stepData.currentManeuverType) {
|
||||
Maneuver.TYPE_TURN_NORMAL_RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT
|
||||
Maneuver.TYPE_STRAIGHT -> LaneDirection.SHAPE_STRAIGHT
|
||||
ManeuverType.TYPE_TURN_NORMAL_RIGHT.ordinal -> LaneDirection.SHAPE_NORMAL_RIGHT
|
||||
ManeuverType.TYPE_STRAIGHT.ordinal -> LaneDirection.SHAPE_STRAIGHT
|
||||
else
|
||||
-> LaneDirection.SHAPE_UNKNOWN
|
||||
}
|
||||
@@ -130,8 +131,8 @@ class IconMapper {
|
||||
|
||||
"left_slight", "slight_left" -> {
|
||||
when (stepData.currentManeuverType) {
|
||||
Maneuver.TYPE_TURN_NORMAL_LEFT -> LaneDirection.SHAPE_SLIGHT_LEFT
|
||||
Maneuver.TYPE_KEEP_LEFT -> LaneDirection.SHAPE_SLIGHT_LEFT
|
||||
ManeuverType.TYPE_TURN_NORMAL_LEFT.ordinal -> LaneDirection.SHAPE_SLIGHT_LEFT
|
||||
ManeuverType.TYPE_KEEP_LEFT.ordinal -> LaneDirection.SHAPE_SLIGHT_LEFT
|
||||
else
|
||||
-> LaneDirection.SHAPE_UNKNOWN
|
||||
}
|
||||
@@ -139,8 +140,8 @@ class IconMapper {
|
||||
|
||||
"right_slight", "slight_right" -> {
|
||||
when (stepData.currentManeuverType) {
|
||||
Maneuver.TYPE_TURN_SLIGHT_RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT
|
||||
Maneuver.TYPE_KEEP_RIGHT -> LaneDirection.SHAPE_SLIGHT_RIGHT
|
||||
ManeuverType.TYPE_TURN_SLIGHT_RIGHT.ordinal -> LaneDirection.SHAPE_NORMAL_RIGHT
|
||||
ManeuverType.TYPE_KEEP_RIGHT.ordinal -> LaneDirection.SHAPE_SLIGHT_RIGHT
|
||||
else
|
||||
-> LaneDirection.SHAPE_UNKNOWN
|
||||
}
|
||||
@@ -212,8 +213,8 @@ class IconMapper {
|
||||
return when (direction) {
|
||||
"left_straight" -> {
|
||||
when (stepData.currentManeuverType) {
|
||||
Maneuver.TYPE_TURN_NORMAL_LEFT -> "left_o_straight_x"
|
||||
Maneuver.TYPE_STRAIGHT -> "left_x_straight_o"
|
||||
ManeuverType.TYPE_TURN_NORMAL_LEFT.ordinal -> "left_o_straight_x"
|
||||
ManeuverType.TYPE_STRAIGHT.ordinal -> "left_x_straight_o"
|
||||
else
|
||||
-> "left_x_straight_x"
|
||||
}
|
||||
@@ -221,29 +222,29 @@ class IconMapper {
|
||||
|
||||
"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"
|
||||
ManeuverType.TYPE_TURN_NORMAL_RIGHT.ordinal -> "right_x_straight_x"
|
||||
ManeuverType.TYPE_STRAIGHT.ordinal -> "right_x_straight_o"
|
||||
ManeuverType.TYPE_TURN_SLIGHT_RIGHT.ordinal -> "right_o_straight_o"
|
||||
else
|
||||
-> "right_x_straight_x"
|
||||
}
|
||||
}
|
||||
|
||||
"right" -> if (stepData.currentManeuverType == Maneuver.TYPE_TURN_NORMAL_RIGHT) "${direction}_o" else "${direction}_x"
|
||||
"left" -> if (stepData.currentManeuverType == Maneuver.TYPE_TURN_NORMAL_LEFT) "${direction}_o" else "${direction}_x"
|
||||
"straight" -> if (stepData.currentManeuverType == Maneuver.TYPE_STRAIGHT
|
||||
|| stepData.currentManeuverType == Maneuver.TYPE_KEEP_LEFT
|
||||
|| stepData.currentManeuverType == Maneuver.TYPE_KEEP_RIGHT
|
||||
"right" -> if (stepData.currentManeuverType == ManeuverType.TYPE_TURN_NORMAL_RIGHT.ordinal) "${direction}_o" else "${direction}_x"
|
||||
"left" -> if (stepData.currentManeuverType == ManeuverType.TYPE_TURN_NORMAL_LEFT.ordinal) "${direction}_o" else "${direction}_x"
|
||||
"straight" -> if (stepData.currentManeuverType == ManeuverType.TYPE_STRAIGHT.ordinal
|
||||
|| stepData.currentManeuverType == ManeuverType.TYPE_KEEP_LEFT.ordinal
|
||||
|| stepData.currentManeuverType == ManeuverType.TYPE_KEEP_RIGHT.ordinal
|
||||
) "${direction}_o" else "${direction}_x"
|
||||
|
||||
"right_slight", "slight_right" -> if (stepData.currentManeuverType == Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||
|| stepData.currentManeuverType == Maneuver.TYPE_TURN_NORMAL_RIGHT
|
||||
|| stepData.currentManeuverType == Maneuver.TYPE_KEEP_RIGHT
|
||||
"right_slight", "slight_right" -> if (stepData.currentManeuverType == ManeuverType.TYPE_TURN_SLIGHT_RIGHT.ordinal
|
||||
|| stepData.currentManeuverType == ManeuverType.TYPE_TURN_NORMAL_RIGHT.ordinal
|
||||
|| stepData.currentManeuverType == ManeuverType.TYPE_KEEP_RIGHT.ordinal
|
||||
) "slight_right_o" else "slight_right_x"
|
||||
|
||||
"left_slight", "slight_left" -> if (stepData.currentManeuverType == Maneuver.TYPE_TURN_SLIGHT_LEFT
|
||||
|| stepData.currentManeuverType == Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||
|| stepData.currentManeuverType == Maneuver.TYPE_KEEP_LEFT
|
||||
"left_slight", "slight_left" -> if (stepData.currentManeuverType == ManeuverType.TYPE_TURN_SLIGHT_LEFT.ordinal
|
||||
|| stepData.currentManeuverType == ManeuverType.TYPE_TURN_NORMAL_LEFT.ordinal
|
||||
|| stepData.currentManeuverType == ManeuverType.TYPE_KEEP_LEFT.ordinal
|
||||
) "slight_left_o" else "slight_left_x"
|
||||
|
||||
else -> {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.kouros.navigation.model
|
||||
//import com.kouros.navigation.data.Preferences.boxStore
|
||||
import android.content.Context
|
||||
import android.location.Location
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||
import androidx.compose.runtime.toMutableStateList
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
@@ -147,7 +148,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
|
||||
fun loadRoute(
|
||||
context: Context,
|
||||
currentLocation: Location,
|
||||
destination: Location,
|
||||
destination: List<Location>,
|
||||
carOrientation: Float
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
@@ -181,9 +182,11 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
|
||||
)
|
||||
if (data.isNotEmpty()) {
|
||||
val trafficData = rebuildTraffic(data)
|
||||
traffic.postValue(
|
||||
trafficData
|
||||
)
|
||||
if (trafficData.isNotEmpty()) {
|
||||
traffic.postValue(
|
||||
trafficData
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
@@ -234,7 +237,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
|
||||
repository.getRoute(
|
||||
context,
|
||||
currentLocation,
|
||||
location,
|
||||
listOf(location),
|
||||
carOrientation,
|
||||
getSearchFilter(context)
|
||||
)
|
||||
|
||||
@@ -102,6 +102,12 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
|
||||
0
|
||||
)
|
||||
|
||||
val alternativeRoutes = repository.alternativeRoutesFlow.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.WhileSubscribed(5_000),
|
||||
false
|
||||
)
|
||||
|
||||
fun onShow3DChanged(enabled: Boolean) {
|
||||
viewModelScope.launch { repository.setShow3D(enabled) }
|
||||
}
|
||||
@@ -159,4 +165,7 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
|
||||
viewModelScope.launch { repository.setEngineType(mode) }
|
||||
}
|
||||
|
||||
fun onAlternativeRoutes(enabled: Boolean) {
|
||||
viewModelScope.launch { repository.setAlternativeRoutes(enabled) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,9 @@ class SettingsRepository(
|
||||
val engineTypeFlow: Flow<Int> =
|
||||
dataStoreManager.engineTypeFlow
|
||||
|
||||
val alternativeRoutesFlow: Flow<Boolean> =
|
||||
dataStoreManager.alternativeRoutesFlow
|
||||
|
||||
suspend fun setShow3D(enabled: Boolean) {
|
||||
dataStoreManager.setShow3D(enabled)
|
||||
}
|
||||
@@ -109,4 +112,8 @@ class SettingsRepository(
|
||||
suspend fun setEngineType(mode: Int) {
|
||||
dataStoreManager.setEngineType(mode)
|
||||
}
|
||||
|
||||
suspend fun setAlternativeRoutes(enabled: Boolean) {
|
||||
dataStoreManager.setAlternativeRoutes(enabled)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,4 +71,5 @@
|
||||
<string name="combustion">Combustion</string>
|
||||
<string name="electric">Electric</string>
|
||||
<string name="engine_type">Engine type</string>
|
||||
<string name="alternative_routes">Alternative routes</string>
|
||||
</resources>
|
||||
|
||||
@@ -55,4 +55,5 @@
|
||||
<string name="combustion">Combustion</string>
|
||||
<string name="electric">Electric</string>
|
||||
<string name="engine_type">Engine type</string>
|
||||
<string name="alternative_routes">Alternative routes</string>
|
||||
</resources>
|
||||
|
||||
@@ -55,4 +55,5 @@
|
||||
<string name="combustion">Combustion</string>
|
||||
<string name="electric">Electric</string>
|
||||
<string name="engine_type">Engine type</string>
|
||||
<string name="alternative_routes">Alternative routes</string>
|
||||
</resources>
|
||||
|
||||
@@ -58,4 +58,5 @@
|
||||
<string name="combustion">Combustion</string>
|
||||
<string name="electric">Electric</string>
|
||||
<string name="engine_type">Engine type</string>
|
||||
<string name="alternative_routes">Alternative routes</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user