Lanes
This commit is contained in:
@@ -14,8 +14,8 @@ android {
|
|||||||
applicationId = "com.kouros.navigation"
|
applicationId = "com.kouros.navigation"
|
||||||
minSdk = 33
|
minSdk = 33
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 23
|
versionCode = 28
|
||||||
versionName = "0.1.3.23"
|
versionName = "0.1.3.28"
|
||||||
base.archivesName = "navi-$versionName"
|
base.archivesName = "navi-$versionName"
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ 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.homeHohenwaldeck
|
||||||
import com.kouros.navigation.data.Constants.homeLocation
|
import com.kouros.navigation.data.Constants.homeVogelhart
|
||||||
import com.kouros.navigation.data.StepData
|
import com.kouros.navigation.data.StepData
|
||||||
import com.kouros.navigation.model.BaseStyleModel
|
import com.kouros.navigation.model.BaseStyleModel
|
||||||
import com.kouros.navigation.model.MockLocation
|
import com.kouros.navigation.model.MockLocation
|
||||||
@@ -62,7 +62,6 @@ 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
|
||||||
@@ -89,12 +88,14 @@ class MainActivity : ComponentActivity() {
|
|||||||
val observer = Observer<String> { newRoute ->
|
val observer = Observer<String> { newRoute ->
|
||||||
if (newRoute.isNotEmpty()) {
|
if (newRoute.isNotEmpty()) {
|
||||||
routeModel.startNavigation(newRoute, applicationContext)
|
routeModel.startNavigation(newRoute, applicationContext)
|
||||||
routeData.value = routeModel.route.routeGeoJson
|
routeData.value = routeModel.curRoute.routeGeoJson
|
||||||
|
if (useMock) {
|
||||||
simulate()
|
simulate()
|
||||||
//test()
|
//test()
|
||||||
///gpx(applicationContext)
|
///gpx(applicationContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
val cameraPosition = MutableLiveData(
|
val cameraPosition = MutableLiveData(
|
||||||
CameraPosition(
|
CameraPosition(
|
||||||
zoom = 15.0,
|
zoom = 15.0,
|
||||||
@@ -109,8 +110,6 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
private var loadRecentPlaces = false
|
private var loadRecentPlaces = false
|
||||||
|
|
||||||
private var overpass = false
|
|
||||||
|
|
||||||
lateinit var baseStyle: BaseStyle.Json
|
lateinit var baseStyle: BaseStyle.Json
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -132,8 +131,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
if (useMock) {
|
if (useMock) {
|
||||||
mock = MockLocation(locationManager)
|
mock = MockLocation(locationManager)
|
||||||
mock.setMockLocation(
|
mock.setMockLocation(
|
||||||
home2Location.latitude,
|
homeHohenwaldeck.latitude,
|
||||||
home2Location.longitude
|
homeHohenwaldeck.longitude
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,7 +156,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
Content()
|
Content()
|
||||||
// auto navigate
|
// auto navigate
|
||||||
if (useMock) {
|
if (useMock) {
|
||||||
//navigationViewModel.loadRoute(applicationContext, homeLocation, home2Location, 0F)
|
navigationViewModel.loadRoute(applicationContext, homeHohenwaldeck, homeVogelhart, 0F)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -255,7 +254,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
if (isNavigating()) {
|
if (isNavigating()) {
|
||||||
updateLocation(currentLocation, navigationViewModel)
|
updateLocation(currentLocation, navigationViewModel)
|
||||||
stepData.value = currentStep()
|
stepData.value = currentStep()
|
||||||
if (route.currentStep + 1 <= legs.steps.size) {
|
if (route.currentStep + 1 <= curLeg.steps.size) {
|
||||||
nextStepData.value = nextStep()
|
nextStepData.value = nextStep()
|
||||||
}
|
}
|
||||||
if (maneuverType in 39..42
|
if (maneuverType in 39..42
|
||||||
@@ -284,8 +283,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun stopNavigation(closeSheet: () -> Unit) {
|
fun stopNavigation(closeSheet: () -> Unit) {
|
||||||
val latitude = routeModel.route.waypoints!![0][1]
|
val latitude = routeModel.curRoute.waypoints[0][1]
|
||||||
val longitude = routeModel.route.waypoints!![0][0]
|
val longitude = routeModel.curRoute.waypoints[0][0]
|
||||||
closeSheet()
|
closeSheet()
|
||||||
routeModel.stopNavigation()
|
routeModel.stopNavigation()
|
||||||
if (useMock) {
|
if (useMock) {
|
||||||
@@ -325,10 +324,10 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
fun simulate() {
|
fun simulate() {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
for ((index, waypoint) in routeModel.route.waypoints!!.withIndex()) {
|
for ((index, waypoint) in routeModel.curRoute.waypoints.withIndex()) {
|
||||||
if (routeModel.isNavigating()) {
|
if (routeModel.isNavigating()) {
|
||||||
var deviation = 0.0
|
var deviation = 0.0
|
||||||
if (index in 0..routeModel.route.waypoints!!.size) {
|
if (index in 0..routeModel.curRoute.waypoints.size) {
|
||||||
mock.setMockLocation(waypoint[1] + deviation, waypoint[0])
|
mock.setMockLocation(waypoint[1] + deviation, waypoint[0])
|
||||||
delay(500L) //
|
delay(500L) //
|
||||||
}
|
}
|
||||||
@@ -338,7 +337,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
for ((index, step) in routeModel.legs.steps.withIndex()) {
|
for ((index, step) in routeModel.curLeg.steps.withIndex()) {
|
||||||
if (index in 3..3) {
|
if (index in 3..3) {
|
||||||
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||||
routeModel.updateLocation(
|
routeModel.updateLocation(
|
||||||
@@ -349,7 +348,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
if (step.leftStepDistance == 70.0) {
|
if (step.leftStepDistance == 70.0) {
|
||||||
println("")
|
println("")
|
||||||
}
|
}
|
||||||
if (index + 1 <= routeModel.legs.steps.size) {
|
if (index + 1 <= routeModel.curLeg.steps.size) {
|
||||||
//nextStepData.value = routeModel.nextStep()
|
//nextStepData.value = routeModel.nextStep()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ class NavigationSession : Session(), NavigationScreen.Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
@@ -184,7 +183,7 @@ 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,
|
carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL,
|
||||||
carContext.mainExecutor,
|
carContext.mainExecutor,
|
||||||
carCompassListener)
|
carCompassListener)
|
||||||
carSensors.addCarHardwareLocationListener(
|
carSensors.addCarHardwareLocationListener(
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import com.kouros.navigation.car.map.getPaddingValues
|
|||||||
import com.kouros.navigation.car.map.rememberBaseStyle
|
import com.kouros.navigation.car.map.rememberBaseStyle
|
||||||
import com.kouros.navigation.car.navigation.RouteCarModel
|
import com.kouros.navigation.car.navigation.RouteCarModel
|
||||||
import com.kouros.navigation.data.Constants.ROUTING_ENGINE
|
import com.kouros.navigation.data.Constants.ROUTING_ENGINE
|
||||||
import com.kouros.navigation.data.Constants.homeLocation
|
import com.kouros.navigation.data.Constants.homeVogelhart
|
||||||
import com.kouros.navigation.data.ObjectBox
|
import com.kouros.navigation.data.ObjectBox
|
||||||
import com.kouros.navigation.data.RouteEngine
|
import com.kouros.navigation.data.RouteEngine
|
||||||
import com.kouros.navigation.model.RouteModel
|
import com.kouros.navigation.model.RouteModel
|
||||||
@@ -55,11 +55,11 @@ class SurfaceRenderer(
|
|||||||
|
|
||||||
var lastLocation = location(0.0, 0.0)
|
var lastLocation = location(0.0, 0.0)
|
||||||
|
|
||||||
var carOrientation = 0F
|
var carOrientation = 999F
|
||||||
private val cameraPosition = MutableLiveData(
|
private val cameraPosition = MutableLiveData(
|
||||||
CameraPosition(
|
CameraPosition(
|
||||||
zoom = 15.0,
|
zoom = 15.0,
|
||||||
target = Position(latitude = homeLocation.latitude, longitude = homeLocation.longitude)
|
target = Position(latitude = homeVogelhart.latitude, longitude = homeVogelhart.longitude)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
private var visibleArea = MutableLiveData(
|
private var visibleArea = MutableLiveData(
|
||||||
@@ -245,11 +245,14 @@ class SurfaceRenderer(
|
|||||||
fun updateLocation(location: Location) {
|
fun updateLocation(location: Location) {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
if (viewStyle == ViewStyle.VIEW || viewStyle == ViewStyle.PAN_VIEW) {
|
if (viewStyle == ViewStyle.VIEW || viewStyle == ViewStyle.PAN_VIEW) {
|
||||||
val bearing = bearing(
|
val bearing = if (carOrientation == 999F)
|
||||||
|
bearing(
|
||||||
lastLocation,
|
lastLocation,
|
||||||
location,
|
location,
|
||||||
cameraPosition.value!!.bearing
|
cameraPosition.value!!.bearing
|
||||||
)
|
) else {
|
||||||
|
carOrientation.toDouble()
|
||||||
|
}
|
||||||
val zoom = if (viewStyle == ViewStyle.VIEW) {
|
val zoom = if (viewStyle == ViewStyle.VIEW) {
|
||||||
calculateZoom(location.speed.toDouble())
|
calculateZoom(location.speed.toDouble())
|
||||||
} else {
|
} else {
|
||||||
@@ -281,16 +284,16 @@ class SurfaceRenderer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setRouteData() {
|
fun setRouteData() {
|
||||||
routeData.value = routeModel.route.routeGeoJson
|
routeData.value = routeModel.curRoute.routeGeoJson
|
||||||
viewStyle = ViewStyle.VIEW
|
viewStyle = ViewStyle.VIEW
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setPreviewRouteData(routeModel: RouteModel) {
|
fun setPreviewRouteData(routeModel: RouteModel) {
|
||||||
viewStyle = ViewStyle.PREVIEW
|
viewStyle = ViewStyle.PREVIEW
|
||||||
with(routeModel) {
|
with(routeModel) {
|
||||||
routeData.value = route.routeGeoJson
|
routeData.value = curRoute.routeGeoJson
|
||||||
centerLocation = route.centerLocation
|
centerLocation = curRoute.centerLocation
|
||||||
previewDistance = route.summary!!.distance
|
previewDistance = curRoute.summary.distance
|
||||||
}
|
}
|
||||||
updateCameraPosition(
|
updateCameraPosition(
|
||||||
0.0,
|
0.0,
|
||||||
|
|||||||
@@ -158,21 +158,31 @@ fun RouteLayer(routeData: String?) {
|
|||||||
@Composable
|
@Composable
|
||||||
fun AmenityLayer(routeData: String?) {
|
fun AmenityLayer(routeData: String?) {
|
||||||
if (routeData != null && routeData.isNotEmpty()) {
|
if (routeData != null && routeData.isNotEmpty()) {
|
||||||
val color = if (routeData.contains(Constants.PHARMACY)) {
|
var color = const(Color.Red)
|
||||||
const(Color.Red)
|
var img = image(painterResource(R.drawable.local_pharmacy_48px), drawAsSdf = true)
|
||||||
} else if (routeData.contains(Constants.CHARGING_STATION)) {
|
if (routeData.contains(Constants.CHARGING_STATION)) {
|
||||||
const(Color.Blue)
|
color = const(Color.Green)
|
||||||
} else {
|
img = image(painterResource(R.drawable.ev_station_48px), drawAsSdf = true)
|
||||||
const(Color.Black)
|
} else if (routeData.contains(Constants.FUEL_STATION)){
|
||||||
|
color = const(Color.Black)
|
||||||
|
img = image(painterResource(R.drawable.local_gas_station_48px), drawAsSdf = true)
|
||||||
}
|
}
|
||||||
val routes = rememberGeoJsonSource(GeoJsonData.JsonString(routeData))
|
val routes = rememberGeoJsonSource(GeoJsonData.JsonString(routeData))
|
||||||
SymbolLayer(
|
SymbolLayer(
|
||||||
id = "amenity-layer",
|
id = "amenity-layer",
|
||||||
source = routes,
|
source = routes,
|
||||||
iconImage = image(painterResource(R.drawable.ev_station_48px), drawAsSdf = true),
|
iconImage = img,
|
||||||
iconColor = color,
|
iconColor = color,
|
||||||
iconOpacity = const(2.0f),
|
iconOpacity = const(2.0f),
|
||||||
iconSize = const(3.0f),
|
iconSize =
|
||||||
|
interpolate(
|
||||||
|
type = exponential(1.2f),
|
||||||
|
input = zoom(),
|
||||||
|
5 to const(0.7f),
|
||||||
|
6 to const(1.0f),
|
||||||
|
7 to const(2.0f),
|
||||||
|
20 to const(4f),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ class NavigationScreen(
|
|||||||
invalidate()
|
invalidate()
|
||||||
val mainThreadHandler = Handler(carContext.mainLooper)
|
val mainThreadHandler = Handler(carContext.mainLooper)
|
||||||
mainThreadHandler.post {
|
mainThreadHandler.post {
|
||||||
object : CountDownTimer(3000, 1000) {
|
object : CountDownTimer(2000, 1000) {
|
||||||
override fun onTick(millisUntilFinished: Long) {}
|
override fun onTick(millisUntilFinished: Long) {}
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
navigationType = NavigationType.NAVIGATION
|
navigationType = NavigationType.NAVIGATION
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ import androidx.annotation.DrawableRes
|
|||||||
import androidx.car.app.CarContext
|
import androidx.car.app.CarContext
|
||||||
import androidx.car.app.CarToast
|
import androidx.car.app.CarToast
|
||||||
import androidx.car.app.Screen
|
import androidx.car.app.Screen
|
||||||
|
import androidx.car.app.constraints.ConstraintManager
|
||||||
import androidx.car.app.model.Action
|
import androidx.car.app.model.Action
|
||||||
import androidx.car.app.model.Action.FLAG_DEFAULT
|
import androidx.car.app.model.Action.FLAG_DEFAULT
|
||||||
import androidx.car.app.model.Action.FLAG_PRIMARY
|
|
||||||
import androidx.car.app.model.ActionStrip
|
import androidx.car.app.model.ActionStrip
|
||||||
import androidx.car.app.model.CarColor
|
|
||||||
import androidx.car.app.model.CarIcon
|
import androidx.car.app.model.CarIcon
|
||||||
import androidx.car.app.model.CarText
|
import androidx.car.app.model.CarText
|
||||||
import androidx.car.app.model.DurationSpan
|
import androidx.car.app.model.DurationSpan
|
||||||
@@ -18,19 +17,17 @@ import androidx.car.app.model.Header
|
|||||||
import androidx.car.app.model.ItemList
|
import androidx.car.app.model.ItemList
|
||||||
import androidx.car.app.model.ListTemplate
|
import androidx.car.app.model.ListTemplate
|
||||||
import androidx.car.app.model.MessageTemplate
|
import androidx.car.app.model.MessageTemplate
|
||||||
|
import androidx.car.app.model.OnClickListener
|
||||||
import androidx.car.app.model.Row
|
import androidx.car.app.model.Row
|
||||||
import androidx.car.app.model.Template
|
import androidx.car.app.model.Template
|
||||||
import androidx.car.app.navigation.model.MapController
|
import androidx.car.app.navigation.model.MapController
|
||||||
import androidx.car.app.navigation.model.MapWithContentTemplate
|
import androidx.car.app.navigation.model.MapWithContentTemplate
|
||||||
import androidx.car.app.navigation.model.NavigationTemplate
|
|
||||||
import androidx.car.app.navigation.model.RoutingInfo
|
|
||||||
import androidx.core.graphics.drawable.IconCompat
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
import androidx.lifecycle.Observer
|
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.car.navigation.RouteCarModel
|
||||||
import com.kouros.navigation.data.NavigationRepository
|
|
||||||
import com.kouros.navigation.data.Place
|
import com.kouros.navigation.data.Place
|
||||||
import com.kouros.navigation.model.ViewModel
|
import com.kouros.navigation.model.ViewModel
|
||||||
import com.kouros.navigation.utils.location
|
import com.kouros.navigation.utils.location
|
||||||
@@ -79,9 +76,14 @@ class RoutePreviewScreen(
|
|||||||
.setFlags(FLAG_DEFAULT)
|
.setFlags(FLAG_DEFAULT)
|
||||||
.setIcon(navigateActionIcon)
|
.setIcon(navigateActionIcon)
|
||||||
.setOnClickListener { this.onNavigate() }
|
.setOnClickListener { this.onNavigate() }
|
||||||
|
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
val itemListBuilder = ItemList.Builder()
|
||||||
|
var i = 0
|
||||||
|
routeModel.route.routes.forEach { it ->
|
||||||
|
itemListBuilder.addItem(createRow(i++, navigateAction))
|
||||||
|
}
|
||||||
|
|
||||||
val header = Header.Builder()
|
val header = Header.Builder()
|
||||||
.setStartHeaderAction(Action.BACK)
|
.setStartHeaderAction(Action.BACK)
|
||||||
.setTitle(carContext.getString(R.string.route_preview))
|
.setTitle(carContext.getString(R.string.route_preview))
|
||||||
@@ -93,13 +95,30 @@ class RoutePreviewScreen(
|
|||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val message = if (routeModel.isNavigating() && routeModel.route.waypoints!!.isNotEmpty()) {
|
val message =
|
||||||
createRouteText()
|
if (routeModel.isNavigating() && routeModel.curRoute.waypoints!!.isNotEmpty()) {
|
||||||
|
createRouteText(0)
|
||||||
} else {
|
} else {
|
||||||
CarText.Builder("Wait")
|
CarText.Builder("Wait")
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
val messageTemplate = MessageTemplate.Builder(
|
if (routeModel.route.routes.size == 1) {
|
||||||
|
val timer = object : CountDownTimer(5000, 1000) {
|
||||||
|
override fun onTick(millisUntilFinished: Long) {}
|
||||||
|
override fun onFinish() {
|
||||||
|
onNavigate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
val content = if (routeModel.route.routes.size > 1) {
|
||||||
|
ListTemplate.Builder()
|
||||||
|
.setHeader(header)
|
||||||
|
.setSingleList(itemListBuilder.build())
|
||||||
|
.build()
|
||||||
|
} else {
|
||||||
|
MessageTemplate.Builder(
|
||||||
message
|
message
|
||||||
)
|
)
|
||||||
.setHeader(header)
|
.setHeader(header)
|
||||||
@@ -107,16 +126,9 @@ class RoutePreviewScreen(
|
|||||||
.setLoading(message.toString() == "Wait")
|
.setLoading(message.toString() == "Wait")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val timer = object : CountDownTimer(5000, 1000) {
|
|
||||||
override fun onTick(millisUntilFinished: Long) {}
|
|
||||||
override fun onFinish() {
|
|
||||||
//onNavigate()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
timer.start()
|
|
||||||
|
|
||||||
return MapWithContentTemplate.Builder()
|
return MapWithContentTemplate.Builder()
|
||||||
.setContentTemplate(messageTemplate)
|
.setContentTemplate(content)
|
||||||
.setMapController(
|
.setMapController(
|
||||||
MapController.Builder().setMapActionStrip(
|
MapController.Builder().setMapActionStrip(
|
||||||
getMapActionStrip()
|
getMapActionStrip()
|
||||||
@@ -176,10 +188,14 @@ class RoutePreviewScreen(
|
|||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private fun createRouteText(): CarText {
|
private fun createRouteText(index: Int): CarText {
|
||||||
val time = routeModel.route.summary!!.duration
|
val time = routeModel.route.routes[index].summary.duration
|
||||||
|
println("Duration $time")
|
||||||
val length =
|
val length =
|
||||||
BigDecimal(routeModel.route.summary!!.distance).setScale(1, RoundingMode.HALF_EVEN)
|
BigDecimal(routeModel.route.routes[index].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
|
||||||
@@ -188,14 +204,27 @@ class RoutePreviewScreen(
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createRow(index: Int, action: Action): Row {
|
||||||
|
val route = createRouteText(index)
|
||||||
|
val titleText = "$index"
|
||||||
|
return Row.Builder()
|
||||||
|
.setTitle(route)
|
||||||
|
.setOnClickListener(OnClickListener { onRouteSelected(index) })
|
||||||
|
.addText(titleText)
|
||||||
|
.addAction(action)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
private fun onNavigate() {
|
private fun onNavigate() {
|
||||||
setResult(destination)
|
setResult(destination)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onRouteSelected(index: Int) {
|
private fun onRouteSelected(index: Int) {
|
||||||
setResult(destination)
|
routeModel.currentRouteIndex = index
|
||||||
finish()
|
surfaceRenderer.setPreviewRouteData(routeModel)
|
||||||
|
//setResult(destination)
|
||||||
|
//finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMapActionStrip(): ActionStrip {
|
fun getMapActionStrip(): ActionStrip {
|
||||||
|
|||||||
@@ -122,17 +122,8 @@ object Constants {
|
|||||||
|
|
||||||
val categories = listOf("Tankstelle", "Apotheke", "Ladestationen")
|
val categories = listOf("Tankstelle", "Apotheke", "Ladestationen")
|
||||||
/** The initial location to use as an anchor for searches. */
|
/** The initial location to use as an anchor for searches. */
|
||||||
val homeLocation: Location = Location(LocationManager.GPS_PROVIDER)
|
val homeVogelhart = location(11.5793748, 48.185749)
|
||||||
val home2Location: Location = Location(LocationManager.GPS_PROVIDER)
|
val homeHohenwaldeck = location( 11.594322, 48.1164817)
|
||||||
|
|
||||||
init {
|
|
||||||
// Vogelhartstr. 17
|
|
||||||
homeLocation.latitude = 48.185749
|
|
||||||
homeLocation.longitude = 11.5793748
|
|
||||||
// Hohenwaldeckstr. 27
|
|
||||||
home2Location.latitude = 48.1164817
|
|
||||||
home2Location.longitude = 11.594322
|
|
||||||
}
|
|
||||||
|
|
||||||
const val SHARED_PREF_KEY = "NavigationPrefs"
|
const val SHARED_PREF_KEY = "NavigationPrefs"
|
||||||
|
|
||||||
@@ -151,7 +142,7 @@ object Constants {
|
|||||||
|
|
||||||
const val MAXIMAL_SNAP_CORRECTION = 50.0
|
const val MAXIMAL_SNAP_CORRECTION = 50.0
|
||||||
|
|
||||||
const val MAXIMAL_ROUTE_DEVIATION = 100.0
|
const val MAXIMAL_ROUTE_DEVIATION = 80.0
|
||||||
|
|
||||||
const val DESTINATION_ARRIVAL_DISTANCE = 40.0
|
const val DESTINATION_ARRIVAL_DISTANCE = 40.0
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ abstract class NavigationRepository {
|
|||||||
val route = getRoute(currentLocation, location, carOrientation, 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.curRoute.summary.distance
|
||||||
}
|
}
|
||||||
|
|
||||||
fun searchPlaces(search: String, location: Location) : String {
|
fun searchPlaces(search: String, location: Location) : String {
|
||||||
|
|||||||
@@ -21,33 +21,23 @@ import org.maplibre.geojson.Point
|
|||||||
data class Route(
|
data class Route(
|
||||||
|
|
||||||
val routeEngine: Int,
|
val routeEngine: Int,
|
||||||
val summary: Summary?,
|
val routes: List<com.kouros.navigation.data.route.Routes>,
|
||||||
val legs: List<Leg>?,
|
|
||||||
val routeGeoJson: String = "",
|
|
||||||
val centerLocation: Location = location(0.0, 0.0),
|
|
||||||
var currentStep: Int = 0,
|
var currentStep: Int = 0,
|
||||||
val waypoints: List<List<Double>>?,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
data class Builder(
|
data class Builder(
|
||||||
|
|
||||||
var routeEngine: Int = 0,
|
var routeEngine: Int = 0,
|
||||||
var summary: Summary? = null,
|
var summary: Summary = Summary(),
|
||||||
var legs: List<Leg>? = null,
|
var routes: List<com.kouros.navigation.data.route.Routes> = emptyList(),
|
||||||
var routeGeoJson: String = "",
|
|
||||||
var centerLocation: Location = location(0.0, 0.0),
|
|
||||||
var waypoints: List<List<Double>>? = null,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun routeType(routeEngine: Int) = apply { this.routeEngine = routeEngine }
|
fun routeType(routeEngine: Int) = apply { this.routeEngine = routeEngine }
|
||||||
fun summary(summary: Summary) = apply { this.summary = summary }
|
fun routes(routes: List<com.kouros.navigation.data.route.Routes>) = apply {
|
||||||
fun legs(legs: List<Leg>) = apply { this.legs = legs }
|
this.routes = routes
|
||||||
fun routeGeoJson(routeGeoJson: String) = apply {
|
|
||||||
this.routeGeoJson = 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 route(route: String) = apply {
|
fun route(route: String) = apply {
|
||||||
if (route.isNotEmpty() && route != "[]") {
|
if (route.isNotEmpty() && route != "[]") {
|
||||||
val gson = GsonBuilder().serializeNulls().create()
|
val gson = GsonBuilder().serializeNulls().create()
|
||||||
@@ -74,26 +64,30 @@ data class Route(
|
|||||||
fun build(): Route {
|
fun build(): Route {
|
||||||
return Route(
|
return Route(
|
||||||
routeEngine = this.routeEngine,
|
routeEngine = this.routeEngine,
|
||||||
summary = this.summary,
|
routes = this.routes,
|
||||||
legs = this.legs,
|
|
||||||
waypoints = this.waypoints,
|
|
||||||
routeGeoJson = this.routeGeoJson,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildEmpty(): Route {
|
fun buildEmpty(): Route {
|
||||||
return Route(
|
return Route(
|
||||||
routeEngine = 0,
|
routeEngine = 0,
|
||||||
summary = Summary(0.0, 0.0),
|
//summary = Summary(0.0, 0.0),
|
||||||
legs = emptyList(),
|
routes = emptyList(),
|
||||||
waypoints = emptyList(),
|
// legs = emptyList(),
|
||||||
routeGeoJson = "",
|
//waypoints = emptyList(),
|
||||||
|
//routeGeoJson = "",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val legs: List<Leg>
|
||||||
|
get() = routes.first().legs
|
||||||
|
|
||||||
|
|
||||||
fun currentStep(): Step {
|
fun currentStep(): Step {
|
||||||
return if (legs != null && legs.isNotEmpty()) {
|
|
||||||
|
return if (legs.isNotEmpty()) {
|
||||||
legs.first().steps[currentStep]
|
legs.first().steps[currentStep]
|
||||||
} else {
|
} else {
|
||||||
Step(maneuver = Maneuver(waypoints = emptyList(), location = location(0.0, 0.0)))
|
Step(maneuver = Maneuver(waypoints = emptyList(), location = location(0.0, 0.0)))
|
||||||
@@ -102,7 +96,7 @@ data class Route(
|
|||||||
|
|
||||||
fun nextStep(): Step {
|
fun nextStep(): Step {
|
||||||
val nextIndex = currentStep + 1
|
val nextIndex = currentStep + 1
|
||||||
return if (nextIndex < legs!!.first().steps.size) {
|
return if (nextIndex < legs.first().steps.size) {
|
||||||
legs.first().steps[nextIndex]
|
legs.first().steps[nextIndex]
|
||||||
} else {
|
} else {
|
||||||
throw IndexOutOfBoundsException("No next maneuver available.")
|
throw IndexOutOfBoundsException("No next maneuver available.")
|
||||||
|
|||||||
@@ -21,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&alternatives=2"
|
val routeLocation = "${currentLocation.longitude},${currentLocation.latitude};${location.longitude},${location.latitude}?steps=true&alternatives=0"
|
||||||
return fetchUrl(routeUrl + routeLocation + exclude, true)
|
return fetchUrl(routeUrl + routeLocation + exclude, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import com.kouros.navigation.data.route.Leg
|
|||||||
import com.kouros.navigation.data.route.Maneuver as RouteManeuver
|
import com.kouros.navigation.data.route.Maneuver as RouteManeuver
|
||||||
import com.kouros.navigation.data.route.Step
|
import com.kouros.navigation.data.route.Step
|
||||||
import com.kouros.navigation.data.route.Summary
|
import com.kouros.navigation.data.route.Summary
|
||||||
|
import com.kouros.navigation.utils.GeoUtils.createCenterLocation
|
||||||
import com.kouros.navigation.utils.GeoUtils.createLineStringCollection
|
import com.kouros.navigation.utils.GeoUtils.createLineStringCollection
|
||||||
import com.kouros.navigation.utils.GeoUtils.decodePolyline
|
import com.kouros.navigation.utils.GeoUtils.decodePolyline
|
||||||
import com.kouros.navigation.utils.location
|
import com.kouros.navigation.utils.location
|
||||||
@@ -14,26 +15,32 @@ import com.kouros.navigation.utils.location
|
|||||||
class OsrmRoute {
|
class OsrmRoute {
|
||||||
|
|
||||||
fun mapToOsrm(routeJson: OsrmResponse, builder: Route.Builder) {
|
fun mapToOsrm(routeJson: OsrmResponse, builder: Route.Builder) {
|
||||||
val waypoints = mutableListOf<List<Double>>()
|
|
||||||
val summary = Summary()
|
|
||||||
summary.distance = routeJson.routes.first().distance!! / 1000
|
val routes = mutableListOf<com.kouros.navigation.data.route.Routes>()
|
||||||
summary.duration = routeJson.routes.first().duration!! / 1000
|
|
||||||
val steps = mutableListOf<Step>()
|
|
||||||
var stepIndex = 0
|
var stepIndex = 0
|
||||||
routeJson.routes.first().legs.first().steps.forEach {
|
routeJson.routes.forEach { route ->
|
||||||
|
val legs = mutableListOf<Leg>()
|
||||||
|
val waypoints = mutableListOf<List<Double>>()
|
||||||
|
val summary = Summary(route.duration!!, route.distance!! / 1000)
|
||||||
|
route.legs.forEach { leg ->
|
||||||
|
val steps = mutableListOf<Step>()
|
||||||
|
leg.steps.forEach { step ->
|
||||||
val intersections = mutableListOf<Intersection>()
|
val intersections = mutableListOf<Intersection>()
|
||||||
if (it.maneuver != null) {
|
if (step.maneuver != null) {
|
||||||
val points = decodePolyline(it.geometry!!, 5)
|
val points = decodePolyline(step.geometry!!, 5)
|
||||||
waypoints.addAll(points)
|
waypoints.addAll(points)
|
||||||
val maneuver = RouteManeuver(
|
val maneuver = RouteManeuver(
|
||||||
bearingBefore = it.maneuver.bearingBefore ?: 0,
|
bearingBefore = step.maneuver.bearingBefore ?: 0,
|
||||||
bearingAfter = it.maneuver.bearingAfter ?: 0,
|
bearingAfter = step.maneuver.bearingAfter ?: 0,
|
||||||
type = convertType(it.maneuver),
|
type = convertType(step.maneuver),
|
||||||
waypoints = points,
|
waypoints = points,
|
||||||
location = location(it.maneuver.location[0], it.maneuver.location[1])
|
location = location(
|
||||||
|
step.maneuver.location[0],
|
||||||
|
step.maneuver.location[1]
|
||||||
)
|
)
|
||||||
|
)
|
||||||
it.intersections.forEach { it2 ->
|
step.intersections.forEach { it2 ->
|
||||||
if (it2.location[0] != 0.0) {
|
if (it2.location[0] != 0.0) {
|
||||||
val lanes = mutableListOf<Lane>()
|
val lanes = mutableListOf<Lane>()
|
||||||
it2.lanes.forEach { it3 ->
|
it2.lanes.forEach { it3 ->
|
||||||
@@ -51,9 +58,9 @@ class OsrmRoute {
|
|||||||
}
|
}
|
||||||
val step = Step(
|
val step = Step(
|
||||||
index = stepIndex,
|
index = stepIndex,
|
||||||
name = it.name!!,
|
name = step.name!!,
|
||||||
distance = it.distance!! / 1000,
|
distance = step.distance!! / 1000,
|
||||||
duration = it.duration!!,
|
duration = step.duration!!,
|
||||||
maneuver = maneuver,
|
maneuver = maneuver,
|
||||||
intersection = intersections
|
intersection = intersections
|
||||||
)
|
)
|
||||||
@@ -61,14 +68,22 @@ class OsrmRoute {
|
|||||||
stepIndex += 1
|
stepIndex += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val leg = Leg(steps)
|
legs.add(Leg(steps))
|
||||||
|
}
|
||||||
|
val routeGeoJson = createLineStringCollection(waypoints)
|
||||||
|
val centerLocation = createCenterLocation(createLineStringCollection(waypoints))
|
||||||
|
val newRoute = com.kouros.navigation.data.route.Routes(
|
||||||
|
legs,
|
||||||
|
summary,
|
||||||
|
routeGeoJson,
|
||||||
|
centerLocation = centerLocation,
|
||||||
|
waypoints = waypoints
|
||||||
|
)
|
||||||
|
routes.add(newRoute)
|
||||||
|
}
|
||||||
builder
|
builder
|
||||||
.routeType(1)
|
.routeType(1)
|
||||||
.summary(summary)
|
.routes(routes)
|
||||||
.routeGeoJson(createLineStringCollection(waypoints))
|
|
||||||
.legs(listOf(leg))
|
|
||||||
.waypoints(waypoints.toList())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertType(maneuver: Maneuver): Int {
|
fun convertType(maneuver: Maneuver): Int {
|
||||||
@@ -93,12 +108,24 @@ class OsrmRoute {
|
|||||||
|
|
||||||
ManeuverType.continue_.value -> {
|
ManeuverType.continue_.value -> {
|
||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_STRAIGHT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_STRAIGHT
|
||||||
|
if (maneuver.modifier == "right") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_RIGHT
|
||||||
|
}
|
||||||
|
if (maneuver.modifier == "left") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ManeuverType.newName.value -> {
|
ManeuverType.newName.value -> {
|
||||||
if (maneuver.modifier == "straight") {
|
if (maneuver.modifier == "straight") {
|
||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_STRAIGHT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_STRAIGHT
|
||||||
}
|
}
|
||||||
|
if (maneuver.modifier == "slight right") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||||
|
}
|
||||||
|
if (maneuver.modifier == "slight left") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ManeuverType.turn.value,
|
ManeuverType.turn.value,
|
||||||
@@ -110,7 +137,7 @@ class OsrmRoute {
|
|||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_LEFT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||||
}
|
}
|
||||||
if (maneuver.modifier == "straight") {
|
if (maneuver.modifier == "straight") {
|
||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_STRAIGHT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +147,12 @@ class OsrmRoute {
|
|||||||
if (maneuver.modifier == "left") {
|
if (maneuver.modifier == "left") {
|
||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_LEFT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||||
}
|
}
|
||||||
|
if (maneuver.modifier == "slight right") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||||
|
}
|
||||||
|
if (maneuver.modifier == "slight left") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ManeuverType.offRamp.value
|
ManeuverType.offRamp.value
|
||||||
@@ -127,6 +160,15 @@ class OsrmRoute {
|
|||||||
if (maneuver.modifier == "slight right") {
|
if (maneuver.modifier == "slight right") {
|
||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||||
}
|
}
|
||||||
|
if (maneuver.modifier == "right") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_RIGHT
|
||||||
|
}
|
||||||
|
if (maneuver.modifier == "slight left") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT
|
||||||
|
}
|
||||||
|
if (maneuver.modifier == "left") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_NORMAL_LEFT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ManeuverType.fork.value
|
ManeuverType.fork.value
|
||||||
@@ -134,10 +176,6 @@ class OsrmRoute {
|
|||||||
if (maneuver.modifier == "slight left") {
|
if (maneuver.modifier == "slight left") {
|
||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ManeuverType.fork.value
|
|
||||||
-> {
|
|
||||||
if (maneuver.modifier == "slight right") {
|
if (maneuver.modifier == "slight right") {
|
||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||||
}
|
}
|
||||||
@@ -148,6 +186,21 @@ class OsrmRoute {
|
|||||||
if (maneuver.modifier == "slight left") {
|
if (maneuver.modifier == "slight left") {
|
||||||
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_LEFT
|
||||||
}
|
}
|
||||||
|
if (maneuver.modifier == "slight right") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_TURN_SLIGHT_RIGHT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ManeuverType.roundAbout.value
|
||||||
|
-> {
|
||||||
|
if (maneuver.modifier == "right") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ManeuverType.exitRoundabout.value
|
||||||
|
-> {
|
||||||
|
if (maneuver.modifier == "right") {
|
||||||
|
newType = androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_EXIT_CCW
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newType
|
return newType
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,12 @@
|
|||||||
package com.kouros.navigation.data.route
|
package com.kouros.navigation.data.route
|
||||||
|
|
||||||
class Routes (
|
import android.location.Location
|
||||||
var legs : List<Leg> = arrayListOf()
|
import com.kouros.navigation.utils.location
|
||||||
|
|
||||||
|
class Routes(
|
||||||
|
val legs: List<Leg> = arrayListOf(),
|
||||||
|
val summary: Summary,
|
||||||
|
val routeGeoJson: String,
|
||||||
|
val centerLocation: Location = location(0.0, 0.0),
|
||||||
|
val waypoints: List<List<Double>>,
|
||||||
)
|
)
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.kouros.navigation.data.route
|
package com.kouros.navigation.data.route
|
||||||
|
|
||||||
data class Summary(
|
data class Summary(
|
||||||
|
// sec
|
||||||
var duration : Double = 0.0,
|
var duration : Double = 0.0,
|
||||||
|
// km
|
||||||
var distance : Double = 0.0,
|
var distance : Double = 0.0,
|
||||||
)
|
)
|
||||||
@@ -15,9 +15,7 @@ class ValhallaRoute {
|
|||||||
|
|
||||||
fun mapJsonToValhalla(routeJson: ValhallaResponse, builder: Route.Builder) {
|
fun mapJsonToValhalla(routeJson: ValhallaResponse, builder: Route.Builder) {
|
||||||
val waypoints = decodePolyline(routeJson.legs[0].shape)
|
val waypoints = decodePolyline(routeJson.legs[0].shape)
|
||||||
val summary = Summary()
|
val summary = Summary(routeJson.summaryValhalla.time, routeJson.summaryValhalla.length)
|
||||||
summary.distance = routeJson.summaryValhalla.length
|
|
||||||
summary.duration = routeJson.summaryValhalla.time
|
|
||||||
val steps = mutableListOf<Step>()
|
val steps = mutableListOf<Step>()
|
||||||
var stepIndex = 0
|
var stepIndex = 0
|
||||||
routeJson.legs[0].maneuvers.forEach {
|
routeJson.legs[0].maneuvers.forEach {
|
||||||
@@ -39,13 +37,13 @@ class ValhallaRoute {
|
|||||||
steps.add(step)
|
steps.add(step)
|
||||||
stepIndex += 1
|
stepIndex += 1
|
||||||
}
|
}
|
||||||
val leg = Leg(steps)
|
|
||||||
builder
|
builder
|
||||||
.routeType(1)
|
.routeType(1)
|
||||||
.summary(summary)
|
// TODO
|
||||||
.routeGeoJson(createLineStringCollection(waypoints))
|
.routes(emptyList())
|
||||||
.legs(listOf(leg))
|
//.summary(summary)
|
||||||
.waypoints(waypoints)
|
//.routeGeoJson(createLineStringCollection(waypoints))
|
||||||
|
//.waypoints(waypoints)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun convertType(maneuver: Maneuvers): Int {
|
fun convertType(maneuver: Maneuvers): Int {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import com.kouros.navigation.data.StepData
|
|||||||
import com.kouros.navigation.data.route.Intersection
|
import com.kouros.navigation.data.route.Intersection
|
||||||
import com.kouros.navigation.data.route.Lane
|
import com.kouros.navigation.data.route.Lane
|
||||||
import com.kouros.navigation.data.route.Leg
|
import com.kouros.navigation.data.route.Leg
|
||||||
|
import com.kouros.navigation.data.route.Routes
|
||||||
import com.kouros.navigation.data.valhalla.ManeuverType
|
import com.kouros.navigation.data.valhalla.ManeuverType
|
||||||
import com.kouros.navigation.utils.GeoUtils.createCenterLocation
|
|
||||||
import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue
|
import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue
|
||||||
import com.kouros.navigation.utils.location
|
import com.kouros.navigation.utils.location
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -48,9 +48,12 @@ open class RouteModel() {
|
|||||||
var lastLocation: Location = location(0.0, 0.0)
|
var lastLocation: Location = location(0.0, 0.0)
|
||||||
var bearing: Float = 0F
|
var bearing: Float = 0F
|
||||||
|
|
||||||
|
var currentRouteIndex = 0
|
||||||
|
val curRoute: Routes
|
||||||
|
get() = route.routes[currentRouteIndex]
|
||||||
|
|
||||||
val legs: Leg
|
val curLeg: Leg
|
||||||
get() = route.legs!!.first()
|
get() = route.routes[currentRouteIndex].legs.first()
|
||||||
|
|
||||||
fun startNavigation(routeString: String, context: Context) {
|
fun startNavigation(routeString: String, context: Context) {
|
||||||
val routeEngine = getIntKeyValue(context = context, ROUTING_ENGINE)
|
val routeEngine = getIntKeyValue(context = context, ROUTING_ENGINE)
|
||||||
@@ -58,8 +61,6 @@ open class RouteModel() {
|
|||||||
.routeEngine(routeEngine)
|
.routeEngine(routeEngine)
|
||||||
.route(routeString)
|
.route(routeString)
|
||||||
.build()
|
.build()
|
||||||
// TODO:
|
|
||||||
route = route.copy(centerLocation = createCenterLocation(route.routeGeoJson))
|
|
||||||
navigating = true
|
navigating = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ open class RouteModel() {
|
|||||||
route = Route.Builder().buildEmpty()
|
route = Route.Builder().buildEmpty()
|
||||||
navigating = false
|
navigating = false
|
||||||
arrived = false
|
arrived = false
|
||||||
maneuverType = 0
|
maneuverType = Maneuver.TYPE_UNKNOWN
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +81,7 @@ open class RouteModel() {
|
|||||||
|
|
||||||
private fun findStep(location: Location) {
|
private fun findStep(location: Location) {
|
||||||
var nearestDistance = 100000.0f
|
var nearestDistance = 100000.0f
|
||||||
for ((index, step) in legs.steps.withIndex()) {
|
for ((index, step) in curLeg.steps.withIndex()) {
|
||||||
if (index >= route.currentStep) {
|
if (index >= route.currentStep) {
|
||||||
for ((wayIndex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
for ((wayIndex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||||
if (wayIndex >= step.waypointIndex) {
|
if (wayIndex >= step.waypointIndex) {
|
||||||
@@ -149,7 +150,7 @@ open class RouteModel() {
|
|||||||
val distanceToNextStep = leftStepDistance()
|
val distanceToNextStep = leftStepDistance()
|
||||||
val isNearNextManeuver = distanceToNextStep in 0.0..NEXT_STEP_THRESHOLD
|
val isNearNextManeuver = distanceToNextStep in 0.0..NEXT_STEP_THRESHOLD
|
||||||
val shouldAdvance =
|
val shouldAdvance =
|
||||||
isNearNextManeuver && route.currentStep < (route.legs!!.first().steps.size)
|
isNearNextManeuver && route.currentStep < (route.legs.first().steps.size)
|
||||||
|
|
||||||
// Determine the maneuver type and corresponding icon
|
// Determine the maneuver type and corresponding icon
|
||||||
var curManeuverType = if (hasArrived(currentStep.maneuver.type)) {
|
var curManeuverType = if (hasArrived(currentStep.maneuver.type)) {
|
||||||
@@ -221,8 +222,8 @@ open class RouteModel() {
|
|||||||
fun travelLeftTime(): Double {
|
fun travelLeftTime(): Double {
|
||||||
var timeLeft = 0.0
|
var timeLeft = 0.0
|
||||||
// time for next step until end step
|
// time for next step until end step
|
||||||
for (i in route.currentStep + 1..<legs.steps.size) {
|
for (i in route.currentStep + 1..<curLeg.steps.size) {
|
||||||
val step = legs.steps[i]
|
val step = curLeg.steps[i]
|
||||||
timeLeft += step.duration
|
timeLeft += step.duration
|
||||||
}
|
}
|
||||||
// time for current step
|
// time for current step
|
||||||
@@ -261,7 +262,7 @@ open class RouteModel() {
|
|||||||
/** Returns the left distance in km. */
|
/** Returns the left distance in km. */
|
||||||
fun travelLeftDistance(): Double {
|
fun travelLeftDistance(): Double {
|
||||||
var leftDistance = 0.0
|
var leftDistance = 0.0
|
||||||
for (i in route.currentStep + 1..<legs.steps.size) {
|
for (i in route.currentStep + 1..<curLeg.steps.size) {
|
||||||
val step = route.legs!![0].steps[i]
|
val step = route.legs!![0].steps[i]
|
||||||
leftDistance += step.distance
|
leftDistance += step.distance
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,6 +302,11 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun saveRecent(place: Place) {
|
fun saveRecent(place: Place) {
|
||||||
|
if (place.category == Constants.FUEL_STATION
|
||||||
|
|| place.category == Constants.CHARGING_STATION
|
||||||
|
|| place.category == Constants.PHARMACY) {
|
||||||
|
return
|
||||||
|
}
|
||||||
place.category = Constants.RECENT
|
place.category = Constants.RECENT
|
||||||
savePlace(place)
|
savePlace(place)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,16 +92,16 @@ fun calculateZoom(speed: Double?): Double {
|
|||||||
in 61..70 -> 16.5
|
in 61..70 -> 16.5
|
||||||
else -> 16.0
|
else -> 16.0
|
||||||
}
|
}
|
||||||
return zoom.toDouble()
|
return zoom
|
||||||
}
|
}
|
||||||
|
|
||||||
fun previewZoom(previewDistance: Double): Double {
|
fun previewZoom(previewDistance: Double): Double {
|
||||||
when (previewDistance) {
|
when (previewDistance) {
|
||||||
in 0.0..10.0 -> return 13.0
|
in 0.0..10.0 -> return 13.5
|
||||||
in 10.0..20.0 -> return 11.0
|
in 10.0..20.0 -> return 11.5
|
||||||
in 20.0..30.0 -> return 10.0
|
in 20.0..30.0 -> return 10.5
|
||||||
}
|
}
|
||||||
return 9.0
|
return 9.5
|
||||||
}
|
}
|
||||||
|
|
||||||
fun calculateTilt(newZoom: Double, tilt: Double): Double =
|
fun calculateTilt(newZoom: Double, tilt: Double): Double =
|
||||||
|
|||||||
@@ -47,6 +47,6 @@
|
|||||||
<string name="pharmacy">Apotheke</string>
|
<string name="pharmacy">Apotheke</string>
|
||||||
<string name="charging_station">Ladestation</string>
|
<string name="charging_station">Ladestation</string>
|
||||||
<string name="speed_camera">Speed camera</string>
|
<string name="speed_camera">Speed camera</string>
|
||||||
<string name="use_car_location">Auto Location verwenden</string>
|
<string name="use_car_location">Auto GPS verwenden</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.13.2"
|
agp = "9.0.0"
|
||||||
androidSdkTurf = "6.0.1"
|
androidSdkTurf = "6.0.1"
|
||||||
gradle = "8.13.2"
|
gradle = "9.0.0"
|
||||||
koinAndroid = "4.1.1"
|
koinAndroid = "4.1.1"
|
||||||
koinAndroidxCompose = "4.1.1"
|
koinAndroidxCompose = "4.1.1"
|
||||||
koinComposeViewmodel = "4.1.1"
|
koinComposeViewmodel = "4.1.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user