Serialize Json
This commit is contained in:
@@ -45,6 +45,7 @@ dependencies {
|
||||
implementation(libs.androidx.ui)
|
||||
implementation(libs.maplibre.compose)
|
||||
//implementation(libs.maplibre.composeMaterial3)
|
||||
|
||||
implementation(project(":common:data"))
|
||||
implementation(libs.androidx.runtime.livedata)
|
||||
implementation(libs.androidx.compose.foundation)
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
package com.kouros.navigation.car
|
||||
|
||||
import android.location.Location
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.graphics.vector.Path
|
||||
import androidx.compose.ui.graphics.vector.PathData
|
||||
import androidx.compose.ui.graphics.vector.VectorPainter
|
||||
import androidx.compose.ui.graphics.vector.path
|
||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.times
|
||||
import kotlinx.serialization.json.buildJsonObject
|
||||
import kotlinx.serialization.json.put
|
||||
import org.maplibre.compose.camera.CameraState
|
||||
import org.maplibre.compose.expressions.dsl.asNumber
|
||||
import org.maplibre.compose.expressions.dsl.condition
|
||||
import org.maplibre.compose.expressions.dsl.const
|
||||
import org.maplibre.compose.expressions.dsl.div
|
||||
import org.maplibre.compose.expressions.dsl.dp
|
||||
import org.maplibre.compose.expressions.dsl.feature
|
||||
import org.maplibre.compose.expressions.dsl.gt
|
||||
import org.maplibre.compose.expressions.dsl.image
|
||||
import org.maplibre.compose.expressions.dsl.minus
|
||||
import org.maplibre.compose.expressions.dsl.offset
|
||||
import org.maplibre.compose.expressions.dsl.plus
|
||||
import org.maplibre.compose.expressions.dsl.switch
|
||||
import org.maplibre.compose.expressions.value.IconRotationAlignment
|
||||
import org.maplibre.compose.expressions.value.SymbolAnchor
|
||||
import org.maplibre.compose.layers.CircleLayer
|
||||
import org.maplibre.compose.layers.SymbolLayer
|
||||
import org.maplibre.compose.location.LocationClickHandler
|
||||
import org.maplibre.compose.location.LocationPuckColors
|
||||
import org.maplibre.compose.location.LocationPuckSizes
|
||||
import org.maplibre.compose.sources.GeoJsonData
|
||||
import org.maplibre.compose.sources.GeoJsonSource
|
||||
import org.maplibre.compose.sources.rememberGeoJsonSource
|
||||
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.cos
|
||||
import kotlin.math.sin
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@Composable
|
||||
public fun LocationPuck(
|
||||
idPrefix: String,
|
||||
locationState: Location,
|
||||
cameraState: CameraState,
|
||||
oldLocationThreshold: Duration = 30.seconds,
|
||||
accuracyThreshold: Float = 50f,
|
||||
colors: LocationPuckColors = LocationPuckColors(),
|
||||
sizes: LocationPuckSizes = LocationPuckSizes(),
|
||||
showBearing: Boolean = true,
|
||||
showBearingAccuracy: Boolean = true,
|
||||
onClick: LocationClickHandler? = null,
|
||||
onLongClick: LocationClickHandler? = null,
|
||||
) {
|
||||
val bearingPainter = rememberBearingPainter(sizes, colors)
|
||||
val bearingAccuracyPainter =
|
||||
rememberBearingAccuracyPainter(
|
||||
sizes = sizes,
|
||||
colors = colors,
|
||||
bearingAccuracy = locationState.bearingAccuracyDegrees
|
||||
)
|
||||
val locationSource = rememberLocationSource(locationState)
|
||||
|
||||
CircleLayer(
|
||||
id = "$idPrefix-accuracy",
|
||||
source = locationSource,
|
||||
visible =
|
||||
accuracyThreshold <= Float.POSITIVE_INFINITY &&
|
||||
locationState.let { it.accuracy > accuracyThreshold },
|
||||
radius =
|
||||
switch(
|
||||
condition(
|
||||
test =
|
||||
feature["age"].asNumber() gt const(oldLocationThreshold.inWholeNanoseconds.toFloat()),
|
||||
output = const(0.dp),
|
||||
),
|
||||
fallback =
|
||||
(feature["accuracy"].asNumber() / const(cameraState.metersPerDpAtTarget.toFloat())).dp,
|
||||
),
|
||||
color = const(colors.accuracyFillColor),
|
||||
strokeColor = const(colors.accuracyStrokeColor),
|
||||
strokeWidth = const(sizes.accuracyStrokeWidth),
|
||||
)
|
||||
|
||||
CircleLayer(
|
||||
id = "$idPrefix-shadow",
|
||||
source = locationSource,
|
||||
visible = sizes.shadowSize > 0.dp,
|
||||
radius = const(sizes.dotRadius + sizes.dotStrokeWidth + sizes.shadowSize),
|
||||
color = const(colors.shadowColor),
|
||||
blur = const(sizes.shadowBlur),
|
||||
translate = const(DpOffset(0.dp, 1.dp)),
|
||||
)
|
||||
|
||||
CircleLayer(
|
||||
id = "$idPrefix-dot",
|
||||
source = locationSource,
|
||||
visible = true,
|
||||
radius = const(sizes.dotRadius),
|
||||
color =
|
||||
switch(
|
||||
condition(
|
||||
test =
|
||||
feature["age"].asNumber() gt const(oldLocationThreshold.inWholeNanoseconds.toFloat()),
|
||||
output = const(colors.dotFillColorOldLocation),
|
||||
),
|
||||
fallback = const(colors.dotFillColorCurrentLocation),
|
||||
),
|
||||
strokeColor = const(colors.dotStrokeColor),
|
||||
strokeWidth = const(sizes.dotStrokeWidth),
|
||||
)
|
||||
|
||||
SymbolLayer(
|
||||
id = "$idPrefix-bearing",
|
||||
source = locationSource,
|
||||
visible = showBearing,
|
||||
iconImage = image(bearingPainter),
|
||||
iconAnchor = const(SymbolAnchor.Center),
|
||||
iconRotate = feature["bearing"].asNumber(const(0f)) + const(45f),
|
||||
iconOffset =
|
||||
offset(
|
||||
-(sizes.dotRadius + sizes.dotStrokeWidth) * sqrt(2f) / 2f,
|
||||
-(sizes.dotRadius + sizes.dotStrokeWidth) * sqrt(2f) / 2f,
|
||||
),
|
||||
iconRotationAlignment = const(IconRotationAlignment.Map),
|
||||
iconAllowOverlap = const(true),
|
||||
)
|
||||
|
||||
SymbolLayer(
|
||||
id = "$idPrefix-bearingAccuracy",
|
||||
source = locationSource,
|
||||
visible =
|
||||
showBearingAccuracy,
|
||||
iconImage = image(bearingAccuracyPainter),
|
||||
iconAnchor = const(SymbolAnchor.Center),
|
||||
iconRotate =
|
||||
feature["bearing"].asNumber(const(0f)) -
|
||||
const(90f) -
|
||||
feature["bearingAccuracy"].asNumber(const(0f)),
|
||||
iconRotationAlignment = const(IconRotationAlignment.Map),
|
||||
iconAllowOverlap = const(true),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberBearingPainter(
|
||||
sizes: LocationPuckSizes,
|
||||
colors: LocationPuckColors,
|
||||
): VectorPainter {
|
||||
return rememberVectorPainter(
|
||||
defaultWidth = sizes.bearingSize,
|
||||
defaultHeight = sizes.bearingSize,
|
||||
autoMirror = false,
|
||||
) { viewportWidth, viewportHeight ->
|
||||
Path(
|
||||
pathData =
|
||||
PathData {
|
||||
moveTo(0f, 0f)
|
||||
lineTo(0f, viewportHeight)
|
||||
lineTo(viewportWidth, 0f)
|
||||
close()
|
||||
},
|
||||
fill = SolidColor(colors.bearingColor),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberBearingAccuracyPainter(
|
||||
sizes: LocationPuckSizes,
|
||||
colors: LocationPuckColors,
|
||||
bearingAccuracy: Float,
|
||||
): VectorPainter {
|
||||
val density by rememberUpdatedState(LocalDensity.current)
|
||||
|
||||
val dotRadius by rememberUpdatedState(sizes.dotRadius)
|
||||
val dotStrokeWidth by rememberUpdatedState(sizes.dotStrokeWidth)
|
||||
val bearingColor by rememberUpdatedState(colors.bearingColor)
|
||||
|
||||
val bearingAccuracy by rememberUpdatedState(bearingAccuracy)
|
||||
|
||||
val bearingAccuracyVector by remember {
|
||||
derivedStateOf {
|
||||
val radius = with(density) { Offset(dotRadius.toPx(), dotRadius.toPx()) }
|
||||
|
||||
val deltaDegrees = 2 * bearingAccuracy
|
||||
val delta = (PI * deltaDegrees / 180.0).toFloat()
|
||||
|
||||
val width = 2 * dotRadius + 2 * dotStrokeWidth
|
||||
val height = 2 * dotRadius + 2 * dotStrokeWidth
|
||||
|
||||
val center = with(density) { Offset((width / 2).toPx(), (height / 2).toPx()) }
|
||||
|
||||
val start = center + Offset(radius.x, 0f)
|
||||
val end = center + Offset(radius.x * cos(delta), radius.y * sin(delta))
|
||||
|
||||
ImageVector.Builder(
|
||||
defaultWidth = width,
|
||||
defaultHeight = height,
|
||||
viewportWidth = with(density) { width.toPx() },
|
||||
viewportHeight = with(density) { height.toPx() },
|
||||
autoMirror = false,
|
||||
)
|
||||
.apply {
|
||||
path(
|
||||
stroke = SolidColor(bearingColor),
|
||||
strokeLineWidth = with(density) { dotStrokeWidth.toPx() },
|
||||
) {
|
||||
moveTo(start.x, start.y)
|
||||
arcTo(radius.x, radius.y, 0f, delta > PI, delta > 0, end.x, end.y)
|
||||
}
|
||||
}
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
return rememberVectorPainter(bearingAccuracyVector)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberLocationSource(locationState: Location): GeoJsonSource {
|
||||
val features =
|
||||
remember(locationState) {
|
||||
val location = locationState
|
||||
FeatureCollection(
|
||||
Feature(
|
||||
geometry = Point(location.longitude, location.latitude),
|
||||
properties =
|
||||
buildJsonObject {
|
||||
put("accuracy", location.accuracy)
|
||||
put("bearing", location.bearing)
|
||||
//put("bearingAccuracy", location.bearingAccuracy)
|
||||
//put("age", location.timestamp.elapsedNow().inWholeNanoseconds)
|
||||
},
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return rememberGeoJsonSource(GeoJsonData.Features(features))
|
||||
}
|
||||
|
||||
public typealias LocationClickHandler = (org.maplibre.compose.location.Location) -> Unit
|
||||
@@ -167,14 +167,14 @@ class NavigationSession : Session() {
|
||||
}
|
||||
|
||||
fun test(location: Location?) {
|
||||
if (routeModel.isNavigating() && locationIndex < routeModel.polylineLocations.size) {
|
||||
val loc = routeModel.polylineLocations[locationIndex]
|
||||
if (routeModel.isNavigating() && locationIndex < routeModel.route.waypoints.size) {
|
||||
val loc = routeModel.route.waypoints[locationIndex]
|
||||
val curLocation = Location(LocationManager.GPS_PROVIDER)
|
||||
curLocation.longitude = loc[0]
|
||||
curLocation.latitude = loc[1]
|
||||
curLocation.longitude = loc[0] + 0.0003
|
||||
curLocation.latitude = loc[1] + 0.0002
|
||||
update(curLocation)
|
||||
locationIndex += 1
|
||||
if (locationIndex > routeModel.polylineLocations.size) {
|
||||
if (locationIndex > routeModel.route.waypoints.size) {
|
||||
val locationManager =
|
||||
carContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
locationManager.removeUpdates(mLocationListener)
|
||||
@@ -185,16 +185,10 @@ class NavigationSession : Session() {
|
||||
}
|
||||
|
||||
fun update(location: Location) {
|
||||
surfaceRenderer.updateLocation(location)
|
||||
if (routeModel.isNavigating()) {
|
||||
routeModel.updateLocation(location)
|
||||
// if (routeModel.distanceToRoute > 50) {
|
||||
// routeModel.stopNavigation()
|
||||
// locationIndex = 0
|
||||
// surfaceRenderer.setRouteData()
|
||||
// navigationScreen.reRoute()
|
||||
// }
|
||||
navigationScreen.updateTrip()
|
||||
}
|
||||
surfaceRenderer.updateLocation(location)
|
||||
}
|
||||
}
|
||||
@@ -26,17 +26,17 @@ import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.setViewTreeLifecycleOwner
|
||||
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.utils.NavigationUtils
|
||||
import com.kouros.navigation.utils.NavigationUtils.snapLocation
|
||||
import com.kouros.navigation.utils.calculateZoom
|
||||
import org.maplibre.compose.camera.CameraPosition
|
||||
import org.maplibre.compose.camera.rememberCameraState
|
||||
import org.maplibre.compose.expressions.dsl.const
|
||||
import org.maplibre.compose.layers.FillLayer
|
||||
import org.maplibre.compose.layers.LineLayer
|
||||
import org.maplibre.compose.location.LocationPuck
|
||||
import org.maplibre.compose.location.LocationPuckColors
|
||||
import org.maplibre.compose.location.rememberDefaultLocationProvider
|
||||
import org.maplibre.compose.location.rememberUserLocationState
|
||||
import org.maplibre.compose.location.LocationPuckSizes
|
||||
import org.maplibre.compose.map.MaplibreMap
|
||||
import org.maplibre.compose.sources.GeoJsonData
|
||||
import org.maplibre.compose.sources.getBaseSource
|
||||
@@ -63,11 +63,12 @@ class SurfaceRenderer(
|
||||
|
||||
val previewRouteData = MutableLiveData("")
|
||||
|
||||
lateinit var centerLocation : Location
|
||||
lateinit var centerLocation: Location
|
||||
var preview = false
|
||||
|
||||
lateinit var mapView: ComposeView
|
||||
|
||||
var panView = false
|
||||
val tilt = 55.0
|
||||
val padding = PaddingValues(start = 150.dp, top = 250.dp)
|
||||
|
||||
@@ -154,8 +155,6 @@ class SurfaceRenderer(
|
||||
|
||||
@Composable
|
||||
fun MapView() {
|
||||
val locationProvider = rememberDefaultLocationProvider()
|
||||
val locationState = rememberUserLocationState(locationProvider)
|
||||
val position: CameraPosition? by cameraPosition.observeAsState()
|
||||
val route: String? by routeData.observeAsState()
|
||||
val previewRoute: String? by previewRouteData.observeAsState()
|
||||
@@ -174,18 +173,19 @@ class SurfaceRenderer(
|
||||
)
|
||||
MaplibreMap(
|
||||
cameraState = cameraState,
|
||||
//baseStyle = BaseStyle.Uri("https://tiles.openfreemap.org/styles/liberty"),
|
||||
baseStyle = BaseStyle.Uri("https://kouros-online.de/liberty"),
|
||||
baseStyle = BaseStyle.Uri(Constants.STYLE),
|
||||
) {
|
||||
getBaseSource(id = "openmaptiles")?.let { tiles ->
|
||||
FillLayer(id = "example", visible = false, source = tiles, sourceLayer = "building")
|
||||
RouteLayer(route, previewRoute)
|
||||
}
|
||||
|
||||
LocationPuck(
|
||||
idPrefix = "user-location",
|
||||
locationState = locationState,
|
||||
locationState = lastLocation,
|
||||
cameraState = cameraState,
|
||||
accuracyThreshold = 10f,
|
||||
sizes = LocationPuckSizes(dotRadius = 10.dp),
|
||||
colors = LocationPuckColors(accuracyStrokeColor = Color.Green)
|
||||
)
|
||||
}
|
||||
@@ -264,6 +264,7 @@ class SurfaceRenderer(
|
||||
/** Handles the map zoom-in and zoom-out events. */
|
||||
fun handleScale(zoomSign: Int) {
|
||||
synchronized(this) {
|
||||
panView = true
|
||||
val newZoom = if (zoomSign < 0) {
|
||||
cameraPosition.value!!.zoom - 1.0
|
||||
} else {
|
||||
@@ -281,27 +282,33 @@ class SurfaceRenderer(
|
||||
fun updateLocation(location: Location) {
|
||||
synchronized(this) {
|
||||
if (!preview) {
|
||||
var snapedLocation = location
|
||||
var bearing: Double
|
||||
if (routeModel.isNavigating()) {
|
||||
snapedLocation = snapLocation(location, routeModel.maneuverLocations())
|
||||
bearing = routeModel.currentStep().bearing
|
||||
} else {
|
||||
bearing = cameraPosition.value!!.bearing
|
||||
if (lastLocation.latitude != location.latitude) {
|
||||
if (lastLocation.distanceTo(location) > 5) {
|
||||
bearing = lastLocation.bearingTo(location).toDouble()
|
||||
if (lastLocation.latitude != snapedLocation.latitude) {
|
||||
if (lastLocation.distanceTo(snapedLocation) > 5) {
|
||||
bearing = lastLocation.bearingTo(snapedLocation).toDouble()
|
||||
}
|
||||
}
|
||||
}
|
||||
val zoom = NavigationUtils().calculateZoom(location.speed.toDouble())
|
||||
val zoom = if (!panView) {
|
||||
calculateZoom(snapedLocation.speed.toDouble())
|
||||
} else {
|
||||
cameraPosition.value!!.zoom
|
||||
}
|
||||
cameraPosition.postValue(
|
||||
cameraPosition.value!!.copy(
|
||||
bearing = bearing,
|
||||
zoom = zoom,
|
||||
padding = getPaddingValues(),
|
||||
target = Position(location.longitude, location.latitude),
|
||||
target = Position(snapedLocation.longitude, snapedLocation.latitude),
|
||||
)
|
||||
)
|
||||
lastLocation = location
|
||||
lastLocation = snapedLocation
|
||||
} else {
|
||||
val bearing = 0.0
|
||||
val zoom = 11.0
|
||||
@@ -319,12 +326,13 @@ class SurfaceRenderer(
|
||||
|
||||
|
||||
fun setRouteData() {
|
||||
routeData.value = routeModel.route
|
||||
routeData.value = routeModel.route.routeGeoJson
|
||||
preview = false
|
||||
panView = false
|
||||
}
|
||||
|
||||
fun setPreviewRouteData(routeModel: RouteModel) {
|
||||
previewRouteData.value = routeModel.route
|
||||
previewRouteData.value = routeModel.route.routeGeoJson
|
||||
centerLocation = routeModel.centerLocation
|
||||
preview = true
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ class RouteCarModel() : RouteModel() {
|
||||
|
||||
/** Returns the current [Step] with information such as the cue text and images. */
|
||||
fun currentStep(carContext: CarContext): Step {
|
||||
val maneuver = (maneuvers[maneuverIndex] as JSONObject)
|
||||
val maneuverType = maneuver.getInt("type")
|
||||
val maneuver = route.currentManeuver()
|
||||
val maneuverType = maneuver.type
|
||||
|
||||
val stepData = currentStep()
|
||||
|
||||
@@ -53,9 +53,9 @@ class RouteCarModel() : RouteModel() {
|
||||
}
|
||||
when (stepData.leftDistance) {
|
||||
in 0.0..100.0 -> {
|
||||
if (maneuverIndex < maneuvers.length()) {
|
||||
val maneuver = (maneuvers[maneuverIndex + 1] as JSONObject)
|
||||
val maneuverType = maneuver.getInt("type")
|
||||
if (route.currentIndex < route.maneuvers.size) {
|
||||
val maneuver = route.nextManeuver()
|
||||
val maneuverType = maneuver.type
|
||||
routing = routingData(maneuverType, carContext)
|
||||
}
|
||||
}
|
||||
@@ -77,22 +77,22 @@ class RouteCarModel() : RouteModel() {
|
||||
|
||||
/** Returns the next [Step] with information such as the cue text and images. */
|
||||
fun nextStep(carContext: CarContext): Step {
|
||||
val maneuver = (maneuvers[maneuverIndex + 1] as JSONObject)
|
||||
val maneuverType = maneuver.getInt("type")
|
||||
val maneuver = route.nextManeuver()
|
||||
val maneuverType = maneuver.type
|
||||
val routing = routingData(maneuverType, carContext)
|
||||
var text = ""
|
||||
val distanceLeft = leftStepDistance() * 1000
|
||||
|
||||
when (distanceLeft) {
|
||||
in 0.0..100.0 -> {
|
||||
if (maneuver.optJSONArray("street_names") != null) {
|
||||
text = maneuver.getJSONArray("street_names").get(0) as String
|
||||
if (maneuver.streetNames != null && maneuver.streetNames!!.isNotEmpty()) {
|
||||
text = maneuver.streetNames!![0]
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
if (maneuver.optJSONArray("street_names") != null) {
|
||||
text = maneuver.getJSONArray("street_names").get(0) as String
|
||||
if (maneuver.streetNames != null && maneuver.streetNames!!.isNotEmpty()) {
|
||||
text = maneuver.streetNames!![0]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,40 +113,42 @@ class RouteCarModel() : RouteModel() {
|
||||
var type = Maneuver.TYPE_DEPART
|
||||
var currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_name_change)
|
||||
when (routeManeuverType) {
|
||||
ManeuverType.Destination.value,
|
||||
ManeuverType.DestinationLeft.value,
|
||||
ManeuverType.DestinationRight.value
|
||||
-> {
|
||||
type = Maneuver.TYPE_DESTINATION
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_destination)
|
||||
}
|
||||
|
||||
ManeuverType.None.value -> {
|
||||
type = Maneuver.TYPE_STRAIGHT
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_name_change)
|
||||
}
|
||||
|
||||
ManeuverType.Destination.value,
|
||||
ManeuverType.DestinationRight.value,
|
||||
ManeuverType.DestinationLeft.value,
|
||||
-> {
|
||||
type = Maneuver.TYPE_DESTINATION
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_destination)
|
||||
}
|
||||
ManeuverType.Right.value -> {
|
||||
type = Maneuver.TYPE_TURN_NORMAL_RIGHT
|
||||
// currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_normal_right)
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.turn_right_48px1)
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_normal_right)
|
||||
}
|
||||
|
||||
ManeuverType.Left.value -> {
|
||||
type = Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_normal_left)
|
||||
}
|
||||
|
||||
ManeuverType.RampRight.value -> {
|
||||
type = Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_slight_right)
|
||||
}
|
||||
ManeuverType.RampLeft.value -> {
|
||||
type = Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_normal_left)
|
||||
}
|
||||
|
||||
ManeuverType.ExitRight.value -> {
|
||||
type = Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_slight_right)
|
||||
}
|
||||
|
||||
ManeuverType.StayRight.value -> {
|
||||
type = Maneuver.TYPE_KEEP_RIGHT
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_name_change)
|
||||
}
|
||||
ManeuverType.StayLeft.value -> {
|
||||
type = Maneuver.TYPE_KEEP_LEFT
|
||||
currentTurnIcon = createCarIcon(carContext, R.drawable.ic_turn_name_change)
|
||||
|
||||
@@ -51,7 +51,6 @@ class NavigationScreen(
|
||||
}
|
||||
|
||||
override fun onGetTemplate(): Template {
|
||||
// Log.i(TAG, "onGetTemplate NavigationScreen")
|
||||
val actionStripBuilder: ActionStrip.Builder = ActionStrip.Builder()
|
||||
actionStripBuilder.addAction(
|
||||
Action.Builder()
|
||||
@@ -149,7 +148,7 @@ class NavigationScreen(
|
||||
}
|
||||
return RoutingInfo.Builder()
|
||||
.setCurrentStep(
|
||||
routeModel.currentStep(carContext = carContext),
|
||||
routeModel.currentStep(carContext = carContext),
|
||||
Distance.create(currentDistance, displayUnit)
|
||||
)
|
||||
.setNextStep(routeModel.nextStep(carContext = carContext))
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.location.Location
|
||||
import android.net.Uri
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.util.Log
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
@@ -22,6 +23,7 @@ import com.kouros.android.cars.carappservice.R
|
||||
import com.kouros.navigation.car.SurfaceRenderer
|
||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Constants.TAG
|
||||
import com.kouros.navigation.data.NavigationRepository
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.model.ViewModel
|
||||
|
||||
@@ -49,7 +49,6 @@ import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.model.ViewModel
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/** Creates a screen using the new [androidx.car.app.navigation.model.MapWithContentTemplate] */
|
||||
class RoutePreviewScreen(
|
||||
@@ -110,7 +109,7 @@ class RoutePreviewScreen(
|
||||
|
||||
val itemListBuilder = ItemList.Builder()
|
||||
|
||||
if (routeModel.polylineLocations.isNotEmpty()) {
|
||||
if (routeModel.isNavigating() && routeModel.route.waypoints.isNotEmpty()) {
|
||||
itemListBuilder.addItem(createRow(0, navigateAction))
|
||||
}
|
||||
|
||||
@@ -201,9 +200,8 @@ class RoutePreviewScreen(
|
||||
|
||||
|
||||
private fun createRouteText(index: Int): CarText {
|
||||
val time = routeModel.routeTime
|
||||
|
||||
val length = BigDecimal(routeModel.routeDistance).setScale(1, RoundingMode.HALF_EVEN)
|
||||
val time = routeModel.route.summary.time
|
||||
val length = BigDecimal(routeModel.route.distance).setScale(1, RoundingMode.HALF_EVEN)
|
||||
val firstRoute = SpannableString(" \u00b7 $length km")
|
||||
firstRoute.setSpan(
|
||||
DurationSpan.create(time.toLong()), 0, 1,0
|
||||
|
||||
@@ -17,7 +17,7 @@ import com.kouros.navigation.car.SurfaceRenderer
|
||||
import com.kouros.navigation.data.Category
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Place
|
||||
import com.kouros.navigation.utils.NavigationUtils.Utils.getBoundingBox
|
||||
import com.kouros.navigation.utils.NavigationUtils.getBoundingBox
|
||||
|
||||
|
||||
class SearchScreen(
|
||||
@@ -42,8 +42,6 @@ class SearchScreen(
|
||||
|
||||
val searchItemListBuilder = ItemList.Builder()
|
||||
.setNoItemsMessage("No search results to show")
|
||||
|
||||
println("OnGetTemplate SearchScreen ${categories.size}")
|
||||
if (!isSearching) {
|
||||
categories.forEach {
|
||||
it.name
|
||||
@@ -111,7 +109,7 @@ class SearchScreen(
|
||||
|
||||
geocoder.getFromLocationName(
|
||||
searchText, 5,
|
||||
lowerLeftLat, lowerLeftLon, upperRightLat, upperRightLon
|
||||
//lowerLeftLat, lowerLeftLon, upperRightLat, upperRightLon
|
||||
) {
|
||||
for (address in it) {
|
||||
val name: String = address.getAddressLine(0)
|
||||
@@ -145,7 +143,6 @@ class SearchScreen(
|
||||
isSearching = false
|
||||
}
|
||||
val itemList = searchItemListBuilder.build()
|
||||
println("Searching ${itemList.items.size}")
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user