Settings
This commit is contained in:
@@ -66,6 +66,8 @@ import org.koin.androidx.compose.koinViewModel
|
||||
import org.maplibre.compose.camera.CameraPosition
|
||||
import org.maplibre.compose.camera.rememberCameraState
|
||||
import org.maplibre.compose.expressions.dsl.const
|
||||
import org.maplibre.compose.layers.Anchor
|
||||
import org.maplibre.compose.layers.CircleLayer
|
||||
import org.maplibre.compose.layers.FillLayer
|
||||
import org.maplibre.compose.layers.LineLayer
|
||||
import org.maplibre.compose.location.DesiredAccuracy
|
||||
@@ -375,7 +377,7 @@ class MainActivity : ComponentActivity() {
|
||||
var snapedLocation = location
|
||||
var bearing: Double
|
||||
if (routeModel.isNavigating()) {
|
||||
snapedLocation = snapLocation(location, routeModel.maneuverLocations())
|
||||
snapedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
||||
bearing = routeModel.currentStep().bearing
|
||||
routeModel.updateLocation(snapedLocation)
|
||||
instruction.value = routeModel.currentStep()
|
||||
|
||||
@@ -35,7 +35,7 @@ class NavigationSession : Session() {
|
||||
lateinit var surfaceRenderer: SurfaceRenderer
|
||||
var locationIndex = 0
|
||||
|
||||
val test = false
|
||||
val test = true
|
||||
|
||||
var mLocationListener: LocationListenerCompat = LocationListenerCompat { location: Location? ->
|
||||
updateLocation(location)
|
||||
|
||||
@@ -27,18 +27,22 @@ 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.data.Constants.SHOW_THREED_BUILDING
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue
|
||||
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.Anchor
|
||||
import org.maplibre.compose.layers.FillLayer
|
||||
import org.maplibre.compose.layers.LineLayer
|
||||
import org.maplibre.compose.location.LocationPuckColors
|
||||
import org.maplibre.compose.location.LocationPuckSizes
|
||||
import org.maplibre.compose.map.MaplibreMap
|
||||
import org.maplibre.compose.sources.GeoJsonData
|
||||
import org.maplibre.compose.sources.Source
|
||||
import org.maplibre.compose.sources.getBaseSource
|
||||
import org.maplibre.compose.sources.rememberGeoJsonSource
|
||||
import org.maplibre.compose.style.BaseStyle
|
||||
@@ -176,7 +180,7 @@ class SurfaceRenderer(
|
||||
baseStyle = BaseStyle.Uri(Constants.STYLE),
|
||||
) {
|
||||
getBaseSource(id = "openmaptiles")?.let { tiles ->
|
||||
FillLayer(id = "example", visible = false, source = tiles, sourceLayer = "building")
|
||||
BuildingLayer(tiles)
|
||||
RouteLayer(route, previewRoute)
|
||||
}
|
||||
|
||||
@@ -219,6 +223,20 @@ class SurfaceRenderer(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BuildingLayer(tiles: Source) {
|
||||
if (!getBooleanKeyValue(context = mCarContext, SHOW_THREED_BUILDING)) {
|
||||
Anchor.Replace("building-3d") {
|
||||
FillLayer(
|
||||
id = "remove-building",
|
||||
visible = false,
|
||||
source = tiles,
|
||||
sourceLayer = "building"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RouteLayer(routeData: String?, previewRoute: String?) {
|
||||
if (routeData!!.isNotEmpty()) {
|
||||
@@ -285,7 +303,7 @@ class SurfaceRenderer(
|
||||
var snapedLocation = location
|
||||
var bearing: Double
|
||||
if (routeModel.isNavigating()) {
|
||||
snapedLocation = snapLocation(location, routeModel.maneuverLocations())
|
||||
snapedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
||||
bearing = routeModel.currentStep().bearing
|
||||
} else {
|
||||
bearing = cameraPosition.value!!.bearing
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.Header
|
||||
import androidx.car.app.model.ItemList
|
||||
import androidx.car.app.model.ListTemplate
|
||||
import androidx.car.app.model.Row
|
||||
import androidx.car.app.model.Template
|
||||
import androidx.car.app.model.Toggle
|
||||
import com.kouros.android.cars.carappservice.R
|
||||
import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING
|
||||
import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue
|
||||
import com.kouros.navigation.utils.NavigationUtils.setBooleanKeyValue
|
||||
|
||||
class DisplaySettings(private val carContext: CarContext) : Screen(carContext) {
|
||||
|
||||
private var buildingToggleState = false
|
||||
|
||||
init {
|
||||
buildingToggleState = getBooleanKeyValue(carContext, SHOW_THREED_BUILDING)
|
||||
}
|
||||
|
||||
override fun onGetTemplate(): Template {
|
||||
val listBuilder = ItemList.Builder()
|
||||
val buildingToggle: Toggle =
|
||||
Toggle.Builder { checked: Boolean ->
|
||||
if (checked) {
|
||||
setBooleanKeyValue(carContext, true, SHOW_THREED_BUILDING)
|
||||
} else {
|
||||
setBooleanKeyValue(carContext, false, SHOW_THREED_BUILDING)
|
||||
}
|
||||
buildingToggleState = !buildingToggleState
|
||||
}.setChecked(buildingToggleState).build()
|
||||
listBuilder.addItem(buildRowForTemplate(R.string.threed_building, buildingToggle))
|
||||
|
||||
return ListTemplate.Builder()
|
||||
.setSingleList(listBuilder.build())
|
||||
.setHeader(
|
||||
Header.Builder()
|
||||
.setTitle(carContext.getString(R.string.content_limits))
|
||||
.setStartHeaderAction(Action.BACK)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
||||
private fun buildRowForTemplate(title: Int, toggle: Toggle): Row {
|
||||
return Row.Builder()
|
||||
.setTitle(carContext.getString(title))
|
||||
.setToggle(toggle)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,15 @@ class NavigationScreen(
|
||||
//.setFlags(Action.FLAG_IS_PERSISTENT)
|
||||
.build()
|
||||
)
|
||||
actionStripBuilder.addAction(
|
||||
Action.Builder()
|
||||
.setIcon(routeModel.createCarIcon(carContext, R.drawable.ic_favorite_white_24dp))
|
||||
.setOnClickListener {
|
||||
screenManager.push(SettingsScreen(carContext))
|
||||
}
|
||||
//.setFlags(Action.FLAG_IS_PERSISTENT)
|
||||
.build()
|
||||
)
|
||||
return if (routeModel.isNavigating()) {
|
||||
getNavigationTemplate(actionStripBuilder)
|
||||
} else {
|
||||
@@ -187,6 +196,24 @@ class NavigationScreen(
|
||||
surfaceRenderer.handleScale(-1)
|
||||
}
|
||||
.build())
|
||||
if (surfaceRenderer.panView)
|
||||
{
|
||||
actionStripBuilder.addAction(
|
||||
Action.Builder()
|
||||
.setIcon(
|
||||
CarIcon.Builder(
|
||||
IconCompat.createWithResource(
|
||||
carContext,
|
||||
R.drawable.ic_pan_24
|
||||
)
|
||||
)
|
||||
.build()
|
||||
).setOnClickListener {
|
||||
surfaceRenderer.panView = false
|
||||
}
|
||||
.build()
|
||||
)
|
||||
}
|
||||
return actionStripBuilder
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.kouros.navigation.car.screen
|
||||
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.constraints.ConstraintManager
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.Header
|
||||
import androidx.car.app.model.ItemList
|
||||
import androidx.car.app.model.ListTemplate
|
||||
import androidx.car.app.model.Row
|
||||
import androidx.car.app.model.Template
|
||||
import androidx.car.app.model.Toggle
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import com.kouros.android.cars.carappservice.R
|
||||
import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING
|
||||
import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue
|
||||
import com.kouros.navigation.utils.NavigationUtils.setBooleanKeyValue
|
||||
|
||||
|
||||
class NavigationSettings(private val carContext: CarContext) : Screen(carContext) {
|
||||
|
||||
|
||||
override fun onGetTemplate(): Template {
|
||||
val listBuilder = ItemList.Builder()
|
||||
|
||||
|
||||
listBuilder.addItem(
|
||||
buildRowForTemplate(
|
||||
R.string.list_limit,
|
||||
ConstraintManager.CONTENT_LIMIT_TYPE_LIST
|
||||
)
|
||||
)
|
||||
|
||||
return ListTemplate.Builder()
|
||||
.setSingleList(listBuilder.build())
|
||||
.setHeader(
|
||||
Header.Builder()
|
||||
.setTitle(carContext.getString(R.string.content_limits))
|
||||
.setStartHeaderAction(Action.BACK)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildRowForTemplate(title: Int, contentLimitType: Int): Row {
|
||||
return Row.Builder()
|
||||
.setTitle(carContext.getString(title))
|
||||
.addText(
|
||||
carContext
|
||||
.getCarService(ConstraintManager::class.java)
|
||||
.getContentLimit(contentLimitType).toString()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.kouros.navigation.car.screen
|
||||
|
||||
import android.content.Context
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.Header
|
||||
import androidx.car.app.model.ItemList
|
||||
import androidx.car.app.model.ListTemplate
|
||||
import androidx.car.app.model.Row
|
||||
import androidx.car.app.model.Template
|
||||
import androidx.car.app.model.Toggle
|
||||
import androidx.core.content.edit
|
||||
import com.kouros.android.cars.carappservice.R
|
||||
import com.kouros.navigation.car.NavigationSession
|
||||
|
||||
/** A screen demonstrating selectable lists. */
|
||||
class SettingsScreen(
|
||||
carContext: CarContext,
|
||||
) : Screen(carContext) {
|
||||
|
||||
override fun onGetTemplate(): Template {
|
||||
|
||||
val listBuilder = ItemList.Builder()
|
||||
listBuilder.addItem(
|
||||
buildRowForTemplate(
|
||||
DisplaySettings(carContext),
|
||||
R.string.display
|
||||
)
|
||||
)
|
||||
listBuilder.addItem(
|
||||
buildRowForTemplate(
|
||||
NavigationSettings(carContext),
|
||||
R.string.navigation_settings
|
||||
)
|
||||
)
|
||||
|
||||
return ListTemplate.Builder()
|
||||
.setSingleList(listBuilder.build())
|
||||
.setHeader(
|
||||
Header.Builder()
|
||||
.setTitle(
|
||||
(carContext.getString(R.string.settings_action_title))
|
||||
)
|
||||
.setStartHeaderAction(Action.BACK)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun buildRowForTemplate(screen: Screen, title: Int): Row {
|
||||
return Row.Builder()
|
||||
.setTitle(carContext.getString(title))
|
||||
.setOnClickListener { screenManager.push(screen) }
|
||||
.setBrowsable(true)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
@@ -351,8 +351,9 @@
|
||||
<string name="location_description_text_label" msgid="2779911545316756419">"Textlabel"</string>
|
||||
<string name="parking_vs_driving_demo_title" msgid="3367862800135053111">"Demo: Parken im Vergleich zu Fahren"</string>
|
||||
<string name="latest_feature_details" msgid="6843008350392721502">"Displays in Autos."</string>
|
||||
<string name="latest_feature_title" msgid="7929405790070777460">"Neueste Funktionen"</string>
|
||||
<string name="loading_toggle_enabled" msgid="8828072732804454994">"Laden aktiviert"</string>
|
||||
<string name="navigation_settings" msgid="7929405790070777460">"Navigation"</string>
|
||||
<string name="display">Anzeige</string>
|
||||
<string name="threed_building" msgid="8828072732804454994">"3D Gebäude"</string>
|
||||
<string name="loading_toggle_disabled" msgid="7689738885077382673">"Laden deaktiviert"</string>
|
||||
<string name="loading_screen" msgid="4771507490730308794">"Ladebildschirm"</string>
|
||||
<string name="vector_toggle_details" msgid="1301305340033556819">"Schieberegler zum Hinzufügen/Entfernen von Farben"</string>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright (C) 2021 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -479,8 +478,9 @@
|
||||
|
||||
<string name="parking_vs_driving_demo_title">Parking Vs Driving Demo</string>
|
||||
<string name="latest_feature_details">Cluster Displays in cars!</string>
|
||||
<string name="latest_feature_title">Latest Features</string>
|
||||
<string name="loading_toggle_enabled">Loading enabled</string>
|
||||
<string name="navigation_settings">Navigation</string>
|
||||
<string name="display">Display</string>
|
||||
<string name="threed_building">3D Building</string>
|
||||
<string name="loading_toggle_disabled">Loading disabled</string>
|
||||
<string name="loading_screen">Loading screen</string>
|
||||
<string name="vector_toggle_details">Toggle to add/remove color</string>
|
||||
|
||||
@@ -118,7 +118,7 @@ data class ValhallaLocation (
|
||||
|
||||
object Constants {
|
||||
|
||||
const val STYLE: String = "https://kouros-online.de/liberty2"
|
||||
const val STYLE: String = "https://kouros-online.de/liberty.json"
|
||||
//baseStyle = BaseStyle.Uri("https://tiles.openfreemap.org/styles/liberty"),
|
||||
const val TAG: String = "Navigation"
|
||||
|
||||
@@ -138,6 +138,11 @@ object Constants {
|
||||
home2Location.latitude = 48.1164817
|
||||
home2Location.longitude = 11.594322
|
||||
}
|
||||
|
||||
const val SHARED_PREF_KEY = "NavigationPrefs"
|
||||
|
||||
const val SHOW_THREED_BUILDING = "Show3D"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ data class Route (
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
val maneuvers: List<Maneuvers>,
|
||||
var maneuvers: List<Maneuvers>,
|
||||
|
||||
/**
|
||||
* The distance traveled from origin to destination.
|
||||
@@ -43,8 +43,6 @@ data class Route (
|
||||
|
||||
val time: Double,
|
||||
|
||||
var routingManeuvers : List<Maneuvers>,
|
||||
|
||||
var routeGeoJson : String,
|
||||
|
||||
var currentIndex: Int
|
||||
@@ -63,8 +61,6 @@ data class Route (
|
||||
|
||||
private lateinit var trip : Trip
|
||||
|
||||
private lateinit var routingManeuvers: List<Maneuvers>
|
||||
|
||||
private var routeGeoJson = ""
|
||||
|
||||
fun route (route: String ) = apply {
|
||||
@@ -87,21 +83,22 @@ data class Route (
|
||||
points.add(point)
|
||||
}
|
||||
pointLocations = points
|
||||
val routings = mutableListOf<Maneuvers>()
|
||||
for (maneuver in maneuvers) {
|
||||
routings.add(maneuver)
|
||||
}
|
||||
this.routingManeuvers = routings
|
||||
this.routeGeoJson = createGeoJson(waypoints)
|
||||
return Route(
|
||||
maneuvers, distance, waypoints, pointLocations, summary, trip, time, routingManeuvers, routeGeoJson, 0
|
||||
maneuvers, distance, waypoints, pointLocations, summary, trip, time, routeGeoJson, 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun maneuverLocations(): List<Point> {
|
||||
val beginShapeIndex = currentManeuver().beginShapeIndex
|
||||
val endShapeIndex = currentManeuver().endShapeIndex
|
||||
return pointLocations.subList(beginShapeIndex, endShapeIndex)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
waypoints = mutableListOf()
|
||||
routingManeuvers = mutableListOf()
|
||||
maneuvers = mutableListOf()
|
||||
routeGeoJson = ""
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,6 @@ open class RouteModel() {
|
||||
fun currentStep(): StepData {
|
||||
val maneuver = route.currentManeuver()
|
||||
var text = ""
|
||||
println("Maneuver $maneuver")
|
||||
if (maneuver.streetNames != null && maneuver.streetNames.isNotEmpty()) {
|
||||
text = maneuver.streetNames[0]
|
||||
}
|
||||
@@ -156,16 +155,10 @@ open class RouteModel() {
|
||||
return nearestLocation
|
||||
}
|
||||
|
||||
fun maneuverLocations(): List<Point> {
|
||||
val beginShapeIndex = route.currentManeuver().beginShapeIndex
|
||||
val endShapeIndex = route.currentManeuver().endShapeIndex
|
||||
return route.pointLocations.subList(beginShapeIndex, endShapeIndex)
|
||||
}
|
||||
|
||||
fun travelLeftTime(): Double {
|
||||
var timeLeft = 0.0
|
||||
for (i in route.currentIndex + 1..<route.routingManeuvers.size) {
|
||||
val maneuver = route.routingManeuvers[i]
|
||||
for (i in route.currentIndex + 1..<route.maneuvers.size) {
|
||||
val maneuver = route.maneuvers[i]
|
||||
timeLeft += maneuver.time
|
||||
}
|
||||
if (endIndex > 0) {
|
||||
@@ -180,7 +173,7 @@ open class RouteModel() {
|
||||
|
||||
/** Returns the current [Step] left distance in km. */
|
||||
fun leftStepDistance(): Double {
|
||||
val maneuver = route.routingManeuvers[route.currentIndex]
|
||||
val maneuver = route.currentManeuver()
|
||||
var leftDistance = maneuver.length
|
||||
if (endIndex > 0) {
|
||||
leftDistance = (distanceToStepEnd / 1000).toDouble()
|
||||
@@ -190,12 +183,12 @@ open class RouteModel() {
|
||||
|
||||
fun travelLeftDistance(): Double {
|
||||
var leftDistance = 0.0
|
||||
for (i in route.currentIndex + 1..<route.routingManeuvers.size) {
|
||||
val maneuver = route.routingManeuvers[i]
|
||||
for (i in route.currentIndex + 1..<route.maneuvers.size) {
|
||||
val maneuver = route.maneuvers[i]
|
||||
leftDistance += maneuver.length
|
||||
}
|
||||
if (endIndex > 0) {
|
||||
val maneuver = route.routingManeuvers[route.currentIndex]
|
||||
val maneuver = route.currentManeuver()
|
||||
val curDistance = maneuver.length
|
||||
val percent = 100 * (endIndex - currentIndex) / (endIndex - beginIndex)
|
||||
val time = curDistance * percent / 100
|
||||
@@ -215,7 +208,6 @@ open class RouteModel() {
|
||||
fun stopNavigation() {
|
||||
route.clear()
|
||||
navigating = false
|
||||
//maneuverIndex = 0
|
||||
currentIndex = 0
|
||||
distanceToStepEnd = 0F
|
||||
beginIndex = 0
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.kouros.navigation.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import androidx.core.content.edit
|
||||
import com.kouros.navigation.data.Constants.SHARED_PREF_KEY
|
||||
import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING
|
||||
import com.kouros.navigation.data.GeoJsonFeature
|
||||
import com.kouros.navigation.data.GeoJsonFeatureCollection
|
||||
import com.kouros.navigation.data.GeoJsonLineString
|
||||
@@ -25,6 +29,28 @@ import kotlin.math.sin
|
||||
|
||||
object NavigationUtils {
|
||||
|
||||
fun getBooleanKeyValue(context: Context, key: String) : Boolean {
|
||||
return context
|
||||
.getSharedPreferences(
|
||||
SHARED_PREF_KEY,
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
.getBoolean(key, false)
|
||||
}
|
||||
|
||||
fun setBooleanKeyValue(context: Context, `val`: Boolean, key: String) {
|
||||
context
|
||||
.getSharedPreferences(
|
||||
SHARED_PREF_KEY,
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
.edit {
|
||||
putBoolean(
|
||||
key, `val`
|
||||
)
|
||||
apply()
|
||||
}
|
||||
}
|
||||
fun snapLocation(location: Location, stepCoordinates: List<Point>): Location {
|
||||
val oldPoint = Point.fromLngLat(location.longitude, location.latitude)
|
||||
if (stepCoordinates.size > 1) {
|
||||
|
||||
Reference in New Issue
Block a user