Overpass, Traffic
This commit is contained in:
@@ -4,9 +4,9 @@ import androidx.compose.ui.graphics.Color
|
||||
|
||||
val NavigationColorLight = Color(0xFF17A119)
|
||||
|
||||
val NavigationColorDark = Color(0xFF03411F)
|
||||
val NavigationColorDark = Color(0xFF07568C)
|
||||
|
||||
val RouteColor = Color(0xFF195D02)
|
||||
val RouteColor = Color(0xFF5201B4)
|
||||
|
||||
val SpeedColor = Color(0xFF262525)
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.kouros.navigation.data.tomtom.TomTomRoute
|
||||
import com.kouros.navigation.data.valhalla.ValhallaResponse
|
||||
import com.kouros.navigation.data.valhalla.ValhallaRoute
|
||||
import com.kouros.navigation.utils.location
|
||||
import kotlinx.coroutines.selects.whileSelect
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
@@ -102,16 +103,22 @@ data class Route(
|
||||
return if (isRouteValid()) {
|
||||
legs().first().steps[currentStepIndex]
|
||||
} else {
|
||||
Step(maneuver = Maneuver(waypoints = emptyList(), location = location(0.0, 0.0)))
|
||||
Step(maneuver = Maneuver(waypoints = emptyList(), location = location(0.0, 0.0), leftDistance = emptyList()))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maneuver locations to snap location
|
||||
*/
|
||||
fun maneuverLocations(): List<Point> {
|
||||
val wayPointIndex = currentStep().waypointIndex
|
||||
val waypoints = currentStep().maneuver.waypoints
|
||||
val points = mutableListOf<Point>()
|
||||
for (loc in waypoints) {
|
||||
val point = Point.fromLngLat(loc[0], loc[1])
|
||||
points.add(point)
|
||||
for ((index,loc) in waypoints.withIndex()) {
|
||||
if (index >= wayPointIndex && points.size < 20) {
|
||||
val point = Point.fromLngLat(loc[0], loc[1])
|
||||
points.add(point)
|
||||
}
|
||||
}
|
||||
return points
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.kouros.navigation.utils.GeoUtils.createCenterLocation
|
||||
import com.kouros.navigation.utils.GeoUtils.createLineStringCollection
|
||||
import com.kouros.navigation.utils.GeoUtils.decodePolyline
|
||||
import com.kouros.navigation.utils.location
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
class OsrmRoute {
|
||||
|
||||
@@ -27,8 +28,22 @@ class OsrmRoute {
|
||||
val steps = mutableListOf<Step>()
|
||||
leg.steps.forEach { step ->
|
||||
val intersections = mutableListOf<Intersection>()
|
||||
val leftDistance = mutableListOf<Float>()
|
||||
var lastLocation = location(0.0,0.0)
|
||||
val points = decodePolyline(step.geometry, 5)
|
||||
waypoints.addAll(points)
|
||||
// calculate left step distance for each point
|
||||
var leftStepDistance = step.distance
|
||||
leftDistance.add(leftStepDistance.toFloat())
|
||||
points.forEach {
|
||||
if (lastLocation.latitude != 0.0) {
|
||||
val curLocation = location(it[0], it[1])
|
||||
val dist = curLocation.distanceTo(lastLocation).absoluteValue
|
||||
leftStepDistance -= dist
|
||||
leftDistance.add(leftStepDistance.toFloat())
|
||||
}
|
||||
lastLocation = location(it[0], it[1])
|
||||
}
|
||||
val maneuver = RouteManeuver(
|
||||
bearingBefore = step.maneuver.bearingBefore,
|
||||
bearingAfter = step.maneuver.bearingAfter,
|
||||
@@ -38,7 +53,8 @@ class OsrmRoute {
|
||||
location = location(
|
||||
step.maneuver.location[0],
|
||||
step.maneuver.location[1]
|
||||
)
|
||||
),
|
||||
leftDistance = leftDistance
|
||||
)
|
||||
step.intersections.forEach { it2 ->
|
||||
if (it2.location[0] != 0.0) {
|
||||
|
||||
@@ -56,7 +56,6 @@ class Overpass {
|
||||
""".trimMargin()
|
||||
|
||||
Log.d("OverpassApi", "Overpass Query: $searchQuery")
|
||||
|
||||
val connection = (URL(overpassUrl).openConnection() as HttpURLConnection).apply {
|
||||
requestMethod = "POST"
|
||||
setRequestProperty("Accept", "application/json")
|
||||
|
||||
@@ -9,6 +9,7 @@ data class Tags(
|
||||
val lanes: String = "",
|
||||
val lit: String = "",
|
||||
val maxspeed: String = "0",
|
||||
@SerializedName("maxspeed:variable") val maxSpeedVariable: String = "",
|
||||
val name: String = "",
|
||||
val oneway: String = "",
|
||||
val ref: String = "",
|
||||
|
||||
@@ -12,6 +12,7 @@ data class Maneuver(
|
||||
val street: String = "",
|
||||
val message: String = "",
|
||||
val pointIndex: Int = 0,
|
||||
val leftDistance: List<Float>
|
||||
)
|
||||
|
||||
enum class ManeuverType(val value: Int) {
|
||||
|
||||
@@ -40,8 +40,8 @@ class TomTomRepository : NavigationRepository() {
|
||||
}
|
||||
if (useLocal) {
|
||||
return fetchUrl(
|
||||
//"http://192.168.1.37/tomtom_routing.json",
|
||||
"http://192.168.1.37/verona.json",
|
||||
"http://192.168.1.37/tomtom_routing.json",
|
||||
//"http://192.168.1.37/verona.json",
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@ 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.decodePolyline
|
||||
import com.kouros.navigation.utils.isNumeric
|
||||
import com.kouros.navigation.utils.location
|
||||
import kotlin.math.absoluteValue
|
||||
import com.kouros.navigation.data.route.Maneuver as RouteManeuver
|
||||
|
||||
|
||||
@@ -53,6 +55,27 @@ class TomTomRoute {
|
||||
val instruction = route.guidance.instructions[index]
|
||||
val street = lastInstruction.street ?: ""
|
||||
val maneuverStreet = instruction.street ?: ""
|
||||
val leftDistance = mutableListOf<Float>()
|
||||
var lastLocation = location(0.0, 0.0)
|
||||
stepDistance =
|
||||
route.guidance.instructions[index].routeOffsetInMeters - stepDistance
|
||||
stepDuration =
|
||||
route.guidance.instructions[index].travelTimeInSeconds - stepDuration
|
||||
// calculate left step distance for each point
|
||||
var leftStepDistance = stepDistance
|
||||
leftDistance.add(leftStepDistance.toFloat())
|
||||
points.subList(
|
||||
lastPointIndex,
|
||||
instruction.pointIndex + 1,
|
||||
).forEach {
|
||||
if (lastLocation.latitude != 0.0) {
|
||||
val curLocation = location(it[0], it[1])
|
||||
val dist = curLocation.distanceTo(lastLocation).absoluteValue
|
||||
leftStepDistance -= dist
|
||||
leftDistance.add(leftStepDistance.toFloat())
|
||||
}
|
||||
lastLocation = location(it[0], it[1])
|
||||
}
|
||||
val maneuver = RouteManeuver(
|
||||
bearingBefore = 0,
|
||||
bearingAfter = 0,
|
||||
@@ -67,9 +90,9 @@ class TomTomRoute {
|
||||
),
|
||||
street = maneuverStreet,
|
||||
message = instruction.message,
|
||||
pointIndex = instruction.pointIndex
|
||||
pointIndex = instruction.pointIndex,
|
||||
leftDistance = leftDistance
|
||||
)
|
||||
|
||||
lastPointIndex = instruction.pointIndex
|
||||
val intersections = mutableListOf<Intersection>()
|
||||
route.sections?.forEach { section ->
|
||||
@@ -95,10 +118,7 @@ class TomTomRoute {
|
||||
intersections.add(Intersection(waypoints[startIndex], lanes))
|
||||
}
|
||||
}
|
||||
stepDistance =
|
||||
route.guidance.instructions[index].routeOffsetInMeters - stepDistance
|
||||
stepDuration =
|
||||
route.guidance.instructions[index].travelTimeInSeconds - stepDuration
|
||||
|
||||
val roadNumbers = if (lastInstruction.roadNumbers != null) {
|
||||
lastInstruction.roadNumbers
|
||||
} else {
|
||||
@@ -212,6 +232,7 @@ class TomTomRoute {
|
||||
"TAKE_EXIT" -> {
|
||||
newType = ManeuverType.TYPE_TURN_SLIGHT_RIGHT.value
|
||||
}
|
||||
|
||||
"WAYPOINT_RIGHT" -> {
|
||||
newType = ManeuverType.TYPE_WAYPOINT_RIGHT.value
|
||||
}
|
||||
@@ -227,9 +248,9 @@ private fun exitNumber(
|
||||
) {
|
||||
0
|
||||
} else {
|
||||
try {
|
||||
if (isNumeric(instruction.exitNumber)) {
|
||||
instruction.exitNumber.toInt()
|
||||
} catch (e: NumberFormatException) {
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ class ValhallaRoute {
|
||||
type = convertType(it),
|
||||
waypoints =waypoints.subList(it.beginShapeIndex, it.endShapeIndex+1),
|
||||
// TODO: calculate from ShapeIndex !
|
||||
location = location(0.0, 0.0)
|
||||
location = location(0.0, 0.0),
|
||||
leftDistance = emptyList()
|
||||
|
||||
)
|
||||
var name = ""
|
||||
|
||||
@@ -2,12 +2,14 @@ package com.kouros.navigation.model
|
||||
|
||||
import android.content.Context
|
||||
import android.location.Location
|
||||
import android.util.Log
|
||||
|
||||
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||
import androidx.compose.runtime.toMutableStateList
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Constants.SPEED_BEARING_DEVIATION
|
||||
@@ -24,6 +26,7 @@ import com.kouros.navigation.data.overpass.Overpass
|
||||
import com.kouros.navigation.utils.bearingPositive
|
||||
import com.kouros.navigation.utils.countryCodeSpeedLimit
|
||||
import com.kouros.navigation.utils.getSettingsRepository
|
||||
import com.kouros.navigation.utils.isNumeric
|
||||
import com.kouros.navigation.utils.location
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
@@ -115,7 +118,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
|
||||
MutableLiveData()
|
||||
}
|
||||
|
||||
val gson: com.google.gson.Gson = GsonBuilder().create()
|
||||
val gson: Gson = GsonBuilder().create()
|
||||
|
||||
/**
|
||||
* Retrieves recent places from Preferences as a Flow.
|
||||
@@ -432,7 +435,7 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
|
||||
val search = mutableListOf<ElementSearch>()
|
||||
|
||||
speedElements.filter { it.type == "way"}.forEach {
|
||||
var distance = 0F
|
||||
var distance: Float
|
||||
var maxDistance = 1000F
|
||||
var geometryFirstLocation = location(0.0, 0.0)
|
||||
var geometryLastLocation = location(0.0, 0.0)
|
||||
@@ -466,7 +469,11 @@ class NavigationViewModel(private val repository: NavigationRepository) : ViewMo
|
||||
speed = if (element.tags.maxspeed == "none" && element.tags.highway == "motorway") {
|
||||
countryCodeSpeedLimit(countryCode)
|
||||
} else {
|
||||
element.tags.maxspeed.toInt()
|
||||
if (isNumeric(element.tags.maxspeed)) {
|
||||
element.tags.maxspeed.toInt()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
return speed
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.kouros.navigation.data.Constants.NEAREST_LOCATION_DISTANCE
|
||||
import com.kouros.navigation.data.Constants.SPEED_UPDATE_DISTANCE
|
||||
import com.kouros.navigation.utils.location
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
class RouteCalculator(var routeModel: RouteModel) {
|
||||
|
||||
@@ -17,10 +18,11 @@ class RouteCalculator(var routeModel: RouteModel) {
|
||||
fun findStep(location: Location) {
|
||||
var nearestDistance = MAXIMUM_LOCATION_DISTANCE
|
||||
for ((index, step) in routeModel.curLeg.steps.withIndex()) {
|
||||
var distance = 0F
|
||||
if (index >= routeModel.navState.route.currentStepIndex) {
|
||||
for ((wayIndex, waypoint) in step.maneuver.waypoints.withIndex()) {
|
||||
if (wayIndex >= step.waypointIndex) {
|
||||
val distance = location.distanceTo(location(waypoint[0], waypoint[1]))
|
||||
distance = location.distanceTo(location(waypoint[0], waypoint[1]))
|
||||
if (distance < nearestDistance) {
|
||||
nearestDistance = distance
|
||||
routeModel.navState.route.currentStepIndex = step.index
|
||||
@@ -28,9 +30,12 @@ class RouteCalculator(var routeModel: RouteModel) {
|
||||
step.wayPointLocation = location(waypoint[0], waypoint[1])
|
||||
}
|
||||
}
|
||||
if (nearestDistance < NEAREST_LOCATION_DISTANCE && distance > NEAREST_LOCATION_DISTANCE * 10) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nearestDistance < NEAREST_LOCATION_DISTANCE) {
|
||||
if (nearestDistance < NEAREST_LOCATION_DISTANCE && distance > NEAREST_LOCATION_DISTANCE * 10) {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -69,19 +74,15 @@ class RouteCalculator(var routeModel: RouteModel) {
|
||||
fun leftStepDistance(): Double {
|
||||
val step = routeModel.route.currentStep()
|
||||
var leftDistance = 0F
|
||||
for (i in step.waypointIndex..<step.maneuver.waypoints.size - 1) {
|
||||
val loc1 = location(step.maneuver.waypoints[i][0], step.maneuver.waypoints[i][1])
|
||||
val loc2 =
|
||||
location(step.maneuver.waypoints[i + 1][0], step.maneuver.waypoints[i + 1][1])
|
||||
val locationDistance = loc1.distanceTo(routeModel.navState.lastLocation)
|
||||
val distance = loc1.distanceTo(loc2)
|
||||
leftDistance += if (locationDistance < distance) {
|
||||
locationDistance
|
||||
} else {
|
||||
distance
|
||||
if (step.waypointIndex < step.maneuver.waypoints.size -1) {
|
||||
leftDistance = step.maneuver.leftDistance[step.waypointIndex]
|
||||
val waypointLocation = location(step.maneuver.waypoints[step.waypointIndex][0], step.maneuver.waypoints[step.waypointIndex][1])
|
||||
if (routeModel.navState.lastLocation.latitude != 0.0) {
|
||||
val locationDistance = waypointLocation.distanceTo(routeModel.navState.lastLocation)
|
||||
leftDistance -= locationDistance
|
||||
}
|
||||
}
|
||||
return leftDistance.toDouble()
|
||||
return leftDistance.absoluteValue.toDouble()
|
||||
}
|
||||
|
||||
/** Returns the left distance in m. */
|
||||
|
||||
@@ -139,6 +139,11 @@ fun Double.round(numFractionDigits: Int): Double {
|
||||
return (this * factor).roundToInt() / factor
|
||||
}
|
||||
|
||||
fun isNumeric(toCheck: String): Boolean {
|
||||
val regex = "-?[0-9]+(\\.[0-9]+)?".toRegex()
|
||||
return toCheck.matches(regex)
|
||||
}
|
||||
|
||||
fun duration(
|
||||
viewStyle: ViewStyle,
|
||||
bearing: Double,
|
||||
|
||||
@@ -44,7 +44,7 @@ class RouteModelTest {
|
||||
return Step(
|
||||
index = index,
|
||||
waypointIndex = waypointIndex,
|
||||
maneuver = Maneuver(waypoints = waypoints, location = mock()),
|
||||
maneuver = Maneuver(waypoints = waypoints, location = mock(), leftDistance = mock()),
|
||||
duration = duration,
|
||||
distance = distance,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user