This commit is contained in:
Dimitris
2026-03-30 09:18:04 +02:00
parent 8ca450cd10
commit bd8a497fbe
7 changed files with 63 additions and 46 deletions
@@ -80,7 +80,10 @@ class SurfaceRenderer(
val cameraPosition = MutableLiveData( val cameraPosition = MutableLiveData(
CameraPosition( CameraPosition(
zoom = 16.0, zoom = 16.0,
target = Position(latitude = homeVogelhart.latitude, longitude = homeVogelhart.longitude) target = Position(
latitude = homeVogelhart.latitude,
longitude = homeVogelhart.longitude
)
) )
) )
@@ -261,12 +264,13 @@ class SurfaceRenderer(
*/ */
@Composable @Composable
fun MapView() { fun MapView() {
val darkMode =
val darkMode = settingsViewModel(carContext, viewModelStoreOwner).darkMode.collectAsState().value settingsViewModel(carContext, viewModelStoreOwner).darkMode.collectAsState().value
val showBuildings = settingsViewModel(carContext, viewModelStoreOwner).show3D.collectAsState().value val showBuildings =
settingsViewModel(carContext, viewModelStoreOwner).show3D.collectAsState().value
val position: CameraPosition? by cameraPosition.observeAsState() val position: CameraPosition? by cameraPosition.observeAsState()
val route: String? by routeData.observeAsState() val route: String? by routeData.observeAsState()
val traffic: Map<String, String> ? by trafficData.observeAsState() val traffic: Map<String, String>? by trafficData.observeAsState()
val speedCameras: String? by speedCamerasData.observeAsState() val speedCameras: String? by speedCamerasData.observeAsState()
val paddingValues = getPaddingValues(height, viewStyle) val paddingValues = getPaddingValues(height, viewStyle)
val cameraState = cameraState(paddingValues, position, tilt) val cameraState = cameraState(paddingValues, position, tilt)
@@ -297,7 +301,12 @@ class SurfaceRenderer(
darkMode: Boolean darkMode: Boolean
) { ) {
val cameraDuration = val cameraDuration =
duration(viewStyle == ViewStyle.PREVIEW, position!!.bearing, lastBearing, lastLocationUpdate) duration(
viewStyle == ViewStyle.PREVIEW,
position!!.bearing,
lastBearing,
lastLocationUpdate
)
val currentSpeed: Float? by speed.observeAsState() val currentSpeed: Float? by speed.observeAsState()
val maximumSpeed: Int? by maxSpeed.observeAsState() val maximumSpeed: Int? by maxSpeed.observeAsState()
val streetName: String? by street.observeAsState() val streetName: String? by street.observeAsState()
@@ -328,7 +337,7 @@ class SurfaceRenderer(
} }
override fun onCreate(owner: LifecycleOwner) { override fun onCreate(owner: LifecycleOwner) {
style.observe(owner, :: onBaseStyleStateUpdated) style.observe(owner, ::onBaseStyleStateUpdated)
Log.i(TAG, "SurfaceRenderer created") Log.i(TAG, "SurfaceRenderer created")
carContext.getCarService(AppManager::class.java) carContext.getCarService(AppManager::class.java)
.setSurfaceCallback(mSurfaceCallback) .setSurfaceCallback(mSurfaceCallback)
@@ -348,7 +357,9 @@ class SurfaceRenderer(
} else { } else {
cameraPosition.value!!.zoom + 1.0 cameraPosition.value!!.zoom + 1.0
} }
if (viewStyle == ViewStyle.VIEW) {
tilt = calculateTilt(newZoom, tilt) tilt = calculateTilt(newZoom, tilt)
}
updateCameraPosition( updateCameraPosition(
cameraPosition.value!!.bearing, cameraPosition.value!!.bearing,
newZoom, newZoom,
@@ -362,7 +373,7 @@ class SurfaceRenderer(
* Calculates appropriate bearing, zoom, and maintains view style. * Calculates appropriate bearing, zoom, and maintains view style.
* Uses car orientation sensor if available, otherwise falls back to location bearing. * Uses car orientation sensor if available, otherwise falls back to location bearing.
*/ */
fun updateLocation(location: Location, streetName : String) { fun updateLocation(location: Location, streetName: String) {
synchronized(this) { synchronized(this) {
street.value = streetName street.value = streetName
if (viewStyle == ViewStyle.VIEW || viewStyle == ViewStyle.PAN_VIEW) { if (viewStyle == ViewStyle.VIEW || viewStyle == ViewStyle.PAN_VIEW) {
@@ -416,7 +427,7 @@ class SurfaceRenderer(
* Updates camera position with new bearing, zoom, and target. * Updates camera position with new bearing, zoom, and target.
* Posts update to LiveData for UI observation. * Posts update to LiveData for UI observation.
*/ */
fun updateCameraPosition(bearing: Double, zoom: Double, target: Position, tilt: Double) { fun updateCameraPosition(bearing: Double = 0.0, zoom: Double, target: Position, tilt: Double) {
synchronized(this) { synchronized(this) {
cameraPosition.postValue( cameraPosition.postValue(
cameraPosition.value!!.copy( cameraPosition.value!!.copy(
@@ -433,7 +444,7 @@ class SurfaceRenderer(
/** /**
* Updates traffic incident data on the map. * Updates traffic incident data on the map.
*/ */
fun setTrafficData(traffic: Map<String, String> ) { fun setTrafficData(traffic: Map<String, String>) {
trafficData.value = traffic as MutableMap<String, String>? trafficData.value = traffic as MutableMap<String, String>?
} }
@@ -455,7 +466,22 @@ class SurfaceRenderer(
Position(centerLocation.longitude, centerLocation.latitude), 0.0 Position(centerLocation.longitude, centerLocation.latitude), 0.0
) )
}
/**
* Sets up standard view mode with camera position.
* Calculates appropriate zoom
*/
fun setStandardView() {
viewStyle = ViewStyle.VIEW
setRouteData("")
val zoom = calculateZoom(0.0)
tilt = calculateTilt(zoom, tilt)
updateCameraPosition(
tilt = tilt,
zoom = zoom,
target = Position(lastLocation.longitude, lastLocation.latitude)
)
} }
/** /**
@@ -465,10 +491,11 @@ class SurfaceRenderer(
synchronized(this) { synchronized(this) {
viewStyle = ViewStyle.AMENITY_VIEW viewStyle = ViewStyle.AMENITY_VIEW
routeData.value = route routeData.value = route
tilt = 0.0
updateCameraPosition( updateCameraPosition(
0.0, zoom = 14.0,
14.0, target = Position(location.longitude, location.latitude),
target = Position(location.longitude, location.latitude), tilt tilt = tilt
) )
} }
} }
@@ -33,6 +33,7 @@ import com.kouros.navigation.data.RouteColor
import com.kouros.navigation.data.SpeedColor import com.kouros.navigation.data.SpeedColor
import com.kouros.navigation.data.ViewStyle import com.kouros.navigation.data.ViewStyle
import com.kouros.navigation.utils.isMetricSystem import com.kouros.navigation.utils.isMetricSystem
import com.kouros.navigation.utils.location
import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.CameraPosition
import org.maplibre.compose.camera.CameraState import org.maplibre.compose.camera.CameraState
import org.maplibre.compose.camera.rememberCameraState import org.maplibre.compose.camera.rememberCameraState
@@ -60,6 +61,7 @@ import org.maplibre.compose.sources.getBaseSource
import org.maplibre.compose.sources.rememberGeoJsonSource import org.maplibre.compose.sources.rememberGeoJsonSource
import org.maplibre.compose.style.BaseStyle import org.maplibre.compose.style.BaseStyle
import org.maplibre.spatialk.geojson.Position import org.maplibre.spatialk.geojson.Position
import kotlin.time.Duration.Companion.seconds
@Composable @Composable
@@ -105,6 +107,8 @@ fun MapLibre(
BuildingLayer(tiles) BuildingLayer(tiles)
} }
if (viewStyle == ViewStyle.AMENITY_VIEW) { if (viewStyle == ViewStyle.AMENITY_VIEW) {
val lastLocation = location(cameraState.position.target.longitude, cameraState.position.target.latitude)
Puck(cameraState, lastLocation)
AmenityLayer(route) AmenityLayer(route)
} else { } else {
RouteLayer(route, traffic!!) RouteLayer(route, traffic!!)
@@ -112,8 +116,7 @@ fun MapLibre(
} }
SpeedCameraLayer(speedCameras) SpeedCameraLayer(speedCameras)
} }
//val lastLocation = location(cameraState.position.target.longitude, cameraState.position.target.latitude)
//Puck(cameraState, lastLocation)
} }
} }
@@ -573,22 +576,7 @@ fun Puck(cameraState: CameraState, location: Location) {
locationState = location, locationState = location,
cameraState = cameraState, cameraState = cameraState,
accuracyThreshold = 10f, accuracyThreshold = 10f,
showBearing = false, oldLocationThreshold = 2.seconds,
sizes = LocationPuckSizes(dotRadius = 10.dp),
colors = LocationPuckColors(
dotFillColorCurrentLocation = Color.Cyan,
accuracyStrokeColor = Color.Green
)
)
}
@Composable
fun PuckState(cameraState: CameraState, userLocationState: UserLocationState) {
LocationPuck(
idPrefix = "user-location1",
locationState = userLocationState,
cameraState = cameraState,
accuracyThreshold = 10f,
showBearing = false, showBearing = false,
sizes = LocationPuckSizes(dotRadius = 10.dp), sizes = LocationPuckSizes(dotRadius = 10.dp),
colors = LocationPuckColors( colors = LocationPuckColors(
@@ -320,7 +320,7 @@ open class NavigationScreen(
return NavigationTemplate.Builder() return NavigationTemplate.Builder()
.setNavigationInfo(RoutingInfo.Builder().setLoading(true).build()) .setNavigationInfo(RoutingInfo.Builder().setLoading(true).build())
.setActionStrip(actionStripBuilder.build()) .setActionStrip(actionStripBuilder.build())
// .setBackgroundColor(routeModel.backGroundColor()) .setBackgroundColor(backGroundColor)
.build() .build()
} }
@@ -28,6 +28,7 @@ import com.kouros.navigation.data.Constants.CONTACTS
import com.kouros.navigation.data.Constants.FAVORITES import com.kouros.navigation.data.Constants.FAVORITES
import com.kouros.navigation.data.Constants.RECENT import com.kouros.navigation.data.Constants.RECENT
import com.kouros.navigation.data.Place import com.kouros.navigation.data.Place
import com.kouros.navigation.data.ViewStyle
import com.kouros.navigation.model.NavigationViewModel import com.kouros.navigation.model.NavigationViewModel
import com.kouros.navigation.utils.getSettingsRepository import com.kouros.navigation.utils.getSettingsRepository
@@ -5,7 +5,6 @@ import android.text.SpannableStringBuilder
import android.text.Spanned import android.text.Spanned
import android.util.Log import android.util.Log
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.annotation.DrawableRes
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
@@ -13,7 +12,6 @@ import androidx.car.app.constraints.ConstraintManager
import androidx.car.app.model.Action import androidx.car.app.model.Action
import androidx.car.app.model.Action.FLAG_DEFAULT import androidx.car.app.model.Action.FLAG_DEFAULT
import androidx.car.app.model.Action.FLAG_IS_PERSISTENT import androidx.car.app.model.Action.FLAG_IS_PERSISTENT
import androidx.car.app.model.ActionStrip
import androidx.car.app.model.CarColor import androidx.car.app.model.CarColor
import androidx.car.app.model.CarIcon import androidx.car.app.model.CarIcon
import androidx.car.app.model.CarText import androidx.car.app.model.CarText
@@ -37,6 +35,7 @@ import androidx.lifecycle.lifecycleScope
import com.kouros.data.R import com.kouros.data.R
import com.kouros.navigation.car.SurfaceRenderer import com.kouros.navigation.car.SurfaceRenderer
import com.kouros.navigation.car.navigation.RouteCarModel import com.kouros.navigation.car.navigation.RouteCarModel
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.data.route.Routes import com.kouros.navigation.data.route.Routes
@@ -74,7 +73,6 @@ class RoutePreviewScreen(
private val backPressedCallback = object : OnBackPressedCallback(false) { private val backPressedCallback = object : OnBackPressedCallback(false) {
override fun handleOnBackPressed() { override fun handleOnBackPressed() {
invalidate()
} }
} }
@@ -141,10 +139,10 @@ class RoutePreviewScreen(
} }
} }
val street = if (destination.street.isNullOrEmpty()) { val street = if (destination.street.isEmpty()) {
carContext.getString((R.string.route_preview)) carContext.getString((R.string.route_preview))
} else { } else {
destination.street.toString() destination.street
} }
val header = Header.Builder() val header = Header.Builder()
.setStartHeaderAction(Action.BACK) .setStartHeaderAction(Action.BACK)
@@ -79,7 +79,7 @@ class SearchScreen(
navigationViewModel navigationViewModel
) )
) { obj: Any? -> ) { obj: Any? ->
surfaceRenderer.viewStyle = ViewStyle.VIEW surfaceRenderer.setStandardView()
if (obj != null) { if (obj != null) {
setResult(obj) setResult(obj)
finish() finish()
@@ -96,7 +96,7 @@ class SearchScreen(
recentPlaces recentPlaces
) )
) { obj: Any? -> ) { obj: Any? ->
surfaceRenderer.viewStyle = ViewStyle.VIEW surfaceRenderer.setStandardView()
if (obj != null) { if (obj != null) {
setResult(obj) setResult(obj)
finish() finish()
@@ -143,9 +143,12 @@ fun duration(
val cameraDuration = if ((lastBearing - bearing).absoluteValue > 20.0) { val cameraDuration = if ((lastBearing - bearing).absoluteValue > 20.0) {
2.seconds 2.seconds
} else { } else {
3.seconds val updateDuration = java.time.Duration.between(LocalDateTime.now(), lastLocationUpdate)
//val updateDuration = java.time.Duration.between(LocalDateTime.now(), lastLocationUpdate) if (updateDuration.toMillis().absoluteValue < 1000) {
//((updateDuration!!.toMillis().absoluteValue * 1.2).toDuration(DurationUnit.MILLISECONDS)) 2.seconds
} else {
((updateDuration!!.toMillis().absoluteValue * 1.2).toDuration(DurationUnit.MILLISECONDS))
}
} }
return cameraDuration return cameraDuration
} }