Categories

This commit is contained in:
Dimitris
2026-03-09 18:55:13 +01:00
parent 8c103a1f96
commit 61ce09f393
38 changed files with 864 additions and 338 deletions

View File

@@ -78,7 +78,7 @@ data class Locations (
data class SearchFilter(
var avoidMotorway: Boolean = false,
var avoidTollway : Boolean = false,
var avoidFerry : Boolean = false,
)
@@ -93,10 +93,6 @@ data class ValhallaLocation (
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 TAG: String = "Navigation"
const val CATEGORIES: String = "Categories"
@@ -132,6 +128,8 @@ object Constants {
const val MAXIMUM_LOCATION_DISTANCE = 100000F
const val TRAFFIC_UPDATE = 300
const val INSTRUCTION_DISTANCE = 50
const val GMS_CAR_SPEED_PERMISSION = "com.google.android.gms.permission.CAR_SPEED"
const val AUTOMOTIVE_CAR_SPEED_PERMISSION = "android.car.permission.CAR_SPEED"

View File

@@ -55,18 +55,7 @@ abstract class NavigationRepository {
): Double {
if (currentLocation.latitude == 0.0)
return 0.0
val osrm = OsrmRepository()
val route = osrm.getRoute(context, currentLocation, location, carOrientation, SearchFilter())
val gson = GsonBuilder().serializeNulls().create()
val osrmJson = gson.fromJson(route, OsrmResponse::class.java)
if (osrmJson.routes.isEmpty()) {
return 0.0
}
return osrmJson.routes.first().distance
// return osrmJson.destinations.first().distance?.toDouble() ?: 0.0
///val routeModel = RouteModel()
//routeModel.startNavigation(route, context)
//return routeModel.curRoute.summary.distance
return currentLocation.distanceTo(location).toDouble()
}
fun searchPlaces(search: String, location: Location): String {

View File

@@ -35,6 +35,8 @@ class DataStoreManager(private val context: Context) {
val AVOID_TOLLWAY = booleanPreferencesKey("AvoidTollway")
val AVOID_FERRY = booleanPreferencesKey("AvoidFerry")
val CAR_LOCATION = booleanPreferencesKey("CarLocation")
val ROUTING_ENGINE = intPreferencesKey("RoutingEngine")
@@ -49,6 +51,8 @@ class DataStoreManager(private val context: Context) {
val GUIDANCE_AUDIO = intPreferencesKey("GuidanceAudio")
val TRAFFIC = booleanPreferencesKey("Traffic")
}
// Read values
@@ -73,6 +77,11 @@ class DataStoreManager(private val context: Context) {
preferences[PreferencesKeys.AVOID_TOLLWAY] == true
}
val avoidFerryFlow: Flow<Boolean> =
context.dataStore.data.map { preferences ->
preferences[PreferencesKeys.AVOID_FERRY] == true
}
val useCarLocationFlow: Flow<Boolean> =
context.dataStore.data.map { preferences ->
preferences[PreferencesKeys.CAR_LOCATION] == true
@@ -115,6 +124,11 @@ class DataStoreManager(private val context: Context) {
?: 0
}
val trafficFlow: Flow<Boolean> =
context.dataStore.data.map { preferences ->
preferences[PreferencesKeys.TRAFFIC] == true
}
// Save values
suspend fun setShow3D(enabled: Boolean) {
context.dataStore.edit { preferences ->
@@ -140,6 +154,12 @@ class DataStoreManager(private val context: Context) {
}
}
suspend fun setAvoidFerry(enabled: Boolean) {
context.dataStore.edit { preferences ->
preferences[PreferencesKeys.AVOID_FERRY] = enabled
}
}
suspend fun setCarLocation(enabled: Boolean) {
context.dataStore.edit { preferences ->
preferences[PreferencesKeys.CAR_LOCATION] = enabled
@@ -182,4 +202,9 @@ class DataStoreManager(private val context: Context) {
}
}
suspend fun setTraffic(enabled: Boolean) {
context.dataStore.edit { preferences ->
preferences[PreferencesKeys.TRAFFIC] = enabled
}
}
}

View File

@@ -25,6 +25,9 @@ class OsrmRepository : NavigationRepository() {
if (searchFilter.avoidTollway) {
exclude = "$exclude&exclude=toll"
}
if (searchFilter.avoidFerry) {
exclude = "$exclude&exclude=ferry"
}
val routeLocation = "${currentLocation.longitude},${currentLocation.latitude};${location.longitude},${location.latitude}?steps=true&alternatives=false"
return fetchUrl(routeUrl + routeLocation + exclude, true)
}

View File

@@ -44,6 +44,9 @@ class TomTomRepository : NavigationRepository() {
if (searchFilter.avoidTollway) {
filter = "$filter&avoid=tollRoads"
}
if (searchFilter.avoidFerry) {
filter = "$filter&avoid=ferries"
}
val repository = getSettingsRepository(context)
val tomtomApiKey = runBlocking { repository.tomTomApiKeyFlow.first() }
val currentLocale = Locale.getDefault()
@@ -65,6 +68,10 @@ class TomTomRepository : NavigationRepository() {
override fun getTraffic(context: Context, location: Location, carOrientation: Float): String {
val repository = getSettingsRepository(context)
val tomtomApiKey = runBlocking { repository.tomTomApiKeyFlow.first() }
val showTraffic = runBlocking { repository.trafficFlow.first() }
if (!showTraffic) {
return ""
}
val bbox = calculateSquareRadius(location.latitude, location.longitude, 15.0)
return if (useAssetTraffic) {
val trafficJson = context.resources.openRawResource(R.raw.tomtom_traffic)

View File

@@ -119,17 +119,11 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
val recentPlaces = settingsRepository.recentPlacesFlow.first()
val gson = GsonBuilder().serializeNulls().create()
val places = gson.fromJson(recentPlaces, Places::class.java)
val place = places.places.minByOrNull { it.lastDate.dec() }
if (place != null) {
for (place in places.places.sortedBy { it.lastDate }) {
val plLocation = location(place.longitude, place.latitude)
val distance = repository.getRouteDistance(
location,
plLocation,
carOrientation,
context
)
place.distance = distance.toFloat()
if (place.distance > 1F) {
val distance = plLocation.distanceTo(location)
place.distance = distance
if (place.distance > 200F) {
recentPlace.postValue(place)
return@launch
}
@@ -152,7 +146,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
val gson = GsonBuilder().serializeNulls().create()
val recentPlaces = gson.fromJson(rp, Places::class.java)
val pl = mutableListOf<Place>()
var id : Long = 0
var id: Long = 0
if (rp.isNotEmpty()) {
for (place in recentPlaces.places) {
if (place.category.equals(Constants.RECENT)) {
@@ -509,7 +503,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
val gson = GsonBuilder().serializeNulls().create()
val settingsRepository = getSettingsRepository(context)
val rp = settingsRepository.recentPlacesFlow.first()
var id : Long = 0
var id: Long = 0
if (rp.isNotEmpty()) {
val recentPlaces =
gson.fromJson(rp, Places::class.java).places.sortedBy { it.lastDate }
@@ -579,9 +573,10 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
*/
fun getSearchFilter(context: Context): SearchFilter {
val repository = getSettingsRepository(context)
val avoidMotorway = runBlocking { repository.avoidMotorwayFlow.first() }
val avoidTollway = runBlocking { repository.avoidTollwayFlow.first() }
return SearchFilter(avoidMotorway, avoidTollway)
val avoidMotorway = runBlocking { repository.avoidMotorwayFlow.first() }
val avoidTollway = runBlocking { repository.avoidTollwayFlow.first() }
val avoidFerry = runBlocking { repository.avoidFerryFlow.first() }
return SearchFilter(avoidMotorway, avoidTollway, avoidFerry)
}
/**
@@ -591,7 +586,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
fun loadRecentPlace(context: Context): SnapshotStateList<Place?> {
val pl = mutableListOf<Place>()
val settingsRepository = getSettingsRepository(context)
val rp = runBlocking { settingsRepository.recentPlacesFlow.first()}
val rp = runBlocking { settingsRepository.recentPlacesFlow.first() }
if (rp.isNotEmpty()) {
val gson = GsonBuilder().serializeNulls().create()
val recentPlaces = gson.fromJson(rp, Places::class.java).places.sortedBy { it.lastDate }

View File

@@ -36,6 +36,12 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
false
)
val avoidFerry = repository.avoidFerryFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
false
)
val carLocation = repository.carLocationFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
@@ -78,6 +84,12 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
0
)
val traffic = repository.trafficFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000),
false
)
fun onShow3DChanged(enabled: Boolean) {
viewModelScope.launch { repository.setShow3D(enabled) }
}
@@ -94,6 +106,11 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
viewModelScope.launch { repository.setAvoidTollway(enabled) }
}
fun onAvoidFerry(enabled: Boolean) {
viewModelScope.launch { repository.setAvoidFerry(enabled) }
}
fun onCarLocation(enabled: Boolean) {
viewModelScope.launch { repository.setCarLocation(enabled) }
}
@@ -118,4 +135,7 @@ class SettingsViewModel(private val repository: SettingsRepository) : ViewModel(
viewModelScope.launch { repository.setGuidanceAudio(mode) }
}
fun onTraffic(enabled: Boolean) {
viewModelScope.launch { repository.setTraffic(enabled) }
}
}

View File

@@ -17,6 +17,9 @@ class SettingsRepository(
val avoidTollwayFlow: Flow<Boolean> =
dataStoreManager.avoidTollwayFlow
val avoidFerryFlow: Flow<Boolean> =
dataStoreManager.avoidFerryFlow
val carLocationFlow: Flow<Boolean> =
dataStoreManager.useCarLocationFlow
@@ -29,7 +32,6 @@ class SettingsRepository(
val tomTomApiKeyFlow: Flow<String> =
dataStoreManager.tomTomApiKeyFlow
val recentPlacesFlow: Flow<String> =
dataStoreManager.recentPlacesFlow
@@ -39,6 +41,8 @@ class SettingsRepository(
val guidanceAudioFlow: Flow<Int> =
dataStoreManager.guidanceAudioFlow
val trafficFlow: Flow<Boolean> =
dataStoreManager.trafficFlow
suspend fun setShow3D(enabled: Boolean) {
dataStoreManager.setShow3D(enabled)
@@ -56,6 +60,10 @@ class SettingsRepository(
dataStoreManager.setAvoidTollway(enabled)
}
suspend fun setAvoidFerry(enabled: Boolean) {
dataStoreManager.setAvoidFerry(enabled)
}
suspend fun setCarLocation(enabled: Boolean) {
dataStoreManager.setCarLocation(enabled)
}
@@ -84,4 +92,7 @@ class SettingsRepository(
dataStoreManager.setGuidanceAudio(mode)
}
suspend fun setTraffic(enabled: Boolean) {
dataStoreManager.setTraffic(enabled)
}
}

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M240,400L480,400L480,200Q480,200 480,200Q480,200 480,200L240,200Q240,200 240,200Q240,200 240,200L240,400ZM160,840L160,200Q160,167 183.5,143.5Q207,120 240,120L480,120Q513,120 536.5,143.5Q560,167 560,200L560,480L610,480Q639,480 659.5,500.5Q680,521 680,550L680,735Q680,752 694,766Q708,780 725,780Q743,780 756.5,766Q770,752 770,735L770,360L760,360Q743,360 731.5,348.5Q720,337 720,320L720,240L740,240L740,180L780,180L780,240L820,240L820,180L860,180L860,240L880,240L880,320Q880,337 868.5,348.5Q857,360 840,360L830,360L830,735Q830,777 799.5,808.5Q769,840 725,840Q682,840 651,808.5Q620,777 620,735L620,550Q620,545 617.5,542.5Q615,540 610,540L560,540L560,840L160,840ZM340,760L440,600L380,600L380,480L280,640L340,640L340,760Z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M220,408L489,408L489,180Q489,180 489,180Q489,180 489,180L220,180Q220,180 220,180Q220,180 220,180L220,408ZM160,840L160,180Q160,156 178,138Q196,120 220,120L489,120Q513,120 531,138Q549,156 549,180L549,468L614,468Q634.71,468 649.36,482.64Q664,497.29 664,518L664,737Q664,759 681.5,773.5Q699,788 722,788Q745,788 765,773.5Q785,759 785,737L785,350L770,350Q757.25,350 748.63,341.37Q740,332.75 740,320L740,230L760,230L760,180L790,180L790,230L830,230L830,180L860,180L860,230L880,230L880,320Q880,332.75 871.38,341.37Q862.75,350 850,350L835,350L835,736.69Q835,780 801,810Q767,840 721.82,840Q677.66,840 645.83,810Q614,780 614,737L614,518Q614,518 614,518Q614,518 614,518L549,518L549,840L160,840ZM337,746L425,606L372,606L372,501L285,641L337,641L337,746Z"/>
</vector>

View File

@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M120,840L120,760L200,520L120,280L120,200L628,200L686,40L780,74L734,200L840,200L840,280L760,520L840,760L840,840L120,840ZM440,680L520,680L520,560L640,560L640,480L520,480L520,360L440,360L440,480L320,480L320,560L440,560L440,680Z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M120,840L120,780L207,525L120,270L120,210L647,210L709,40L777,67L725,210L840,210L840,270L752,525L840,780L840,840L120,840ZM452,679L512,679L512,555L636,555L636,495L512,495L512,371L452,371L452,495L328,495L328,555L452,555L452,679ZM182,780L778,780L690,525L778,270L182,270L270,525L182,780ZM480,525L480,525L480,525L480,525L480,525L480,525Z"/>
</vector>

View File

@@ -38,6 +38,7 @@
<string name="drive_now">Losfahren</string>
<string name="avoid_tolls_row_title" msgid="5194057244144831024">"Mautstraßen vermeiden"</string>
<string name="avoid_highways_row_title" msgid="4711913426200490304">"Autobahnen vermeiden"</string>
<string name="avoid_ferries">Fähren vermeiden</string>
<string name="recent_destinations">Letzte Ziele</string>
<string name="contacts">Kontakte</string>
<string name="route_preview">Route Vorschau</string>
@@ -46,20 +47,22 @@
<string name="fuel_station">Tankstelle</string>
<string name="pharmacy">Apotheke</string>
<string name="charging_station">Ladestation</string>
<string name="speed_camera">Speed camera</string>
<string name="speed_camera">Blitzer</string>
<string name="use_car_location">Auto GPS verwenden</string>
<string name="tomtom">TomTom\t</string>
<string name="options">Optionen</string>
<string name="tomtom_api_key">TomTom ApiKey</string>
<string name="use_car_settings">Verwende Auto Einstellungen</string>
<string name="exit_number">Ausfahrt nummer</string>
<string name="navigation_icon_description">Navigations Icon</string>
<string name="distance_units">Entfernungseinheiten</string>
<string name="automaticaly">Automatisch</string>
<string name="automatically">Automatisch</string>
<string name="kilometer">Kilometer</string>
<string name="miles">Meilen</string>
<string name="audio_settings">Töne</string>
<string name="muted">Stummgeschaltet</string>
<string name="unmuted">Ton an</string>
<string name="alerts_only">Nur Alarme</string>
<string name="no_categories">Keine Kategorien</string>
<string name="general">Allgemein</string>
<string name="traffic">Verkehr anzeigen</string>
</resources>

View File

@@ -17,6 +17,7 @@
<string name="stop_action_title">Διακοπή</string>
<string name="avoid_highways_row_title">Αποφυγή αυτοκινητοδρόμων</string>
<string name="avoid_tolls_row_title">Αποφυγή διοδίων</string>
<string name="avoid_ferries">Αποφυγή φέρι μποτ</string>
<string name="no_places">Δεν βρέθηκαν τοποθεσίες</string>
<string name="recent_destinations">Πρόσφατοι προορισμοί</string>
<string name="contacts">Επαφές</string>
@@ -38,11 +39,14 @@
<string name="exit_number">Αριθμός εξόδου</string>
<string name="navigation_icon_description">Εικονίδιο πλοήγησης</string>
<string name="distance_units">Μονάδες απόστασης</string>
<string name="automaticaly">Αυτόματα</string>
<string name="automatically">Αυτόματα</string>
<string name="kilometer">Χιλιόμετρα</string>
<string name="miles">Μίλια</string>
<string name="audio_settings">Φωνητική καθοδήγηση</string>
<string name="muted">Σίγαση</string>
<string name="unmuted">Ήχος ενεργός</string>
<string name="alerts_only">Μόνο ειδοποιήσεις</string>
</resources>
<string name="no_categories">Δεν υπάρχουν κατηγορίες</string>
<string name="general">Γενικά</string>
<string name="traffic">Εμφάνιση κίνησης</string>
</resources>

View File

@@ -17,6 +17,7 @@
<string name="stop_action_title">Zatrzymaj</string>
<string name="avoid_highways_row_title">Unikaj autostrad</string>
<string name="avoid_tolls_row_title">Unikaj opłat drogowych</string>
<string name="avoid_ferries">Unikaj promów</string>
<string name="no_places">Brak miejsc</string>
<string name="recent_destinations">Ostatnie cele</string>
<string name="contacts">Kontakty</string>
@@ -38,11 +39,14 @@
<string name="exit_number">Numer zjazdu</string>
<string name="navigation_icon_description">Ikona nawigacji</string>
<string name="distance_units">Jednostki odległości</string>
<string name="automaticaly">Automatycznie</string>
<string name="automatically">Automatycznie</string>
<string name="kilometer">Kilometry</string>
<string name="miles">Mile</string>
<string name="audio_settings">Wskazówki głosowe</string>
<string name="muted">Wyciszony</string>
<string name="unmuted">Dźwięk włączony</string>
<string name="alerts_only">Tylko ostrzeżenia</string>
</resources>
<string name="no_categories">Brak kategorii do wyświetlenia</string>
<string name="general">Ogólne</string>
<string name="traffic">Pokaż natężenie ruchu</string>
</resources>

View File

@@ -17,6 +17,7 @@
<string name="stop_action_title">Stop</string>
<string name="avoid_highways_row_title">Avoid highways</string>
<string name="avoid_tolls_row_title">Avoid tolls rows</string>
<string name="avoid_ferries">Avoid ferries</string>
<string name="no_places">No places</string>
<string name="recent_destinations">Recent destinations</string>
<string name="contacts">Contacts</string>
@@ -34,18 +35,21 @@
<string name="osrm" translatable="false">Osrm</string>
<string name="routing_engine" translatable="false">Routing engine</string>
<string name="use_car_location">Use car location</string>
<string name="tomtom" translatable="false">TomTom\t</string>
<string name="tomtom" translatable="false">TomTom</string>
<string name="options">Options</string>
<string name="tomtom_api_key">TomTom ApiKey</string>
<string name="use_car_settings">Use car settings</string>
<string name="exit_number">Exit number</string>
<string name="navigation_icon_description">Navigation icon</string>
<string name="distance_units">Distance units</string>
<string name="automaticaly">Automaticaly</string>
<string name="automatically">Automatically</string>
<string name="kilometer">Kilometer</string>
<string name="miles">Miles</string>
<string name="audio_settings">Guidance audio</string>
<string name="muted">Muted</string>
<string name="unmuted">Unmuted</string>
<string name="alerts_only">Alerts only</string>
<string name="no_categories">No categories to show</string>
<string name="general">General</string>
<string name="traffic">Show traffic</string>
</resources>