Lanes
This commit is contained in:
@@ -43,6 +43,7 @@ import com.kouros.data.R
|
|||||||
import com.kouros.navigation.MainApplication.Companion.navigationViewModel
|
import com.kouros.navigation.MainApplication.Companion.navigationViewModel
|
||||||
import com.kouros.navigation.data.Constants
|
import com.kouros.navigation.data.Constants
|
||||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
||||||
|
import com.kouros.navigation.data.Constants.home2Location
|
||||||
import com.kouros.navigation.data.Constants.homeLocation
|
import com.kouros.navigation.data.Constants.homeLocation
|
||||||
import com.kouros.navigation.data.StepData
|
import com.kouros.navigation.data.StepData
|
||||||
import com.kouros.navigation.model.BaseStyleModel
|
import com.kouros.navigation.model.BaseStyleModel
|
||||||
@@ -61,6 +62,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
import org.maplibre.compose.camera.CameraPosition
|
import org.maplibre.compose.camera.CameraPosition
|
||||||
import org.maplibre.compose.location.DesiredAccuracy
|
import org.maplibre.compose.location.DesiredAccuracy
|
||||||
import org.maplibre.compose.location.Location
|
import org.maplibre.compose.location.Location
|
||||||
@@ -76,7 +78,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
val routeModel = RouteModel()
|
val routeModel = RouteModel()
|
||||||
var tilt = 50.0
|
var tilt = 50.0
|
||||||
val useMock = true
|
val useMock = false
|
||||||
val stepData: MutableLiveData<StepData> by lazy {
|
val stepData: MutableLiveData<StepData> by lazy {
|
||||||
MutableLiveData<StepData>()
|
MutableLiveData<StepData>()
|
||||||
}
|
}
|
||||||
@@ -90,7 +92,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
routeData.value = routeModel.route.routeGeoJson
|
routeData.value = routeModel.route.routeGeoJson
|
||||||
simulate()
|
simulate()
|
||||||
//test()
|
//test()
|
||||||
//gpx(applicationContext)
|
///gpx(applicationContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val cameraPosition = MutableLiveData(
|
val cameraPosition = MutableLiveData(
|
||||||
@@ -130,8 +132,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
if (useMock) {
|
if (useMock) {
|
||||||
mock = MockLocation(locationManager)
|
mock = MockLocation(locationManager)
|
||||||
mock.setMockLocation(
|
mock.setMockLocation(
|
||||||
location?.latitude ?: homeLocation.latitude,
|
home2Location.latitude,
|
||||||
location?.longitude ?: homeLocation.longitude
|
home2Location.longitude
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,6 +155,10 @@ class MainActivity : ComponentActivity() {
|
|||||||
requiredPermissions = listOf(permissions.first()),
|
requiredPermissions = listOf(permissions.first()),
|
||||||
onGranted = {
|
onGranted = {
|
||||||
Content()
|
Content()
|
||||||
|
// auto navigate
|
||||||
|
if (useMock) {
|
||||||
|
//navigationViewModel.loadRoute(applicationContext, homeLocation, home2Location, 0F)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -172,7 +178,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
)
|
)
|
||||||
val userLocationState = rememberUserLocationState(locationProvider)
|
val userLocationState = rememberUserLocationState(locationProvider)
|
||||||
val locationState = locationProvider.location.collectAsState()
|
val locationState = locationProvider.location.collectAsState()
|
||||||
updateLocation(locationState.value)
|
updateLocation(locationState.value)
|
||||||
var latitude by remember { mutableDoubleStateOf(0.0) }
|
var latitude by remember { mutableDoubleStateOf(0.0) }
|
||||||
if (locationState.value != null) {
|
if (locationState.value != null) {
|
||||||
latitude = locationState.value!!.position.latitude
|
latitude = locationState.value!!.position.latitude
|
||||||
@@ -271,7 +277,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
)
|
)
|
||||||
lastLocation = currentLocation
|
lastLocation = currentLocation
|
||||||
if (!loadRecentPlaces) {
|
if (!loadRecentPlaces) {
|
||||||
navigationViewModel.loadRecentPlaces(applicationContext, lastLocation)
|
navigationViewModel.loadRecentPlaces(applicationContext, lastLocation, 0F)
|
||||||
loadRecentPlaces = true
|
loadRecentPlaces = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,21 +339,34 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
for ((index, step) in routeModel.legs.steps.withIndex()) {
|
for ((index, step) in routeModel.legs.steps.withIndex()) {
|
||||||
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
if (index in 3..3) {
|
||||||
routeModel.updateLocation(location(waypoint[0], waypoint[1]), navigationViewModel)
|
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||||
val step = routeModel.currentStep()
|
routeModel.updateLocation(
|
||||||
println("Street: ${step.instruction} Dist: ${step.leftStepDistance} ${step.currentManeuverType}")
|
location(waypoint[0], waypoint[1]),
|
||||||
if (index + 1 <= routeModel.legs.steps.size) {
|
navigationViewModel
|
||||||
//nextStepData.value = routeModel.nextStep()
|
)
|
||||||
|
val step = routeModel.currentStep()
|
||||||
|
if (step.leftStepDistance == 70.0) {
|
||||||
|
println("")
|
||||||
|
}
|
||||||
|
if (index + 1 <= routeModel.legs.steps.size) {
|
||||||
|
//nextStepData.value = routeModel.nextStep()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun test2() {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
// Balanstr.
|
||||||
|
mock.setMockLocation( 48.119357, 11.599130)
|
||||||
|
}
|
||||||
|
}
|
||||||
fun gpx(context: Context) {
|
fun gpx(context: Context) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val parser = GPXParser()
|
val parser = GPXParser()
|
||||||
val input = context.resources.openRawResource(R.raw.vh)
|
val input = context.resources.openRawResource(R.raw.hv)
|
||||||
val parsedGpx: Gpx? = parser.parse(input) // consider using a background thread
|
val parsedGpx: Gpx? = parser.parse(input) // consider using a background thread
|
||||||
parsedGpx?.let {
|
parsedGpx?.let {
|
||||||
val tracks = parsedGpx.tracks
|
val tracks = parsedGpx.tracks
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ fun Home(
|
|||||||
Button(onClick = {
|
Button(onClick = {
|
||||||
val places = viewModel.loadRecentPlace()
|
val places = viewModel.loadRecentPlace()
|
||||||
val toLocation = location(places.first()!!.longitude, places.first()!!.latitude)
|
val toLocation = location(places.first()!!.longitude, places.first()!!.latitude)
|
||||||
viewModel.loadRoute(applicationContext, location, toLocation)
|
viewModel.loadRoute(applicationContext, location, toLocation, 0F)
|
||||||
closeSheet()
|
closeSheet()
|
||||||
}) {
|
}) {
|
||||||
Icon(
|
Icon(
|
||||||
@@ -207,7 +207,7 @@ private fun SearchPlaces(
|
|||||||
viewModel.saveRecent(pl)
|
viewModel.saveRecent(pl)
|
||||||
val toLocation =
|
val toLocation =
|
||||||
location(place.lon.toDouble(), place.lat.toDouble())
|
location(place.lon.toDouble(), place.lat.toDouble())
|
||||||
viewModel.loadRoute(context, location, toLocation)
|
viewModel.loadRoute(context, location, toLocation, 0F)
|
||||||
closeSheet()
|
closeSheet()
|
||||||
}
|
}
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -245,7 +245,7 @@ private fun RecentPlaces(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clickable {
|
.clickable {
|
||||||
val toLocation = location(place.longitude, place.latitude)
|
val toLocation = location(place.longitude, place.latitude)
|
||||||
viewModel.loadRoute(context, location, toLocation)
|
viewModel.loadRoute(context, location, toLocation, 0F)
|
||||||
closeSheet()
|
closeSheet()
|
||||||
}
|
}
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import androidx.car.app.hardware.common.CarValue
|
|||||||
import androidx.car.app.hardware.common.OnCarDataAvailableListener
|
import androidx.car.app.hardware.common.OnCarDataAvailableListener
|
||||||
import androidx.car.app.hardware.info.CarHardwareLocation
|
import androidx.car.app.hardware.info.CarHardwareLocation
|
||||||
import androidx.car.app.hardware.info.CarSensors
|
import androidx.car.app.hardware.info.CarSensors
|
||||||
|
import androidx.car.app.hardware.info.Compass
|
||||||
import androidx.car.app.hardware.info.Speed
|
import androidx.car.app.hardware.info.Speed
|
||||||
import androidx.core.location.LocationListenerCompat
|
import androidx.core.location.LocationListenerCompat
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
@@ -104,6 +105,17 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val carCompassListener: OnCarDataAvailableListener<Compass?> =
|
||||||
|
OnCarDataAvailableListener { data ->
|
||||||
|
if (data.orientations.status == CarValue.STATUS_SUCCESS) {
|
||||||
|
val orientation = data.orientations.value
|
||||||
|
if (orientation != null) {
|
||||||
|
surfaceRenderer.carOrientation = orientation[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val carSpeedListener = OnCarDataAvailableListener<Speed> { data ->
|
val carSpeedListener = OnCarDataAvailableListener<Speed> { data ->
|
||||||
if (data.displaySpeedMetersPerSecond.status == CarValue.STATUS_SUCCESS) {
|
if (data.displaySpeedMetersPerSecond.status == CarValue.STATUS_SUCCESS) {
|
||||||
val speed = data.displaySpeedMetersPerSecond.value
|
val speed = data.displaySpeedMetersPerSecond.value
|
||||||
@@ -172,6 +184,9 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
val useCarLocation = getBooleanKeyValue(carContext, CAR_LOCATION)
|
val useCarLocation = getBooleanKeyValue(carContext, CAR_LOCATION)
|
||||||
if (useCarLocation) {
|
if (useCarLocation) {
|
||||||
val carSensors = carContext.getCarService(CarHardwareManager::class.java).carSensors
|
val carSensors = carContext.getCarService(CarHardwareManager::class.java).carSensors
|
||||||
|
carSensors.addCompassListener(CarSensors.UPDATE_RATE_FASTEST,
|
||||||
|
carContext.mainExecutor,
|
||||||
|
carCompassListener)
|
||||||
carSensors.addCarHardwareLocationListener(
|
carSensors.addCarHardwareLocationListener(
|
||||||
CarSensors.UPDATE_RATE_FASTEST,
|
CarSensors.UPDATE_RATE_FASTEST,
|
||||||
carContext.mainExecutor,
|
carContext.mainExecutor,
|
||||||
@@ -191,8 +206,7 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
SearchScreen(
|
SearchScreen(
|
||||||
carContext,
|
carContext,
|
||||||
surfaceRenderer,
|
surfaceRenderer,
|
||||||
location,
|
navigationViewModel
|
||||||
navigationViewModel,
|
|
||||||
// TODO: Uri
|
// TODO: Uri
|
||||||
)
|
)
|
||||||
) { obj: Any? ->
|
) { obj: Any? ->
|
||||||
@@ -229,7 +243,7 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
carContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
carContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
val location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
|
val location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
navigationViewModel.loadRecentPlace(location = location, carContext)
|
navigationViewModel.loadRecentPlace(location = location, surfaceRenderer.carOrientation, carContext)
|
||||||
updateLocation(location)
|
updateLocation(location)
|
||||||
locationManager.requestLocationUpdates(
|
locationManager.requestLocationUpdates(
|
||||||
LocationManager.GPS_PROVIDER,
|
LocationManager.GPS_PROVIDER,
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ class SurfaceRenderer(
|
|||||||
) : DefaultLifecycleObserver {
|
) : DefaultLifecycleObserver {
|
||||||
|
|
||||||
var lastLocation = location(0.0, 0.0)
|
var lastLocation = location(0.0, 0.0)
|
||||||
|
|
||||||
|
var carOrientation = 0F
|
||||||
private val cameraPosition = MutableLiveData(
|
private val cameraPosition = MutableLiveData(
|
||||||
CameraPosition(
|
CameraPosition(
|
||||||
zoom = 15.0,
|
zoom = 15.0,
|
||||||
@@ -303,7 +305,7 @@ class SurfaceRenderer(
|
|||||||
routeData.value = route
|
routeData.value = route
|
||||||
updateCameraPosition(
|
updateCameraPosition(
|
||||||
0.0,
|
0.0,
|
||||||
12.0,
|
14.0,
|
||||||
target = Position(location.longitude, location.latitude)
|
target = Position(location.longitude, location.latitude)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,8 +160,10 @@ fun AmenityLayer(routeData: String?) {
|
|||||||
if (routeData != null && routeData.isNotEmpty()) {
|
if (routeData != null && routeData.isNotEmpty()) {
|
||||||
val color = if (routeData.contains(Constants.PHARMACY)) {
|
val color = if (routeData.contains(Constants.PHARMACY)) {
|
||||||
const(Color.Red)
|
const(Color.Red)
|
||||||
|
} else if (routeData.contains(Constants.CHARGING_STATION)) {
|
||||||
|
const(Color.Blue)
|
||||||
} else {
|
} else {
|
||||||
const(Color.Green)
|
const(Color.Black)
|
||||||
}
|
}
|
||||||
val routes = rememberGeoJsonSource(GeoJsonData.JsonString(routeData))
|
val routes = rememberGeoJsonSource(GeoJsonData.JsonString(routeData))
|
||||||
SymbolLayer(
|
SymbolLayer(
|
||||||
@@ -169,6 +171,7 @@ fun AmenityLayer(routeData: String?) {
|
|||||||
source = routes,
|
source = routes,
|
||||||
iconImage = image(painterResource(R.drawable.ev_station_48px), drawAsSdf = true),
|
iconImage = image(painterResource(R.drawable.ev_station_48px), drawAsSdf = true),
|
||||||
iconColor = color,
|
iconColor = color,
|
||||||
|
iconOpacity = const(2.0f),
|
||||||
iconSize = const(3.0f),
|
iconSize = const(3.0f),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -188,10 +191,10 @@ fun SpeedCameraLayer(speedCameras: String?) {
|
|||||||
interpolate(
|
interpolate(
|
||||||
type = exponential(1.2f),
|
type = exponential(1.2f),
|
||||||
input = zoom(),
|
input = zoom(),
|
||||||
5 to const(0.4f),
|
5 to const(0.7f),
|
||||||
6 to const(0.7f),
|
6 to const(1.0f),
|
||||||
7 to const(1.75f),
|
7 to const(2.0f),
|
||||||
20 to const(3f),
|
20 to const(4f),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ class RouteCarModel() : RouteModel() {
|
|||||||
.setIcon(createCarIcon(carContext, stepData.icon))
|
.setIcon(createCarIcon(carContext, stepData.icon))
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
.setRoad(destination.street!!)
|
if (destination.street != null) {
|
||||||
|
step.setRoad(destination.street!!)
|
||||||
|
}
|
||||||
if (stepData.lane.isNotEmpty()) {
|
if (stepData.lane.isNotEmpty()) {
|
||||||
addLanes(carContext, step, stepData)
|
addLanes(carContext, step, stepData)
|
||||||
}
|
}
|
||||||
@@ -222,13 +224,17 @@ class RouteCarModel() : RouteModel() {
|
|||||||
|
|
||||||
fun showSpeedCamera(carContext: CarContext, distance: Double, maxSpeed: String?) {
|
fun showSpeedCamera(carContext: CarContext, distance: Double, maxSpeed: String?) {
|
||||||
carContext.getCarService<AppManager?>(AppManager::class.java)
|
carContext.getCarService<AppManager?>(AppManager::class.java)
|
||||||
.showAlert(createAlert(carContext, distance, maxSpeed))
|
.showAlert(createAlert(carContext, distance, maxSpeed, createCarIcon(carContext, R.drawable.speed_camera_24px)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createAlert(carContext: CarContext, distance: Double, maxSpeed: String?): Alert {
|
fun createAlert(
|
||||||
|
carContext: CarContext,
|
||||||
|
distance: Double,
|
||||||
|
maxSpeed: String?,
|
||||||
|
icon: CarIcon
|
||||||
|
): Alert {
|
||||||
val title = createCarText(carContext, R.string.speed_camera)
|
val title = createCarText(carContext, R.string.speed_camera)
|
||||||
val subtitle = CarText.create(maxSpeed!!)
|
val subtitle = CarText.create(maxSpeed!!)
|
||||||
val icon = CarIcon.ALERT
|
|
||||||
|
|
||||||
val dismissAction: Action = createToastAction(
|
val dismissAction: Action = createToastAction(
|
||||||
carContext,
|
carContext,
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import androidx.core.graphics.drawable.IconCompat
|
|||||||
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.ViewStyle
|
import com.kouros.navigation.car.ViewStyle
|
||||||
|
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||||
import com.kouros.navigation.data.Category
|
import com.kouros.navigation.data.Category
|
||||||
import com.kouros.navigation.data.Constants.CHARGING_STATION
|
import com.kouros.navigation.data.Constants.CHARGING_STATION
|
||||||
import com.kouros.navigation.data.Constants.FUEL_STATION
|
import com.kouros.navigation.data.Constants.FUEL_STATION
|
||||||
@@ -23,8 +24,7 @@ import com.kouros.navigation.model.ViewModel
|
|||||||
class CategoriesScreen(
|
class CategoriesScreen(
|
||||||
private val carContext: CarContext,
|
private val carContext: CarContext,
|
||||||
private val surfaceRenderer: SurfaceRenderer,
|
private val surfaceRenderer: SurfaceRenderer,
|
||||||
private val location: Location,
|
private val viewModel: ViewModel,
|
||||||
private val viewModel: ViewModel
|
|
||||||
) : Screen(carContext) {
|
) : Screen(carContext) {
|
||||||
|
|
||||||
var categories: List<Category> = listOf(
|
var categories: List<Category> = listOf(
|
||||||
@@ -47,7 +47,6 @@ class CategoriesScreen(
|
|||||||
CategoryScreen(
|
CategoryScreen(
|
||||||
carContext,
|
carContext,
|
||||||
surfaceRenderer,
|
surfaceRenderer,
|
||||||
location,
|
|
||||||
it.id,
|
it.id,
|
||||||
viewModel
|
viewModel
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ import androidx.lifecycle.Observer
|
|||||||
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.NavigationMessage
|
import com.kouros.navigation.car.navigation.NavigationMessage
|
||||||
|
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||||
import com.kouros.navigation.data.Constants
|
import com.kouros.navigation.data.Constants
|
||||||
import com.kouros.navigation.data.NavigationRepository
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.data.overpass.Elements
|
import com.kouros.navigation.data.overpass.Elements
|
||||||
import com.kouros.navigation.model.ViewModel
|
import com.kouros.navigation.model.ViewModel
|
||||||
import com.kouros.navigation.utils.GeoUtils.createPointCollection
|
import com.kouros.navigation.utils.GeoUtils.createPointCollection
|
||||||
@@ -31,9 +32,8 @@ import kotlin.math.min
|
|||||||
class CategoryScreen(
|
class CategoryScreen(
|
||||||
private val carContext: CarContext,
|
private val carContext: CarContext,
|
||||||
private val surfaceRenderer: SurfaceRenderer,
|
private val surfaceRenderer: SurfaceRenderer,
|
||||||
location: Location,
|
|
||||||
private val category: String,
|
private val category: String,
|
||||||
private val viewModel: ViewModel
|
private val viewModel: ViewModel,
|
||||||
) : Screen(carContext) {
|
) : Screen(carContext) {
|
||||||
|
|
||||||
var elements = listOf<Elements>()
|
var elements = listOf<Elements>()
|
||||||
@@ -58,7 +58,7 @@ class CategoryScreen(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
viewModel.elements.observe(this, observer)
|
viewModel.elements.observe(this, observer)
|
||||||
viewModel.getAmenities(category, location)
|
viewModel.getAmenities(category, surfaceRenderer.lastLocation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -126,6 +126,28 @@ class CategoryScreen(
|
|||||||
} else {
|
} else {
|
||||||
row.addText(carText("${it.tags.openingHours}"))
|
row.addText(carText("${it.tags.openingHours}"))
|
||||||
}
|
}
|
||||||
|
val navigationMessage = NavigationMessage(carContext)
|
||||||
|
row.addAction(
|
||||||
|
Action.Builder()
|
||||||
|
.setOnClickListener {
|
||||||
|
viewModel.loadRoute(
|
||||||
|
carContext,
|
||||||
|
currentLocation = surfaceRenderer.lastLocation,
|
||||||
|
location(it.lon!!, it.lat!!),
|
||||||
|
surfaceRenderer.carOrientation
|
||||||
|
)
|
||||||
|
setResult(
|
||||||
|
Place(
|
||||||
|
name = name,
|
||||||
|
category = Constants.CHARGING_STATION,
|
||||||
|
latitude = it.lat!!,
|
||||||
|
longitude = it.lon!!
|
||||||
|
)
|
||||||
|
)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
.setIcon(navigationMessage.createCarIcon(R.drawable.navigation_48px))
|
||||||
|
.build())
|
||||||
return row.build()
|
return row.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ class NavigationScreen(
|
|||||||
surfaceRenderer.speedCamerasData.value = speedData
|
surfaceRenderer.speedCamerasData.value = speedData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModel.route.observe(this, observer)
|
viewModel.route.observe(this, observer)
|
||||||
viewModel.recentPlace.observe(this, recentObserver)
|
viewModel.recentPlace.observe(this, recentObserver)
|
||||||
@@ -297,7 +298,12 @@ class NavigationScreen(
|
|||||||
)
|
)
|
||||||
.setOnClickListener {
|
.setOnClickListener {
|
||||||
val navigateTo = location(recentPlace.longitude, recentPlace.latitude)
|
val navigateTo = location(recentPlace.longitude, recentPlace.latitude)
|
||||||
viewModel.loadRoute(carContext, surfaceRenderer.lastLocation, navigateTo)
|
viewModel.loadRoute(
|
||||||
|
carContext,
|
||||||
|
surfaceRenderer.lastLocation,
|
||||||
|
navigateTo,
|
||||||
|
surfaceRenderer.carOrientation
|
||||||
|
)
|
||||||
routeModel.destination = recentPlace
|
routeModel.destination = recentPlace
|
||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
@@ -394,7 +400,11 @@ class NavigationScreen(
|
|||||||
private fun startSearchScreen() {
|
private fun startSearchScreen() {
|
||||||
screenManager
|
screenManager
|
||||||
.pushForResult(
|
.pushForResult(
|
||||||
SearchScreen(carContext, surfaceRenderer, surfaceRenderer.lastLocation, viewModel)
|
SearchScreen(
|
||||||
|
carContext,
|
||||||
|
surfaceRenderer,
|
||||||
|
viewModel
|
||||||
|
)
|
||||||
) { obj: Any? ->
|
) { obj: Any? ->
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
val place = obj as Place
|
val place = obj as Place
|
||||||
@@ -416,7 +426,12 @@ class NavigationScreen(
|
|||||||
val location = location(place.longitude, place.latitude)
|
val location = location(place.longitude, place.latitude)
|
||||||
viewModel.saveRecent(place)
|
viewModel.saveRecent(place)
|
||||||
currentNavigationLocation = location
|
currentNavigationLocation = location
|
||||||
viewModel.loadRoute(carContext, surfaceRenderer.lastLocation, location)
|
viewModel.loadRoute(
|
||||||
|
carContext,
|
||||||
|
surfaceRenderer.lastLocation,
|
||||||
|
location,
|
||||||
|
surfaceRenderer.carOrientation
|
||||||
|
)
|
||||||
routeModel.destination = place
|
routeModel.destination = place
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
@@ -447,7 +462,12 @@ class NavigationScreen(
|
|||||||
|
|
||||||
fun reRoute(destination: Place) {
|
fun reRoute(destination: Place) {
|
||||||
val dest = location(destination.longitude, destination.latitude)
|
val dest = location(destination.longitude, destination.latitude)
|
||||||
viewModel.loadRoute(carContext, surfaceRenderer.lastLocation, dest)
|
viewModel.loadRoute(
|
||||||
|
carContext,
|
||||||
|
surfaceRenderer.lastLocation,
|
||||||
|
dest,
|
||||||
|
surfaceRenderer.carOrientation
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateTrip(location: Location) {
|
fun updateTrip(location: Location) {
|
||||||
@@ -495,10 +515,10 @@ class NavigationScreen(
|
|||||||
val bearingSpeedCamera = location.bearingTo(location(camera.lon!!, camera.lat!!))
|
val bearingSpeedCamera = location.bearingTo(location(camera.lon!!, camera.lat!!))
|
||||||
val bearingRoute = surfaceRenderer.lastLocation.bearingTo(location)
|
val bearingRoute = surfaceRenderer.lastLocation.bearingTo(location)
|
||||||
|
|
||||||
if (camera.distance < 80
|
if (camera.distance < 80) {
|
||||||
&& (bearingSpeedCamera.absoluteValue - bearingRoute.absoluteValue).absoluteValue < 15.0
|
if ((bearingSpeedCamera.absoluteValue - bearingRoute.absoluteValue).absoluteValue < 20.0) {
|
||||||
) {
|
routeModel.showSpeedCamera(carContext, camera.distance, camera.tags.maxspeed)
|
||||||
routeModel.showSpeedCamera(carContext, camera.distance, camera.tags.maxspeed)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import com.kouros.navigation.model.ViewModel
|
|||||||
class PlaceListScreen(
|
class PlaceListScreen(
|
||||||
private val carContext: CarContext,
|
private val carContext: CarContext,
|
||||||
private val surfaceRenderer: SurfaceRenderer,
|
private val surfaceRenderer: SurfaceRenderer,
|
||||||
private val location: Location,
|
|
||||||
private val category: String,
|
private val category: String,
|
||||||
private val viewModel: ViewModel
|
private val viewModel: ViewModel
|
||||||
) : Screen(carContext) {
|
) : Screen(carContext) {
|
||||||
@@ -63,13 +62,21 @@ class PlaceListScreen(
|
|||||||
|
|
||||||
fun loadPlaces() {
|
fun loadPlaces() {
|
||||||
if (category == RECENT) {
|
if (category == RECENT) {
|
||||||
viewModel.loadRecentPlaces(carContext, location)
|
viewModel.loadRecentPlaces(
|
||||||
|
carContext,
|
||||||
|
surfaceRenderer.lastLocation,
|
||||||
|
surfaceRenderer.carOrientation
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if (category == CONTACTS) {
|
if (category == CONTACTS) {
|
||||||
viewModel.loadContacts(carContext)
|
viewModel.loadContacts(carContext)
|
||||||
}
|
}
|
||||||
if (category == FAVORITES) {
|
if (category == FAVORITES) {
|
||||||
viewModel.loadFavorites(carContext, location)
|
viewModel.loadFavorites(
|
||||||
|
carContext,
|
||||||
|
surfaceRenderer.lastLocation,
|
||||||
|
surfaceRenderer.carOrientation
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,9 +84,14 @@ class PlaceListScreen(
|
|||||||
val itemListBuilder = ItemList.Builder()
|
val itemListBuilder = ItemList.Builder()
|
||||||
.setNoItemsMessage(carContext.getString(R.string.no_places))
|
.setNoItemsMessage(carContext.getString(R.string.no_places))
|
||||||
places.forEach {
|
places.forEach {
|
||||||
|
val street = if (it.street != null) {
|
||||||
|
it.street
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
val row = Row.Builder()
|
val row = Row.Builder()
|
||||||
.setImage(contactIcon(it.avatar, it.category))
|
.setImage(contactIcon(it.avatar, it.category))
|
||||||
.setTitle("${it.street!!} ${it.city}")
|
.setTitle("$street ${it.city}")
|
||||||
.setOnClickListener {
|
.setOnClickListener {
|
||||||
val place = Place(
|
val place = Place(
|
||||||
0,
|
0,
|
||||||
|
|||||||
@@ -61,7 +61,12 @@ class RoutePreviewScreen(
|
|||||||
init {
|
init {
|
||||||
viewModel.previewRoute.observe(this, observer)
|
viewModel.previewRoute.observe(this, observer)
|
||||||
val location = location(destination.longitude, destination.latitude)
|
val location = location(destination.longitude, destination.latitude)
|
||||||
viewModel.loadPreviewRoute(carContext, surfaceRenderer.lastLocation, location)
|
viewModel.loadPreviewRoute(
|
||||||
|
carContext,
|
||||||
|
surfaceRenderer.lastLocation,
|
||||||
|
location,
|
||||||
|
surfaceRenderer.carOrientation
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onGetTemplate(): Template {
|
override fun onGetTemplate(): Template {
|
||||||
@@ -173,7 +178,8 @@ class RoutePreviewScreen(
|
|||||||
|
|
||||||
private fun createRouteText(): CarText {
|
private fun createRouteText(): CarText {
|
||||||
val time = routeModel.route.summary!!.duration
|
val time = routeModel.route.summary!!.duration
|
||||||
val length = BigDecimal(routeModel.route.summary!!.distance).setScale(1, RoundingMode.HALF_EVEN)
|
val length =
|
||||||
|
BigDecimal(routeModel.route.summary!!.distance).setScale(1, RoundingMode.HALF_EVEN)
|
||||||
val firstRoute = SpannableString(" \u00b7 $length km")
|
val firstRoute = SpannableString(" \u00b7 $length km")
|
||||||
firstRoute.setSpan(
|
firstRoute.setSpan(
|
||||||
DurationSpan.create(time.toLong()), 0, 1, 0
|
DurationSpan.create(time.toLong()), 0, 1, 0
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.kouros.navigation.car.screen
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import android.net.Uri
|
|
||||||
import androidx.car.app.CarContext
|
import androidx.car.app.CarContext
|
||||||
import androidx.car.app.Screen
|
import androidx.car.app.Screen
|
||||||
import androidx.car.app.model.Action
|
import androidx.car.app.model.Action
|
||||||
@@ -17,9 +16,9 @@ import androidx.lifecycle.Observer
|
|||||||
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.ViewStyle
|
import com.kouros.navigation.car.ViewStyle
|
||||||
|
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||||
import com.kouros.navigation.data.Category
|
import com.kouros.navigation.data.Category
|
||||||
import com.kouros.navigation.data.Constants
|
import com.kouros.navigation.data.Constants
|
||||||
import com.kouros.navigation.data.NavigationRepository
|
|
||||||
import com.kouros.navigation.data.Place
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.data.nominatim.SearchResult
|
import com.kouros.navigation.data.nominatim.SearchResult
|
||||||
import com.kouros.navigation.model.ViewModel
|
import com.kouros.navigation.model.ViewModel
|
||||||
@@ -28,8 +27,7 @@ import com.kouros.navigation.model.ViewModel
|
|||||||
class SearchScreen(
|
class SearchScreen(
|
||||||
carContext: CarContext,
|
carContext: CarContext,
|
||||||
private var surfaceRenderer: SurfaceRenderer,
|
private var surfaceRenderer: SurfaceRenderer,
|
||||||
private var location: Location,
|
private val viewModel: ViewModel,
|
||||||
private val viewModel: ViewModel
|
|
||||||
) : Screen(carContext) {
|
) : Screen(carContext) {
|
||||||
|
|
||||||
var isSearchComplete: Boolean = false
|
var isSearchComplete: Boolean = false
|
||||||
@@ -73,7 +71,6 @@ class SearchScreen(
|
|||||||
CategoriesScreen(
|
CategoriesScreen(
|
||||||
carContext,
|
carContext,
|
||||||
surfaceRenderer,
|
surfaceRenderer,
|
||||||
location,
|
|
||||||
viewModel
|
viewModel
|
||||||
)
|
)
|
||||||
) { obj: Any? ->
|
) { obj: Any? ->
|
||||||
@@ -89,7 +86,6 @@ class SearchScreen(
|
|||||||
PlaceListScreen(
|
PlaceListScreen(
|
||||||
carContext,
|
carContext,
|
||||||
surfaceRenderer,
|
surfaceRenderer,
|
||||||
location,
|
|
||||||
it.id,
|
it.id,
|
||||||
viewModel
|
viewModel
|
||||||
)
|
)
|
||||||
@@ -119,7 +115,7 @@ class SearchScreen(
|
|||||||
object : SearchCallback {
|
object : SearchCallback {
|
||||||
override fun onSearchSubmitted(searchTerm: String) {
|
override fun onSearchSubmitted(searchTerm: String) {
|
||||||
isSearchComplete = true
|
isSearchComplete = true
|
||||||
viewModel.searchPlaces(searchTerm, location)
|
viewModel.searchPlaces(searchTerm, surfaceRenderer.lastLocation)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.setHeaderAction(Action.BACK)
|
.setHeaderAction(Action.BACK)
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ abstract class NavigationRepository {
|
|||||||
private val nominatimUrl = "https://kouros-online.de/nominatim/"
|
private val nominatimUrl = "https://kouros-online.de/nominatim/"
|
||||||
|
|
||||||
|
|
||||||
abstract fun getRoute(currentLocation: Location, location: Location, searchFilter: SearchFilter): String
|
abstract fun getRoute(currentLocation: Location, location: Location, carOrientation: Float, searchFilter: SearchFilter): String
|
||||||
|
|
||||||
fun getRouteDistance(currentLocation: Location, location: Location, searchFilter: SearchFilter, context: Context): Double {
|
fun getRouteDistance(currentLocation: Location, location: Location, carOrientation : Float, searchFilter: SearchFilter, context: Context): Double {
|
||||||
val route = getRoute(currentLocation, location, searchFilter)
|
val route = getRoute(currentLocation, location, carOrientation, searchFilter)
|
||||||
val routeModel = RouteModel()
|
val routeModel = RouteModel()
|
||||||
routeModel.startNavigation(route, context)
|
routeModel.startNavigation(route, context)
|
||||||
return routeModel.route.summary!!.distance
|
return routeModel.route.summary!!.distance
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ data class Route(
|
|||||||
this.routeGeoJson = routeGeoJson
|
this.routeGeoJson = routeGeoJson
|
||||||
centerLocation = createCenterLocation(routeGeoJson)
|
centerLocation = createCenterLocation(routeGeoJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun routeEngine(routeEngine: Int) = apply { this.routeEngine = routeEngine }
|
fun routeEngine(routeEngine: Int) = apply { this.routeEngine = routeEngine }
|
||||||
fun waypoints(waypoints: List<List<Double>>) = apply { this.waypoints = waypoints }
|
fun waypoints(waypoints: List<List<Double>>) = apply { this.waypoints = waypoints }
|
||||||
fun route(route: String) = apply {
|
fun route(route: String) = apply {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class OsrmRepository : NavigationRepository() {
|
|||||||
override fun getRoute(
|
override fun getRoute(
|
||||||
currentLocation: Location,
|
currentLocation: Location,
|
||||||
location: Location,
|
location: Location,
|
||||||
|
carOrientation: Float,
|
||||||
searchFilter: SearchFilter
|
searchFilter: SearchFilter
|
||||||
): String {
|
): String {
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ class OsrmRepository : NavigationRepository() {
|
|||||||
if (searchFilter.avoidTollway) {
|
if (searchFilter.avoidTollway) {
|
||||||
exclude = "$exclude&exclude=toll"
|
exclude = "$exclude&exclude=toll"
|
||||||
}
|
}
|
||||||
val routeLocation = "${currentLocation.longitude},${currentLocation.latitude};${location.longitude},${location.latitude}?steps=true"
|
val routeLocation = "${currentLocation.longitude},${currentLocation.latitude};${location.longitude},${location.latitude}?steps=true&alternatives=2"
|
||||||
return fetchUrl(routeUrl + routeLocation + exclude, true)
|
return fetchUrl(routeUrl + routeLocation + exclude, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,6 +62,7 @@ class OsrmRoute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val leg = Leg(steps)
|
val leg = Leg(steps)
|
||||||
|
|
||||||
builder
|
builder
|
||||||
.routeType(1)
|
.routeType(1)
|
||||||
.summary(summary)
|
.summary(summary)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
|||||||
|
package com.kouros.navigation.data.route
|
||||||
|
|
||||||
|
class Routes (
|
||||||
|
var legs : List<Leg> = arrayListOf()
|
||||||
|
)
|
||||||
@@ -12,7 +12,12 @@ private const val routeUrl = "https://kouros-online.de/valhalla/route?json="
|
|||||||
|
|
||||||
class ValhallaRepository : NavigationRepository() {
|
class ValhallaRepository : NavigationRepository() {
|
||||||
|
|
||||||
override fun getRoute(currentLocation: Location, location: Location, searchFilter: SearchFilter): String {
|
override fun getRoute(
|
||||||
|
currentLocation: Location,
|
||||||
|
location: Location,
|
||||||
|
carOrientation: Float,
|
||||||
|
searchFilter: SearchFilter
|
||||||
|
): String {
|
||||||
|
|
||||||
var exclude = ""
|
var exclude = ""
|
||||||
if (searchFilter.avoidMotorway) {
|
if (searchFilter.avoidMotorway) {
|
||||||
@@ -23,7 +28,11 @@ class ValhallaRepository : NavigationRepository() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val vLocation = listOf(
|
val vLocation = listOf(
|
||||||
Locations(lat = currentLocation.latitude, lon = currentLocation.longitude, search_filter = exclude),
|
Locations(
|
||||||
|
lat = currentLocation.latitude,
|
||||||
|
lon = currentLocation.longitude,
|
||||||
|
search_filter = exclude
|
||||||
|
),
|
||||||
Locations(lat = location.latitude, lon = location.longitude, search_filter = exclude)
|
Locations(lat = location.latitude, lon = location.longitude, search_filter = exclude)
|
||||||
)
|
)
|
||||||
val valhallaLocation = ValhallaLocation(
|
val valhallaLocation = ValhallaLocation(
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ open class RouteModel() {
|
|||||||
val interBearing = location.bearingTo(location(it.location[0], it.location[1]))
|
val interBearing = location.bearingTo(location(it.location[0], it.location[1]))
|
||||||
if (distance < nearestDistance) {
|
if (distance < nearestDistance) {
|
||||||
nearestDistance = distance
|
nearestDistance = distance
|
||||||
if (distance <= NEXT_STEP_THRESHOLD) {
|
if (distance <= NEXT_STEP_THRESHOLD * 3) {
|
||||||
if ((interBearing.absoluteValue - route.currentStep().maneuver.bearingAfter.absoluteValue).absoluteValue < 10) {
|
if ((interBearing.absoluteValue - route.currentStep().maneuver.bearingAfter.absoluteValue).absoluteValue < 20) {
|
||||||
inter = it
|
inter = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,11 +171,11 @@ open class RouteModel() {
|
|||||||
val maneuverIcon = maneuverIcon(curManeuverType)
|
val maneuverIcon = maneuverIcon(curManeuverType)
|
||||||
maneuverType = curManeuverType
|
maneuverType = curManeuverType
|
||||||
|
|
||||||
val lanes = if (shouldAdvance) {
|
val lanes = currentLanes(location)
|
||||||
currentLanes(location)
|
|
||||||
} else {
|
if (lanes.isNotEmpty())
|
||||||
emptyList()
|
println("Street: $streetName Dist: $distanceToNextStep Lane: ${lanes.size}")
|
||||||
}
|
|
||||||
// Construct and return the final StepData object
|
// Construct and return the final StepData object
|
||||||
return StepData(
|
return StepData(
|
||||||
streetName,
|
streetName,
|
||||||
@@ -186,6 +186,7 @@ open class RouteModel() {
|
|||||||
travelLeftDistance(),
|
travelLeftDistance(),
|
||||||
lanes
|
lanes
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -334,7 +335,7 @@ open class RouteModel() {
|
|||||||
fun createLaneIcon(context: Context, stepData: StepData): IconCompat {
|
fun createLaneIcon(context: Context, stepData: StepData): IconCompat {
|
||||||
val bitmaps = mutableListOf<Bitmap>()
|
val bitmaps = mutableListOf<Bitmap>()
|
||||||
stepData.lane.forEach {
|
stepData.lane.forEach {
|
||||||
if (it.indications.isNotEmpty()) { //&& it.valid) {
|
if (it.indications.isNotEmpty()) {
|
||||||
Collections.sort<String>(it.indications)
|
Collections.sort<String>(it.indications)
|
||||||
val resource = laneToResource(it.indications, stepData)
|
val resource = laneToResource(it.indications, stepData)
|
||||||
if (resource.isNotEmpty()) {
|
if (resource.isNotEmpty()) {
|
||||||
@@ -357,7 +358,7 @@ open class RouteModel() {
|
|||||||
return bitmaps.first()
|
return bitmaps.first()
|
||||||
}
|
}
|
||||||
val bmOverlay = createBitmap(
|
val bmOverlay = createBitmap(
|
||||||
bitmaps.first().getWidth() * (bitmaps.size),
|
bitmaps.first().getWidth() * (bitmaps.size * 1.5).toInt(),
|
||||||
bitmaps.first().getHeight(),
|
bitmaps.first().getHeight(),
|
||||||
bitmaps.first().getConfig()!!
|
bitmaps.first().getConfig()!!
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
MutableLiveData()
|
MutableLiveData()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadRecentPlace(location: Location, context: Context) {
|
fun loadRecentPlace(location: Location, carOrientation: Float, context: Context) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val placeBox = boxStore.boxFor(Place::class)
|
val placeBox = boxStore.boxFor(Place::class)
|
||||||
@@ -85,7 +85,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
query.close()
|
query.close()
|
||||||
for (place in results) {
|
for (place in results) {
|
||||||
val plLocation = location(place.longitude, place.latitude)
|
val plLocation = location(place.longitude, place.latitude)
|
||||||
val distance = repository.getRouteDistance(location, plLocation, SearchFilter(), context)
|
val distance = repository.getRouteDistance(location, plLocation, carOrientation, SearchFilter(), context)
|
||||||
place.distance = distance.toFloat()
|
place.distance = distance.toFloat()
|
||||||
if (place.distance > 1F) {
|
if (place.distance > 1F) {
|
||||||
recentPlace.postValue(place)
|
recentPlace.postValue(place)
|
||||||
@@ -98,7 +98,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadRecentPlaces(context: Context, location: Location) {
|
fun loadRecentPlaces(context: Context, location: Location, carOrientation : Float) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val placeBox = boxStore.boxFor(Place::class)
|
val placeBox = boxStore.boxFor(Place::class)
|
||||||
@@ -115,6 +115,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
repository.getRouteDistance(
|
repository.getRouteDistance(
|
||||||
location,
|
location,
|
||||||
plLocation,
|
plLocation,
|
||||||
|
carOrientation,
|
||||||
getSearchFilter(context), context
|
getSearchFilter(context), context
|
||||||
)
|
)
|
||||||
place.distance = distance.toFloat()
|
place.distance = distance.toFloat()
|
||||||
@@ -127,7 +128,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadFavorites(context: Context, location: Location) {
|
fun loadFavorites(context: Context, location: Location, carOrientation: Float) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val placeBox = boxStore.boxFor(Place::class)
|
val placeBox = boxStore.boxFor(Place::class)
|
||||||
@@ -140,7 +141,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
for (place in results) {
|
for (place in results) {
|
||||||
val plLocation = location(place.longitude, place.latitude)
|
val plLocation = location(place.longitude, place.latitude)
|
||||||
val distance =
|
val distance =
|
||||||
repository.getRouteDistance(location, plLocation, getSearchFilter(context), context)
|
repository.getRouteDistance(location, plLocation, carOrientation, getSearchFilter(context), context)
|
||||||
place.distance = distance.toFloat()
|
place.distance = distance.toFloat()
|
||||||
}
|
}
|
||||||
favorites.postValue(results)
|
favorites.postValue(results)
|
||||||
@@ -150,13 +151,14 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadRoute(context: Context, currentLocation: Location, location: Location) {
|
fun loadRoute(context: Context, currentLocation: Location, location: Location, carOrientation : Float) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
route.postValue(
|
route.postValue(
|
||||||
repository.getRoute(
|
repository.getRoute(
|
||||||
currentLocation,
|
currentLocation,
|
||||||
location,
|
location,
|
||||||
|
carOrientation,
|
||||||
getSearchFilter(context)
|
getSearchFilter(context)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -166,13 +168,14 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadPreviewRoute(context: Context, currentLocation: Location, location: Location) {
|
fun loadPreviewRoute(context: Context, currentLocation: Location, location: Location, carOrientation: Float) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
previewRoute.postValue(
|
previewRoute.postValue(
|
||||||
repository.getRoute(
|
repository.getRoute(
|
||||||
currentLocation,
|
currentLocation,
|
||||||
location,
|
location,
|
||||||
|
carOrientation,
|
||||||
getSearchFilter(context)
|
getSearchFilter(context)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -369,7 +372,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun loadPlaces2(context: Context, location: Location): SnapshotStateList<Place?> {
|
fun loadPlaces2(context: Context, location: Location, carOrientation: Float): SnapshotStateList<Place?> {
|
||||||
val results = listOf<Place>()
|
val results = listOf<Place>()
|
||||||
try {
|
try {
|
||||||
val placeBox = boxStore.boxFor(Place::class)
|
val placeBox = boxStore.boxFor(Place::class)
|
||||||
@@ -382,7 +385,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
for (place in results) {
|
for (place in results) {
|
||||||
val plLocation = location(place.longitude, place.latitude)
|
val plLocation = location(place.longitude, place.latitude)
|
||||||
val distance =
|
val distance =
|
||||||
repository.getRouteDistance(location, plLocation, getSearchFilter(context), context)
|
repository.getRouteDistance(location, plLocation, carOrientation, getSearchFilter(context), context)
|
||||||
place.distance = distance.toFloat()
|
place.distance = distance.toFloat()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
<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="M340,760L440,600L380,600L380,480L280,640L340,640L340,760ZM240,400L480,400L480,200Q480,200 480,200Q480,200 480,200L240,200Q240,200 240,200Q240,200 240,200L240,400ZM240,760L480,760L480,480L240,480L240,760ZM160,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,840ZM480,760L240,760L240,760L480,760Z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -6,5 +6,5 @@
|
|||||||
android:tint="?attr/colorControlNormal">
|
android:tint="?attr/colorControlNormal">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@android:color/white"
|
android:fillColor="@android:color/white"
|
||||||
android:pathData="M337,746L425,606L372,606L372,501L285,641L337,641L337,746ZM220,408L489,408L489,180Q489,180 489,180Q489,180 489,180L220,180Q220,180 220,180Q220,180 220,180L220,408ZM220,780L489,780L489,468L220,468L220,780ZM160,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,840ZM489,780L220,780L220,780L489,780Z"/>
|
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>
|
</vector>
|
||||||
|
|||||||
Reference in New Issue
Block a user