Refactoring Route, Speed
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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<BaseStyle.Uri>,
|
||||
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()) {
|
||||
|
||||
@@ -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<String> { 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<Elements>()
|
||||
val speedObserver = Observer<List<Elements>> { cameras ->
|
||||
speedCameras = cameras
|
||||
|
||||
val coordinates = mutableListOf<List<Double>>()
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -52,7 +52,7 @@ class RoutePreviewScreen(
|
||||
val navigationMessage = NavigationMessage(carContext)
|
||||
val observer = Observer<String> { route ->
|
||||
if (route.isNotEmpty()) {
|
||||
routeModel.startNavigation(route)
|
||||
routeModel.startNavigation(route, carContext)
|
||||
surfaceRenderer.setPreviewRouteData(routeModel)
|
||||
invalidate()
|
||||
}
|
||||
|
||||
@@ -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="M190,840L160,810L480,80L800,810L770,840L480,708L190,840Z"/>
|
||||
</vector>
|
||||
Reference in New Issue
Block a user