TomTom Routing

This commit is contained in:
Dimitris
2026-02-09 08:44:57 +01:00
parent 0d51c6121d
commit e9474695bf
8 changed files with 95 additions and 70 deletions

View File

@@ -33,12 +33,6 @@ abstract class NavigationRepository {
//private val nominatimUrl = "https://kouros-online.de/nominatim/"
val tomtomApiKey = "678k5v6940cSXXIS5oD92qIrDgW3RBZ3"
private val tomtomUrl = "https://api.tomtom.com/traffic/services/5/incidentDetails"
private val tomtomFields =
"{incidents{type,geometry{type,coordinates},properties{iconCategory,events{description}}}}"
abstract fun getRoute(
context: Context,
@@ -48,6 +42,7 @@ abstract class NavigationRepository {
searchFilter: SearchFilter
): String
abstract fun getTraffic(context: Context, location: Location, carOrientation: Float): String
fun getRouteDistance(
currentLocation: Location,
location: Location,
@@ -78,23 +73,7 @@ abstract class NavigationRepository {
)
}
fun getTraffic(context: Context, location: Location, carOrientation: Float): String {
val useAsset = false
val bbox = calculateSquareRadius(location.latitude, location.longitude, 15.0)
return if (useAsset) {
val trafficJson = context.resources.openRawResource(R.raw.tomtom_traffic)
trafficJson.bufferedReader().use { it.readText() }
} else {
val trafficResult = fetchUrl(
"$tomtomUrl?key=$tomtomApiKey&bbox=$bbox&fields=$tomtomFields&language=en-GB&timeValidityFilter=present",
false
)
trafficResult.replace(
"{\"incidents\":",
"{\"type\": \"FeatureCollection\", \"features\":"
)
}
}
fun fetchUrl(url: String, authenticator: Boolean): String {
try {

View File

@@ -26,4 +26,12 @@ class OsrmRepository : NavigationRepository() {
val routeLocation = "${currentLocation.longitude},${currentLocation.latitude};${location.longitude},${location.latitude}?steps=true&alternatives=0"
return fetchUrl(routeUrl + routeLocation + exclude, true)
}
override fun getTraffic(
context: Context,
location: Location,
carOrientation: Float
): String {
TODO("Not yet implemented")
}
}

View File

@@ -5,10 +5,19 @@ import android.location.Location
import com.kouros.data.R
import com.kouros.navigation.data.NavigationRepository
import com.kouros.navigation.data.SearchFilter
import com.kouros.navigation.utils.GeoUtils.calculateSquareRadius
private const val routeUrl = "https://api.tomtom.com/routing/1/calculateRoute/"
val tomtomApiKey = "678k5v6940cSXXIS5oD92qIrDgW3RBZ3"
val tomtomTrafficUrl = "https://api.tomtom.com/traffic/services/5/incidentDetails"
private val tomtomFields =
"{incidents{type,geometry{type,coordinates},properties{iconCategory,events{description}}}}"
class TomTomRepository : NavigationRepository() {
override fun getRoute(
context: Context,
@@ -17,9 +26,9 @@ class TomTomRepository : NavigationRepository() {
carOrientation: Float,
searchFilter: SearchFilter
): String {
//val routeJson = context.resources.openRawResource(R.raw.tomom_routing)
//val routeJsonString = routeJson.bufferedReader().use { it.readText() }
//return routeJsonString
val routeJson = context.resources.openRawResource(R.raw.tomom_routing)
val routeJsonString = routeJson.bufferedReader().use { it.readText() }
return routeJsonString
val url =
routeUrl + "${currentLocation.latitude},${currentLocation.longitude}:${location.latitude},${location.longitude}" +
"/json?vehicleHeading=90&sectionType=traffic&report=effectiveSettings&routeType=eco" +
@@ -33,4 +42,22 @@ class TomTomRepository : NavigationRepository() {
false
)
}
override fun getTraffic(context: Context, location: Location, carOrientation: Float): String {
val useAsset = true
val bbox = calculateSquareRadius(location.latitude, location.longitude, 15.0)
return if (useAsset) {
val trafficJson = context.resources.openRawResource(R.raw.tomtom_traffic)
trafficJson.bufferedReader().use { it.readText() }
} else {
val trafficResult = fetchUrl(
"$tomtomTrafficUrl?key=$tomtomApiKey&bbox=$bbox&fields=$tomtomFields&language=en-GB&timeValidityFilter=present",
false
)
trafficResult.replace(
"{\"incidents\":",
"{\"type\": \"FeatureCollection\", \"features\":"
)
}
}
}

View File

@@ -47,4 +47,12 @@ class ValhallaRepository : NavigationRepository() {
val routeLocation = Json.encodeToString(valhallaLocation)
return fetchUrl(routeUrl + routeLocation, true)
}
override fun getTraffic(
context: Context,
location: Location,
carOrientation: Float
): String {
TODO("Not yet implemented")
}
}

View File

@@ -136,25 +136,25 @@ open class RouteModel() {
}
return lanes
var inter = Intersection()
var nearestDistance = 100000.0f
route.currentStep().intersection.forEach {
if (it.lane.isNotEmpty()) {
val distance = location.distanceTo(location(it.location[0], it.location[1]))
val interBearing = location.bearingTo(location(it.location[0], it.location[1]))
if (distance < nearestDistance) {
nearestDistance = distance
if (distance <= NEXT_STEP_THRESHOLD * 3) {
if (route.routeEngine == RouteEngine.TOMTOM.ordinal
|| (interBearing.absoluteValue - route.currentStep().maneuver.bearingAfter.absoluteValue).absoluteValue < 20
) {
inter = it
}
}
}
}
}
return inter.lane
// var inter = Intersection()
// var nearestDistance = 100000.0f
// route.currentStep().intersection.forEach {
// if (it.lane.isNotEmpty()) {
// val distance = location.distanceTo(location(it.location[0], it.location[1]))
// val interBearing = location.bearingTo(location(it.location[0], it.location[1]))
// if (distance < nearestDistance) {
// nearestDistance = distance
// if (distance <= NEXT_STEP_THRESHOLD * 3) {
// if (route.routeEngine == RouteEngine.TOMTOM.ordinal
// || (interBearing.absoluteValue - route.currentStep().maneuver.bearingAfter.absoluteValue).absoluteValue < 20
// ) {
// inter = it
// }
// }
// }
// }
// }
// return inter.lane
}
fun updateSpeedLimit(location: Location, viewModel: ViewModel) = runBlocking {
@@ -188,7 +188,7 @@ open class RouteModel() {
fun currentStep(): StepData {
val distanceToNextStep = leftStepDistance()
// Determine the maneuver type and corresponding icon
val currentStep = route.nextStep(1) // This advances the route's state
val currentStep = route.nextStep(1)
// Safely get the street name from the maneuver
val streetName = currentStep.name
val curManeuverType = currentStep.maneuver.type
@@ -270,7 +270,8 @@ open class RouteModel() {
/** Returns the current [Step] left distance in m. */
fun leftStepDistance(): Double {
val step = route.currentStep()
var leftDistance = 0.0
println(step.index)
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 =

View File

@@ -135,7 +135,7 @@
"source": "openmaptiles",
"source-layer": "landuse",
"filter": ["==", ["get", "class"], "track"],
"paint": {"fill-color": "#DEE3CD"}
"paint": {"fill-color": "rgba(67, 67, 65, 1)"}
},
{
"id": "landuse_cemetery",
@@ -151,7 +151,7 @@
"source": "openmaptiles",
"source-layer": "landuse",
"filter": ["==", ["get", "class"], "hospital"],
"paint": {"fill-color": "#fde"}
"paint": {"fill-color": "rgba(51, 45, 48, 1)"}
},
{
"id": "landuse_school",
@@ -362,7 +362,7 @@
["==", ["get", "brunnel"], "tunnel"],
["match", ["get", "class"], ["service", "track"], true, false]
],
"layout": {"line-join": "round"},
"layout": {"line-join": "round", "visibility": "none"},
"paint": {
"line-color": "#cfcdca",
"line-dasharray": [0.5, 0.25],
@@ -535,6 +535,7 @@
["==", ["get", "brunnel"], "tunnel"],
["match", ["get", "class"], ["path", "pedestrian"], true, false]
],
"layout": {"visibility": "none"},
"paint": {
"line-color": "hsl(0,0%,100%)",
"line-dasharray": [1, 0.75],
@@ -588,7 +589,7 @@
["==", ["get", "brunnel"], "tunnel"],
["match", ["get", "class"], ["service", "track"], true, false]
],
"layout": {"line-join": "round"},
"layout": {"line-join": "round", "visibility": "none"},
"paint": {
"line-color": "#fff",
"line-width": [
@@ -616,7 +617,7 @@
],
"layout": {"line-join": "round"},
"paint": {
"line-color": "#fff4c6",
"line-color": "rgba(72, 72, 67, 1)",
"line-width": [
"interpolate",
["exponential", 1.2],