diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6edaee2..6eecabd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,8 +14,8 @@ android { applicationId = "com.kouros.navigation" minSdk = 33 targetSdk = 36 - versionCode = 14 - versionName = "0.1.3.14" + versionCode = 15 + versionName = "0.1.3.15" base.archivesName = "navi-$versionName" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/kouros/navigation/MainApplication.kt b/app/src/main/java/com/kouros/navigation/MainApplication.kt index 640c37d..24c402a 100644 --- a/app/src/main/java/com/kouros/navigation/MainApplication.kt +++ b/app/src/main/java/com/kouros/navigation/MainApplication.kt @@ -2,22 +2,34 @@ package com.kouros.navigation import android.app.Application import android.content.Context +import com.kouros.navigation.data.Constants.DARK_MODE_SETTINGS +import com.kouros.navigation.data.Constants.ROUTE_ENGINE +import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING import com.kouros.navigation.data.NavigationRepository import com.kouros.navigation.data.ObjectBox +import com.kouros.navigation.data.RouteEngine import com.kouros.navigation.data.osrm.OsrmRepository import com.kouros.navigation.data.valhalla.ValhallaRepository import com.kouros.navigation.di.appModule import com.kouros.navigation.model.ViewModel +import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue +import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue +import com.kouros.navigation.utils.NavigationUtils.getRouteEngine +import com.kouros.navigation.utils.NavigationUtils.setIntKeyValue import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger import org.koin.core.context.startKoin import org.koin.core.logger.Level +import org.maplibre.compose.expressions.dsl.switch + class MainApplication : Application() { override fun onCreate() { super.onCreate() ObjectBox.init(this); appContext = applicationContext + setIntKeyValue(appContext!!, RouteEngine.VALHALLA.ordinal, ROUTE_ENGINE) + navigationViewModel = getRouteEngine(appContext!!) startKoin { androidLogger(Level.DEBUG) androidContext(this@MainApplication) @@ -26,11 +38,12 @@ class MainApplication : Application() { } companion object { + var appContext: Context? = null private set var useContacts = false - val navigationViewModel = ViewModel(ValhallaRepository()) + lateinit var navigationViewModel : ViewModel } } \ No newline at end of file diff --git a/app/src/main/java/com/kouros/navigation/di/appModule.kt b/app/src/main/java/com/kouros/navigation/di/appModule.kt index 6be255b..711e612 100644 --- a/app/src/main/java/com/kouros/navigation/di/appModule.kt +++ b/app/src/main/java/com/kouros/navigation/di/appModule.kt @@ -11,4 +11,5 @@ import org.koin.dsl.module val appModule = module { viewModelOf(::ViewModel) singleOf(::ValhallaRepository) + singleOf(::OsrmRepository) } \ No newline at end of file diff --git a/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt b/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt index 0d1a8e8..5ce4c79 100644 --- a/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt +++ b/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt @@ -48,7 +48,9 @@ import com.kouros.navigation.ui.theme.NavigationTheme import com.kouros.navigation.utils.bearing import com.kouros.navigation.utils.calculateZoom import com.kouros.navigation.utils.location +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.async import kotlinx.coroutines.delay @@ -77,7 +79,7 @@ class MainActivity : ComponentActivity() { var lastLocation = location(0.0, 0.0) val observer = Observer { newRoute -> if (newRoute.isNotEmpty()) { - routeModel.startNavigation(newRoute) + routeModel.startNavigation(newRoute, applicationContext) routeData.value = routeModel.route.routeGeoJson simulate() //test() @@ -295,12 +297,15 @@ class MainActivity : ComponentActivity() { } } - @OptIn(DelicateCoroutinesApi::class) - fun simulate() = GlobalScope.async { - for ((index, step) in routeModel.legs.steps.withIndex()) { - for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) { - mock.setMockLocation(waypoint[1], waypoint[0]) - delay(600L) // + fun simulate() { + CoroutineScope(Dispatchers.IO).launch { + for ((index, step) in routeModel.legs.steps.withIndex()) { + for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) { + if (routeModel.isNavigating()) { + mock.setMockLocation(waypoint[1], waypoint[0]) + delay(800L) // + } + } } } } diff --git a/app/src/main/java/com/kouros/navigation/ui/MapView.kt b/app/src/main/java/com/kouros/navigation/ui/MapView.kt index ae8a67c..58bf246 100644 --- a/app/src/main/java/com/kouros/navigation/ui/MapView.kt +++ b/app/src/main/java/com/kouros/navigation/ui/MapView.kt @@ -62,7 +62,13 @@ fun MapView( Column { NavigationInfo(step) Box(contentAlignment = Alignment.Center) { - MapLibre(applicationContext, cameraState, baseStyle, route, ViewStyle.VIEW) + MapLibre( + applicationContext, + cameraState, + baseStyle, + route, + ViewStyle.VIEW + ) LocationTrackingEffect( locationState = userLocationState, ) { diff --git a/app/src/main/java/com/kouros/navigation/ui/SearchSheet.kt b/app/src/main/java/com/kouros/navigation/ui/SearchSheet.kt index 0ae2588..22186ff 100644 --- a/app/src/main/java/com/kouros/navigation/ui/SearchSheet.kt +++ b/app/src/main/java/com/kouros/navigation/ui/SearchSheet.kt @@ -257,7 +257,7 @@ private fun RecentPlaces( modifier = Modifier.size(24.dp, 24.dp), ) ListItem( - headlineContent = { Text("${place.name} ${place.postalCode}") }, + headlineContent = { Text("${place.street} ${place.postalCode} ${place.city}") }, modifier = Modifier .clickable { val toLocation = location(place.longitude, place.latitude) diff --git a/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt b/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt index be58e6a..67e3aeb 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt @@ -24,11 +24,15 @@ import com.kouros.navigation.car.screen.RequestPermissionScreen import com.kouros.navigation.car.screen.SearchScreen import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION import com.kouros.navigation.data.Constants.MAXIMAL_SNAP_CORRECTION +import com.kouros.navigation.data.Constants.ROUTE_ENGINE import com.kouros.navigation.data.Constants.TAG import com.kouros.navigation.data.NavigationRepository +import com.kouros.navigation.data.osrm.OsrmRepository import com.kouros.navigation.data.valhalla.ValhallaRepository import com.kouros.navigation.model.ViewModel import com.kouros.navigation.utils.GeoUtils.snapLocation +import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue +import com.kouros.navigation.utils.NavigationUtils.getRouteEngine class NavigationSession : Session(), NavigationScreen.Listener { @@ -69,7 +73,7 @@ class NavigationSession : Session(), NavigationScreen.Listener { } } - val navigationViewModel = ViewModel(ValhallaRepository()) + lateinit var navigationViewModel : ViewModel init { val lifecycle: Lifecycle = lifecycle @@ -77,6 +81,8 @@ class NavigationSession : Session(), NavigationScreen.Listener { } override fun onCreateScreen(intent: Intent): Screen { + + navigationViewModel = getRouteEngine(carContext) routeModel = RouteCarModel() surfaceRenderer = SurfaceRenderer(carContext, lifecycle, routeModel) diff --git a/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt b/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt index 50f1aba..88fdc73 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt @@ -34,6 +34,7 @@ import com.kouros.navigation.car.map.cameraState import com.kouros.navigation.car.map.getPaddingValues import com.kouros.navigation.car.navigation.RouteCarModel import com.kouros.navigation.data.Constants +import com.kouros.navigation.data.Constants.homeLocation import com.kouros.navigation.data.ObjectBox import com.kouros.navigation.model.RouteModel import com.kouros.navigation.utils.bearing @@ -57,7 +58,7 @@ class SurfaceRenderer( private val cameraPosition = MutableLiveData( CameraPosition( zoom = 15.0, - target = Position(latitude = 48.1857475, longitude = 11.5793627) + target = Position(latitude = homeLocation.latitude, longitude = homeLocation.longitude) ) ) private var visibleArea = MutableLiveData( @@ -68,6 +69,7 @@ class SurfaceRenderer( var height = 0 var lastBearing = 0.0 val routeData = MutableLiveData("") + val speedCamerasData = MutableLiveData("") val speed = MutableLiveData(0F) lateinit var centerLocation: Location var viewStyle = ViewStyle.VIEW @@ -165,11 +167,11 @@ class SurfaceRenderer( } } - @Composable fun MapView() { val position: CameraPosition? by cameraPosition.observeAsState() val route: String? by routeData.observeAsState() + val speedCameras: String? by speedCamerasData.observeAsState() val paddingValues = getPaddingValues(height, viewStyle) val cameraState = cameraState(paddingValues, position, tilt) @@ -177,7 +179,7 @@ class SurfaceRenderer( mutableStateOf(BaseStyle.Uri(Constants.STYLE)) } DarkMode(carContext, baseStyle) - MapLibre(carContext, cameraState, baseStyle, route, viewStyle) + MapLibre(carContext, cameraState, baseStyle, route, viewStyle, speedCameras) ShowPosition(cameraState, position, paddingValues) } @@ -189,9 +191,15 @@ class SurfaceRenderer( ) { val cameraDuration = duration(viewStyle == ViewStyle.PREVIEW, position!!.bearing, lastBearing) - val currentSpeed: Float? by speed.observeAsState() + val currentSpeed: Float? by speed.observeAsState() if (viewStyle == ViewStyle.VIEW) { - DrawNavigationImages(paddingValues, currentSpeed, routeModel.routeState.maxSpeed, width, height) + DrawNavigationImages( + paddingValues, + currentSpeed, + routeModel.routeState.maxSpeed, + width, + height + ) } LaunchedEffect(position, viewStyle) { cameraState.animateTo( @@ -237,7 +245,11 @@ class SurfaceRenderer( fun updateLocation(location: Location) { synchronized(this) { if (viewStyle == ViewStyle.VIEW || viewStyle == ViewStyle.PAN_VIEW) { - val bearing = bearing(lastLocation, location, cameraPosition.value!!.bearing) + val bearing = bearing( + lastLocation, + location, + cameraPosition.value!!.bearing + ) val zoom = if (viewStyle == ViewStyle.VIEW) { calculateZoom(location.speed.toDouble()) } else { diff --git a/common/car/src/main/java/com/kouros/navigation/car/map/LocationPuck.kt b/common/car/src/main/java/com/kouros/navigation/car/map/LocationPuck.kt index 6dc5cdf..a2cf5d5 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/map/LocationPuck.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/map/LocationPuck.kt @@ -47,6 +47,7 @@ import org.maplibre.spatialk.geojson.Feature import org.maplibre.spatialk.geojson.FeatureCollection import org.maplibre.spatialk.geojson.Point import kotlin.math.PI +import kotlin.math.absoluteValue import kotlin.math.cos import kotlin.math.sin import kotlin.math.sqrt @@ -244,8 +245,8 @@ private fun rememberLocationSource(locationState: Location): GeoJsonSource { buildJsonObject { put("accuracy", location.accuracy) put("bearing", location.bearing) - //put("bearingAccuracy", location.bearingAccuracy) - //put("age", location.timestamp.elapsedNow().inWholeNanoseconds) + put("bearingAccuracy", location.hasBearingAccuracy()) + put("age", location.time.absoluteValue) }, ) ) diff --git a/common/car/src/main/java/com/kouros/navigation/car/map/MapView.kt b/common/car/src/main/java/com/kouros/navigation/car/map/MapView.kt index 10f67c3..dda37e7 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/map/MapView.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/map/MapView.kt @@ -1,6 +1,5 @@ package com.kouros.navigation.car.map -import android.annotation.SuppressLint import android.location.Location import android.content.Context import androidx.compose.foundation.Canvas @@ -36,6 +35,7 @@ import com.kouros.navigation.data.RouteColor import com.kouros.navigation.data.SpeedColor import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue +import com.kouros.navigation.utils.location import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.CameraState import org.maplibre.compose.camera.rememberCameraState @@ -89,7 +89,8 @@ fun MapLibre( cameraState: CameraState, baseStyle: MutableState, route: String?, - viewStyle: ViewStyle + viewStyle: ViewStyle, + speedCameras: String? = "" ) { MaplibreMap( options = MapOptions( @@ -108,11 +109,12 @@ fun MapLibre( } else { RouteLayer(route) } + SpeedCameraLayer(speedCameras) } + //val lastLocation = location(cameraState.position.target.longitude, cameraState.position.target.latitude) //Puck(cameraState, lastLocation) } } - @Composable fun RouteLayer(routeData: String?) { if (routeData != null && routeData.isNotEmpty()) { @@ -167,6 +169,28 @@ fun AmenityLayer(routeData: String?) { } } +@Composable +fun SpeedCameraLayer(speedCameras: String?) { + if (speedCameras != null && speedCameras.isNotEmpty()) { + val color = const(Color.DarkGray) + val cameraSource = rememberGeoJsonSource(GeoJsonData.JsonString(speedCameras)) + SymbolLayer( + id = "speed-camera-layer", + source = cameraSource, + iconImage = image(painterResource(R.drawable.speed_camera_48px), drawAsSdf = true), + iconColor = color, + iconSize = + interpolate( + type = exponential(1.2f), + input = zoom(), + 5 to const(0.4f), + 6 to const(0.7f), + 7 to const(1.75f), + 20 to const(3f), + ), + ) + } +} @Composable fun BuildingLayer(tiles: Source) { Anchor.Replace("building-3d") { @@ -188,7 +212,9 @@ fun DrawNavigationImages( height: Int ) { NavigationImage(padding, width, height) - CurrentSpeed(width, height, speed) + if (speed != null) { + CurrentSpeed(width, height, speed, maxSpeed) + } if (speed != null && maxSpeed > 0 && (speed * 3.6) > maxSpeed) { MaxSpeed(width, height, maxSpeed) } @@ -211,7 +237,8 @@ fun NavigationImage(padding: PaddingValues, width: Int, height: Int) { painter = painterResource(id = R.drawable.navigation_48px), "Navigation", tint = color.copy(alpha = 0.7f), - modifier = Modifier.size(imageSize.dp, imageSize.dp) + modifier = Modifier + .size(imageSize.dp, imageSize.dp) .scale(scaleX = 1f, scaleY = 0.7f), ) } @@ -221,7 +248,8 @@ fun NavigationImage(padding: PaddingValues, width: Int, height: Int) { private fun CurrentSpeed( width: Int, height: Int, - speed: Float? + curSpeed: Float, + maxSpeed: Int ) { val radius = 32 Box( @@ -234,7 +262,8 @@ private fun CurrentSpeed( ) { val textMeasurerSpeed = rememberTextMeasurer() val textMeasurerKm = rememberTextMeasurer() - val speed = (speed!! * 3.6).toInt().toString() + val speed = (curSpeed * 3.6).toInt().toString() + val kmh = "km/h" val styleSpeed = TextStyle( fontSize = 22.sp, @@ -245,10 +274,10 @@ private fun CurrentSpeed( fontSize = 12.sp, color = Color.White, ) - val textLayoutSpeed = remember(speed) { + val textLayoutSpeed = remember(speed, maxSpeed) { textMeasurerSpeed.measure(speed, styleSpeed) } - val textLayoutKm = remember(kmh) { + val textLayoutKm = remember(kmh, maxSpeed) { textMeasurerSpeed.measure(kmh, styleKm) } Canvas(modifier = Modifier.fillMaxSize()) { diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt index ca390dc..3602bf9 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt @@ -34,6 +34,7 @@ import com.kouros.navigation.data.Place import com.kouros.navigation.data.nominatim.SearchResult import com.kouros.navigation.data.overpass.Elements import com.kouros.navigation.model.ViewModel +import com.kouros.navigation.utils.GeoUtils import com.kouros.navigation.utils.bearing import com.kouros.navigation.utils.location import kotlin.math.absoluteValue @@ -60,7 +61,7 @@ class NavigationScreen( val observer = Observer { route -> if (route.isNotEmpty()) { navigationType = NavigationType.NAVIGATION - routeModel.startNavigation(route) + routeModel.startNavigation(route, carContext) surfaceRenderer.setRouteData() invalidate() } @@ -92,6 +93,16 @@ class NavigationScreen( var speedCameras = listOf() val speedObserver = Observer> { cameras -> speedCameras = cameras + + val coordinates = mutableListOf>() + val loc = location(0.0, 0.0) + cameras.forEach { + val loc = + location(longitude = it.lon!!, latitude = it.lat!!) + coordinates.add(listOf(it.lon!!, it.lat!!)) + } + val speedData = GeoUtils.createPointCollection(coordinates, "radar") + surfaceRenderer.speedCamerasData.value =speedData } init { @@ -339,7 +350,7 @@ class NavigationScreen( private fun settingsAction(): Action { return Action.Builder() - .setIcon(routeModel.createCarIcon(carContext, R.drawable.settings_applications_48px)) + .setIcon(routeModel.createCarIcon(carContext, R.drawable.settings_48px)) .setOnClickListener { screenManager.push(SettingsScreen(carContext)) } @@ -472,7 +483,7 @@ class NavigationScreen( private fun updateSpeedCamera(location: Location) { if (lastCameraSearch++ % 100 == 0) { - viewModel.getSpeedCameras(location) + viewModel.getSpeedCameras(location, 5.0) } if (speedCameras.isNotEmpty()) { updateDistance(location) diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt index acd6776..b201da7 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/PlaceListScreen.kt @@ -54,13 +54,13 @@ class PlaceListScreen( } init { - if (category == Constants.RECENT) { + if (category == RECENT) { viewModel.places.observe(this, observer) } - if (category == Constants.CONTACTS) { + if (category == CONTACTS) { viewModel.contactAddress.observe(this, observerAddress) } - if (category == Constants.FAVORITES) { + if (category == FAVORITES) { viewModel.favorites.observe(this, observer) } loadPlaces() @@ -84,7 +84,7 @@ class PlaceListScreen( places.forEach { val row = Row.Builder() .setImage(contactIcon(it.avatar, it.category)) - .setTitle(it.name!!) + .setTitle("${it.street!!} ${it.city}") .setOnClickListener { val place = Place( 0, @@ -152,7 +152,7 @@ class PlaceListScreen( .setIcon( RouteCarModel().createCarIcon( carContext, - R.drawable.ic_pan_24 + R.drawable.ic_close_white_24dp ) ) .setOnClickListener { @@ -167,7 +167,7 @@ class PlaceListScreen( .build() fun contactIcon(avatar: Uri?, category: String?): CarIcon { - if (category == Constants.RECENT || avatar == null) { + if (category == RECENT || avatar == null) { return CarIcon.Builder( IconCompat.createWithResource( carContext, R.drawable.ic_place_white_24dp diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt index 6e7261e..7ca4558 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt @@ -52,7 +52,7 @@ class RoutePreviewScreen( val navigationMessage = NavigationMessage(carContext) val observer = Observer { route -> if (route.isNotEmpty()) { - routeModel.startNavigation(route) + routeModel.startNavigation(route, carContext) surfaceRenderer.setPreviewRouteData(routeModel) invalidate() } diff --git a/common/car/src/main/res/drawable/navigation_48px.xml b/common/car/src/main/res/drawable/navigation_48px.xml deleted file mode 100644 index a86fcc9..0000000 --- a/common/car/src/main/res/drawable/navigation_48px.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/common/data/src/main/java/com/kouros/navigation/data/Color.kt b/common/data/src/main/java/com/kouros/navigation/data/Color.kt index e318032..4b4ffa7 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Color.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Color.kt @@ -8,6 +8,6 @@ val RouteColor = Color(0xFF5582D0) val SpeedColor = Color(0xFF262525) -val MaxSpeedColor = Color(0xFF262525) +val MaxSpeedColor = Color(0xFFB71515) val PlaceColor = Color(0xFF868005) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/Data.kt b/common/data/src/main/java/com/kouros/navigation/data/Data.kt index cd1421f..b143562 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Data.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Data.kt @@ -124,9 +124,12 @@ data class BoundingBox ( object Constants { - const val STYLE: String = "https://kouros-online.de/liberty.json" - const val STYLE_DARK: String = "https://kouros-online.de/liberty_night.json" - //const val STYLE: String = "https://tiles.openfreemap.org/styles/liberty" + //const val STYLE: String = "https://kouros-online.de/liberty.json" + + //const val STYLE_DARK: String = "https://kouros-online.de/liberty_night.json" + + const val STYLE: String = "https://tiles.openfreemap.org/styles/liberty" + const val STYLE_DARK: String = "https://tiles.openfreemap.org/styles/liberty" const val TAG: String = "Navigation" const val CATEGORIES: String = "Categories" @@ -176,9 +179,10 @@ object Constants { const val DESTINATION_ARRIVAL_DISTANCE = 40.0 + val ROUTE_ENGINE = RouteEngine.VALHALLA.name } enum class RouteEngine { VALHALLA, OSRM, GRAPHHOPPER -} \ No newline at end of file +} diff --git a/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt b/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt index 462ab13..e852219 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt @@ -16,6 +16,7 @@ package com.kouros.navigation.data +import android.content.Context import android.location.Location import com.kouros.navigation.data.overpass.Elements import com.kouros.navigation.model.RouteModel @@ -36,10 +37,10 @@ abstract class NavigationRepository { abstract fun getRoute(currentLocation: Location, location: Location, searchFilter: SearchFilter): String - fun getRouteDistance(currentLocation: Location, location: Location, searchFilter: SearchFilter): Double { + fun getRouteDistance(currentLocation: Location, location: Location, searchFilter: SearchFilter, context: Context): Double { val route = getRoute(currentLocation, location, searchFilter) val routeModel = RouteModel() - routeModel.startNavigation(route) + routeModel.startNavigation(route, context) return routeModel.route.summary!!.distance } diff --git a/common/data/src/main/java/com/kouros/navigation/data/Route.kt b/common/data/src/main/java/com/kouros/navigation/data/Route.kt index 842516f..f886edb 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Route.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Route.kt @@ -2,6 +2,7 @@ package com.kouros.navigation.data import android.location.Location import com.google.gson.GsonBuilder +import com.kouros.navigation.data.Constants.ROUTE_ENGINE import com.kouros.navigation.data.osrm.OsrmResponse import com.kouros.navigation.data.osrm.OsrmRoute import com.kouros.navigation.data.route.Leg @@ -10,6 +11,8 @@ 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.NavigationUtils.getIntKeyValue +import com.kouros.navigation.utils.NavigationUtils.getRouteEngine import com.kouros.navigation.utils.location import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement @@ -23,39 +26,51 @@ data class Route( val summary: Summary?, val legs: List?, val routeGeoJson: String = "", - val centerLocation : Location = location(0.0, 0.0), - var currentStep : Int = 0, + val centerLocation: Location = location(0.0, 0.0), + var currentStep: Int = 0, val waypoints: List>?, - ) { +) { - data class Builder ( + data class Builder( - var routeEngine : Int = RouteEngine.VALHALLA.ordinal, + var routeEngine: Int = 0, var summary: Summary? = null, var legs: List? = null, var routeGeoJson: String = "", var centerLocation: Location = location(0.0, 0.0), - var waypoints : List>? = null,) { + var waypoints: List>? = null, + ) { - fun routeType (routeEngine: Int) = apply {this.routeEngine = routeEngine } + fun routeType(routeEngine: Int) = apply { this.routeEngine = routeEngine } fun summary(summary: Summary) = apply { this.summary = summary } fun legs(legs: List) = apply { this.legs = legs } fun routeGeoJson(routeGeoJson: String) = apply { this.routeGeoJson = routeGeoJson centerLocation = createCenterLocation(routeGeoJson) } - fun waypoints(waypoints: List>) = apply { this.waypoints = waypoints } + + fun routeEngine(routeEngine: Int) = apply { this.routeEngine = routeEngine } + fun waypoints(waypoints: List>) = apply { this.waypoints = waypoints } fun route(route: String) = apply { if (route.isNotEmpty() && route != "[]") { val gson = GsonBuilder().serializeNulls().create() - if (routeEngine == RouteEngine.VALHALLA.ordinal) { - val jsonObject: Map = Json.parseToJsonElement(route).jsonObject - val routeJson = gson.fromJson(jsonObject["trip"].toString(), ValhallaResponse::class.java) + when (this.routeEngine) { + RouteEngine.VALHALLA.ordinal -> { + val jsonObject: Map = + Json.parseToJsonElement(route).jsonObject + val routeJson = + gson.fromJson( + jsonObject["trip"].toString(), + ValhallaResponse::class.java + ) ValhallaRoute().mapJsonToValhalla(routeJson, this) - } else { + } + + else -> { val osrmJson = gson.fromJson(route, OsrmResponse::class.java) OsrmRoute().mapToOsrm(osrmJson, this) } + } } } diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRepository.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRepository.kt index 206ed7f..14c9e55 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRepository.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRepository.kt @@ -4,7 +4,7 @@ import android.location.Location import com.kouros.navigation.data.NavigationRepository import com.kouros.navigation.data.SearchFilter -private const val routeUrl = "https://router.project-osrm.org/route/v1/driving/" +private const val routeUrl = "https://kouros-online.de/osrm/route/v1/driving/" class OsrmRepository : NavigationRepository() { override fun getRoute( @@ -12,7 +12,7 @@ class OsrmRepository : NavigationRepository() { location: Location, searchFilter: SearchFilter ): String { - val routeLocation = "${currentLocation.latitude},${currentLocation.longitude};${location.latitude},${location.longitude}?steps=true" + val routeLocation = "${currentLocation.longitude},${currentLocation.latitude};${location.longitude},${location.latitude}?steps=true" return fetchUrl(routeUrl + routeLocation, true) } } \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRoute.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRoute.kt index 450ad5c..169b1ac 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRoute.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRoute.kt @@ -1,11 +1,84 @@ package com.kouros.navigation.data.osrm import com.kouros.navigation.data.Route -import com.kouros.navigation.data.valhalla.ValhallaResponse +import com.kouros.navigation.data.route.Leg +import com.kouros.navigation.data.route.Maneuver as RouteManeuver +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 OsrmRoute { fun mapToOsrm(routeJson: OsrmResponse, builder: Route.Builder) { - + val waypoints = mutableListOf>() + val summary = Summary() + summary.distance = routeJson.routes.first().distance!! + summary.duration = routeJson.routes.first().duration!! + val steps = mutableListOf() + var stepIndex = 0 + routeJson.routes.first().legs.first().steps.forEach { + if (it.maneuver != null) { + val points = decodePolyline(it.geometry!!, 5) + waypoints.addAll(points) + val maneuver = RouteManeuver( + bearingBefore = it.maneuver!!.bearingBefore ?: 0, + bearingAfter = it.maneuver!!.bearingAfter ?: 0, + type = convertType(it.maneuver!!), + waypoints = points + ) + val step = Step( index = stepIndex, name = it.name!!, distance = it.distance!!, duration = it.duration!!, maneuver = maneuver) + steps.add(step) + stepIndex += 1 + } + } + val leg = Leg(steps) + builder + .routeType(1) + .summary(summary) + .routeGeoJson(createLineStringCollection(waypoints)) + .legs(listOf(leg)) + .waypoints(waypoints.toList()) } + + fun convertType(maneuver: Maneuver): Int { + var newType = 0 + when (maneuver.type) { + ManeuverType.depart.value -> { + newType = androidx.car.app.navigation.model.Maneuver.TYPE_DEPART + } + ManeuverType.arrive.value -> { + newType = androidx.car.app.navigation.model.Maneuver.TYPE_DESTINATION + } + ManeuverType.continue_.value -> { + newType = androidx.car.app.navigation.model.Maneuver.TYPE_STRAIGHT + } + ManeuverType.turn.value -> { + if (maneuver.modifier == "right") { + newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_RIGHT + } + } + } + return newType + } +} + +enum class ManeuverType(val value: String) { + turn("turn"), + depart("depart"), + arrive("arrive"), + merge("merge"), + onRamp("on ramp"), + offRamp("off ramp"), + fork("fork"), + endOfRoad("end of road"), + continue_("continue"), + roundAbout("roundabout"), + rotary("rotary"), + roundaboutTurn("roundabout turn"), + notification("notification"), + exitRoundabout("exit roundabout"), + exitRotary("exit rotary") + + } \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/overpass/Overpass.kt b/common/data/src/main/java/com/kouros/navigation/data/overpass/Overpass.kt index 1be014a..fe1845b 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/overpass/Overpass.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/overpass/Overpass.kt @@ -10,7 +10,10 @@ import java.net.URL class Overpass { - val overpassUrl = "https://overpass.kumi.systems/api/interpreter" + //val overpassUrl = "https://overpass.kumi.systems/api/interpreter" + val overpassUrl = "https://kouros-online.de/overpass/interpreter" + + fun getAround(radius: Int, linestring: String) : List { val httpURLConnection = URL(overpassUrl).openConnection() as HttpURLConnection httpURLConnection.requestMethod = "POST" @@ -28,7 +31,7 @@ class Overpass { |); |out body; """.trimMargin() - println("way[highway](around:$radius,$linestring)") + //println("way[highway](around:$radius,$linestring)") return overpassApi(httpURLConnection, searchQuery) } @@ -71,7 +74,7 @@ class Overpass { .use { it.readText() } // defaults to UTF-8 val gson = GsonBuilder().serializeNulls().create() val overpass = gson.fromJson(response, Amenity::class.java) - //println("Overpass: $response") + // println("Overpass: $response") return overpass.elements } return emptyList() diff --git a/common/data/src/main/java/com/kouros/navigation/data/styles/liberty.json b/common/data/src/main/java/com/kouros/navigation/data/styles/liberty.json index 3315449..0eab21c 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/styles/liberty.json +++ b/common/data/src/main/java/com/kouros/navigation/data/styles/liberty.json @@ -245,6 +245,7 @@ "type": "fill", "source": "openmaptiles", "source-layer": "water", + "maxzoom": 24, "filter": ["!=", ["get", "brunnel"], "tunnel"], "paint": {"fill-color": "rgb(158,189,255)"} }, @@ -860,6 +861,7 @@ true, false ], + "layout": {"visibility": "visible"}, "paint": {"fill-pattern": "pedestrian_polygon"} }, { @@ -1376,11 +1378,13 @@ "type": "line", "source": "openmaptiles", "source-layer": "transportation", + "maxzoom": 24, "filter": [ "all", ["match", ["get", "brunnel"], ["bridge", "tunnel"], false, true], ["==", ["get", "class"], "transit"] ], + "layout": {"visibility": "visible"}, "paint": { "line-color": "#bbb", "line-width": [ @@ -2201,7 +2205,8 @@ "text-font": ["Noto Sans Italic"], "text-max-width": 9, "text-offset": [0, 0.6], - "text-size": 12 + "text-size": 12, + "visibility": "none" }, "paint": { "text-color": "#666", @@ -2240,7 +2245,8 @@ "text-font": ["Noto Sans Italic"], "text-max-width": 9, "text-offset": [0, 0.6], - "text-size": 12 + "text-size": 12, + "visibility": "none" }, "paint": { "text-color": "#666", @@ -2279,7 +2285,8 @@ "text-font": ["Noto Sans Italic"], "text-max-width": 9, "text-offset": [0, 0.6], - "text-size": 12 + "text-size": 12, + "visibility": "none" }, "paint": { "text-color": "#666", @@ -2313,7 +2320,8 @@ "text-font": ["Noto Sans Italic"], "text-max-width": 9, "text-offset": [0.9, 0], - "text-size": 12 + "text-size": 12, + "visibility": "none" }, "paint": { "text-color": "#2e5a80", diff --git a/common/data/src/main/java/com/kouros/navigation/data/styles/liberty_night.json b/common/data/src/main/java/com/kouros/navigation/data/styles/liberty_night.json index 2250e59..0ae6cce 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/styles/liberty_night.json +++ b/common/data/src/main/java/com/kouros/navigation/data/styles/liberty_night.json @@ -137,7 +137,7 @@ "source": "openmaptiles", "source-layer": "landuse", "filter": ["==", ["get", "class"], "pitch"], - "paint": {"fill-color": "#DEE3CD"} + "paint": {"fill-color": "rgba(49, 49, 40, 1)"} }, { "id": "landuse_track", @@ -247,7 +247,7 @@ "source": "openmaptiles", "source-layer": "water", "filter": ["!=", ["get", "brunnel"], "tunnel"], - "paint": {"fill-color": "rgb(158,189,255)"} + "paint": {"fill-color": "rgba(34, 54, 98, 1)"} }, { "id": "landcover_sand", @@ -255,7 +255,7 @@ "source": "openmaptiles", "source-layer": "landcover", "filter": ["==", ["get", "class"], "sand"], - "paint": {"fill-color": "rgba(247, 239, 195, 1)"} + "paint": {"fill-color": "rgba(148, 146, 138, 1)"} }, { "id": "aeroway_fill", @@ -654,7 +654,7 @@ ], "layout": {"line-join": "round"}, "paint": { - "line-color": "#fff", + "line-color": "rgba(74, 64, 64, 1)", "line-width": [ "interpolate", ["exponential", 1.2], @@ -706,7 +706,7 @@ ], "layout": {"line-join": "round"}, "paint": { - "line-color": "#fff4c6", + "line-color": "rgba(72, 70, 58, 1)", "line-width": [ "interpolate", ["exponential", 1.2], @@ -1154,7 +1154,7 @@ ], "layout": {"line-cap": "round", "line-join": "round"}, "paint": { - "line-color": "#fff", + "line-color": "rgba(55, 53, 53, 1)", "line-width": [ "interpolate", ["exponential", 1.2], @@ -1691,7 +1691,7 @@ ["match", ["get", "class"], ["path", "pedestrian"], true, false] ], "paint": { - "line-color": "hsl(0,0%,100%)", + "line-color": "rgba(107, 102, 102, 1)", "line-dasharray": [1, 0.3], "line-width": [ "interpolate", @@ -2208,7 +2208,8 @@ "text-font": ["Noto Sans Italic"], "text-max-width": 9, "text-offset": [0, 0.6], - "text-size": 12 + "text-size": 12, + "visibility": "none" }, "paint": { "text-color": "#666", @@ -2247,7 +2248,8 @@ "text-font": ["Noto Sans Italic"], "text-max-width": 9, "text-offset": [0, 0.6], - "text-size": 12 + "text-size": 12, + "visibility": "none" }, "paint": { "text-color": "#666", @@ -2286,7 +2288,8 @@ "text-font": ["Noto Sans Italic"], "text-max-width": 9, "text-offset": [0, 0.6], - "text-size": 12 + "text-size": 12, + "visibility": "none" }, "paint": { "text-color": "#666", @@ -2320,7 +2323,8 @@ "text-font": ["Noto Sans Italic"], "text-max-width": 9, "text-offset": [0.9, 0], - "text-size": 12 + "text-size": 12, + "visibility": "none" }, "paint": { "text-color": "#2e5a80", diff --git a/common/data/src/main/java/com/kouros/navigation/data/ManeuverType.kt b/common/data/src/main/java/com/kouros/navigation/data/valhalla/ManeuverType.kt similarity index 95% rename from common/data/src/main/java/com/kouros/navigation/data/ManeuverType.kt rename to common/data/src/main/java/com/kouros/navigation/data/valhalla/ManeuverType.kt index 515bfab..2d10d26 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/ManeuverType.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/valhalla/ManeuverType.kt @@ -1,4 +1,4 @@ -package com.kouros.navigation.data +package com.kouros.navigation.data.valhalla enum class ManeuverType(val value: Int) { None(0), diff --git a/common/data/src/main/java/com/kouros/navigation/data/valhalla/ValhallaRepository.kt b/common/data/src/main/java/com/kouros/navigation/data/valhalla/ValhallaRepository.kt index 5ec0274..54e7532 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/valhalla/ValhallaRepository.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/valhalla/ValhallaRepository.kt @@ -8,6 +8,8 @@ import com.kouros.navigation.data.ValhallaLocation import kotlinx.serialization.json.Json private const val routeUrl = "https://kouros-online.de/valhalla/route?json=" + + class ValhallaRepository : NavigationRepository() { override fun getRoute(currentLocation: Location, location: Location, searchFilter: SearchFilter): String { diff --git a/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt b/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt index 0354413..281eac0 100644 --- a/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt +++ b/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt @@ -1,20 +1,28 @@ package com.kouros.navigation.model +import android.content.Context import android.location.Location import androidx.car.app.navigation.model.Maneuver import androidx.car.app.navigation.model.Step import com.kouros.data.R import com.kouros.navigation.data.Constants.NEXT_STEP_THRESHOLD -import com.kouros.navigation.data.ManeuverType +import com.kouros.navigation.data.Constants.ROUTE_ENGINE +import com.kouros.navigation.data.valhalla.ManeuverType import com.kouros.navigation.data.Place import com.kouros.navigation.data.Route +import com.kouros.navigation.data.RouteEngine import com.kouros.navigation.data.StepData import com.kouros.navigation.data.route.Leg +import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue import com.kouros.navigation.utils.location +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.invoke import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import java.util.concurrent.TimeUnit import kotlin.math.roundToInt @@ -43,8 +51,10 @@ open class RouteModel() { val legs: Leg get() = routeState.route!!.legs!!.first() - fun startNavigation(routeString: String) { + fun startNavigation(routeString: String, context: Context) { + val routeEngine = getIntKeyValue(context = context, ROUTE_ENGINE) val newRoute = Route.Builder() + .routeEngine(routeEngine) .route(routeString) .build() this.routeState = routeState.copy( @@ -65,15 +75,13 @@ open class RouteModel() { @OptIn(DelicateCoroutinesApi::class) fun updateLocation(location: Location, viewModel: ViewModel) { findStep(location) - GlobalScope.launch(Dispatchers.IO) { - updateSpeedLimit(location, viewModel) - } + 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) { + if (index >= route.currentStep) { for ((wayIndex, waypoint) in step.maneuver.waypoints.withIndex()) { if (wayIndex >= step.waypointIndex) { val distance = location.distanceTo(location(waypoint[0], waypoint[1])) @@ -83,22 +91,31 @@ open class RouteModel() { step.waypointIndex = wayIndex } } + if (nearestDistance == 0F) { + break + } } } + if (nearestDistance == 0F) { + break + } } + //println("Current Index ${route.currentStep} WayPoint: ${route.currentStep().waypointIndex}") } - fun updateSpeedLimit(location: Location, viewModel: ViewModel) { - // speed limit - val distance = routeState.lastSpeedLocation.distanceTo(location) - if (distance > 500 || routeState.lastSpeedIndex < route.currentStep) { - routeState = routeState.copy(lastSpeedIndex = route.currentStep) - routeState = routeState.copy(lastSpeedLocation = location) - val elements = viewModel.getMaxSpeed(location) - elements.forEach { - if (it.tags.name != null && it.tags.maxspeed != null) { - val speed = it.tags.maxspeed!!.toInt() - routeState = routeState.copy(maxSpeed = speed) + fun updateSpeedLimit(location: Location, viewModel: ViewModel) = runBlocking { + CoroutineScope(Dispatchers.IO).launch { + // speed limit + val distance = routeState.lastSpeedLocation.distanceTo(location) + if (distance > 500 || routeState.lastSpeedIndex < route.currentStep) { + routeState = routeState.copy(lastSpeedIndex = route.currentStep) + routeState = routeState.copy(lastSpeedLocation = location) + val elements = viewModel.getMaxSpeed(location) + elements.forEach { + if (it.tags.name != null && it.tags.maxspeed != null) { + val speed = it.tags.maxspeed!!.toInt() + routeState = routeState.copy(maxSpeed = speed) + } } } } @@ -148,11 +165,9 @@ open class RouteModel() { val maneuverType = step.maneuver.type val distanceLeft = leftStepDistance() var text = "" - when (distanceLeft) { in 0.0..NEXT_STEP_THRESHOLD -> { } - else -> { if (step.name.isNotEmpty()) { text = step.name @@ -174,11 +189,13 @@ open class RouteModel() { fun travelLeftTime(): Double { var timeLeft = 0.0 + // time for next step until end step for (i in route.currentStep + 1..() amenities.forEach { val plLocation = @@ -380,7 +380,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { for (place in results) { val plLocation = location(place.longitude, place.latitude) val distance = - repository.getRouteDistance(location, plLocation, getSearchFilter(context)) + repository.getRouteDistance(location, plLocation, getSearchFilter(context), context) place.distance = distance.toFloat() } } catch (e: Exception) { diff --git a/common/data/src/main/java/com/kouros/navigation/utils/GeoUtils.kt b/common/data/src/main/java/com/kouros/navigation/utils/GeoUtils.kt index 3565541..4dbbc72 100644 --- a/common/data/src/main/java/com/kouros/navigation/utils/GeoUtils.kt +++ b/common/data/src/main/java/com/kouros/navigation/utils/GeoUtils.kt @@ -10,6 +10,7 @@ import org.maplibre.spatialk.geojson.Feature import org.maplibre.spatialk.geojson.dsl.addFeature import org.maplibre.spatialk.geojson.dsl.buildFeatureCollection import org.maplibre.spatialk.geojson.dsl.buildLineString +import org.maplibre.spatialk.geojson.dsl.buildMultiPoint import org.maplibre.spatialk.geojson.toJson import org.maplibre.turf.TurfMeasurement import org.maplibre.turf.TurfMisc @@ -32,8 +33,9 @@ object GeoUtils { return newLocation } - fun decodePolyline(encoded: String, vararg precisionOptional: Int): List> { - val precision = if (precisionOptional.isNotEmpty()) precisionOptional[0] else 6 + + fun decodePolyline(encoded: String, precision: Int = 6,): List> { + //val precisionOptional = if (precisionOptional.isNotEmpty()) precisionOptional[0] else 6 val factor = 10.0.pow(precision) var lat = 0 diff --git a/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt b/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt index 791b991..ffa9035 100644 --- a/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt +++ b/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt @@ -4,7 +4,12 @@ import android.content.Context import android.location.Location import android.location.LocationManager import androidx.core.content.edit +import com.kouros.navigation.data.Constants.ROUTE_ENGINE import com.kouros.navigation.data.Constants.SHARED_PREF_KEY +import com.kouros.navigation.data.RouteEngine +import com.kouros.navigation.data.osrm.OsrmRepository +import com.kouros.navigation.data.valhalla.ValhallaRepository +import com.kouros.navigation.model.ViewModel import java.time.LocalDateTime import java.time.ZoneId import java.time.ZoneOffset @@ -20,6 +25,14 @@ import kotlin.time.Duration.Companion.seconds object NavigationUtils { + fun getRouteEngine(context: Context): ViewModel { + val routeEngine = getIntKeyValue(context = context, ROUTE_ENGINE) + return when (routeEngine) { + RouteEngine.VALHALLA.ordinal -> ViewModel(ValhallaRepository()) + else -> ViewModel(OsrmRepository()) + } + } + fun getBooleanKeyValue(context: Context, key: String): Boolean { return context .getSharedPreferences( @@ -43,13 +56,13 @@ object NavigationUtils { } } - fun getIntKeyValue(context: Context, key: String): Int { + fun getIntKeyValue(context: Context, key: String, default: Int = 0): Int { return context .getSharedPreferences( SHARED_PREF_KEY, Context.MODE_PRIVATE ) - .getInt(key, 0) + .getInt(key, default) } fun setIntKeyValue(context: Context, `val`: Int, key: String) { diff --git a/common/data/src/main/res/drawable/navigation_48px.xml b/common/data/src/main/res/drawable/navigation_48px.xml index e87c0a6..a86fcc9 100644 --- a/common/data/src/main/res/drawable/navigation_48px.xml +++ b/common/data/src/main/res/drawable/navigation_48px.xml @@ -6,5 +6,5 @@ android:tint="?attr/colorControlNormal"> + android:pathData="M190,840L160,810L480,80L800,810L770,840L480,708L190,840Z"/> diff --git a/common/data/src/main/res/drawable/settings_48px.xml b/common/data/src/main/res/drawable/settings_48px.xml new file mode 100644 index 0000000..cc2ff14 --- /dev/null +++ b/common/data/src/main/res/drawable/settings_48px.xml @@ -0,0 +1,10 @@ + + + diff --git a/common/data/src/main/res/drawable/settings_applications_48px.xml b/common/data/src/main/res/drawable/settings_applications_48px.xml deleted file mode 100644 index b4c399f..0000000 --- a/common/data/src/main/res/drawable/settings_applications_48px.xml +++ /dev/null @@ -1,10 +0,0 @@ - - -