Overpass
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
package com.kouros.navigation.car
|
||||
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import com.kouros.navigation.data.overpass.Overpass
|
||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
import com.kouros.navigation.utils.location
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Test
|
||||
|
||||
class OverpassTest {
|
||||
|
||||
val location = Location(LocationManager.GPS_PROVIDER)
|
||||
|
||||
@Test
|
||||
fun `maxSpeed Schmalkaldener 30 `() {
|
||||
val curLocation = location(11.582495, 48.186863)
|
||||
executeSpeedTest( curLocation, "Schmalkaldener Straße", emptyList(), 90, 30)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `maxSpeed Ingolstädter 50 `() {
|
||||
val curLocation = location(11.584384, 48.186338)
|
||||
executeSpeedTest( curLocation, "Ingolstädter Straße", listOf("B13"), 180, 50)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `maxSpeed Isarring 50 `() {
|
||||
val curLocation = location(11.5989114, 48.1694783)
|
||||
executeSpeedTest( curLocation, "Isarring", listOf("B2R"), 190, 50)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `maxSpeed A94 `() {
|
||||
val curLocation = location(11.88117, 48.16595)
|
||||
executeSpeedTest( curLocation, "", listOf("A94", "E552"), 90, 130)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `maxSpeed Fendsbach `() {
|
||||
val curLocation = location(11.94989, 48.21522)
|
||||
executeSpeedTest( curLocation, "Fendsbach", listOf("St 2331"), 0, 60)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `maxSpeed Leopoldstraße `() {
|
||||
val locations = listOf(
|
||||
location(11.5854771, 48.1778470),
|
||||
location(11.5855582, 48.1756081),
|
||||
location(11.5854672, 48.1753093),
|
||||
location(11.5850147, 48.1774400)
|
||||
)
|
||||
|
||||
executeSpeedTest( locations[0], "Leopoldstraße", emptyList(), 0, 50)
|
||||
executeSpeedTest( locations[1], "Leopoldstraße", emptyList(), 180, 30)
|
||||
executeSpeedTest( locations[2], "Leopoldstraße", emptyList(), 180, 30)
|
||||
executeSpeedTest( locations[3], "Leopoldstraße", emptyList(), 180, 50)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `maxSpeed Egnatia `() {
|
||||
val locations = listOf(
|
||||
location(20.645487, 39.552875),
|
||||
location(20.686672, 39.838547),
|
||||
)
|
||||
|
||||
executeSpeedTest( locations[0], "", listOf("E90", "E92"), 100, 120)
|
||||
executeSpeedTest( locations[1], "", listOf("E853"), 320, 90)
|
||||
}
|
||||
|
||||
fun executeSpeedTest(
|
||||
curLocation: Location,
|
||||
street: String,
|
||||
roadNumbers: List<String>,
|
||||
routeBearing: Int,
|
||||
result: Int
|
||||
) {
|
||||
val viewModel = NavigationViewModel(TomTomRepository())
|
||||
val lineString = "${curLocation.latitude},${curLocation.longitude}"
|
||||
val elements = Overpass().getSpeedLimit(600F, lineString, street, roadNumbers)
|
||||
viewModel.speedElements.addAll(elements)
|
||||
assertNotEquals(0, viewModel.speedElements.size)
|
||||
|
||||
val speed = viewModel.calculateSpeedLimit(
|
||||
curLocation,
|
||||
routeBearing.toFloat(),
|
||||
"DEU",
|
||||
)
|
||||
assertEquals(result, speed)
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,14 @@ import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.kouros.navigation.data.Constants.homeHohenwaldeck
|
||||
import com.kouros.navigation.data.RouteEngine
|
||||
import com.kouros.navigation.data.overpass.Overpass
|
||||
import com.kouros.navigation.data.route.ManeuverType
|
||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||
import com.kouros.navigation.model.NavigationViewModel
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
import com.kouros.navigation.utils.getSettingsRepository
|
||||
import com.kouros.navigation.utils.location
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
import org.junit.Test
|
||||
@@ -69,7 +71,7 @@ class RouteModelTest {
|
||||
val repository = getSettingsRepository(appContext)
|
||||
runBlocking { repository.setRoutingEngine(RouteEngine.TOMTOM.ordinal) }
|
||||
val routeJsonString = TomTomRepository().fetchUrl(
|
||||
"https://kouros-online.de/tomtom_routing.json",
|
||||
"http://192.168.1.37/tomtom_routing.json",
|
||||
false
|
||||
)
|
||||
assertNotEquals("", routeJsonString)
|
||||
@@ -201,6 +203,7 @@ class RouteModelTest {
|
||||
|
||||
@Test
|
||||
fun simulate() {
|
||||
val viewModel = NavigationViewModel(TomTomRepository())
|
||||
for ((index, waypoint) in routeModel.curRoute.waypoints.withIndex()) {
|
||||
if (routeModel.isNavigating()) {
|
||||
val curLocation = location(waypoint[0], waypoint[1])
|
||||
@@ -244,9 +247,12 @@ class RouteModelTest {
|
||||
val curLocation = location(waypoint[0], waypoint[1])
|
||||
if (routeModel.isNavigating()) {
|
||||
if (index in 16..43) {
|
||||
routeModel.updateLocation(curLocation, NavigationViewModel(TomTomRepository()))
|
||||
routeModel.updateLocation(
|
||||
curLocation,
|
||||
NavigationViewModel(TomTomRepository())
|
||||
)
|
||||
val stepData = routeModel.currentStep()
|
||||
assertEquals(stepData.leftStepDistance, distance[index-16], 1.0)
|
||||
assertEquals(stepData.leftStepDistance, distance[index - 16], 1.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@ import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.kouros.data.BuildConfig
|
||||
import com.kouros.navigation.data.Constants.a9
|
||||
import com.kouros.navigation.data.Constants.a94
|
||||
import com.kouros.navigation.data.Constants.homeVogelhart
|
||||
import com.kouros.navigation.data.Constants.ioannina
|
||||
import com.kouros.navigation.data.Constants.subislawa
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
@@ -92,21 +98,29 @@ class DeviceLocationManager(
|
||||
@SuppressLint("MissingPermission")
|
||||
fun startLocationUpdates(minTimeMs: Long = 1000, minDistanceM: Float = 5f) {
|
||||
if (isListening) return
|
||||
val setIndividualLocation = BuildConfig.DEBUG
|
||||
|
||||
// Get and deliver last known location first
|
||||
val lastLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
|
||||
if (lastLocation != null) {
|
||||
onInitialLocation(lastLocation)
|
||||
onLocationUpdate(lastLocation)
|
||||
if (setIndividualLocation) {
|
||||
onInitialLocation(homeVogelhart)
|
||||
onLocationUpdate(homeVogelhart)
|
||||
} else {
|
||||
onInitialLocation(lastLocation)
|
||||
onLocationUpdate(lastLocation)
|
||||
}
|
||||
}
|
||||
|
||||
// Start continuous location updates
|
||||
locationManager.requestLocationUpdates(
|
||||
LocationManager.GPS_PROVIDER,
|
||||
minTimeMs,
|
||||
minDistanceM,
|
||||
locationListener
|
||||
)
|
||||
if (!setIndividualLocation) {
|
||||
locationManager.requestLocationUpdates(
|
||||
LocationManager.GPS_PROVIDER,
|
||||
minTimeMs,
|
||||
minDistanceM,
|
||||
locationListener
|
||||
)
|
||||
}
|
||||
isListening = true
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
||||
|
||||
var lastRouteDate: LocalDateTime = LocalDateTime.now()
|
||||
|
||||
var lastAlert : Long = 0
|
||||
var navigationManagerStarted = false
|
||||
|
||||
/**
|
||||
@@ -462,29 +463,30 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
||||
* Snaps location to route and checks for deviation requiring reroute.
|
||||
*/
|
||||
private fun handleNavigationLocation(location: Location) {
|
||||
val startTime = System.currentTimeMillis()
|
||||
routeModel.updateLocation(location, navigationViewModel)
|
||||
if (routeModel.navState.arrived) return
|
||||
if (guidanceAudio == 1) {
|
||||
handleGuidanceAudio()
|
||||
}
|
||||
val snappedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
||||
val streetName = routeModel.currentStep().street
|
||||
val currentDate = LocalDateTime.now(ZoneOffset.UTC)
|
||||
|
||||
if (snapLocation(location, streetName)) {
|
||||
checkTraffic(currentDate, location)
|
||||
updateSpeedCamera(location)
|
||||
checkRoute(currentDate, location)
|
||||
if (checkLocationDeviation(location, snappedLocation, streetName)) {
|
||||
if (routeModel.navState.arrived) return
|
||||
if (guidanceAudio == 1) {
|
||||
handleGuidanceAudio()
|
||||
}
|
||||
val currentDate = LocalDateTime.now(ZoneOffset.UTC)
|
||||
checkTraffic(currentDate, snappedLocation)
|
||||
updateSpeedCamera(snappedLocation)
|
||||
checkRoute(currentDate, snappedLocation)
|
||||
updateNavigationScreen()
|
||||
checkArrival()
|
||||
}
|
||||
val endTime = System.currentTimeMillis() - startTime
|
||||
Log.d(TAG, "handleNavigationLocation: $endTime")
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the surface renderer with snapped location and street name.
|
||||
* Checks if maximal route deviation is exceeded and reroutes if needed.
|
||||
* Checks if the location deviation is acceptable.
|
||||
*/
|
||||
private fun snapLocation(location: Location, streetName: String): Boolean {
|
||||
val snappedLocation = snapLocation(location, routeModel.route.maneuverLocations())
|
||||
private fun checkLocationDeviation(location: Location, snappedLocation: Location, streetName: String): Boolean {
|
||||
val distance = location.distanceTo(snappedLocation)
|
||||
when {
|
||||
distance > MAXIMAL_ROUTE_DEVIATION -> {
|
||||
@@ -514,6 +516,9 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
||||
return
|
||||
}
|
||||
|
||||
val currentStep = routeModel.route.currentStep()
|
||||
val stepData = routeModel.currentStep()
|
||||
|
||||
navigationScreen.updateTrip(
|
||||
isNavigating = routeModel.isNavigating(),
|
||||
isRerouting = false,
|
||||
@@ -526,7 +531,8 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
||||
shouldShowNextStep = false,
|
||||
shouldShowLanes = true,
|
||||
junctionImage = null,
|
||||
backGroundColor = routeModel.backGroundColor()
|
||||
backGroundColor = routeModel.backGroundColor(),
|
||||
message = stepData.message,
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -786,18 +792,15 @@ class NavigationSession : CarSession(), NavigationListener, NavigationObserverCa
|
||||
val sortedList = updatedCameras.sortedWith(compareBy { it.distance })
|
||||
val camera = sortedList.firstOrNull() ?: return
|
||||
val bearingRoute = surfaceRenderer.lastLocation.bearingTo(location)
|
||||
val bearingSpeedCamera = if (camera.tags.direction != null) {
|
||||
try {
|
||||
camera.tags.direction!!.toFloat()
|
||||
} catch (e: Exception) {
|
||||
0F
|
||||
}
|
||||
} else {
|
||||
location.bearingTo(location(camera.lon, camera.lat)).absoluteValue
|
||||
val bearingSpeedCamera = try {
|
||||
camera.tags.direction.toFloat()
|
||||
} catch (e: Exception) {
|
||||
0F
|
||||
}
|
||||
if (camera.distance < 80) {
|
||||
if (camera.distance < 80 && (System.currentTimeMillis() - lastAlert > 5000)) {
|
||||
if ((bearingSpeedCamera - bearingRoute.absoluteValue).absoluteValue < 15.0) {
|
||||
routeModel.showSpeedCamera(carContext, camera.distance, camera.tags.maxspeed)
|
||||
lastAlert = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import android.location.Location
|
||||
import android.util.Log
|
||||
import androidx.car.app.AppManager
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.Session
|
||||
import androidx.car.app.SurfaceCallback
|
||||
import androidx.car.app.SurfaceContainer
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@@ -156,8 +155,6 @@ class SurfaceRenderer(
|
||||
Log.i(TAG, "Surface available $surfaceContainer")
|
||||
lifecycleOwner = CustomLifecycleOwner()
|
||||
lifecycleOwner.performRestore(null)
|
||||
// technically, we only really need any one of these instead of all 3
|
||||
// add them to be consistent with the actual lifecycle.
|
||||
lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
|
||||
lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
lifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
@@ -301,7 +298,7 @@ class SurfaceRenderer(
|
||||
) {
|
||||
val cameraDuration =
|
||||
duration(
|
||||
viewStyle == ViewStyle.PREVIEW,
|
||||
viewStyle,
|
||||
position!!.bearing,
|
||||
lastBearing,
|
||||
lastLocationUpdate
|
||||
@@ -351,13 +348,11 @@ class SurfaceRenderer(
|
||||
viewStyle = ViewStyle.PAN_VIEW
|
||||
}
|
||||
val newZoom = if (zoomSign < 0) {
|
||||
cameraPosition.value!!.zoom - 0.2
|
||||
cameraPosition.value!!.zoom - 1
|
||||
} else {
|
||||
cameraPosition.value!!.zoom + 0.2
|
||||
}
|
||||
if (viewStyle == ViewStyle.VIEW) {
|
||||
tilt = calculateTilt(newZoom, tilt)
|
||||
cameraPosition.value!!.zoom + 1
|
||||
}
|
||||
tilt = calculateTilt(viewStyle, newZoom, tilt)
|
||||
updateCameraPosition(
|
||||
cameraPosition.value!!.bearing,
|
||||
newZoom,
|
||||
@@ -411,6 +406,7 @@ class SurfaceRenderer(
|
||||
synchronized(this) {
|
||||
routeData.value = routeGeoJson
|
||||
viewStyle = ViewStyle.VIEW
|
||||
updateLocation(lastLocation, "")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,7 +475,7 @@ class SurfaceRenderer(
|
||||
}
|
||||
viewStyle = ViewStyle.VIEW
|
||||
val zoom = calculateZoom(0.0)
|
||||
tilt = calculateTilt(zoom, tilt)
|
||||
tilt = calculateTilt(viewStyle, zoom, tilt)
|
||||
updateCameraPosition(
|
||||
tilt = tilt,
|
||||
zoom = zoom,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.kouros.navigation.car.map
|
||||
|
||||
import android.location.Location
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
@@ -33,6 +32,7 @@ import com.kouros.navigation.data.NavigationColorLight
|
||||
import com.kouros.navigation.data.RouteColor
|
||||
import com.kouros.navigation.data.SpeedColor
|
||||
import com.kouros.navigation.data.ViewStyle
|
||||
import com.kouros.navigation.utils.GeoUtils.createEndCollection
|
||||
import com.kouros.navigation.utils.isMetricSystem
|
||||
import com.kouros.navigation.utils.location
|
||||
import org.maplibre.compose.camera.CameraPosition
|
||||
@@ -49,11 +49,8 @@ import org.maplibre.compose.layers.Anchor
|
||||
import org.maplibre.compose.layers.FillLayer
|
||||
import org.maplibre.compose.layers.LineLayer
|
||||
import org.maplibre.compose.layers.SymbolLayer
|
||||
import org.maplibre.compose.location.LocationPuck
|
||||
import org.maplibre.compose.location.LocationPuckColors
|
||||
import org.maplibre.compose.location.LocationPuckSizes
|
||||
import org.maplibre.compose.location.UserLocationState
|
||||
import org.maplibre.compose.map.GestureOptions
|
||||
import org.maplibre.compose.map.MapOptions
|
||||
import org.maplibre.compose.map.MaplibreMap
|
||||
import org.maplibre.compose.map.OrnamentOptions
|
||||
@@ -115,6 +112,7 @@ fun MapLibre(
|
||||
AmenityLayer(route)
|
||||
} else {
|
||||
RouteLayer(route, traffic!!)
|
||||
StartEndLayer(route)
|
||||
//RouteLayerPoint(route )
|
||||
}
|
||||
SpeedCameraLayer(speedCameras)
|
||||
@@ -123,6 +121,30 @@ fun MapLibre(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun StartEndLayer(routeData: String?) {
|
||||
if (!routeData.isNullOrEmpty()) {
|
||||
val end = createEndCollection(routeData)
|
||||
val routes = rememberGeoJsonSource(GeoJsonData.JsonString(end))
|
||||
val img = image(painterResource(R.drawable.sports_score_48px), drawAsSdf = true)
|
||||
SymbolLayer(
|
||||
id = "end-layer",
|
||||
source = routes,
|
||||
iconColor = const(Color.Black),
|
||||
iconImage = img,
|
||||
iconSize =
|
||||
interpolate(
|
||||
type = exponential(2.0f),
|
||||
input = zoom(),
|
||||
5 to const(2.0f),
|
||||
10 to const(2.0f),
|
||||
15 to const(3.0f),
|
||||
20 to const(4.0f),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RouteLayer(routeData: String?, trafficData: Map<String, String>) {
|
||||
if (!routeData.isNullOrEmpty()) {
|
||||
@@ -308,8 +330,8 @@ fun DrawNavigationImages(
|
||||
if (speed != null) {
|
||||
CurrentSpeed(width, height, speed, maxSpeed)
|
||||
}
|
||||
if (speed != null && maxSpeed > 0 && (speed * 3.6) > maxSpeed) {
|
||||
MaxSpeed(width, height, maxSpeed)
|
||||
if (speed != null && maxSpeed > 0) { // && (speed * 3.6) > maxSpeed) {
|
||||
MaxSpeed(width, height, maxSpeed, speed)
|
||||
}
|
||||
//DebugInfo(width, height, lat!!)
|
||||
}
|
||||
@@ -325,9 +347,9 @@ fun NavigationImage(
|
||||
|
||||
val imageSize = (height / 8)
|
||||
val navigationColor = if (darkMode)
|
||||
remember { NavigationColorDark }
|
||||
else
|
||||
remember { NavigationColorLight }
|
||||
else
|
||||
remember { NavigationColorDark }
|
||||
|
||||
val textMeasurerStreet = rememberTextMeasurer()
|
||||
val street = streetName.toString()
|
||||
@@ -397,7 +419,7 @@ private fun CurrentSpeed(
|
||||
maxSpeed: Int
|
||||
) {
|
||||
|
||||
val radius = 34
|
||||
val radius = 36
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
@@ -414,12 +436,12 @@ private fun CurrentSpeed(
|
||||
val kmh = if (isMetricSystem()) "km/h" else "mph"
|
||||
|
||||
val styleSpeed = TextStyle(
|
||||
fontSize = 22.sp,
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = Color.White,
|
||||
)
|
||||
val styleKm = TextStyle(
|
||||
fontSize = 12.sp,
|
||||
fontSize = 14.sp,
|
||||
color = Color.White,
|
||||
)
|
||||
val textLayoutSpeed = remember(speed, maxSpeed) {
|
||||
@@ -464,6 +486,7 @@ private fun MaxSpeed(
|
||||
width: Int,
|
||||
height: Int,
|
||||
maxSpeed: Int,
|
||||
curSpeed: Float,
|
||||
) {
|
||||
val radius = 24
|
||||
Box(
|
||||
@@ -484,6 +507,11 @@ private fun MaxSpeed(
|
||||
val textLayoutSpeed = remember(speed) {
|
||||
textMeasurerSpeed.measure(speed, styleSpeed)
|
||||
}
|
||||
val signColor = if (curSpeed * 3.6 > maxSpeed) {
|
||||
Color.Red
|
||||
} else {
|
||||
Color.Green
|
||||
}
|
||||
Canvas(modifier = Modifier.fillMaxSize()) {
|
||||
drawCircle(
|
||||
center = Offset(
|
||||
@@ -491,7 +519,7 @@ private fun MaxSpeed(
|
||||
y = center.y
|
||||
),
|
||||
radius = radius * 1.3.toFloat(),
|
||||
color = Color.Red,
|
||||
color = signColor,
|
||||
)
|
||||
drawCircle(
|
||||
center = Offset(
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.kouros.navigation.car.navigation
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.util.Log
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.car.app.AppManager
|
||||
import androidx.car.app.CarContext
|
||||
@@ -27,6 +28,7 @@ import androidx.car.app.navigation.model.Trip
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.car.screen.createCarIcon
|
||||
import com.kouros.navigation.data.Constants.TAG
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.data.route.ManeuverType
|
||||
import com.kouros.navigation.model.RouteModel
|
||||
@@ -265,7 +267,7 @@ class RouteCarModel : RouteModel() {
|
||||
R.string.exit_action_title, R.string.exit_action_title,
|
||||
FLAG_DEFAULT
|
||||
)
|
||||
return Alert.Builder( /* alertId: */0, title, /* durationMillis: */5000)
|
||||
return Alert.Builder( /* alertId: */0, title, /* durationMillis: */4000)
|
||||
.setSubtitle(subtitle)
|
||||
.setIcon(icon)
|
||||
.addAction(dismissAction).setCallback(object : AlertCallback {
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.os.SystemClock
|
||||
import androidx.lifecycle.LifecycleCoroutineScope
|
||||
import com.kouros.data.BuildConfig
|
||||
import com.kouros.navigation.data.tomtom.TomTomRepository
|
||||
import com.kouros.navigation.utils.location
|
||||
import io.ticofab.androidgpxparser.parser.GPXParser
|
||||
import io.ticofab.androidgpxparser.parser.domain.Gpx
|
||||
import io.ticofab.androidgpxparser.parser.domain.TrackSegment
|
||||
@@ -49,16 +50,16 @@ class Simulation {
|
||||
simulationJob = lifecycleScope.launch {
|
||||
for ((index, point) in points.withIndex()) {
|
||||
if (index >= 0) {
|
||||
curBearing = lastLocation.bearingTo(location(point[0], point[1]))
|
||||
val fakeLocation = Location(LocationManager.FUSED_PROVIDER).apply {
|
||||
latitude = point[1]
|
||||
longitude = point[0]
|
||||
bearing = curBearing
|
||||
speedAccuracyMetersPerSecond = 1.0f // ~1 m/s
|
||||
speed = 5.0f
|
||||
speed = 10.0f
|
||||
time = System.currentTimeMillis()
|
||||
elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
|
||||
}
|
||||
curBearing = lastLocation.bearingTo(fakeLocation)
|
||||
// Update your app's state as if a real GPS update occurred
|
||||
updateLocation(fakeLocation)
|
||||
// Wait before moving to the next point (e.g., every 1 second)
|
||||
|
||||
@@ -120,11 +120,12 @@ class CategoryScreen(
|
||||
|
||||
private fun createItem(it: Elements, category: String, index: Int): Row {
|
||||
var name = ""
|
||||
if (it.tags.name != null) {
|
||||
name = it.tags.name.toString()
|
||||
name = it.tags.name
|
||||
if (name.isEmpty()) {
|
||||
name = it.tags.operator
|
||||
}
|
||||
if (name.isEmpty()) {
|
||||
name = it.tags.operator.toString()
|
||||
name = "Empty"
|
||||
}
|
||||
val row = Row.Builder()
|
||||
.setOnClickListener {
|
||||
|
||||
@@ -81,6 +81,8 @@ open class NavigationScreen(
|
||||
private var junctionImage: CarIcon? = null
|
||||
private var backGroundColor = CarColor.BLUE
|
||||
|
||||
private var message = ""
|
||||
|
||||
private var showAlternativeRoute = false
|
||||
val observerRecentPlaces = Observer<List<Place>> { newPlaces ->
|
||||
recentPlaces.addAll(newPlaces)
|
||||
@@ -220,9 +222,10 @@ open class NavigationScreen(
|
||||
return NavigationTemplate.Builder()
|
||||
.setNavigationInfo(
|
||||
MessageInfo.Builder(
|
||||
carContext.getString(R.string.arrived_exclamation_msg)
|
||||
message
|
||||
//carContext.getString(R.string.arrived_exclamation_msg)
|
||||
)
|
||||
.setText(street)
|
||||
// .setText(street)
|
||||
.setImage(
|
||||
CarIcon.Builder(
|
||||
IconCompat.createWithResource(
|
||||
@@ -504,7 +507,8 @@ open class NavigationScreen(
|
||||
shouldShowNextStep: Boolean,
|
||||
shouldShowLanes: Boolean,
|
||||
junctionImage: CarIcon?,
|
||||
backGroundColor: CarColor
|
||||
backGroundColor: CarColor,
|
||||
message: String
|
||||
) {
|
||||
this.isNavigating = isNavigating
|
||||
this.isRerouting = isRerouting
|
||||
@@ -518,6 +522,7 @@ open class NavigationScreen(
|
||||
this.shouldShowLanes = shouldShowLanes
|
||||
this.junctionImage = junctionImage
|
||||
this.backGroundColor = backGroundColor
|
||||
this.message = message
|
||||
|
||||
navigationType = NavigationType.NAVIGATION
|
||||
invalidate()
|
||||
|
||||
@@ -72,6 +72,7 @@ class RoutePreviewScreen(
|
||||
|
||||
var loading = true
|
||||
|
||||
var previewReady = false;
|
||||
var flag = FLAG_DEFAULT
|
||||
|
||||
private val backPressedCallback = object : OnBackPressedCallback(false) {
|
||||
@@ -85,6 +86,7 @@ class RoutePreviewScreen(
|
||||
routeModel.startNavigation(route)
|
||||
surfaceRenderer.setPreviewRouteData(routeModel)
|
||||
loading = false
|
||||
previewReady = true
|
||||
if (routeModel.route.routes.size == 1 && showAlternativeRoute) {
|
||||
routeType = RoutePreviewType.SINGLE_ROUTE
|
||||
showAlternativeRoute = false
|
||||
@@ -167,7 +169,8 @@ class RoutePreviewScreen(
|
||||
if (routeModel.isNavigating() && routeModel.curRoute.waypoints.isNotEmpty()) {
|
||||
createRouteText(routeModel.route.routes.first())
|
||||
} else {
|
||||
CarText.Builder("Wait")
|
||||
loading = true
|
||||
CarText.Builder(carContext.getString(R.string.wait))
|
||||
.build()
|
||||
}
|
||||
val content = if (routeType == RoutePreviewType.MULTI_ROUTE) {
|
||||
@@ -191,8 +194,10 @@ class RoutePreviewScreen(
|
||||
})
|
||||
val listContent = MessageTemplate.Builder(message)
|
||||
.setHeader(header.build())
|
||||
.addAction(navigateAction)
|
||||
|
||||
if (previewReady) {
|
||||
listContent.addAction(navigateAction)
|
||||
}
|
||||
if (showAlternativeRoute) {
|
||||
listContent.addAction(selectRouteAction)
|
||||
}
|
||||
@@ -212,14 +217,16 @@ class RoutePreviewScreen(
|
||||
|
||||
)
|
||||
if (routeModel.route.routes.size > 1 && routeType == RoutePreviewType.MULTI_ROUTE && !routeSelected) {
|
||||
template.setActionStrip(createActionStrip {
|
||||
createAction(
|
||||
carContext, R.drawable.navigation_48px,
|
||||
onClickAction = {
|
||||
onNavigate(routeModel.navState.currentRouteIndex)
|
||||
}
|
||||
)
|
||||
})
|
||||
if (previewReady) {
|
||||
template.setActionStrip(createActionStrip {
|
||||
createAction(
|
||||
carContext, R.drawable.navigation_48px,
|
||||
onClickAction = {
|
||||
onNavigate(routeModel.navState.currentRouteIndex)
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
return template.build()
|
||||
}
|
||||
@@ -320,7 +327,9 @@ class RoutePreviewScreen(
|
||||
.setTitle(routeText)
|
||||
.setOnClickListener { onRouteSelected(index) }
|
||||
.addText(street)
|
||||
.addAction(navigateAction)
|
||||
if (previewReady) {
|
||||
row.addAction(navigateAction)
|
||||
}
|
||||
if (route.summary.trafficDelay > 60) {
|
||||
row.addText(createDelay(route))
|
||||
row.setImage(createCarIcon(carContext = carContext, R.drawable.traffic_jam_48px))
|
||||
@@ -346,10 +355,12 @@ class RoutePreviewScreen(
|
||||
}
|
||||
|
||||
private fun onNavigate(index: Int) {
|
||||
destination.routeIndex = index
|
||||
destination.route = navigationViewModel.previewRoute.value.toString()
|
||||
setResult(destination)
|
||||
finish()
|
||||
if (previewReady) {
|
||||
destination.routeIndex = index
|
||||
destination.route = navigationViewModel.previewRoute.value.toString()
|
||||
setResult(destination)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onRouteSelected(index: Int) {
|
||||
|
||||
Reference in New Issue
Block a user