Refactoring Route, Speed
This commit is contained in:
@@ -41,12 +41,9 @@ import com.google.android.gms.location.LocationServices
|
|||||||
import com.kouros.navigation.MainApplication.Companion.navigationViewModel
|
import com.kouros.navigation.MainApplication.Companion.navigationViewModel
|
||||||
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE
|
||||||
import com.kouros.navigation.data.Constants.homeLocation
|
import com.kouros.navigation.data.Constants.homeLocation
|
||||||
import com.kouros.navigation.data.NavigationRepository
|
|
||||||
import com.kouros.navigation.data.StepData
|
import com.kouros.navigation.data.StepData
|
||||||
import com.kouros.navigation.data.valhalla.ValhallaRepository
|
|
||||||
import com.kouros.navigation.model.MockLocation
|
import com.kouros.navigation.model.MockLocation
|
||||||
import com.kouros.navigation.model.RouteModel
|
import com.kouros.navigation.model.RouteModel
|
||||||
import com.kouros.navigation.model.ViewModel
|
|
||||||
import com.kouros.navigation.ui.theme.NavigationTheme
|
import com.kouros.navigation.ui.theme.NavigationTheme
|
||||||
import com.kouros.navigation.utils.bearing
|
import com.kouros.navigation.utils.bearing
|
||||||
import com.kouros.navigation.utils.calculateZoom
|
import com.kouros.navigation.utils.calculateZoom
|
||||||
@@ -114,13 +111,16 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
locationManager = getSystemService(LOCATION_SERVICE) as LocationManager
|
locationManager = getSystemService(LOCATION_SERVICE) as LocationManager
|
||||||
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
|
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
|
||||||
|
fusedLocationClient.lastLocation
|
||||||
|
.addOnSuccessListener { location : android.location.Location? ->
|
||||||
if (useMock) {
|
if (useMock) {
|
||||||
mock = MockLocation(locationManager)
|
mock = MockLocation(locationManager)
|
||||||
mock.setMockLocation(
|
mock.setMockLocation(
|
||||||
homeLocation.latitude,
|
location?.latitude ?: homeLocation.latitude,
|
||||||
homeLocation.longitude
|
location?.longitude ?: homeLocation.longitude
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
CheckPermissionScreen()
|
CheckPermissionScreen()
|
||||||
@@ -165,11 +165,6 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
val step: StepData? by stepData.observeAsState()
|
val step: StepData? by stepData.observeAsState()
|
||||||
val nextStep: StepData? by nextStepData.observeAsState()
|
val nextStep: StepData? by nextStepData.observeAsState()
|
||||||
|
|
||||||
fun openSheet() {
|
|
||||||
scope.launch { scaffoldState.bottomSheetState.expand() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun closeSheet() {
|
fun closeSheet() {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
scaffoldState.bottomSheetState.partialExpand()
|
scaffoldState.bottomSheetState.partialExpand()
|
||||||
@@ -242,7 +237,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
if (routeState.maneuverType == 39
|
if (routeState.maneuverType == 39
|
||||||
&& leftStepDistance() < DESTINATION_ARRIVAL_DISTANCE
|
&& leftStepDistance() < DESTINATION_ARRIVAL_DISTANCE
|
||||||
) {
|
) {
|
||||||
stopNavigation()
|
// stopNavigation()
|
||||||
routeState = routeState.copy(arrived = true)
|
routeState = routeState.copy(arrived = true)
|
||||||
routeData.value = ""
|
routeData.value = ""
|
||||||
}
|
}
|
||||||
@@ -305,7 +300,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
for ((index, step) in routeModel.legs.steps.withIndex()) {
|
for ((index, step) in routeModel.legs.steps.withIndex()) {
|
||||||
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
for ((windex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||||
mock.setMockLocation(waypoint[1], waypoint[0])
|
mock.setMockLocation(waypoint[1], waypoint[0])
|
||||||
delay(1000L) //
|
delay(600L) //
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ class RouteCarModel() : RouteModel() {
|
|||||||
|
|
||||||
val dismissAction: Action = createToastAction(
|
val dismissAction: Action = createToastAction(
|
||||||
carContext,
|
carContext,
|
||||||
R.string.speed_camera, R.string.exit_action_title,
|
R.string.exit_action_title, R.string.exit_action_title,
|
||||||
FLAG_DEFAULT
|
FLAG_DEFAULT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ import com.kouros.navigation.data.Place
|
|||||||
import com.kouros.navigation.data.nominatim.SearchResult
|
import com.kouros.navigation.data.nominatim.SearchResult
|
||||||
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.bearing
|
||||||
import com.kouros.navigation.utils.location
|
import com.kouros.navigation.utils.location
|
||||||
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
class NavigationScreen(
|
class NavigationScreen(
|
||||||
carContext: CarContext,
|
carContext: CarContext,
|
||||||
@@ -490,7 +492,12 @@ class NavigationScreen(
|
|||||||
}
|
}
|
||||||
val sortedList = updatedCameras.sortedWith(compareBy { it.distance })
|
val sortedList = updatedCameras.sortedWith(compareBy { it.distance })
|
||||||
val camera = sortedList.first()
|
val camera = sortedList.first()
|
||||||
if (camera.distance < 80) {
|
val bearingSpeedCamera = location.bearingTo(location(camera.lon!!, camera.lat!!))
|
||||||
|
val bearingRoute = surfaceRenderer.lastLocation.bearingTo(location)
|
||||||
|
|
||||||
|
if (camera.distance < 80
|
||||||
|
&& (bearingSpeedCamera.absoluteValue - bearingRoute.absoluteValue).absoluteValue < 15.0
|
||||||
|
) {
|
||||||
routeModel.showSpeedCamera(carContext, camera.distance, camera.tags.maxspeed)
|
routeModel.showSpeedCamera(carContext, camera.distance, camera.tags.maxspeed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,3 +179,6 @@ object Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum class RouteEngine {
|
||||||
|
VALHALLA, OSRM, GRAPHHOPPER
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@ package com.kouros.navigation.data
|
|||||||
|
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
|
import com.kouros.navigation.data.osrm.OsrmResponse
|
||||||
|
import com.kouros.navigation.data.osrm.OsrmRoute
|
||||||
import com.kouros.navigation.data.route.Leg
|
import com.kouros.navigation.data.route.Leg
|
||||||
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
|
||||||
@@ -28,7 +30,7 @@ data class Route(
|
|||||||
|
|
||||||
data class Builder (
|
data class Builder (
|
||||||
|
|
||||||
var routeEngine : Int = 0,
|
var routeEngine : Int = RouteEngine.VALHALLA.ordinal,
|
||||||
var summary: Summary? = null,
|
var summary: Summary? = null,
|
||||||
var legs: List<Leg>? = null,
|
var legs: List<Leg>? = null,
|
||||||
var routeGeoJson: String = "",
|
var routeGeoJson: String = "",
|
||||||
@@ -46,10 +48,14 @@ data class Route(
|
|||||||
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()
|
||||||
|
if (routeEngine == RouteEngine.VALHALLA.ordinal) {
|
||||||
val jsonObject: Map<String, JsonElement> = Json.parseToJsonElement(route).jsonObject
|
val jsonObject: Map<String, JsonElement> = Json.parseToJsonElement(route).jsonObject
|
||||||
val routeJson =
|
val routeJson = gson.fromJson(jsonObject["trip"].toString(), ValhallaResponse::class.java)
|
||||||
gson.fromJson(jsonObject["trip"].toString(), ValhallaResponse::class.java)
|
|
||||||
ValhallaRoute().mapJsonToValhalla(routeJson, this)
|
ValhallaRoute().mapJsonToValhalla(routeJson, this)
|
||||||
|
} else {
|
||||||
|
val osrmJson = gson.fromJson(route, OsrmResponse::class.java)
|
||||||
|
OsrmRoute().mapToOsrm(osrmJson, this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.kouros.navigation.data.osrm
|
|||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
|
|
||||||
data class OsrmJson (
|
data class OsrmResponse (
|
||||||
|
|
||||||
@SerializedName("code" ) var code : String? = null,
|
@SerializedName("code" ) var code : String? = null,
|
||||||
@SerializedName("routes" ) var routes : ArrayList<Routes> = arrayListOf(),
|
@SerializedName("routes" ) var routes : ArrayList<Routes> = arrayListOf(),
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.kouros.navigation.data.osrm
|
||||||
|
|
||||||
|
import com.kouros.navigation.data.Route
|
||||||
|
import com.kouros.navigation.data.valhalla.ValhallaResponse
|
||||||
|
|
||||||
|
class OsrmRoute {
|
||||||
|
|
||||||
|
fun mapToOsrm(routeJson: OsrmResponse, builder: Route.Builder) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ class Overpass {
|
|||||||
|);
|
|);
|
||||||
|out body;
|
|out body;
|
||||||
""".trimMargin()
|
""".trimMargin()
|
||||||
|
println("way[highway](around:$radius,$linestring)")
|
||||||
return overpassApi(httpURLConnection, searchQuery)
|
return overpassApi(httpURLConnection, searchQuery)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +61,6 @@ class Overpass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun overpassApi(httpURLConnection: HttpURLConnection, searchQuery: String) : List<Elements> {
|
fun overpassApi(httpURLConnection: HttpURLConnection, searchQuery: String) : List<Elements> {
|
||||||
// Send the JSON we created
|
|
||||||
val outputStreamWriter = OutputStreamWriter(httpURLConnection.outputStream)
|
val outputStreamWriter = OutputStreamWriter(httpURLConnection.outputStream)
|
||||||
outputStreamWriter.write(searchQuery)
|
outputStreamWriter.write(searchQuery)
|
||||||
outputStreamWriter.flush()
|
outputStreamWriter.flush()
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.kouros.navigation.data.valhalla
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
|
||||||
import kotlinx.serialization.json.JsonIgnoreUnknownKeys
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
|
||||||
@JsonIgnoreUnknownKeys
|
|
||||||
data class Trip (
|
|
||||||
|
|
||||||
@SerializedName("locations" ) var locations : ArrayList<Locations> = arrayListOf(),
|
|
||||||
@SerializedName("legs" ) var legs : ArrayList<Legs> = arrayListOf(),
|
|
||||||
@SerializedName("summary" ) var summaryValhalla : SummaryValhalla = SummaryValhalla(),
|
|
||||||
@SerializedName("status_message" ) var statusMessage : String = "",
|
|
||||||
@SerializedName("status" ) var status : Int = 0,
|
|
||||||
@SerializedName("units" ) var units : String = "",
|
|
||||||
@SerializedName("language" ) var language : String = "",
|
|
||||||
|
|
||||||
)
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.kouros.navigation.data.valhalla
|
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName
|
|
||||||
import kotlinx.serialization.ExperimentalSerializationApi
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import kotlinx.serialization.json.JsonIgnoreUnknownKeys
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
|
||||||
@JsonIgnoreUnknownKeys
|
|
||||||
data class ValhallaJson (
|
|
||||||
|
|
||||||
@SerializedName("trip" ) var trip : Trip = Trip(),
|
|
||||||
@SerializedName("id" ) var id : String = ""
|
|
||||||
|
|
||||||
)
|
|
||||||
@@ -26,7 +26,7 @@ open class RouteModel() {
|
|||||||
val arrived: Boolean = false,
|
val arrived: Boolean = false,
|
||||||
val maneuverType: Int = 0,
|
val maneuverType: Int = 0,
|
||||||
val travelMessage: String = "",
|
val travelMessage: String = "",
|
||||||
// max speed for street (maneuver)
|
val lastSpeedLocation: Location = location(0.0, 0.0),
|
||||||
val lastSpeedIndex: Int = 0,
|
val lastSpeedIndex: Int = 0,
|
||||||
val maxSpeed: Int = 0,
|
val maxSpeed: Int = 0,
|
||||||
)
|
)
|
||||||
@@ -89,9 +89,11 @@ open class RouteModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun updateSpeedLimit(location: Location, viewModel: ViewModel) {
|
fun updateSpeedLimit(location: Location, viewModel: ViewModel) {
|
||||||
// speed limit for each maneuver index
|
// speed limit
|
||||||
if (routeState.lastSpeedIndex < route.currentStep) {
|
val distance = routeState.lastSpeedLocation.distanceTo(location)
|
||||||
|
if (distance > 500 || routeState.lastSpeedIndex < route.currentStep) {
|
||||||
routeState = routeState.copy(lastSpeedIndex = route.currentStep)
|
routeState = routeState.copy(lastSpeedIndex = route.currentStep)
|
||||||
|
routeState = routeState.copy(lastSpeedLocation = location)
|
||||||
val elements = viewModel.getMaxSpeed(location)
|
val elements = viewModel.getMaxSpeed(location)
|
||||||
elements.forEach {
|
elements.forEach {
|
||||||
if (it.tags.name != null && it.tags.maxspeed != null) {
|
if (it.tags.name != null && it.tags.maxspeed != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user