DEVIATION depends on speed
This commit is contained in:
@@ -17,8 +17,8 @@ android {
|
|||||||
applicationId = "com.kouros.navigation"
|
applicationId = "com.kouros.navigation"
|
||||||
minSdk = 33
|
minSdk = 33
|
||||||
targetSdk = 37
|
targetSdk = 37
|
||||||
versionCode = 121
|
versionCode = 125
|
||||||
versionName = "0.3.1.121"
|
versionName = "0.3.2.125"
|
||||||
base.archivesName = "navi-$versionName"
|
base.archivesName = "navi-$versionName"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ plugins {
|
|||||||
android {
|
android {
|
||||||
namespace = "com.kouros.navigation"
|
namespace = "com.kouros.navigation"
|
||||||
compileSdk {
|
compileSdk {
|
||||||
version = release(36)
|
version = release(37)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ plugins {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.kouros.android.cars.carappservice"
|
namespace = "com.kouros.android.cars.carappservice"
|
||||||
compileSdk = 36
|
compileSdk = 37
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 33
|
minSdk = 33
|
||||||
|
|||||||
@@ -132,12 +132,12 @@ class CarSensorManager(
|
|||||||
|
|
||||||
val carSensors = carHardwareManager.carSensors
|
val carSensors = carHardwareManager.carSensors
|
||||||
carSensors.addCompassListener(
|
carSensors.addCompassListener(
|
||||||
CarSensors.UPDATE_RATE_NORMAL,
|
CarSensors.UPDATE_RATE_FASTEST,
|
||||||
carContext.mainExecutor,
|
carContext.mainExecutor,
|
||||||
carCompassListener
|
carCompassListener
|
||||||
)
|
)
|
||||||
carSensors.addCarHardwareLocationListener(
|
carSensors.addCarHardwareLocationListener(
|
||||||
CarSensors.UPDATE_RATE_UI,
|
CarSensors.UPDATE_RATE_FASTEST,
|
||||||
carContext.mainExecutor,
|
carContext.mainExecutor,
|
||||||
carLocationListener
|
carLocationListener
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,14 +12,8 @@ import androidx.lifecycle.LifecycleOwner
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.kouros.data.BuildConfig
|
import com.kouros.data.BuildConfig
|
||||||
import com.kouros.navigation.data.Constants.a22
|
|
||||||
import com.kouros.navigation.data.Constants.a9
|
|
||||||
import com.kouros.navigation.data.Constants.a94
|
|
||||||
import com.kouros.navigation.data.Constants.homeHohenwaldeck
|
|
||||||
import com.kouros.navigation.data.Constants.homeVogelhart
|
import com.kouros.navigation.data.Constants.homeVogelhart
|
||||||
import com.kouros.navigation.data.Constants.ioannina
|
import com.kouros.navigation.data.Constants.widenmayer
|
||||||
import com.kouros.navigation.data.Constants.isarring
|
|
||||||
import com.kouros.navigation.data.Constants.subislawa
|
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import android.Manifest.permission
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
|
import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.car.app.CarContext
|
import androidx.car.app.CarContext
|
||||||
import androidx.car.app.CarToast
|
import androidx.car.app.CarToast
|
||||||
import androidx.car.app.Screen
|
import androidx.car.app.Screen
|
||||||
@@ -111,7 +113,6 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
|||||||
|
|
||||||
var speedCameras = listOf<Elements>()
|
var speedCameras = listOf<Elements>()
|
||||||
|
|
||||||
|
|
||||||
private var lastRouteCheckLocation = location(0.0, 0.0)
|
private var lastRouteCheckLocation = location(0.0, 0.0)
|
||||||
|
|
||||||
var navigationManagerStarted = false
|
var navigationManagerStarted = false
|
||||||
@@ -463,8 +464,8 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
|||||||
*/
|
*/
|
||||||
private fun handleNavigationLocation(location: Location) {
|
private fun handleNavigationLocation(location: Location) {
|
||||||
val start = System.currentTimeMillis()
|
val start = System.currentTimeMillis()
|
||||||
routeModel.updateLocation(location, navigationViewModel)
|
|
||||||
val snappedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
val snappedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
||||||
|
routeModel.updateLocation(snappedLocation, navigationViewModel)
|
||||||
val streetName = routeModel.currentStep().street
|
val streetName = routeModel.currentStep().street
|
||||||
if (checkLocationDeviation(location, snappedLocation, streetName)) {
|
if (checkLocationDeviation(location, snappedLocation, streetName)) {
|
||||||
if (routeModel.navState.arrived) return
|
if (routeModel.navState.arrived) return
|
||||||
@@ -490,11 +491,21 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
|||||||
snappedLocation: Location,
|
snappedLocation: Location,
|
||||||
streetName: String
|
streetName: String
|
||||||
): Boolean {
|
): Boolean {
|
||||||
|
var maximalRouteDeviation = MAXIMAL_ROUTE_DEVIATION
|
||||||
|
val speed = surfaceRenderer.speed.value
|
||||||
|
if (speed != null) {
|
||||||
|
when (speed) {
|
||||||
|
in 0.0..10.0 -> maximalRouteDeviation = MAXIMAL_ROUTE_DEVIATION
|
||||||
|
in 10.0..20.0 -> maximalRouteDeviation = MAXIMAL_ROUTE_DEVIATION + 200
|
||||||
|
in 20.0..30.0 -> maximalRouteDeviation = MAXIMAL_ROUTE_DEVIATION + 400
|
||||||
|
in 30.0..100.0 -> maximalRouteDeviation = MAXIMAL_ROUTE_DEVIATION + 500
|
||||||
|
}
|
||||||
|
}
|
||||||
val distance = location.distanceTo(snappedLocation)
|
val distance = location.distanceTo(snappedLocation)
|
||||||
when {
|
when {
|
||||||
distance > MAXIMAL_ROUTE_DEVIATION && distance < MAXIMAL_ROUTE_DEVIATION * 10-> {
|
distance > maximalRouteDeviation -> {
|
||||||
stopNavigation()
|
stopNavigation()
|
||||||
navigationScreen.calculateNewRoute(routeModel.navState.destination)
|
navigationScreen.calculateNewRoute(routeModel.navState.destination, distance)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,12 +824,19 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
|||||||
if (camera.distance < 80) {
|
if (camera.distance < 80) {
|
||||||
if ((bearingSpeedCamera - bearingRoute).absoluteValue < 15.0) {
|
if ((bearingSpeedCamera - bearingRoute).absoluteValue < 15.0) {
|
||||||
routeModel.showSpeedCamera(carContext, camera.distance, camera.tags.maxspeed)
|
routeModel.showSpeedCamera(carContext, camera.distance, camera.tags.maxspeed)
|
||||||
camera.distance = 1000.0
|
val cameras = mutableListOf<Elements>()
|
||||||
|
speedCameras.forEach {
|
||||||
|
if (!(camera.lon == it.lon && camera.lat == it.lat)) {
|
||||||
|
cameras.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
speedCameras = cameras
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a new route is needed based on the time since the last update.
|
* Checks if a new route is needed based on the time since the last update.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.kouros.navigation.car.screen
|
|||||||
|
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.util.Log
|
|
||||||
import androidx.car.app.CarContext
|
import androidx.car.app.CarContext
|
||||||
import androidx.car.app.Screen
|
import androidx.car.app.Screen
|
||||||
import androidx.car.app.model.Action
|
import androidx.car.app.model.Action
|
||||||
@@ -33,7 +32,6 @@ import com.kouros.data.R
|
|||||||
import com.kouros.navigation.car.SurfaceRenderer
|
import com.kouros.navigation.car.SurfaceRenderer
|
||||||
import com.kouros.navigation.car.screen.settings.SettingsScreen
|
import com.kouros.navigation.car.screen.settings.SettingsScreen
|
||||||
import com.kouros.navigation.data.Constants
|
import com.kouros.navigation.data.Constants
|
||||||
import com.kouros.navigation.data.Constants.TAG
|
|
||||||
import com.kouros.navigation.data.Place
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.data.ViewStyle
|
import com.kouros.navigation.data.ViewStyle
|
||||||
import com.kouros.navigation.model.NavigationViewModel
|
import com.kouros.navigation.model.NavigationViewModel
|
||||||
@@ -53,6 +51,7 @@ open class NavigationScreen(
|
|||||||
private val navigationViewModel: NavigationViewModel
|
private val navigationViewModel: NavigationViewModel
|
||||||
) : Screen(carContext) {
|
) : Screen(carContext) {
|
||||||
|
|
||||||
|
var deviation = 0F
|
||||||
var recentPlaces = mutableListOf<Place>()
|
var recentPlaces = mutableListOf<Place>()
|
||||||
|
|
||||||
var recentPlace: Place = Place()
|
var recentPlace: Place = Place()
|
||||||
@@ -151,7 +150,8 @@ open class NavigationScreen(
|
|||||||
.setDestinationTravelEstimate(destinationTravelEstimate)
|
.setDestinationTravelEstimate(destinationTravelEstimate)
|
||||||
.setActionStrip(actionStripBuilder.build())
|
.setActionStrip(actionStripBuilder.build())
|
||||||
.setMapActionStrip(
|
.setMapActionStrip(
|
||||||
mapActionStrip(carContext,
|
mapActionStrip(
|
||||||
|
carContext,
|
||||||
surfaceRenderer.viewStyle,
|
surfaceRenderer.viewStyle,
|
||||||
{ zoomPlus() }, { zoomMinus() }, {
|
{ zoomPlus() }, { zoomMinus() }, {
|
||||||
Action.Builder()
|
Action.Builder()
|
||||||
@@ -173,7 +173,8 @@ open class NavigationScreen(
|
|||||||
* Creates and returns a template for the default view state.
|
* Creates and returns a template for the default view state.
|
||||||
*/
|
*/
|
||||||
private fun navigationView(actionStripBuilder: ActionStrip.Builder): Template {
|
private fun navigationView(actionStripBuilder: ActionStrip.Builder): Template {
|
||||||
val mapActionStrip = mapActionStrip(carContext,
|
val mapActionStrip = mapActionStrip(
|
||||||
|
carContext,
|
||||||
surfaceRenderer.viewStyle,
|
surfaceRenderer.viewStyle,
|
||||||
{ zoomPlus() }, { zoomMinus() }, {
|
{ zoomPlus() }, { zoomMinus() }, {
|
||||||
createAction(
|
createAction(
|
||||||
@@ -215,10 +216,6 @@ open class NavigationScreen(
|
|||||||
* Creates and returns a NavigationTemplate specifically for when the destination is reached.
|
* Creates and returns a NavigationTemplate specifically for when the destination is reached.
|
||||||
*/
|
*/
|
||||||
fun navigationArrived(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
|
fun navigationArrived(actionStripBuilder: ActionStrip.Builder): NavigationTemplate {
|
||||||
var street = ""
|
|
||||||
if (destinations.first().address != null) {
|
|
||||||
street = destinations.first().address.toString()
|
|
||||||
}
|
|
||||||
return NavigationTemplate.Builder()
|
return NavigationTemplate.Builder()
|
||||||
.setNavigationInfo(
|
.setNavigationInfo(
|
||||||
MessageInfo.Builder(
|
MessageInfo.Builder(
|
||||||
@@ -239,7 +236,8 @@ open class NavigationScreen(
|
|||||||
.setBackgroundColor(backGroundColor)
|
.setBackgroundColor(backGroundColor)
|
||||||
.setActionStrip(actionStripBuilder.build())
|
.setActionStrip(actionStripBuilder.build())
|
||||||
.setMapActionStrip(
|
.setMapActionStrip(
|
||||||
mapActionStrip(carContext,
|
mapActionStrip(
|
||||||
|
carContext,
|
||||||
surfaceRenderer.viewStyle,
|
surfaceRenderer.viewStyle,
|
||||||
{ zoomPlus() }, { zoomMinus() }, {
|
{ zoomPlus() }, { zoomMinus() }, {
|
||||||
createAction(
|
createAction(
|
||||||
@@ -300,7 +298,8 @@ open class NavigationScreen(
|
|||||||
val builder = MapWithContentTemplate.Builder()
|
val builder = MapWithContentTemplate.Builder()
|
||||||
.setContentTemplate(contentTemplate)
|
.setContentTemplate(contentTemplate)
|
||||||
.setActionStrip(
|
.setActionStrip(
|
||||||
mapActionStrip(carContext,
|
mapActionStrip(
|
||||||
|
carContext,
|
||||||
ViewStyle.VIEW,
|
ViewStyle.VIEW,
|
||||||
{ settingsAction() },
|
{ settingsAction() },
|
||||||
{
|
{
|
||||||
@@ -472,13 +471,14 @@ open class NavigationScreen(
|
|||||||
/**
|
/**
|
||||||
* Initiates recalculation for a new route to the destination.
|
* Initiates recalculation for a new route to the destination.
|
||||||
*/
|
*/
|
||||||
fun calculateNewRoute(destination: Place) {
|
fun calculateNewRoute(destination: Place, distance: Float) {
|
||||||
|
deviation = distance
|
||||||
navigationType = NavigationType.REROUTE
|
navigationType = NavigationType.REROUTE
|
||||||
invalidate()
|
invalidate()
|
||||||
val mainThreadHandler = Handler(carContext.mainLooper)
|
val mainThreadHandler = Handler(carContext.mainLooper)
|
||||||
mainThreadHandler.post {
|
mainThreadHandler.post {
|
||||||
reRouteTimer?.cancel()
|
reRouteTimer?.cancel()
|
||||||
reRouteTimer = object : CountDownTimer(2000, 1000) {
|
reRouteTimer = object : CountDownTimer(5000, 1000) {
|
||||||
override fun onTick(millisUntilFinished: Long) {}
|
override fun onTick(millisUntilFinished: Long) {}
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
navigationType = NavigationType.NAVIGATION
|
navigationType = NavigationType.NAVIGATION
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class PlaceListScreen(
|
|||||||
override fun onGetTemplate(): Template {
|
override fun onGetTemplate(): Template {
|
||||||
val itemListBuilder = ItemList.Builder()
|
val itemListBuilder = ItemList.Builder()
|
||||||
.setNoItemsMessage(carContext.getString(R.string.no_places))
|
.setNoItemsMessage(carContext.getString(R.string.no_places))
|
||||||
recentPlaces.filter { it.category == category }.forEach {
|
recentPlaces.filter { it.category == category && it.distance > 500F }.forEach {
|
||||||
val street = it.street.ifEmpty {
|
val street = it.street.ifEmpty {
|
||||||
it.name
|
it.name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class NavigationScreenTest {
|
|||||||
navigationScreen.navigationType = NavigationType.NAVIGATION
|
navigationScreen.navigationType = NavigationType.NAVIGATION
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
navigationScreen.calculateNewRoute(Place())
|
navigationScreen.calculateNewRoute(Place(), distance)
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assertThat(navigationScreen.navigationType).isEqualTo(NavigationType.REROUTE)
|
assertThat(navigationScreen.navigationType).isEqualTo(NavigationType.REROUTE)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ plugins {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.kouros.data"
|
namespace = "com.kouros.data"
|
||||||
compileSdk = 36
|
compileSdk = 37
|
||||||
|
|
||||||
|
|
||||||
val properties = Properties().apply {
|
val properties = Properties().apply {
|
||||||
|
|||||||
@@ -129,6 +129,8 @@ object Constants {
|
|||||||
const val RESTAURANT: String ="restaurant"
|
const val RESTAURANT: String ="restaurant"
|
||||||
|
|
||||||
/** The initial location to use as an anchor for searches. */
|
/** The initial location to use as an anchor for searches. */
|
||||||
|
|
||||||
|
val widenmayer = location( 11.595721, 48.146113)
|
||||||
val homeVogelhart = location(11.5793748, 48.185749)
|
val homeVogelhart = location(11.5793748, 48.185749)
|
||||||
val homeHohenwaldeck = location( 11.594322, 48.1164817)
|
val homeHohenwaldeck = location( 11.594322, 48.1164817)
|
||||||
val ioannina = location( 20.826237, 39.690174)
|
val ioannina = location( 20.826237, 39.690174)
|
||||||
@@ -140,7 +142,7 @@ object Constants {
|
|||||||
val isarring = location( 11.609696, 48.155116)
|
val isarring = location( 11.609696, 48.155116)
|
||||||
const val NEXT_STEP_THRESHOLD = 500.0
|
const val NEXT_STEP_THRESHOLD = 500.0
|
||||||
|
|
||||||
const val MAXIMAL_SNAP_CORRECTION = 40.0
|
const val MAXIMAL_SNAP_CORRECTION = 50.0
|
||||||
|
|
||||||
const val MAXIMAL_ROUTE_DEVIATION = 100.0
|
const val MAXIMAL_ROUTE_DEVIATION = 100.0
|
||||||
|
|
||||||
|
|||||||
@@ -185,12 +185,10 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
|
|||||||
place.id = id
|
place.id = id
|
||||||
id += 1
|
id += 1
|
||||||
}
|
}
|
||||||
if (place.distance == 0F || place.distance > 500F) {
|
|
||||||
pl.add(place)
|
pl.add(place)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
val sortedList = pl.sortedWith(compareByDescending<Place> { it.navigations }
|
val sortedList = pl.sortedWith(compareByDescending<Place> { it.navigations }
|
||||||
.thenByDescending { it.distance })
|
.thenByDescending { it.distance })
|
||||||
recentPlaces.postValue(sortedList)
|
recentPlaces.postValue(sortedList)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ kotlin.code.style=official
|
|||||||
# thereby reducing the size of the R class for that library
|
# thereby reducing the size of the R class for that library
|
||||||
android.nonTransitiveRClass=true
|
android.nonTransitiveRClass=true
|
||||||
|
|
||||||
|
org.gradle.daemon=true
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.configuration-cache=true
|
org.gradle.configuration-cache=true
|
||||||
|
|||||||
Reference in New Issue
Block a user