Diverse Änderungen

This commit is contained in:
Dimitris
2026-02-24 16:29:13 +01:00
parent 71d3d17847
commit e4b539c4e6
31 changed files with 405 additions and 194 deletions

View File

@@ -14,8 +14,8 @@ android {
applicationId = "com.kouros.navigation"
minSdk = 33
targetSdk = 36
versionCode = 45
versionName = "0.2.0.45"
versionCode = 49
versionName = "0.2.0.49"
base.archivesName = "navi-$versionName"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@@ -82,6 +82,7 @@ dependencies {
implementation(libs.koin.androidx.compose)
implementation(libs.maplibre.compose)
//implementation(libs.maplibre.composeMaterial3)
implementation(libs.androidx.app.projected)
implementation(libs.accompanist.permissions)
implementation(project(":common:data"))
@@ -97,7 +98,7 @@ dependencies {
implementation("com.github.ticofab:android-gpx-parser:2.3.1")
implementation(libs.androidx.navigation.compose)
implementation(libs.kotlinx.serialization.json)
implementation(libs.androidx.foundation.layout)
implementation(libs.androidx.compose.foundation.layout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)

View File

@@ -7,11 +7,16 @@ import android.os.SystemClock
class MockLocation (private var locationManager: LocationManager) {
var curSpeed = 0F
fun setMockLocation(latitude: Double, longitude: Double) {
fun setMockLocation(latitude: Double, longitude: Double, bearing : Float) {
try {
// Set mock location for all providers
setMockLocationForProvider(LocationManager.GPS_PROVIDER, latitude, longitude)
setMockLocationForProvider(LocationManager.NETWORK_PROVIDER, latitude, longitude)
setMockLocationForProvider(LocationManager.GPS_PROVIDER, latitude, longitude, bearing)
setMockLocationForProvider(
LocationManager.NETWORK_PROVIDER,
latitude,
longitude,
bearing
)
} catch (e: NumberFormatException) {
} catch (e: SecurityException) {
} catch (e: Exception) {
@@ -19,7 +24,12 @@ class MockLocation (private var locationManager: LocationManager) {
}
}
private fun setMockLocationForProvider(provider: String, latitude: Double, longitude: Double) {
private fun setMockLocationForProvider(
provider: String,
latitude: Double,
longitude: Double,
bearing: Float
) {
try {
// Check if provider exists
if (!locationManager.allProviders.contains(provider)) {
@@ -52,10 +62,10 @@ class MockLocation (private var locationManager: LocationManager) {
this.speed = 0f
this.time = System.currentTimeMillis()
this.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
this.bearingAccuracyDegrees = 0.0f
this.verticalAccuracyMeters = 0.0f
this.speedAccuracyMetersPerSecond = 0.0f
this.bearing = bearing
}
// Set the mock location
locationManager.setTestProviderLocation(provider, mockLocation)
@@ -79,6 +89,7 @@ class MockLocation (private var locationManager: LocationManager) {
this.bearingAccuracyDegrees = 0.0f
this.verticalAccuracyMeters = 0.0f
this.speedAccuracyMetersPerSecond = 0.0f
this.bearing = bearing
}
locationManager.setTestProviderLocation(provider, mockLocation)
} catch (ex: Exception) {

View File

@@ -77,19 +77,16 @@ import org.maplibre.compose.location.DesiredAccuracy
import org.maplibre.compose.location.Location
import org.maplibre.compose.location.rememberDefaultLocationProvider
import org.maplibre.compose.location.rememberUserLocationState
import org.maplibre.compose.style.BaseStyle
import org.maplibre.spatialk.geojson.Position
import kotlin.time.Duration.Companion.seconds
class MainActivity : ComponentActivity() {
val routeData = MutableLiveData("")
val routeModel = RouteModel()
var tilt = 50.0
val useMock = false
val type = 1 // 1 simulate 2 test 3 gpx 4 testSingle
val type = 3 // 1 simulate 2 test 3 gpx 4 testSingle
val stepData: MutableLiveData<StepData> by lazy {
MutableLiveData()
@@ -125,7 +122,6 @@ class MainActivity : ComponentActivity() {
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var mock: MockLocation
private var loadRecentPlaces = false
lateinit var baseStyle: BaseStyle.Json
@RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
override fun onCreate(savedInstanceState: Bundle?) {
@@ -140,7 +136,7 @@ class MainActivity : ComponentActivity() {
if (useMock) {
mock = MockLocation(locationManager)
mock.setMockLocation(
homeVogelhart.latitude, homeVogelhart.longitude
homeVogelhart.latitude, homeVogelhart.longitude, 0F
)
navigationViewModel.route.observe(this, observer)
}
@@ -190,8 +186,9 @@ class MainActivity : ComponentActivity() {
val appViewModel: AppViewModel = appViewModel()
val darkMode by appViewModel.darkMode.collectAsState()
val sheetPeekHeight = 250.dp
baseStyle = BaseStyleModel().readStyle(applicationContext, darkMode, darkMode == 1)
val baseStyle = BaseStyleModel().readStyle(applicationContext, darkMode, darkMode == 1)
val scaffoldState = rememberBottomSheetScaffoldState()
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
@@ -240,7 +237,7 @@ class MainActivity : ComponentActivity() {
cameraPosition,
routeData,
tilt,
baseStyle
baseStyle,
)
}
if (!routeModel.isNavigating()) {
@@ -304,6 +301,9 @@ class MainActivity : ComponentActivity() {
fun updateLocation(location: Location?) {
if (location != null && lastLocation.latitude != location.position.latitude && lastLocation.longitude != location.position.longitude) {
val currentLocation = location(location.position.longitude, location.position.latitude)
if (location.bearing != null) {
currentLocation.bearing = location.bearing!!.toFloat()
}
if (routeModel.isNavigating()) {
val snapedLocation =
snapLocation(currentLocation, routeModel.route.maneuverLocations())
@@ -315,7 +315,15 @@ class MainActivity : ComponentActivity() {
}
fun updateLocationInternal(currentLocation: android.location.Location, location: Location?) {
val bearing = bearing(lastLocation, currentLocation, cameraPosition.value!!.bearing)
if (currentLocation.hasBearing()) {
routeModel.navState = routeModel.navState.copy(routeBearing = currentLocation.bearing)
}
val bearing = if (currentLocation.hasBearing()) {
currentLocation.bearing.toDouble()
} else {
bearing(lastLocation, currentLocation, cameraPosition.value!!.bearing)
}
with(routeModel) {
if (isNavigating()) {
updateLocation(applicationContext, currentLocation, navigationViewModel)
@@ -348,7 +356,7 @@ class MainActivity : ComponentActivity() {
closeSheet()
routeModel.stopNavigation(applicationContext)
if (useMock) {
mock.setMockLocation(latitude, longitude)
mock.setMockLocation(latitude, longitude, 0F)
}
routeData.value = ""
stepData.value = StepData("", 0.0, 0, 0, 0, 0.0)
@@ -380,14 +388,18 @@ class MainActivity : ComponentActivity() {
fun simulate() {
CoroutineScope(Dispatchers.IO).launch {
var lastLocation = location(0.0, 0.0)
for ((index, waypoint) in routeModel.curRoute.waypoints.withIndex()) {
val curLocation = location(waypoint[0], waypoint[1])
if (routeModel.isNavigating()) {
val deviation = 0.0
if (index in 0..routeModel.curRoute.waypoints.size) {
mock.setMockLocation(waypoint[1], waypoint[0])
val bearing = lastLocation.bearingTo(curLocation)
mock.setMockLocation(waypoint[1], waypoint[0], bearing)
Thread.sleep(1000)
}
}
lastLocation = curLocation
}
}
}
@@ -416,7 +428,7 @@ class MainActivity : ComponentActivity() {
fun testSingleUpdate(latitude: Double, longitude: Double) {
if (1 == 1) {
mock.setMockLocation(latitude, longitude)
mock.setMockLocation(latitude, longitude, 0F)
} else {
routeModel.updateLocation(
applicationContext,
@@ -425,12 +437,12 @@ class MainActivity : ComponentActivity() {
}
val step = routeModel.currentStep()
val nextStep = routeModel.nextStep()
println("Step: ${step.instruction} ${step.leftStepDistance} ${nextStep.currentManeuverType}")
Thread.sleep(1_000)
}
fun gpx(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
var lastLocation = location(0.0, 0.0)
val parser = GPXParser()
val input = context.resources.openRawResource(R.raw.vh)
val parsedGpx: Gpx? = parser.parse(input) // consider using a background thread
@@ -441,18 +453,23 @@ class MainActivity : ComponentActivity() {
segments!!.forEach { seg ->
var lastTime = DateTime.now()
seg!!.trackPoints.forEach { p ->
val curLocation = location(p.longitude, p.latitude)
val ext = p.extensions
val speed: Double?
if (ext != null) {
speed = ext.speed
mock.curSpeed = speed.toFloat()
}
val duration = p.time.millis - lastTime.millis
mock.setMockLocation(p.latitude, p.longitude)
val bearing = lastLocation.bearingTo(curLocation)
println("Bearing $bearing")
mock.setMockLocation(p.latitude, p.longitude, bearing)
if (duration > 0) {
delay(duration / 5)
}
lastTime = p.time
lastLocation = curLocation
}
}
}

View File

@@ -4,26 +4,21 @@ import android.content.Context
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.dp
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.window.layout.WindowMetricsCalculator
import com.kouros.navigation.car.ViewStyle
import com.kouros.navigation.car.map.MapLibre
import com.kouros.navigation.car.map.NavigationImage
import com.kouros.navigation.car.map.rememberBaseStyle
import com.kouros.navigation.data.StepData
import com.kouros.navigation.ui.app.AppViewModel
import com.kouros.navigation.ui.app.appViewModel
import com.kouros.navigation.utils.settingsViewModel
import org.maplibre.compose.camera.CameraPosition
import org.maplibre.compose.camera.rememberCameraState
import org.maplibre.compose.location.LocationTrackingEffect
@@ -64,8 +59,6 @@ fun MapView(
)
)
val rememberBaseStyle = rememberBaseStyle(baseStyle)
val appViewModel: AppViewModel = appViewModel()
val showBuildings by appViewModel.show3D.collectAsState()
@@ -73,9 +66,8 @@ fun MapView(
NavigationInfo(step, nextStep)
Box(contentAlignment = Alignment.Center) {
MapLibre(
applicationContext,
cameraState,
rememberBaseStyle,
baseStyle,
route,
emptyMap(),
ViewStyle.VIEW,