This commit is contained in:
Dimitris
2026-02-21 11:12:22 +01:00
parent 723707dac6
commit 71d3d17847
9 changed files with 50 additions and 103 deletions

View File

@@ -14,8 +14,8 @@ android {
applicationId = "com.kouros.navigation" applicationId = "com.kouros.navigation"
minSdk = 33 minSdk = 33
targetSdk = 36 targetSdk = 36
versionCode = 43 versionCode = 45
versionName = "0.2.0.43" versionName = "0.2.0.45"
base.archivesName = "navi-$versionName" base.archivesName = "navi-$versionName"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
} }

View File

@@ -22,8 +22,6 @@ import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.SheetState
import androidx.compose.material3.SheetValue
import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Text import androidx.compose.material3.Text
@@ -36,7 +34,6 @@ import androidx.compose.runtime.mutableDoubleStateOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -56,15 +53,14 @@ import com.kouros.navigation.MainApplication.Companion.navigationViewModel
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
import com.kouros.navigation.data.Constants.homeVogelhart import com.kouros.navigation.data.Constants.homeVogelhart
import com.kouros.navigation.data.StepData import com.kouros.navigation.data.StepData
import com.kouros.navigation.data.datastore.DataStoreManager
import com.kouros.navigation.model.BaseStyleModel 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.repository.SettingsRepository
import com.kouros.navigation.ui.app.AppViewModel import com.kouros.navigation.ui.app.AppViewModel
import com.kouros.navigation.ui.app.appViewModel import com.kouros.navigation.ui.app.appViewModel
import com.kouros.navigation.ui.navigation.AppNavGraph import com.kouros.navigation.ui.navigation.AppNavGraph
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.bearing import com.kouros.navigation.utils.bearing
import com.kouros.navigation.utils.getSettingsViewModel import com.kouros.navigation.utils.getSettingsViewModel
import com.kouros.navigation.utils.location import com.kouros.navigation.utils.location
@@ -74,9 +70,7 @@ import io.ticofab.androidgpxparser.parser.domain.TrackSegment
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.joda.time.DateTime import org.joda.time.DateTime
import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.CameraPosition
import org.maplibre.compose.location.DesiredAccuracy import org.maplibre.compose.location.DesiredAccuracy
@@ -95,14 +89,13 @@ class MainActivity : ComponentActivity() {
val routeModel = RouteModel() val routeModel = RouteModel()
var tilt = 50.0 var tilt = 50.0
val useMock = false val useMock = false
val type = 3 // 1 simulate 2 test 3 gpx 4 testSingle val type = 1 // 1 simulate 2 test 3 gpx 4 testSingle
var currentIndex = 0
val stepData: MutableLiveData<StepData> by lazy { val stepData: MutableLiveData<StepData> by lazy {
MutableLiveData<StepData>() MutableLiveData()
} }
val nextStepData: MutableLiveData<StepData> by lazy { val nextStepData: MutableLiveData<StepData> by lazy {
MutableLiveData<StepData>() MutableLiveData()
} }
var lastLocation = location(0.0, 0.0) var lastLocation = location(0.0, 0.0)
val observer = Observer<String> { newRoute -> val observer = Observer<String> { newRoute ->
@@ -130,14 +123,10 @@ class MainActivity : ComponentActivity() {
private lateinit var locationManager: LocationManager private lateinit var locationManager: LocationManager
private lateinit var fusedLocationClient: FusedLocationProviderClient private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var mock: MockLocation private lateinit var mock: MockLocation
private var loadRecentPlaces = false private var loadRecentPlaces = false
lateinit var baseStyle: BaseStyle.Json lateinit var baseStyle: BaseStyle.Json
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION]) @RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -226,7 +215,7 @@ class MainActivity : ComponentActivity() {
sheetPeekHeightState.value = sheetPeekHeight sheetPeekHeightState.value = sheetPeekHeight
} }
} }
NavigationTheme (useDarkTheme = darkMode == 1) { NavigationTheme(useDarkTheme = darkMode == 1) {
BottomSheetScaffold( BottomSheetScaffold(
snackbarHost = { snackbarHost = {
SnackbarHost(hostState = snackbarHostState) SnackbarHost(hostState = snackbarHostState)
@@ -268,7 +257,7 @@ class MainActivity : ComponentActivity() {
if (lastRoute.isNotEmpty()) { if (lastRoute.isNotEmpty()) {
navigationViewModel.route.value = lastRoute navigationViewModel.route.value = lastRoute
} }
AppNavGraph(applicationContext = applicationContext, this) AppNavGraph(this)
} }
@Composable @Composable
@@ -315,10 +304,21 @@ class MainActivity : ComponentActivity() {
fun updateLocation(location: Location?) { fun updateLocation(location: Location?) {
if (location != null && lastLocation.latitude != location.position.latitude && lastLocation.longitude != location.position.longitude) { if (location != null && lastLocation.latitude != location.position.latitude && lastLocation.longitude != location.position.longitude) {
val currentLocation = location(location.position.longitude, location.position.latitude) val currentLocation = location(location.position.longitude, location.position.latitude)
if (routeModel.isNavigating()) {
val snapedLocation =
snapLocation(currentLocation, routeModel.route.maneuverLocations())
updateLocationInternal(snapedLocation, location)
} else {
updateLocationInternal(currentLocation, location)
}
}
}
fun updateLocationInternal(currentLocation: android.location.Location, location: Location?) {
val bearing = bearing(lastLocation, currentLocation, cameraPosition.value!!.bearing) val bearing = bearing(lastLocation, currentLocation, cameraPosition.value!!.bearing)
with(routeModel) { with(routeModel) {
if (isNavigating()) { if (isNavigating()) {
updateLocation(applicationContext,currentLocation, navigationViewModel) updateLocation(applicationContext, currentLocation, navigationViewModel)
stepData.value = currentStep() stepData.value = currentStep()
nextStepData.value = nextStep() nextStepData.value = nextStep()
if (navState.maneuverType in 39..42 && routeCalculator.leftStepDistance() < DESTINATION_ARRIVAL_DISTANCE) { if (navState.maneuverType in 39..42 && routeCalculator.leftStepDistance() < DESTINATION_ARRIVAL_DISTANCE) {
@@ -332,7 +332,7 @@ class MainActivity : ComponentActivity() {
val zoom = 16.0 val zoom = 16.0
cameraPosition.postValue( cameraPosition.postValue(
cameraPosition.value!!.copy( cameraPosition.value!!.copy(
zoom = zoom, target = location.position, bearing = bearing zoom = zoom, target = location!!.position, bearing = bearing
), ),
) )
lastLocation = currentLocation lastLocation = currentLocation
@@ -341,7 +341,6 @@ class MainActivity : ComponentActivity() {
loadRecentPlaces = true loadRecentPlaces = true
} }
} }
}
fun stopNavigation(closeSheet: () -> Unit) { fun stopNavigation(closeSheet: () -> Unit) {
val latitude = routeModel.curRoute.waypoints[0][1] val latitude = routeModel.curRoute.waypoints[0][1]
@@ -397,7 +396,8 @@ class MainActivity : ComponentActivity() {
for ((index, step) in routeModel.curLeg.steps.withIndex()) { for ((index, step) in routeModel.curLeg.steps.withIndex()) {
//if (index in 3..3) { //if (index in 3..3) {
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) { for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
routeModel.updateLocation(applicationContext, routeModel.updateLocation(
applicationContext,
location(waypoint[0], waypoint[1]), navigationViewModel location(waypoint[0], waypoint[1]), navigationViewModel
) )
val step = routeModel.currentStep() val step = routeModel.currentStep()
@@ -418,7 +418,8 @@ class MainActivity : ComponentActivity() {
if (1 == 1) { if (1 == 1) {
mock.setMockLocation(latitude, longitude) mock.setMockLocation(latitude, longitude)
} else { } else {
routeModel.updateLocation(applicationContext, routeModel.updateLocation(
applicationContext,
location(longitude, latitude), navigationViewModel location(longitude, latitude), navigationViewModel
) )
} }

View File

@@ -1,52 +0,0 @@
package com.kouros.navigation.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.kouros.navigation.data.NavigationThemeColor
@Composable
fun ThemeColorPicker(
selectedColor: Long,
onColorSelected: (Long) -> Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
NavigationThemeColor.entries.forEach { themeColor ->
val isSelected = selectedColor == themeColor.color
Box(
modifier = Modifier
.size(36.dp)
.clip(CircleShape)
.background(Color(themeColor.color))
.border(
width = if (isSelected) 3.dp else 0.dp,
color = if (isSelected) MaterialTheme.colorScheme.onSurface else Color.Transparent,
shape = CircleShape
)
.clickable {
onColorSelected(themeColor.color)
}
)
}
}
}

View File

@@ -1,6 +1,5 @@
package com.kouros.navigation.ui.navigation package com.kouros.navigation.ui.navigation
import android.content.Context
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable import androidx.navigation.compose.composable
@@ -10,7 +9,7 @@ import com.kouros.navigation.ui.settings.SettingsRoute
@Composable @Composable
fun AppNavGraph(applicationContext: Context, mainActivity: MainActivity) { fun AppNavGraph(mainActivity: MainActivity) {
val navController = rememberNavController() val navController = rememberNavController()
NavHost(navController = navController, startDestination = "startScreen") { NavHost(navController = navController, startDestination = "startScreen") {

View File

@@ -119,8 +119,8 @@ fun NavigationSettings(viewModel: SettingsViewModel) {
TextField( TextField(
value = key, value = key,
onValueChange = { onValueChange = {
viewModel.onTomTomApiKeyChanged(it)
key = it key = it
viewModel::onTomTomApiKeyChanged
}, },
label = { Text(stringResource(R.string.tomtom_api_key)) }, label = { Text(stringResource(R.string.tomtom_api_key)) },
textStyle = TextStyle(color = Color.Green, fontWeight = FontWeight.Bold), textStyle = TextStyle(color = Color.Green, fontWeight = FontWeight.Bold),

View File

@@ -289,6 +289,7 @@ class SurfaceRenderer(
) else { ) else {
carOrientation.toDouble() carOrientation.toDouble()
} }
println("Bearing $bearing")
val zoom = if (viewStyle == ViewStyle.VIEW) { val zoom = if (viewStyle == ViewStyle.VIEW) {
calculateZoom(location.speed.toDouble()) calculateZoom(location.speed.toDouble())
} else { } else {

View File

@@ -13,8 +13,6 @@ import kotlinx.coroutines.runBlocking
private const val routeUrl = "https://api.tomtom.com/routing/1/calculateRoute/" private const val routeUrl = "https://api.tomtom.com/routing/1/calculateRoute/"
//const val tomtomApiKey = "678k5v6940cSXXIS5oD92qIrDgW3RBZ3"
const val tomtomTrafficUrl = "https://api.tomtom.com/traffic/services/5/incidentDetails" const val tomtomTrafficUrl = "https://api.tomtom.com/traffic/services/5/incidentDetails"
private const val tomtomFields = private const val tomtomFields =

View File

@@ -85,7 +85,7 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
viewModelScope.launch { repository.setLastRoute(route) } viewModelScope.launch { repository.setLastRoute(route) }
} }
fun onTomTomApiKeyChanged(route: String) { fun onTomTomApiKeyChanged(key: String) {
viewModelScope.launch { repository.setTomTomApiKey(route) } viewModelScope.launch { repository.setTomTomApiKey(key) }
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB