diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3046cc8..94a4cbc 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,8 +14,8 @@ android { applicationId = "com.kouros.navigation" minSdk = 33 targetSdk = 36 - versionCode = 28 - versionName = "0.1.3.28" + versionCode = 32 + versionName = "0.1.3.32" base.archivesName = "navi-$versionName" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/kouros/navigation/di/appModule.kt b/app/src/main/java/com/kouros/navigation/di/appModule.kt index 23f6d01..f8047cb 100644 --- a/app/src/main/java/com/kouros/navigation/di/appModule.kt +++ b/app/src/main/java/com/kouros/navigation/di/appModule.kt @@ -2,6 +2,7 @@ package com.kouros.navigation.di import com.kouros.navigation.data.NavigationRepository import com.kouros.navigation.data.osrm.OsrmRepository +import com.kouros.navigation.data.tomtom.TomTomRepository import com.kouros.navigation.data.valhalla.ValhallaRepository import com.kouros.navigation.model.BaseStyleModel import com.kouros.navigation.model.ViewModel @@ -14,4 +15,5 @@ val appModule = module { viewModelOf(::ViewModel) singleOf(::ValhallaRepository) singleOf(::OsrmRepository) + singleOf(::TomTomRepository) } \ No newline at end of file diff --git a/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt b/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt index 127f43b..f7fe85e 100644 --- a/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt +++ b/app/src/main/java/com/kouros/navigation/ui/MainActivity.kt @@ -78,6 +78,8 @@ class MainActivity : ComponentActivity() { val routeModel = RouteModel() var tilt = 50.0 val useMock = false + + var currentIndex = 0 val stepData: MutableLiveData by lazy { MutableLiveData() } @@ -113,7 +115,7 @@ class MainActivity : ComponentActivity() { lateinit var baseStyle: BaseStyle.Json init { - navigationViewModel.route.observe(this, observer) + } @RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION]) @@ -127,13 +129,14 @@ class MainActivity : ComponentActivity() { locationManager = getSystemService(LOCATION_SERVICE) as LocationManager fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) fusedLocationClient.lastLocation - .addOnSuccessListener { location: android.location.Location? -> + .addOnSuccessListener { _: android.location.Location? -> if (useMock) { mock = MockLocation(locationManager) mock.setMockLocation( - homeHohenwaldeck.latitude, - homeHohenwaldeck.longitude + homeVogelhart.latitude, + homeVogelhart.longitude ) + navigationViewModel.route.observe(this, observer) } } enableEdgeToEdge() @@ -156,7 +159,12 @@ class MainActivity : ComponentActivity() { Content() // auto navigate if (useMock) { - navigationViewModel.loadRoute(applicationContext, homeHohenwaldeck, homeVogelhart, 0F) + navigationViewModel.loadRoute( + applicationContext, + homeVogelhart, + homeHohenwaldeck, + 0F + ) } }, ) @@ -177,7 +185,7 @@ class MainActivity : ComponentActivity() { ) val userLocationState = rememberUserLocationState(locationProvider) val locationState = locationProvider.location.collectAsState() - updateLocation(locationState.value) + updateLocation(locationState.value) var latitude by remember { mutableDoubleStateOf(0.0) } if (locationState.value != null) { latitude = locationState.value!!.position.latitude @@ -249,6 +257,9 @@ class MainActivity : ComponentActivity() { && lastLocation.longitude != location.position.longitude ) { val currentLocation = location(location.position.longitude, location.position.latitude) + // if (currentIndex == 0) + // navigationViewModel.loadTraffic(applicationContext, currentLocation, 0f) + // currentIndex = 1 val bearing = bearing(lastLocation, currentLocation, cameraPosition.value!!.bearing) with(routeModel) { if (isNavigating()) { @@ -326,7 +337,7 @@ class MainActivity : ComponentActivity() { CoroutineScope(Dispatchers.IO).launch { for ((index, waypoint) in routeModel.curRoute.waypoints.withIndex()) { if (routeModel.isNavigating()) { - var deviation = 0.0 + val deviation = 0.0 if (index in 0..routeModel.curRoute.waypoints.size) { mock.setMockLocation(waypoint[1] + deviation, waypoint[0]) delay(500L) // @@ -359,9 +370,10 @@ class MainActivity : ComponentActivity() { fun test2() { CoroutineScope(Dispatchers.IO).launch { // Balanstr. - mock.setMockLocation( 48.119357, 11.599130) + mock.setMockLocation(48.119357, 11.599130) } } + fun gpx(context: Context) { CoroutineScope(Dispatchers.IO).launch { val parser = GPXParser() diff --git a/app/src/main/java/com/kouros/navigation/ui/MapView.kt b/app/src/main/java/com/kouros/navigation/ui/MapView.kt index 6dc4a3d..6b79535 100644 --- a/app/src/main/java/com/kouros/navigation/ui/MapView.kt +++ b/app/src/main/java/com/kouros/navigation/ui/MapView.kt @@ -16,6 +16,7 @@ import com.kouros.navigation.car.map.MapLibre import com.kouros.navigation.car.map.NavigationImage import com.kouros.navigation.car.map.rememberBaseStyle import com.kouros.navigation.data.StepData +import com.kouros.navigation.data.tomtom.TrafficData import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.rememberCameraState import org.maplibre.compose.location.LocationTrackingEffect @@ -65,6 +66,7 @@ fun MapView( cameraState, rememberBaseStyle, route, + emptyMap(), ViewStyle.VIEW ) LocationTrackingEffect( diff --git a/app/src/main/java/com/kouros/navigation/ui/NavigationScreen.kt b/app/src/main/java/com/kouros/navigation/ui/NavigationScreen.kt index 97dc688..d67894e 100644 --- a/app/src/main/java/com/kouros/navigation/ui/NavigationScreen.kt +++ b/app/src/main/java/com/kouros/navigation/ui/NavigationScreen.kt @@ -28,6 +28,10 @@ fun NavigationInfo(step: StepData?, nextStep: StepData?) { contentDescription = stringResource(id = R.string.accept_action_title), modifier = Modifier.size(48.dp, 48.dp), ) + if (step.currentManeuverType == 46 + || step.currentManeuverType == 45) { + Text(text ="Exit ${step.exitNumber}", fontSize = 20.sp) + } Column { if (step.leftStepDistance < 1000) { Text(text = "${step.leftStepDistance.toInt()} m", fontSize = 25.sp) diff --git a/app/src/main/java/com/kouros/navigation/ui/NavigationSheet.kt b/app/src/main/java/com/kouros/navigation/ui/NavigationSheet.kt index fff0ee5..6469ec1 100755 --- a/app/src/main/java/com/kouros/navigation/ui/NavigationSheet.kt +++ b/app/src/main/java/com/kouros/navigation/ui/NavigationSheet.kt @@ -57,6 +57,15 @@ fun NavigationSheet( modifier = Modifier.size(24.dp, 24.dp), ) } + Button(onClick = { + simulateNavigation() + }) { + Icon( + painter = painterResource(id = R.drawable.ic_zoom_in_24), + "Stop", + modifier = Modifier.size(24.dp, 24.dp), + ) + } } Spacer(Modifier.size(30.dp)) if (!routeModel.isNavigating()) { diff --git a/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt b/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt index a44ab26..bb5476a 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/NavigationSession.kt @@ -30,21 +30,18 @@ import com.kouros.navigation.car.navigation.RouteCarModel import com.kouros.navigation.car.screen.NavigationScreen import com.kouros.navigation.car.screen.RequestPermissionScreen import com.kouros.navigation.car.screen.SearchScreen -import com.kouros.navigation.data.Constants import com.kouros.navigation.data.Constants.CAR_LOCATION import com.kouros.navigation.data.Constants.MAXIMAL_ROUTE_DEVIATION import com.kouros.navigation.data.Constants.MAXIMAL_SNAP_CORRECTION import com.kouros.navigation.data.Constants.TAG import com.kouros.navigation.data.RouteEngine import com.kouros.navigation.data.osrm.OsrmRepository +import com.kouros.navigation.data.tomtom.TomTomRepository import com.kouros.navigation.data.valhalla.ValhallaRepository -import com.kouros.navigation.model.BaseStyleModel import com.kouros.navigation.model.ViewModel import com.kouros.navigation.utils.GeoUtils.snapLocation import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue -import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue import com.kouros.navigation.utils.NavigationUtils.getViewModel -import org.maplibre.compose.style.BaseStyle class NavigationSession : Session(), NavigationScreen.Listener { @@ -93,8 +90,6 @@ class NavigationSession : Session(), NavigationScreen.Listener { lateinit var navigationViewModel: ViewModel - lateinit var baseStyle: BaseStyle.Json - val carLocationListener: OnCarDataAvailableListener = OnCarDataAvailableListener { data -> if (data.location.status == CarValue.STATUS_SUCCESS) { @@ -129,21 +124,21 @@ class NavigationSession : Session(), NavigationScreen.Listener { fun onRoutingEngineStateUpdated(routeEngine : Int) { navigationViewModel = when (routeEngine) { RouteEngine.VALHALLA.ordinal -> ViewModel(ValhallaRepository()) - else -> ViewModel(OsrmRepository()) + RouteEngine.OSRM.ordinal -> ViewModel(OsrmRepository()) + else -> ViewModel(TomTomRepository()) } } + override fun onCreateScreen(intent: Intent): Screen { navigationViewModel = getViewModel(carContext) navigationViewModel.routingEngine.observe(this, ::onRoutingEngineStateUpdated) + routeModel = RouteCarModel() - val darkMode = getIntKeyValue(carContext, Constants.DARK_MODE_SETTINGS) - baseStyle = BaseStyleModel().readStyle(carContext, darkMode, carContext.isDarkMode) - - surfaceRenderer = SurfaceRenderer(carContext, lifecycle, routeModel, baseStyle) + surfaceRenderer = SurfaceRenderer(carContext, lifecycle, routeModel) navigationScreen = NavigationScreen(carContext, surfaceRenderer, routeModel, this, navigationViewModel) diff --git a/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt b/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt index 1f6dc42..dde81fc 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/SurfaceRenderer.kt @@ -29,10 +29,13 @@ import com.kouros.navigation.car.map.cameraState import com.kouros.navigation.car.map.getPaddingValues import com.kouros.navigation.car.map.rememberBaseStyle import com.kouros.navigation.car.navigation.RouteCarModel +import com.kouros.navigation.data.Constants import com.kouros.navigation.data.Constants.ROUTING_ENGINE import com.kouros.navigation.data.Constants.homeVogelhart import com.kouros.navigation.data.ObjectBox import com.kouros.navigation.data.RouteEngine +import com.kouros.navigation.data.tomtom.TrafficData +import com.kouros.navigation.model.BaseStyleModel import com.kouros.navigation.model.RouteModel import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue import com.kouros.navigation.utils.bearing @@ -49,8 +52,7 @@ import org.maplibre.spatialk.geojson.Position class SurfaceRenderer( private var carContext: CarContext, lifecycle: Lifecycle, - private var routeModel: RouteCarModel, - private var baseStyle: BaseStyle.Json + private var routeModel: RouteCarModel ) : DefaultLifecycleObserver { var lastLocation = location(0.0, 0.0) @@ -70,14 +72,20 @@ class SurfaceRenderer( var height = 0 var lastBearing = 0.0 val routeData = MutableLiveData("") + + val trafficData = MutableLiveData(emptyMap()) val speedCamerasData = MutableLiveData("") val speed = MutableLiveData(0F) - lateinit var centerLocation: Location var viewStyle = ViewStyle.VIEW + lateinit var centerLocation: Location var previewDistance = 0.0 lateinit var mapView: ComposeView var tilt = 55.0 - var countDownTimerActive = false + + val style: MutableLiveData by lazy { + MutableLiveData() + } + val mSurfaceCallback: SurfaceCallback = object : SurfaceCallback { lateinit var lifecycleOwner: CustomLifecycleOwner @@ -160,6 +168,7 @@ class SurfaceRenderer( init { lifecycle.addObserver(this) speed.value = 0F + } fun onConnectionStateUpdated(connectionState: Int) { @@ -170,16 +179,24 @@ class SurfaceRenderer( } } + fun onBaseStyleStateUpdated(style: BaseStyle) { + + } + @Composable fun MapView() { - //println("DarkMode ${carContext.isDarkMode}") + + val darkMode = getIntKeyValue(carContext, Constants.DARK_MODE_SETTINGS) + val baseStyle = BaseStyleModel().readStyle(carContext, darkMode, carContext.isDarkMode) + val position: CameraPosition? by cameraPosition.observeAsState() val route: String? by routeData.observeAsState() + val traffic: Map ? by trafficData.observeAsState() val speedCameras: String? by speedCamerasData.observeAsState() val paddingValues = getPaddingValues(height, viewStyle) val cameraState = cameraState(paddingValues, position, tilt) val rememberBaseStyle = rememberBaseStyle(baseStyle) - MapLibre(carContext, cameraState, rememberBaseStyle, route, viewStyle, speedCameras) + MapLibre(carContext, cameraState, rememberBaseStyle, route, traffic, viewStyle, speedCameras) ShowPosition(cameraState, position, paddingValues) } @@ -217,6 +234,7 @@ class SurfaceRenderer( override fun onCreate(owner: LifecycleOwner) { CarConnection(carContext).type.observe(owner, ::onConnectionStateUpdated) + style.observe(owner, :: onBaseStyleStateUpdated) Log.i(TAG, "SurfaceRenderer created") carContext.getCarService(AppManager::class.java) .setSurfaceCallback(mSurfaceCallback) @@ -288,6 +306,10 @@ class SurfaceRenderer( viewStyle = ViewStyle.VIEW } + fun setTrafficData(traffic: Map ) { + trafficData.value = traffic as MutableMap? + } + fun setPreviewRouteData(routeModel: RouteModel) { viewStyle = ViewStyle.PREVIEW with(routeModel) { diff --git a/common/car/src/main/java/com/kouros/navigation/car/map/MapView.kt b/common/car/src/main/java/com/kouros/navigation/car/map/MapView.kt index bff662c..4cd9093 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/map/MapView.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/map/MapView.kt @@ -2,6 +2,7 @@ package com.kouros.navigation.car.map import android.content.Context import android.location.Location +import androidx.car.app.connection.CarConnection import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues @@ -10,18 +11,15 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.Icon import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.drawscope.scale -import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.drawText @@ -34,19 +32,21 @@ import com.kouros.navigation.car.ViewStyle import com.kouros.navigation.data.Constants import com.kouros.navigation.data.Constants.SHOW_THREED_BUILDING import com.kouros.navigation.data.NavigationColor +import com.kouros.navigation.data.ObjectBox import com.kouros.navigation.data.RouteColor import com.kouros.navigation.data.SpeedColor -import com.kouros.navigation.model.BaseStyleModel +import com.kouros.navigation.data.tomtom.TrafficData import com.kouros.navigation.utils.NavigationUtils.getBooleanKeyValue -import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue import org.maplibre.compose.camera.CameraPosition import org.maplibre.compose.camera.CameraState import org.maplibre.compose.camera.rememberCameraState +import org.maplibre.compose.expressions.ast.Expression import org.maplibre.compose.expressions.dsl.const import org.maplibre.compose.expressions.dsl.exponential import org.maplibre.compose.expressions.dsl.image import org.maplibre.compose.expressions.dsl.interpolate import org.maplibre.compose.expressions.dsl.zoom +import org.maplibre.compose.expressions.value.ColorValue import org.maplibre.compose.layers.Anchor import org.maplibre.compose.layers.FillLayer import org.maplibre.compose.layers.LineLayer @@ -92,10 +92,10 @@ fun MapLibre( cameraState: CameraState, baseStyle: BaseStyle.Json, route: String?, + traffic: Map ?, viewStyle: ViewStyle, speedCameras: String? = "" ) { - MaplibreMap( options = MapOptions( ornamentOptions = @@ -111,7 +111,7 @@ fun MapLibre( if (viewStyle == ViewStyle.AMENITY_VIEW) { AmenityLayer(route) } else { - RouteLayer(route) + RouteLayer(route, traffic!!) } SpeedCameraLayer(speedCameras) } @@ -121,7 +121,7 @@ fun MapLibre( } @Composable -fun RouteLayer(routeData: String?) { +fun RouteLayer(routeData: String?, trafficData: Map) { if (routeData != null && routeData.isNotEmpty()) { val routes = rememberGeoJsonSource(GeoJsonData.JsonString(routeData)) LineLayer( @@ -153,6 +153,49 @@ fun RouteLayer(routeData: String?) { ), ) } + trafficData.forEach { + val traffic = rememberGeoJsonSource(GeoJsonData.JsonString(it.value)) + LineLayer( + id = "traffic-${it.key}-casing", + source = traffic, + color = const(Color.White), + width = + interpolate( + type = exponential(1.2f), + input = zoom(), + 5 to const(0.4.dp), + 6 to const(0.8.dp), + 7 to const(2.0.dp), + 20 to const(24.dp), + ), + ) + LineLayer( + id = "traffic-${it.key}", + source = traffic, + color = trafficColor(it.key), + width = + interpolate( + type = exponential(1.2f), + input = zoom(), + 5 to const(0.4.dp), + 6 to const(0.7.dp), + 7 to const(1.75.dp), + 20 to const(22.dp), + ), + ) + + } +} + +fun trafficColor(key: String): Expression { + when (key) { + "queuing" -> return const(Color(0xFFD24417)) + "stationary" -> return const(Color(0xFFFF0000)) + "heavy" -> return const(Color(0xFF6B0404)) + "slow" -> return const(Color(0xFFC41F1F)) + "roadworks" -> return const(Color(0xFF7A631A)) + } + return const(Color.Blue) } @Composable @@ -270,7 +313,7 @@ private fun CurrentSpeed( curSpeed: Float, maxSpeed: Int ) { - val radius = 32 + val radius = 34 Box( modifier = Modifier .padding( @@ -336,7 +379,7 @@ private fun MaxSpeed( height: Int, maxSpeed: Int, ) { - val radius = 20 + val radius = 24 Box( modifier = Modifier .padding( diff --git a/common/car/src/main/java/com/kouros/navigation/car/navigation/RouteCarModel.kt b/common/car/src/main/java/com/kouros/navigation/car/navigation/RouteCarModel.kt index d7fbf10..41349db 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/navigation/RouteCarModel.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/navigation/RouteCarModel.kt @@ -16,6 +16,7 @@ package com.kouros.navigation.car.navigation import android.text.SpannableString +import android.text.Spanned import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.car.app.AppManager @@ -26,22 +27,25 @@ import androidx.car.app.model.Alert import androidx.car.app.model.AlertCallback import androidx.car.app.model.CarColor import androidx.car.app.model.CarIcon +import androidx.car.app.model.CarIconSpan import androidx.car.app.model.CarText import androidx.car.app.model.DateTimeWithZone import androidx.car.app.model.Distance import androidx.car.app.navigation.model.Lane import androidx.car.app.navigation.model.LaneDirection import androidx.car.app.navigation.model.Maneuver +import androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW +import androidx.car.app.navigation.model.Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW import androidx.car.app.navigation.model.Step import androidx.car.app.navigation.model.TravelEstimate import androidx.core.graphics.drawable.IconCompat import com.kouros.data.R import com.kouros.navigation.data.StepData import com.kouros.navigation.model.RouteModel +import org.maplibre.compose.expressions.dsl.step import java.util.Collections import java.util.TimeZone import java.util.concurrent.TimeUnit -import kotlin.text.trim /** A class that provides models for the routing demos. */ class RouteCarModel() : RouteModel() { @@ -50,13 +54,18 @@ class RouteCarModel() : RouteModel() { fun currentStep(carContext: CarContext): Step { val stepData = currentStep() val currentStepCueWithImage: SpannableString = - createString(stepData.instruction) + createString(stepData.instruction) + + val maneuver = Maneuver.Builder(stepData.currentManeuverType) + .setIcon(createCarIcon(carContext, stepData.icon)) + if (stepData.currentManeuverType == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW + || stepData.currentManeuverType == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW) { + maneuver.setRoundaboutExitNumber(stepData.exitNumber) + } val step = Step.Builder(currentStepCueWithImage) .setManeuver( - Maneuver.Builder(stepData.currentManeuverType) - .setIcon(createCarIcon(carContext, stepData.icon)) - .build() + maneuver.build() ) if (destination.street != null) { step.setRoad(destination.street!!) @@ -72,12 +81,16 @@ class RouteCarModel() : RouteModel() { val stepData = nextStep() val currentStepCueWithImage: SpannableString = createString(stepData.instruction) + val maneuver = Maneuver.Builder(stepData.currentManeuverType) + .setIcon(createCarIcon(carContext, stepData.icon)) + if (stepData.currentManeuverType == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CW + || stepData.currentManeuverType == TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW) { + maneuver.setRoundaboutExitNumber(stepData.exitNumber) + } val step = Step.Builder(currentStepCueWithImage) .setManeuver( - Maneuver.Builder(stepData.currentManeuverType) - .setIcon(createCarIcon(carContext, stepData.icon)) - .build() + maneuver.build() ) .build() return step @@ -109,8 +122,8 @@ class RouteCarModel() : RouteModel() { timeToDestinationMillis ) ) - .setRemainingTimeColor(CarColor.YELLOW) - .setRemainingDistanceColor(CarColor.RED) + .setRemainingTimeColor(CarColor.GREEN) + .setRemainingDistanceColor(CarColor.BLUE) if (travelMessage.isNotEmpty()) { travelBuilder.setTripIcon(createCarIcon(carContext, R.drawable.warning_24px)) @@ -203,6 +216,18 @@ class RouteCarModel() : RouteModel() { } } + private fun createStringWithIcon( + carContext: CarContext, + text: String, + @DrawableRes iconRes: Int + ): SpannableString { + val start = 0 + val end = text.length + val span = CarIconSpan.create(createCarIcon(carContext, iconRes), CarIconSpan.ALIGN_CENTER) + val spannableString = SpannableString(text) + spannableString.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) + return spannableString + } fun createString( text: String ): SpannableString { @@ -222,7 +247,7 @@ class RouteCarModel() : RouteModel() { return CarIcon.Builder(iconCompat).build() } - fun showSpeedCamera(carContext: CarContext, distance: Double, maxSpeed: String?) { + fun showSpeedCamera(carContext: CarContext, distance: Double, maxSpeed: String) { carContext.getCarService(AppManager::class.java) .showAlert(createAlert(carContext, distance, maxSpeed, createCarIcon(carContext, R.drawable.speed_camera_24px))) } diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt index 279c13e..baae38b 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/NavigationScreen.kt @@ -31,10 +31,16 @@ import com.kouros.navigation.data.Constants.DESTINATION_ARRIVAL_DISTANCE import com.kouros.navigation.data.Place import com.kouros.navigation.data.nominatim.SearchResult import com.kouros.navigation.data.overpass.Elements +import com.kouros.navigation.data.tomtom.Features +import com.kouros.navigation.data.tomtom.Geometry import com.kouros.navigation.model.ViewModel import com.kouros.navigation.utils.GeoUtils import com.kouros.navigation.utils.location +import java.time.LocalDateTime +import java.time.Period +import java.time.ZoneOffset import kotlin.math.absoluteValue +import kotlin.time.Duration class NavigationScreen( carContext: CarContext, @@ -55,6 +61,7 @@ class NavigationScreen( var recentPlace = Place() var navigationType = NavigationType.VIEW + var lastTrafficDate = LocalDateTime.of(1960, 6, 21, 0, 0) val observer = Observer { route -> if (route.isNotEmpty()) { navigationType = NavigationType.NAVIGATION @@ -71,6 +78,10 @@ class NavigationScreen( invalidate() } } + val trafficObserver = Observer > { traffic -> + surfaceRenderer.setTrafficData(traffic) + invalidate() + } val placeObserver = Observer { searchResult -> val place = Place( @@ -101,6 +112,7 @@ class NavigationScreen( init { viewModel.route.observe(this, observer) + viewModel.traffic.observe(this, trafficObserver); viewModel.recentPlace.observe(this, recentObserver) viewModel.placeLocation.observe(this, placeObserver) viewModel.speedCameras.observe(this, speedObserver) @@ -471,7 +483,14 @@ class NavigationScreen( } fun updateTrip(location: Location) { - updateSpeedCamera(surfaceRenderer.lastLocation) + val current = LocalDateTime.now(ZoneOffset.UTC) + val duration = java.time.Duration.between(current, lastTrafficDate) + if (duration.abs().seconds > 360) { + lastTrafficDate = current + viewModel.loadTraffic(carContext, location, surfaceRenderer.carOrientation) + } + //updateTraffic(location) + updateSpeedCamera(location) with(routeModel) { updateLocation(location, viewModel) if ((maneuverType == Maneuver.TYPE_DESTINATION @@ -512,11 +531,14 @@ class NavigationScreen( } val sortedList = updatedCameras.sortedWith(compareBy { it.distance }) val camera = sortedList.first() - val bearingSpeedCamera = location.bearingTo(location(camera.lon!!, camera.lat!!)) val bearingRoute = surfaceRenderer.lastLocation.bearingTo(location) - + val bearingSpeedCamera = if (camera.tags.direction != null) { + camera.tags.direction!!.toFloat() + } else { + location.bearingTo(location(camera.lon, camera.lat)).absoluteValue + } if (camera.distance < 80) { - if ((bearingSpeedCamera.absoluteValue - bearingRoute.absoluteValue).absoluteValue < 20.0) { + if ((bearingSpeedCamera - bearingRoute.absoluteValue).absoluteValue < 15.0) { routeModel.showSpeedCamera(carContext, camera.distance, camera.tags.maxspeed) } } diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt index 233ede8..24030e9 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutePreviewScreen.kt @@ -190,7 +190,6 @@ class RoutePreviewScreen( private fun createRouteText(index: Int): CarText { val time = routeModel.route.routes[index].summary.duration - println("Duration $time") val length = BigDecimal(routeModel.route.routes[index].summary.distance).setScale( 1, diff --git a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutingSettings.kt b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutingSettings.kt index 6d5d7f2..f39ac10 100644 --- a/common/car/src/main/java/com/kouros/navigation/car/screen/RoutingSettings.kt +++ b/common/car/src/main/java/com/kouros/navigation/car/screen/RoutingSettings.kt @@ -23,7 +23,7 @@ import com.kouros.navigation.utils.NavigationUtils.setBooleanKeyValue import com.kouros.navigation.utils.NavigationUtils.setIntKeyValue class RoutingSettings(private val carContext: CarContext, private var viewModel: ViewModel) : Screen(carContext) { - private var routingEngine = RouteEngine.VALHALLA.ordinal + private var routingEngine = RouteEngine.OSRM.ordinal init { @@ -45,6 +45,11 @@ class RoutingSettings(private val carContext: CarContext, private var viewModel: R.string.osrm, ) ) + .addItem( + buildRowForTemplate( + R.string.tomtom, + ) + ) .setOnSelectedListener { index: Int -> this.onSelected(index) } diff --git a/common/data/src/main/java/com/kouros/navigation/data/Data.kt b/common/data/src/main/java/com/kouros/navigation/data/Data.kt index 4d7845b..10c7ad6 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Data.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Data.kt @@ -68,6 +68,7 @@ data class StepData ( var leftDistance: Double, var lane: List = listOf(Lane(location(0.0, 0.0), valid = false, indications = emptyList())), + var exitNumber: Int = 0, ) @@ -150,5 +151,5 @@ object Constants { enum class RouteEngine { - VALHALLA, OSRM, GRAPHHOPPER + VALHALLA, OSRM, TOMTOM, GRAPHHOPPER } diff --git a/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt b/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt index f492a92..41dea58 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/NavigationRepository.kt @@ -18,16 +18,13 @@ package com.kouros.navigation.data import android.content.Context import android.location.Location -import com.kouros.navigation.data.overpass.Elements +import com.kouros.data.R import com.kouros.navigation.model.RouteModel import com.kouros.navigation.utils.GeoUtils.calculateSquareRadius -import com.kouros.navigation.utils.GeoUtils.getBoundingBox -import org.json.JSONArray import java.net.Authenticator import java.net.HttpURLConnection import java.net.PasswordAuthentication import java.net.URL -import kotlinx.serialization.json.Json abstract class NavigationRepository { @@ -36,27 +33,69 @@ abstract class NavigationRepository { private val nominatimUrl = "https://kouros-online.de/nominatim/" + private val tomtomApiKey = "678k5v6940cSXXIS5oD92qIrDgW3RBZ3" - abstract fun getRoute(currentLocation: Location, location: Location, carOrientation: Float, searchFilter: SearchFilter): String + private val tomtomUrl = "https://api.tomtom.com/traffic/services/5/incidentDetails" - fun getRouteDistance(currentLocation: Location, location: Location, carOrientation : Float, searchFilter: SearchFilter, context: Context): Double { - val route = getRoute(currentLocation, location, carOrientation, searchFilter) + private val tomtomFields = + "{incidents{type,geometry{type,coordinates},properties{iconCategory,events{description}}}}" + + abstract fun getRoute( + context: Context, + currentLocation: Location, + location: Location, + carOrientation: Float, + searchFilter: SearchFilter + ): String + + fun getRouteDistance( + currentLocation: Location, + location: Location, + carOrientation: Float, + searchFilter: SearchFilter, + context: Context + ): Double { + val route = getRoute(context, currentLocation, location, carOrientation, searchFilter) val routeModel = RouteModel() routeModel.startNavigation(route, context) return routeModel.curRoute.summary.distance } - fun searchPlaces(search: String, location: Location) : String { - val box = calculateSquareRadius(location.latitude, location.longitude, 20.0) - val viewbox = "&bounded=1&viewbox=${box[2]},${box[0]},${box[3]},${box[1]}" - return fetchUrl("${nominatimUrl}search?q=$search&format=jsonv2&addressdetails=true$viewbox", false) + fun searchPlaces(search: String, location: Location): String { + val box = calculateSquareRadius(location.latitude, location.longitude, 20.0) + val viewbox = "&bounded=1&viewbox=${box}" + return fetchUrl( + "${nominatimUrl}search?q=$search&format=jsonv2&addressdetails=true$viewbox", + false + ) } - fun reverseAddress(location: Location) : String { - return fetchUrl("${nominatimUrl}reverse?lat=${location.latitude}&lon=${location.longitude}&format=jsonv2&addressdetails=true", false) + fun reverseAddress(location: Location): String { + return fetchUrl( + "${nominatimUrl}reverse?lat=${location.latitude}&lon=${location.longitude}&format=jsonv2&addressdetails=true", + false + ) } - fun fetchUrl(url: String, authenticator : Boolean): String { + 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 { if (authenticator) { Authenticator.setDefault(object : Authenticator() { @@ -79,7 +118,7 @@ abstract class NavigationRepository { val responseCode = httpURLConnection.responseCode if (responseCode == HttpURLConnection.HTTP_OK) { val response = httpURLConnection.inputStream.bufferedReader() - .use { it.readText() } // defaults to UTF-8 + .use { it.readText() } return response } } catch (e: Exception) { diff --git a/common/data/src/main/java/com/kouros/navigation/data/Route.kt b/common/data/src/main/java/com/kouros/navigation/data/Route.kt index 8712a0f..75693a6 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/Route.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/Route.kt @@ -1,6 +1,5 @@ package com.kouros.navigation.data -import android.location.Location import com.google.gson.GsonBuilder import com.kouros.navigation.data.osrm.OsrmResponse import com.kouros.navigation.data.osrm.OsrmRoute @@ -8,9 +7,10 @@ import com.kouros.navigation.data.route.Leg import com.kouros.navigation.data.route.Maneuver import com.kouros.navigation.data.route.Step import com.kouros.navigation.data.route.Summary +import com.kouros.navigation.data.tomtom.TomTomResponse +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.GeoUtils.createCenterLocation import com.kouros.navigation.utils.location import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonElement @@ -38,6 +38,7 @@ data class Route( } fun routeEngine(routeEngine: Int) = apply { this.routeEngine = routeEngine } + fun route(route: String) = apply { if (route.isNotEmpty() && route != "[]") { val gson = GsonBuilder().serializeNulls().create() @@ -52,11 +53,14 @@ data class Route( ) ValhallaRoute().mapJsonToValhalla(routeJson, this) } - - else -> { + RouteEngine.OSRM.ordinal -> { val osrmJson = gson.fromJson(route, OsrmResponse::class.java) OsrmRoute().mapToOsrm(osrmJson, this) } + else -> { + val tomtomJson = gson.fromJson(route, TomTomResponse::class.java) + TomTomRoute().mapToOsrm(tomtomJson, this) + } } } } @@ -71,9 +75,7 @@ data class Route( fun buildEmpty(): Route { return Route( routeEngine = 0, - //summary = Summary(0.0, 0.0), routes = emptyList(), - // legs = emptyList(), //waypoints = emptyList(), //routeGeoJson = "", ) @@ -81,14 +83,18 @@ data class Route( } - val legs: List - get() = routes.first().legs - + fun legs(): List { + return if (routes.isNotEmpty()) { + routes.first().legs + } else { + emptyList() + } + } fun currentStep(): Step { - return if (legs.isNotEmpty()) { - legs.first().steps[currentStep] + return if (routes.isNotEmpty() && legs().isNotEmpty()) { + legs().first().steps[currentStep] } else { Step(maneuver = Maneuver(waypoints = emptyList(), location = location(0.0, 0.0))) } @@ -96,8 +102,8 @@ data class Route( fun nextStep(): Step { val nextIndex = currentStep + 1 - return if (nextIndex < legs.first().steps.size) { - legs.first().steps[nextIndex] + return if (nextIndex < legs().first().steps.size) { + legs().first().steps[nextIndex] } else { throw IndexOutOfBoundsException("No next maneuver available.") } diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/Intersections.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/Intersections.kt index 2ab2696..8d0aec9 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/Intersections.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/Intersections.kt @@ -5,8 +5,8 @@ import com.google.gson.annotations.SerializedName data class Intersections( - @SerializedName("in") var inV: Int? = null, - @SerializedName("out") var out: Int? = null, + @SerializedName("in") var inV: Int = 0, + @SerializedName("out") var out: Int = 0, @SerializedName("entry") var entry: ArrayList = arrayListOf(), @SerializedName("bearings") var bearings: ArrayList = arrayListOf(), @SerializedName("location") var location: ArrayList = arrayListOf(), diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/Legs.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/Legs.kt index d1ad77a..84713ac 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/Legs.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/Legs.kt @@ -6,9 +6,9 @@ import com.google.gson.annotations.SerializedName data class Legs ( @SerializedName("steps" ) var steps : ArrayList = arrayListOf(), - @SerializedName("weight" ) var weight : Double? = null, - @SerializedName("summary" ) var summary : String? = null, - @SerializedName("duration" ) var duration : Double? = null, - @SerializedName("distance" ) var distance : Double? = null + @SerializedName("weight" ) var weight : Double = 0.0, + @SerializedName("summary" ) var summary : String = "", + @SerializedName("duration" ) var duration : Double = 0.0, + @SerializedName("distance" ) var distance : Double = 0.0 ) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/Maneuver.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/Maneuver.kt index d3b0402..07102b5 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/Maneuver.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/Maneuver.kt @@ -3,12 +3,13 @@ package com.kouros.navigation.data.osrm import com.google.gson.annotations.SerializedName -data class Maneuver ( +data class Maneuver( - @SerializedName("bearing_after" ) var bearingAfter : Int? = null, - @SerializedName("bearing_before" ) var bearingBefore : Int? = null, - @SerializedName("location" ) var location : ArrayList = arrayListOf(), - @SerializedName("modifier" ) var modifier : String? = null, - @SerializedName("type" ) var type : String? = null + @SerializedName("bearing_after") var bearingAfter: Int = 0, + @SerializedName("bearing_before") var bearingBefore: Int = 0, + @SerializedName("location") var location: ArrayList = arrayListOf(), + @SerializedName("modifier") var modifier: String = "", + @SerializedName("type") var type: String = "", + @SerializedName("exit") var exit: Int = 0, -) \ No newline at end of file + ) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRepository.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRepository.kt index aa0aa83..1e86d9b 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRepository.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRepository.kt @@ -1,5 +1,6 @@ package com.kouros.navigation.data.osrm +import android.content.Context import android.location.Location import com.kouros.navigation.data.NavigationRepository import com.kouros.navigation.data.SearchFilter @@ -8,6 +9,7 @@ private const val routeUrl = "https://kouros-online.de/osrm/route/v1/driving/" class OsrmRepository : NavigationRepository() { override fun getRoute( + context: Context, currentLocation: Location, location: Location, carOrientation: Float, diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmResponse.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmResponse.kt index 7f8e7d8..2ea7c92 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmResponse.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmResponse.kt @@ -5,7 +5,7 @@ import com.google.gson.annotations.SerializedName data class OsrmResponse ( - @SerializedName("code" ) var code : String? = null, + @SerializedName("code" ) var code : String = "", @SerializedName("routes" ) var routes : ArrayList = arrayListOf(), @SerializedName("waypoints" ) var waypoints : ArrayList = arrayListOf() diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRoute.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRoute.kt index 9c5a8f3..a11dff6 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRoute.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/OsrmRoute.kt @@ -16,57 +16,55 @@ class OsrmRoute { fun mapToOsrm(routeJson: OsrmResponse, builder: Route.Builder) { - val routes = mutableListOf() var stepIndex = 0 routeJson.routes.forEach { route -> val legs = mutableListOf() val waypoints = mutableListOf>() - val summary = Summary(route.duration!!, route.distance!! / 1000) + val summary = Summary(route.duration, route.distance / 1000) route.legs.forEach { leg -> val steps = mutableListOf() leg.steps.forEach { step -> val intersections = mutableListOf() - if (step.maneuver != null) { - val points = decodePolyline(step.geometry!!, 5) - waypoints.addAll(points) - val maneuver = RouteManeuver( - bearingBefore = step.maneuver.bearingBefore ?: 0, - bearingAfter = step.maneuver.bearingAfter ?: 0, - type = convertType(step.maneuver), - waypoints = points, - location = location( - step.maneuver.location[0], - step.maneuver.location[1] - ) + val points = decodePolyline(step.geometry, 5) + waypoints.addAll(points) + val maneuver = RouteManeuver( + bearingBefore = step.maneuver.bearingBefore, + bearingAfter = step.maneuver.bearingAfter, + type = convertType(step.maneuver), + waypoints = points, + exit = step.maneuver.exit, + location = location( + step.maneuver.location[0], + step.maneuver.location[1] ) - step.intersections.forEach { it2 -> - if (it2.location[0] != 0.0) { - val lanes = mutableListOf() - it2.lanes.forEach { it3 -> - if (it3.indications.isNotEmpty() && it3.indications.first() != "none") { - val lane = Lane( - location(it2.location[0], it2.location[1]), - it3.valid, - it3.indications - ) - lanes.add(lane) - } + ) + step.intersections.forEach { it2 -> + if (it2.location[0] != 0.0) { + val lanes = mutableListOf() + it2.lanes.forEach { it3 -> + if (it3.indications.isNotEmpty() && it3.indications.first() != "none") { + val lane = Lane( + location(it2.location[0], it2.location[1]), + it3.valid, + it3.indications + ) + lanes.add(lane) } - intersections.add(Intersection(it2.location, lanes)) } + intersections.add(Intersection(it2.location, lanes)) } - val step = Step( - index = stepIndex, - name = step.name!!, - distance = step.distance!! / 1000, - duration = step.duration!!, - maneuver = maneuver, - intersection = intersections - ) - steps.add(step) - stepIndex += 1 } + val step = Step( + index = stepIndex, + name = step.name, + distance = step.distance / 1000, + duration = step.duration, + maneuver = maneuver, + intersection = intersections + ) + steps.add(step) + stepIndex += 1 } legs.add(Leg(steps)) } diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/Routes.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/Routes.kt index 062778e..0ad7035 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/Routes.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/Routes.kt @@ -8,8 +8,8 @@ data class Routes ( @SerializedName("legs" ) var legs : ArrayList = arrayListOf(), @SerializedName("weight_name" ) var weightName : String? = null, @SerializedName("geometry" ) var geometry : String? = null, - @SerializedName("weight" ) var weight : Double? = null, - @SerializedName("duration" ) var duration : Double? = null, - @SerializedName("distance" ) var distance : Double? = null + @SerializedName("weight" ) var weight : Double = 0.0, + @SerializedName("duration" ) var duration : Double = 0.0, + @SerializedName("distance" ) var distance : Double = 0.0 ) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/Steps.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/Steps.kt index aa4abc2..3370e4d 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/Steps.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/Steps.kt @@ -6,13 +6,13 @@ import com.google.gson.annotations.SerializedName data class Steps ( @SerializedName("intersections" ) var intersections : ArrayList = arrayListOf(), - @SerializedName("driving_side" ) var drivingSide : String? = null, - @SerializedName("geometry" ) var geometry : String? = null, - @SerializedName("maneuver" ) val maneuver : Maneuver? = Maneuver(), - @SerializedName("name" ) var name : String? = null, - @SerializedName("mode" ) var mode : String? = null, - @SerializedName("weight" ) var weight : Double? = null, - @SerializedName("duration" ) var duration : Double? = null, - @SerializedName("distance" ) var distance : Double? = null + @SerializedName("driving_side" ) var drivingSide : String = "", + @SerializedName("geometry" ) var geometry : String = "", + @SerializedName("maneuver" ) val maneuver : Maneuver = Maneuver(), + @SerializedName("name" ) var name : String = "", + @SerializedName("mode" ) var mode : String = "", + @SerializedName("weight" ) var weight : Double = 0.0, + @SerializedName("duration" ) var duration : Double = 0.0, + @SerializedName("distance" ) var distance : Double = 0.0, ) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/Waypoints.kt b/common/data/src/main/java/com/kouros/navigation/data/osrm/Waypoints.kt index d7a20a3..f7d0792 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/osrm/Waypoints.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/osrm/Waypoints.kt @@ -5,9 +5,9 @@ import com.google.gson.annotations.SerializedName data class Waypoints ( - @SerializedName("hint" ) var hint : String? = null, + @SerializedName("hint" ) var hint : String = "", @SerializedName("location" ) var location : ArrayList = arrayListOf(), - @SerializedName("name" ) var name : String? = null, - @SerializedName("distance" ) var distance : Double? = null + @SerializedName("name" ) var name : String = "", + @SerializedName("distance" ) var distance : Double = 0.0, ) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/overpass/Elements.kt b/common/data/src/main/java/com/kouros/navigation/data/overpass/Elements.kt index 50c372c..170df49 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/overpass/Elements.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/overpass/Elements.kt @@ -5,10 +5,10 @@ import com.google.gson.annotations.SerializedName data class Elements ( - @SerializedName("type" ) var type : String? = null, - @SerializedName("id" ) var id : Long? = null, - @SerializedName("lat" ) var lat : Double? = null, - @SerializedName("lon" ) var lon : Double? = null, + @SerializedName("type" ) var type : String = "", + @SerializedName("id" ) var id : Long = 0, + @SerializedName("lat" ) var lat : Double = 0.0, + @SerializedName("lon" ) var lon : Double = 0.0, @SerializedName("tags" ) var tags : Tags = Tags(), var distance : Double = 0.0 diff --git a/common/data/src/main/java/com/kouros/navigation/data/overpass/Overpass.kt b/common/data/src/main/java/com/kouros/navigation/data/overpass/Overpass.kt index 5d797e3..a5bf310 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/overpass/Overpass.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/overpass/Overpass.kt @@ -2,8 +2,7 @@ package com.kouros.navigation.data.overpass import android.location.Location import com.google.gson.GsonBuilder -import com.kouros.navigation.utils.GeoUtils.getOverpassBbox -import kotlinx.serialization.json.Json +import com.kouros.navigation.utils.GeoUtils.getBoundingBox import java.io.OutputStreamWriter import java.net.HttpURLConnection import java.net.URL @@ -41,7 +40,7 @@ class Overpass { location: Location, radius: Double ): List { - val boundingBox = getOverpassBbox(location, radius) + val boundingBox = getBoundingBox(location.latitude, location.longitude, radius) val httpURLConnection = URL(overpassUrl).openConnection() as HttpURLConnection httpURLConnection.requestMethod = "POST" httpURLConnection.setRequestProperty( diff --git a/common/data/src/main/java/com/kouros/navigation/data/overpass/Tags.kt b/common/data/src/main/java/com/kouros/navigation/data/overpass/Tags.kt index 064fbdb..12a9a8e 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/overpass/Tags.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/overpass/Tags.kt @@ -18,7 +18,7 @@ data class Tags( @SerializedName("ref") var ref: String? = null, @SerializedName("socket:type2") var socketType2: String? = null, @SerializedName("socket:type2:output") var socketType2Output: String? = null, - @SerializedName("maxspeed") var maxspeed: String? = null, + @SerializedName("maxspeed") var maxspeed: String = "0", @SerializedName("direction") var direction: String? = null, ) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/route/Maneuver.kt b/common/data/src/main/java/com/kouros/navigation/data/route/Maneuver.kt index f66f0f2..8d43000 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/route/Maneuver.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/route/Maneuver.kt @@ -8,4 +8,5 @@ data class Maneuver( val type: Int = 0, val waypoints: List>, val location: Location, + val exit: Int = 0, ) diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/Events.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Events.kt new file mode 100644 index 0000000..7681742 --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Events.kt @@ -0,0 +1,10 @@ +package com.kouros.navigation.data.tomtom + +import com.google.gson.annotations.SerializedName + + +data class Events ( + + @SerializedName("description" ) var description : String? = null + +) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/Features.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Features.kt new file mode 100644 index 0000000..96d8905 --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Features.kt @@ -0,0 +1,12 @@ +package com.kouros.navigation.data.tomtom + +import com.google.gson.annotations.SerializedName + + +data class Features ( + + @SerializedName("type" ) var type : String? = null, + @SerializedName("properties" ) var properties : Properties? = Properties(), + @SerializedName("geometry" ) var geometry : Geometry? = Geometry() + +) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/Geometry.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Geometry.kt new file mode 100644 index 0000000..4130ca5 --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Geometry.kt @@ -0,0 +1,11 @@ +package com.kouros.navigation.data.tomtom + +import com.google.gson.annotations.SerializedName + + +data class Geometry ( + + @SerializedName("type" ) var type : String? = null, + @SerializedName("coordinates" ) var coordinates : List> = arrayListOf() + +) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/Incidents.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Incidents.kt new file mode 100644 index 0000000..740a14f --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Incidents.kt @@ -0,0 +1,12 @@ +package com.kouros.navigation.data.tomtom + +import com.google.gson.annotations.SerializedName + + +data class Incidents ( + + @SerializedName("type" ) var type : String? = null, + @SerializedName("properties" ) var properties : Properties? = Properties(), + @SerializedName("geometry" ) var geometry : Geometry? = Geometry() + +) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/Properties.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Properties.kt new file mode 100644 index 0000000..2d7cb95 --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Properties.kt @@ -0,0 +1,11 @@ +package com.kouros.navigation.data.tomtom + +import com.google.gson.annotations.SerializedName + + +data class Properties ( + + @SerializedName("iconCategory" ) var iconCategory : Int? = null, + @SerializedName("events" ) var events : ArrayList = arrayListOf() + +) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/Report.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Report.kt new file mode 100644 index 0000000..777120d --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Report.kt @@ -0,0 +1,5 @@ +package com.kouros.navigation.data.tomtom + +data class Report( + val effectiveSettings: List +) \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/TomTomRoute.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/TomTomRoute.kt new file mode 100644 index 0000000..138f6a2 --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/TomTomRoute.kt @@ -0,0 +1,72 @@ +package com.kouros.navigation.data.tomtom + +import com.kouros.navigation.data.Route +import com.kouros.navigation.data.osrm.OsrmResponse +import com.kouros.navigation.data.osrm.OsrmRoute.ManeuverType +import com.kouros.navigation.data.route.Leg +import com.kouros.navigation.data.route.Maneuver +import com.kouros.navigation.data.route.Step +import com.kouros.navigation.data.route.Summary +import com.kouros.navigation.utils.GeoUtils.decodePolyline +import com.kouros.navigation.utils.location +import com.kouros.navigation.data.route.Maneuver as RouteManeuver + +/** +curl -X GET "https://api.tomtom.com/routing/1/calculateRoute/\ +48.1856548,11.57928:48.1183,11.59485/json?\ +vehicleHeading=90§ionType=traffic\ +&report=effectiveSettings&routeType=eco\ +&traffic=true&avoid=unpavedRoadimport com.kouros.navigation.data.route.Maneuver as RouteManeuvers&travelMode=car\ +&vehicleMaxSpeed=120&vehicleCommercial=false\ +&instructionsType=text&language=en-GB§ionType=lanes\ +&routeRepresentation=encodedPolyline\ +&vehicleEngineType=combustion&key=678k5v6940cSXXIS5oD92qIrDgW3RBZ3" + */ + +class TomTomRoute { + + fun mapToOsrm(routeJson: TomTomResponse, builder: Route.Builder) { + routeJson.routes.forEach { route -> + val legs = mutableListOf() + val waypoints = mutableListOf>() + var points = listOf>() + val summary = Summary( + route.summary.travelTimeInSeconds.toDouble(), + route.summary.lengthInMeters.toDouble() / 1000 + ) + route.legs.forEach { leg -> + points = decodePolyline(leg.encodedPolyline, leg.encodedPolylinePrecision) + waypoints.addAll(points) + } + route.guidance.instructions.forEach { instruction -> + instruction.exitNumber +// val maneuver = RouteManeuver( +// // bearingBefore = step.maneuver.bearingBefore, +// //bearingAfter = step.maneuver.bearingAfter, +// type = convertType(instruction.maneuver), +// waypoints = points.subList(section.startPointIndex, section.endPointIndex + 1), +// exit = instruction.exitNumber.toInt(), +// location = location( +// instruction.point.longitude, instruction.point.latitude +// ) +// ) + } + route.sections.forEach { section -> + + + } + + } + println(routeJson) + } + + fun convertType(type: String): Int { + var newType = 0 + when (type) { + "DEPART" -> { + newType = androidx.car.app.navigation.model.Maneuver.TYPE_DEPART + } + } + return newType + } +} \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/Traffic.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Traffic.kt new file mode 100644 index 0000000..8296ab0 --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/Traffic.kt @@ -0,0 +1,12 @@ +package com.kouros.navigation.data.tomtom + +import com.google.gson.annotations.SerializedName + + +data class Traffic ( + + //@SerializedName("incidents" ) var incidents : ArrayList = arrayListOf() + @SerializedName("type" ) var type : String = "", + @SerializedName("features" ) var features : ArrayList = arrayListOf() + +) diff --git a/common/data/src/main/java/com/kouros/navigation/data/tomtom/TrafficData.kt b/common/data/src/main/java/com/kouros/navigation/data/tomtom/TrafficData.kt new file mode 100644 index 0000000..b738464 --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/data/tomtom/TrafficData.kt @@ -0,0 +1,6 @@ +package com.kouros.navigation.data.tomtom + +data class TrafficData ( + var traffic : Traffic , + var trafficData: String = "" +) diff --git a/common/data/src/main/java/com/kouros/navigation/data/valhalla/ValhallaRepository.kt b/common/data/src/main/java/com/kouros/navigation/data/valhalla/ValhallaRepository.kt index 23af098..3a9882f 100644 --- a/common/data/src/main/java/com/kouros/navigation/data/valhalla/ValhallaRepository.kt +++ b/common/data/src/main/java/com/kouros/navigation/data/valhalla/ValhallaRepository.kt @@ -1,5 +1,6 @@ package com.kouros.navigation.data.valhalla +import android.content.Context import android.location.Location import com.kouros.navigation.data.Locations import com.kouros.navigation.data.NavigationRepository @@ -13,6 +14,7 @@ private const val routeUrl = "https://kouros-online.de/valhalla/route?json=" class ValhallaRepository : NavigationRepository() { override fun getRoute( + context: Context, currentLocation: Location, location: Location, carOrientation: Float, diff --git a/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt b/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt index 9b68718..5d51c9d 100644 --- a/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt +++ b/common/data/src/main/java/com/kouros/navigation/model/RouteModel.kt @@ -21,6 +21,7 @@ import com.kouros.navigation.data.route.Lane 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.utils.Levenshtein import com.kouros.navigation.utils.NavigationUtils.getIntKeyValue import com.kouros.navigation.utils.location import kotlinx.coroutines.CoroutineScope @@ -128,16 +129,24 @@ open class RouteModel() { fun updateSpeedLimit(location: Location, viewModel: ViewModel) = runBlocking { CoroutineScope(Dispatchers.IO).launch { + val instruction = currentStep().instruction + val levenshtein = Levenshtein() // speed limit val distance = lastSpeedLocation.distanceTo(location) if (distance > 500 || lastSpeedIndex < route.currentStep) { lastSpeedIndex = route.currentStep - lastSpeedLocation = location val elements = viewModel.getMaxSpeed(location) elements.forEach { - if (it.tags.name != null && it.tags.maxspeed != null) { - val speed = it.tags.maxspeed!!.toInt() - maxSpeed = speed + if (it.tags.name != null) { + if (isNavigating()) { + val distance = + levenshtein.distance(it.tags.name!!, instruction) + if (distance < 5) { + val speed = it.tags.maxspeed.toInt() + maxSpeed = speed + lastSpeedLocation = location + } + } } } } @@ -150,7 +159,7 @@ open class RouteModel() { val distanceToNextStep = leftStepDistance() val isNearNextManeuver = distanceToNextStep in 0.0..NEXT_STEP_THRESHOLD 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 var curManeuverType = if (hasArrived(currentStep.maneuver.type)) { @@ -166,17 +175,16 @@ open class RouteModel() { } // Safely get the street name from the maneuver val streetName = relevantStep.name + var exitNumber = currentStep.maneuver.exit if (shouldAdvance) { curManeuverType = relevantStep.maneuver.type + exitNumber = relevantStep.maneuver.exit } val maneuverIcon = maneuverIcon(curManeuverType) maneuverType = curManeuverType val lanes = currentLanes(location) - if (lanes.isNotEmpty()) - println("Street: $streetName Dist: $distanceToNextStep Lane: ${lanes.size}") - // Construct and return the final StepData object return StepData( streetName, @@ -185,9 +193,9 @@ open class RouteModel() { maneuverIcon, arrivalTime(), travelLeftDistance(), - lanes + lanes, + exitNumber ) - } @@ -215,7 +223,10 @@ open class RouteModel() { maneuverType, maneuverIcon, arrivalTime(), - travelLeftDistance() + travelLeftDistance(), + listOf(Lane(location(0.0, 0.0), valid = false, indications = emptyList())), + step.maneuver.exit + ) } @@ -263,7 +274,7 @@ open class RouteModel() { fun travelLeftDistance(): Double { var leftDistance = 0.0 for (i in route.currentStep + 1.. > by lazy { + MutableLiveData() + } + + val previewRoute: MutableLiveData by lazy { MutableLiveData() } @@ -156,6 +164,7 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { try { route.postValue( repository.getRoute( + context, currentLocation, location, carOrientation, @@ -168,11 +177,46 @@ class ViewModel(private val repository: NavigationRepository) : ViewModel() { } } + fun loadTraffic(context: Context, currentLocation: Location, carOrientation : Float) { + viewModelScope.launch(Dispatchers.IO) { + try { + val data = repository.getTraffic( + context, + currentLocation, + carOrientation + ) + val trafficData = rebuildTraffic(data) + traffic.postValue( + trafficData + ) + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + private fun rebuildTraffic(data: String) : Map { + val featureCollection = FeatureCollection.fromJson(data) + val incidents = mutableMapOf() + val queuing = featureCollection.features()!!.filter { it.properties()!!.get("events").toString().contains("Queuing traffic")} + incidents["queuing"] = FeatureCollection.fromFeatures(queuing).toJson() + val stationary = featureCollection.features()!!.filter { it.properties()!!.get("events").toString().contains("Stationary traffic")} + incidents["stationary"] = FeatureCollection.fromFeatures(stationary).toJson() + val slow = featureCollection.features()!!.filter { it.properties()!!.get("events").toString().contains("Slow traffic")} + incidents["slow"] = FeatureCollection.fromFeatures(slow).toJson() + val heavy = featureCollection.features()!!.filter { it.properties()!!.get("events").toString().contains("Heavy traffic")} + incidents["heavy"] = FeatureCollection.fromFeatures(heavy).toJson() + val roadworks = featureCollection.features()!!.filter { it.properties()!!.get("events").toString().contains("Roadworks")} + incidents["roadworks"] = FeatureCollection.fromFeatures(roadworks).toJson() + + return incidents + } fun loadPreviewRoute(context: Context, currentLocation: Location, location: Location, carOrientation: Float) { viewModelScope.launch(Dispatchers.IO) { try { previewRoute.postValue( repository.getRoute( + context, currentLocation, location, carOrientation, diff --git a/common/data/src/main/java/com/kouros/navigation/utils/GeoUtils.kt b/common/data/src/main/java/com/kouros/navigation/utils/GeoUtils.kt index 662926e..5e4c5f1 100644 --- a/common/data/src/main/java/com/kouros/navigation/utils/GeoUtils.kt +++ b/common/data/src/main/java/com/kouros/navigation/utils/GeoUtils.kt @@ -115,45 +115,31 @@ object GeoUtils { return featureCollection.toJson() } - fun getOverpassBbox(location: Location, radius: Double): String { - - val bbox = getBoundingBox(location.longitude, location.latitude, radius) - val neLon = bbox["ne"]?.get("lon") - val neLat = bbox["ne"]?.get("lat") - val swLon = bbox["sw"]?.get("lon") - val swLat = bbox["sw"]?.get("lat") - return "$swLon,$swLat,$neLon,$neLat" - } /** * Calculate the lat and len of a square around a point. * @return latMin, latMax, lngMin, lngMax */ - fun calculateSquareRadius(lat: Double, lng: Double, radius: Double): DoubleArray { + fun calculateSquareRadius(lat: Double, lng: Double, radius: Double): String { val earthRadius = 6371.0 // earth radius in km val latMin = lat - toDegrees(radius / earthRadius) val latMax = lat + toDegrees(radius / earthRadius) val lngMin = lng - toDegrees(radius / earthRadius / cos(toRadians(lat))) val lngMax = lng + toDegrees(radius / earthRadius / cos(toRadians(lat))) - return doubleArrayOf(latMin, latMax, lngMin, lngMax) + return "$lngMin,$latMin,$lngMax,$latMax" } fun getBoundingBox( lat: Double, lon: Double, radius: Double - ): Map> { + ): String { val earthRadius = 6371.0 val maxLat = lat + toDegrees(radius / earthRadius) val minLat = lat - toDegrees(radius / earthRadius) val maxLon = lon + toDegrees(radius / earthRadius / cos(toRadians(lat))) val minLon = lon - toDegrees(radius / earthRadius / cos(toRadians(lat))) - return mapOf( - "nw" to mapOf("lat" to maxLat, "lon" to minLon), - "ne" to mapOf("lat" to maxLat, "lon" to maxLon), - "sw" to mapOf("lat" to minLat, "lon" to minLon), - "se" to mapOf("lat" to minLat, "lon" to maxLon) - ) + return "$minLat,$minLon,$maxLat,$maxLon" } } \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/utils/Levenshtein.kt b/common/data/src/main/java/com/kouros/navigation/utils/Levenshtein.kt new file mode 100644 index 0000000..b9751e8 --- /dev/null +++ b/common/data/src/main/java/com/kouros/navigation/utils/Levenshtein.kt @@ -0,0 +1,63 @@ +package com.kouros.navigation.utils + +import kotlin.math.min + +/** + * The Levenshtein distance between two words is the minimum number of single-character edits (insertions, deletions or + * substitutions) required to change one string into the other. + * + * This implementation uses dynamic programming (Wagner–Fischer algorithm). + * + * [Levenshtein Distance](https://en.wikipedia.org/wiki/Levenshtein_distance) + */ +class Levenshtein { + + /** + * The Levenshtein distance, or edit distance, between two words is the minimum number of single-character edits + * (insertions, deletions or substitutions) required to change one word into the other. + * + * It is always at least the difference of the sizes of the two strings. + * It is at most the length of the longer string. + * It is `0` if and only if the strings are equal. + * + * @param first first string to compare. + * @param second second string to compare. + * @param limit the maximum result to compute before stopping, terminating calculation early. + * @return the computed Levenshtein distance. + */ + fun distance(first: CharSequence, second: CharSequence, limit: Int = Int.MAX_VALUE): Int { + if (first == second) return 0 + if (first.isEmpty()) return second.length + if (second.isEmpty()) return first.length + + // initial costs is the edit distance from an empty string, which corresponds to the characters to inserts. + // the array size is : length + 1 (empty string) + var cost = IntArray(first.length + 1) { it } + var newCost = IntArray(first.length + 1) + + for (i in 1..second.length) { + // calculate new costs from the previous row. + // the first element of the new row is the edit distance (deletes) to match empty string + newCost[0] = i + var minCost = i + + // fill in the rest of the row + for (j in 1..first.length) { + // if it's the same char at the same position, no edit cost. + val edit = if (first[j - 1] == second[i - 1]) 0 else 1 + val replace = cost[j - 1] + edit + val insert = cost[j] + 1 + val delete = newCost[j - 1] + 1 + newCost[j] = minOf(insert, delete, replace) + minCost = min(minCost, newCost[j]) + } + + if (minCost >= limit) return limit + // flip references of current and previous row + val swap = cost + cost = newCost + newCost = swap + } + return cost.last() + } +} \ No newline at end of file diff --git a/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt b/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt index 32fed71..bce75b9 100644 --- a/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt +++ b/common/data/src/main/java/com/kouros/navigation/utils/NavigationUtils.kt @@ -8,6 +8,7 @@ import com.kouros.navigation.data.Constants.ROUTING_ENGINE import com.kouros.navigation.data.Constants.SHARED_PREF_KEY import com.kouros.navigation.data.RouteEngine import com.kouros.navigation.data.osrm.OsrmRepository +import com.kouros.navigation.data.tomtom.TomTomRepository import com.kouros.navigation.data.valhalla.ValhallaRepository import com.kouros.navigation.model.ViewModel import java.time.LocalDateTime @@ -29,7 +30,8 @@ object NavigationUtils { val routeEngine = getIntKeyValue(context = context, ROUTING_ENGINE) return when (routeEngine) { RouteEngine.VALHALLA.ordinal -> ViewModel(ValhallaRepository()) - else -> ViewModel(OsrmRepository()) + RouteEngine.OSRM.ordinal -> ViewModel(OsrmRepository()) + else -> ViewModel(TomTomRepository()) } } diff --git a/common/data/src/main/res/raw/liberty_night.json b/common/data/src/main/res/raw/liberty_night.json index 0ae6cce..9c1aecb 100644 --- a/common/data/src/main/res/raw/liberty_night.json +++ b/common/data/src/main/res/raw/liberty_night.json @@ -69,17 +69,7 @@ "source-layer": "landuse", "maxzoom": 12, "filter": ["==", ["get", "class"], "residential"], - "paint": { - "fill-color": [ - "interpolate", - ["linear"], - ["zoom"], - 9, - "hsla(0,3%,85%,0.84)", - 12, - "hsla(35,57%,88%,0.49)" - ] - } + "paint": {"fill-color": "rgba(48, 43, 57, 1)"} }, { "id": "landcover_wood", @@ -89,7 +79,7 @@ "filter": ["==", ["get", "class"], "wood"], "paint": { "fill-antialias": false, - "fill-color": "hsla(98,61%,72%,0.7)", + "fill-color": "rgba(21, 28, 16, 0.7)", "fill-opacity": 0.4 } }, @@ -1303,15 +1293,7 @@ ], "layout": {"line-cap": "round", "line-join": "round"}, "paint": { - "line-color": [ - "interpolate", - ["linear"], - ["zoom"], - 5, - "hsl(26,87%,62%)", - 6, - "#ab9" - ], + "line-color": "rgba(12, 84, 84, 1)", "line-width": [ "interpolate", ["exponential", 1.2], @@ -2457,7 +2439,8 @@ "text-field": ["to-string", ["get", "ref"]], "text-font": ["Noto Sans Regular"], "text-rotation-alignment": "viewport", - "text-size": 10 + "text-size": 10, + "visibility": "none" } }, { @@ -2585,7 +2568,8 @@ "text-letter-spacing": 0.1, "text-max-width": 9, "text-size": ["interpolate", ["linear"], ["zoom"], 8, 9, 12, 10], - "text-transform": "uppercase" + "text-transform": "uppercase", + "visibility": "none" }, "paint": { "text-color": "#333", diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/osrm_hv.json b/common/data/src/main/res/raw/osrm_hv.json similarity index 100% rename from common/data/src/main/java/com/kouros/navigation/data/osrm/osrm_hv.json rename to common/data/src/main/res/raw/osrm_hv.json diff --git a/common/data/src/main/java/com/kouros/navigation/data/osrm/osrm_vh.json b/common/data/src/main/res/raw/osrm_vh.json similarity index 100% rename from common/data/src/main/java/com/kouros/navigation/data/osrm/osrm_vh.json rename to common/data/src/main/res/raw/osrm_vh.json diff --git a/common/data/src/main/res/raw/tomom_routing.json b/common/data/src/main/res/raw/tomom_routing.json new file mode 100644 index 0000000..57cd872 --- /dev/null +++ b/common/data/src/main/res/raw/tomom_routing.json @@ -0,0 +1,603 @@ +{ + "formatVersion": "0.0.12", + "report": { + "effectiveSettings": [ + { + "key": "avoid", + "value": "unpavedRoads" + }, + { + "key": "computeBestOrder", + "value": "false" + }, + { + "key": "computeTollAmounts", + "value": "none" + }, + { + "key": "computeTravelTimeFor", + "value": "none" + }, + { + "key": "contentType", + "value": "json" + }, + { + "key": "departAt", + "value": "2026-01-29T08:43:35.397Z" + }, + { + "key": "guidanceVersion", + "value": "1" + }, + { + "key": "includeTollPaymentTypes", + "value": "none" + }, + { + "key": "instructionsType", + "value": "text" + }, + { + "key": "language", + "value": "en-GB" + }, + { + "key": "locations", + "value": "48.18565,11.57928:48.11830,11.59485" + }, + { + "key": "maxAlternatives", + "value": "0" + }, + { + "key": "routeRepresentation", + "value": "encodedPolyline" + }, + { + "key": "routeType", + "value": "eco" + }, + { + "key": "sectionType", + "value": "lanes" + }, + { + "key": "sectionType", + "value": "traffic" + }, + { + "key": "traffic", + "value": "true" + }, + { + "key": "travelMode", + "value": "car" + }, + { + "key": "vehicleAxleWeight", + "value": "0" + }, + { + "key": "vehicleCommercial", + "value": "false" + }, + { + "key": "vehicleEngineType", + "value": "combustion" + }, + { + "key": "vehicleHeading", + "value": "90" + }, + { + "key": "vehicleHeight", + "value": "0.00" + }, + { + "key": "vehicleLength", + "value": "0.00" + }, + { + "key": "vehicleMaxSpeed", + "value": "120" + }, + { + "key": "vehicleNumberOfAxles", + "value": "0" + }, + { + "key": "vehicleWeight", + "value": "0" + }, + { + "key": "vehicleWidth", + "value": "0.00" + } + ] + }, + "routes": [ + { + "summary": { + "lengthInMeters": 10879, + "travelTimeInSeconds": 1170, + "trafficDelayInSeconds": 76, + "trafficLengthInMeters": 1727, + "departureTime": "2026-01-29T09:43:35+01:00", + "arrivalTime": "2026-01-29T10:03:05+01:00" + }, + "legs": [ + { + "summary": { + "lengthInMeters": 10879, + "travelTimeInSeconds": 1170, + "trafficDelayInSeconds": 76, + "trafficLengthInMeters": 1727, + "departureTime": "2026-01-29T09:43:35+01:00", + "arrivalTime": "2026-01-29T10:03:05+01:00" + }, + "encodedPolyline": "sfbeHmqteAEjDQEy@GQ?wDQFkEH{G?M?sA@kB?_FAeC?o@?[@_@\\Ab@CVAz@CJA@?dBGhAGjAExAGlBEvBKdCKTAfCKLAv@ELA|AGnAGt@ClCKjDQpBIf@BXDPDPBF@ZB?S@SAYAUKi@Go@Cc@BgBBs@Bg@JyAJiAXqBDWNs@TaA\\mAFa@Po@`BwF?YL]FSFSl@iB^kALc@L]Ro@f@yAf@{AFQNe@dAoCdBgEx@qBTi@BITe@L[L_@^}@HSXu@pB}El@eAb@e@f@[h@QZCRAL?j@HRFh@Vf@XLJhAn@lAv@TLtAz@r@`@bAn@pAv@f@X~@j@z@h@vBpA`@VHDFFJFf@X`CzApAh@f@L`@Fz@@f@AXEVEVEhA[h@Yn@e@PQFEJKRWV[PW`@w@t@}AHQN]~BiFP]`AoBh@aADGTa@t@aAt@{@PQJKJGFG@Cd@]XSxDmCf@a@n@o@TY\\g@LQHMJSLUP[f@iAPg@b@yAFODMNi@FS|@qCVaAHUHUn@wBHYh@eBpAkEjBiGfAeDj@yADMFQd@sAf@kAJUh@qAf@eAt@sAn@iALSN[p@kAVc@JOLSj@w@z@}@x@q@pAu@p@_@j@Sl@MLCRCb@E`@?^?L@`ABz@?N@~AFdADJ@rAH`DVpCVrAJd@BfHp@zGl@pAJ|ALnGp@jEh@fBJpAFF?P@N@ZCtC]r@GJCFCLCD?TEVEXGhAYzAg@NGv@]`@QJEvB_AXMVK\\Qb@Qn@QJCNAZC^ENA`@FnBb@xEtA^H^JnCl@z@r@`@Pr@TtBlA~C`Bn@\\xAl@PF`@LrAVlCh@bBLl@BlBJdG\\RDjCHn@?pB?xB?R@`@@GxAC^?ZInBIfCAvC?r@@dD@n@@b@@^D`C?TDxAFbBHdB@VHp@RjAJb@NNH`@VlBFf@PzARhBFd@@LRbBFh@\\nC@FNhAb@lEj@tDPpABTBRZlBTdBXjBn@xEBLDTRpAR~@Fb@", + "encodedPolylinePrecision": 5 + } + ], + "sections": [ + { + "startPointIndex": 83, + "endPointIndex": 147, + "sectionType": "TRAFFIC", + "simpleCategory": "JAM", + "effectiveSpeedInKmh": 35, + "delayInSeconds": 76, + "magnitudeOfDelay": 1, + "tec": { + "causes": [ + { + "mainCauseCode": 1 + } + ], + "effectCode": 4 + }, + "eventId": "TTL41048054144049000" + }, + { + "lanes": [ + { + "directions": [ + "SLIGHT_LEFT" + ], + "follow": "SLIGHT_LEFT" + }, + { + "directions": [ + "STRAIGHT" + ] + }, + { + "directions": [ + "STRAIGHT" + ] + }, + { + "directions": [ + "STRAIGHT" + ] + } + ], + "laneSeparators": [ + "SINGLE_SOLID", + "SINGLE_SOLID", + "LONG_DASHED", + "LONG_DASHED", + "SINGLE_SOLID" + ], + "startPointIndex": 42, + "endPointIndex": 45, + "sectionType": "LANES" + }, + { + "lanes": [ + { + "directions": [ + "STRAIGHT" + ], + "follow": "STRAIGHT" + }, + { + "directions": [ + "SLIGHT_RIGHT" + ] + } + ], + "laneSeparators": [ + "SINGLE_SOLID", + "SHORT_DASHED", + "SINGLE_SOLID" + ], + "startPointIndex": 61, + "endPointIndex": 62, + "sectionType": "LANES" + }, + { + "lanes": [ + { + "directions": [ + "SLIGHT_LEFT" + ], + "follow": "SLIGHT_LEFT" + }, + { + "directions": [ + "SLIGHT_LEFT" + ], + "follow": "SLIGHT_LEFT" + }, + { + "directions": [ + "SLIGHT_RIGHT" + ] + } + ], + "laneSeparators": [ + "SINGLE_SOLID", + "LONG_DASHED", + "SHORT_DASHED", + "SINGLE_SOLID" + ], + "startPointIndex": 74, + "endPointIndex": 75, + "sectionType": "LANES" + }, + { + "lanes": [ + { + "directions": [ + "STRAIGHT" + ] + }, + { + "directions": [ + "SLIGHT_RIGHT" + ], + "follow": "SLIGHT_RIGHT" + } + ], + "laneSeparators": [ + "SINGLE_SOLID", + "LONG_DASHED", + "SINGLE_SOLID" + ], + "startPointIndex": 265, + "endPointIndex": 266, + "sectionType": "LANES" + }, + { + "lanes": [ + { + "directions": [ + "LEFT" + ] + }, + { + "directions": [ + "STRAIGHT" + ] + }, + { + "directions": [ + "STRAIGHT" + ] + }, + { + "directions": [ + "RIGHT" + ], + "follow": "RIGHT" + } + ], + "laneSeparators": [ + "SINGLE_SOLID", + "SINGLE_SOLID", + "SINGLE_SOLID", + "SINGLE_SOLID", + "SINGLE_SOLID" + ], + "startPointIndex": 287, + "endPointIndex": 288, + "sectionType": "LANES" + }, + { + "lanes": [ + { + "directions": [ + "LEFT" + ] + }, + { + "directions": [ + "STRAIGHT" + ], + "follow": "STRAIGHT" + }, + { + "directions": [ + "STRAIGHT" + ], + "follow": "STRAIGHT" + }, + { + "directions": [ + "RIGHT" + ] + } + ], + "laneSeparators": [ + "SINGLE_SOLID", + "SHORT_DASHED", + "LONG_DASHED", + "SHORT_DASHED", + "SINGLE_SOLID" + ], + "startPointIndex": 302, + "endPointIndex": 304, + "sectionType": "LANES" + } + ], + "guidance": { + "instructions": [ + { + "routeOffsetInMeters": 0, + "travelTimeInSeconds": 0, + "point": { + "latitude": 48.18554, + "longitude": 11.57927 + }, + "exitNumber": "", + "pointIndex": 0, + "instructionType": "LOCATION_DEPARTURE", + "street": "Vogelhartstraße", + "countryCode": "DEU", + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "DEPART", + "message": "Leave from Vogelhartstraße" + }, + { + "routeOffsetInMeters": 64, + "travelTimeInSeconds": 14, + "point": { + "latitude": 48.18557, + "longitude": 11.57841 + }, + "pointIndex": 1, + "instructionType": "TURN", + "street": "Silcherstraße", + "countryCode": "DEU", + "junctionType": "REGULAR", + "turnAngleInDecimalDegrees": 90, + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "TURN_RIGHT", + "message": "Turn right onto Silcherstraße" + }, + { + "routeOffsetInMeters": 218, + "travelTimeInSeconds": 57, + "point": { + "latitude": 48.18696, + "longitude": 11.57857 + }, + "pointIndex": 5, + "instructionType": "TURN", + "street": "Schmalkaldener Straße", + "countryCode": "DEU", + "junctionType": "REGULAR", + "turnAngleInDecimalDegrees": 90, + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "TURN_RIGHT", + "message": "Turn right onto Schmalkaldener Straße" + }, + { + "routeOffsetInMeters": 650, + "travelTimeInSeconds": 131, + "point": { + "latitude": 48.18686, + "longitude": 11.58437 + }, + "pointIndex": 15, + "instructionType": "TURN", + "roadNumbers": [ + "B13" + ], + "street": "Ingolstädter Straße", + "countryCode": "DEU", + "junctionType": "REGULAR", + "turnAngleInDecimalDegrees": 90, + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "TURN_RIGHT", + "message": "Turn right onto Ingolstädter Straße/B13" + }, + { + "routeOffsetInMeters": 1713, + "travelTimeInSeconds": 266, + "point": { + "latitude": 48.17733, + "longitude": 11.58503 + }, + "pointIndex": 45, + "instructionType": "TURN", + "roadNumbers": [ + "B2R" + ], + "street": "Schenkendorfstraße", + "countryCode": "DEU", + "junctionType": "REGULAR", + "turnAngleInDecimalDegrees": -90, + "possibleCombineWithNext": true, + "drivingSide": "RIGHT", + "maneuver": "TURN_LEFT", + "message": "Turn left onto Schenkendorfstraße/B2R", + "combinedMessage": "Turn left onto Schenkendorfstraße/B2R then keep left at Schenkendorfstraße/B2R toward Messe / ICM" + }, + { + "routeOffsetInMeters": 2067, + "travelTimeInSeconds": 309, + "point": { + "latitude": 48.17678, + "longitude": 11.58957 + }, + "pointIndex": 62, + "instructionType": "TURN", + "roadNumbers": [ + "B2R" + ], + "street": "Schenkendorfstraße", + "countryCode": "DEU", + "signpostText": "Messe / ICM", + "junctionType": "BIFURCATION", + "turnAngleInDecimalDegrees": -45, + "possibleCombineWithNext": true, + "drivingSide": "RIGHT", + "maneuver": "KEEP_LEFT", + "message": "Keep left at Schenkendorfstraße/B2R toward Messe / ICM", + "combinedMessage": "Keep left at Schenkendorfstraße/B2R toward Messe / ICM then keep left at Schenkendorfstraße/B2R toward Passau" + }, + { + "routeOffsetInMeters": 2419, + "travelTimeInSeconds": 332, + "point": { + "latitude": 48.17518, + "longitude": 11.59363 + }, + "pointIndex": 75, + "instructionType": "TURN", + "roadNumbers": [ + "B2R" + ], + "street": "Schenkendorfstraße", + "countryCode": "DEU", + "signpostText": "Passau", + "junctionType": "BIFURCATION", + "turnAngleInDecimalDegrees": -45, + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "KEEP_LEFT", + "message": "Keep left at Schenkendorfstraße/B2R toward Passau" + }, + { + "routeOffsetInMeters": 2774, + "travelTimeInSeconds": 357, + "point": { + "latitude": 48.17329, + "longitude": 11.59747 + }, + "pointIndex": 86, + "instructionType": "DIRECTION_INFO", + "roadNumbers": [ + "B2R" + ], + "street": "Isarring", + "countryCode": "DEU", + "signpostText": "München-Ost", + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "FOLLOW", + "message": "Follow Isarring/B2R toward München-Ost" + }, + { + "routeOffsetInMeters": 8425, + "travelTimeInSeconds": 806, + "point": { + "latitude": 48.13017, + "longitude": 11.61541 + }, + "pointIndex": 266, + "instructionType": "TURN", + "street": "Ampfingstraße", + "countryCode": "DEU", + "junctionType": "REGULAR", + "turnAngleInDecimalDegrees": 45, + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "BEAR_RIGHT", + "message": "Bear right at Ampfingstraße" + }, + { + "routeOffsetInMeters": 9487, + "travelTimeInSeconds": 953, + "point": { + "latitude": 48.12089, + "longitude": 11.61285 + }, + "pointIndex": 288, + "instructionType": "TURN", + "street": "Anzinger Straße", + "countryCode": "DEU", + "junctionType": "REGULAR", + "turnAngleInDecimalDegrees": 90, + "possibleCombineWithNext": true, + "drivingSide": "RIGHT", + "maneuver": "TURN_RIGHT", + "message": "Turn right onto Anzinger Straße", + "combinedMessage": "Turn right onto Anzinger Straße then keep straight on at Sankt-Martin-Straße" + }, + { + "routeOffsetInMeters": 9983, + "travelTimeInSeconds": 1044, + "point": { + "latitude": 48.12087, + "longitude": 11.60621 + }, + "pointIndex": 304, + "instructionType": "TURN", + "street": "Sankt-Martin-Straße", + "countryCode": "DEU", + "junctionType": "REGULAR", + "turnAngleInDecimalDegrees": 0, + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "STRAIGHT", + "message": "Keep straight on at Sankt-Martin-Straße" + }, + { + "routeOffsetInMeters": 10879, + "travelTimeInSeconds": 1170, + "point": { + "latitude": 48.1183, + "longitude": 11.59485 + }, + "pointIndex": 335, + "instructionType": "LOCATION_ARRIVAL", + "street": "Sankt-Martin-Straße", + "countryCode": "DEU", + "possibleCombineWithNext": false, + "drivingSide": "RIGHT", + "maneuver": "ARRIVE", + "message": "You have arrived at Sankt-Martin-Straße" + } + ], + "instructionGroups": [ + { + "firstInstructionIndex": 0, + "lastInstructionIndex": 3, + "groupMessage": "Leave from Vogelhartstraße. Take the Ingolstädter Straße/B13", + "groupLengthInMeters": 1713 + }, + { + "firstInstructionIndex": 4, + "lastInstructionIndex": 7, + "groupMessage": "Take the Schenkendorfstraße, Isarring/B2R toward Messe / ICM, Passau, München-Ost", + "groupLengthInMeters": 6712 + }, + { + "firstInstructionIndex": 8, + "lastInstructionIndex": 11, + "groupMessage": "Take the Ampfingstraße, Anzinger Straße. Continue to your destination at Sankt-Martin-Straße", + "groupLengthInMeters": 2454 + } + ] + } + } + ] +} \ No newline at end of file diff --git a/common/data/src/main/res/raw/tomtom_traffic.json b/common/data/src/main/res/raw/tomtom_traffic.json new file mode 100644 index 0000000..3005575 --- /dev/null +++ b/common/data/src/main/res/raw/tomtom_traffic.json @@ -0,0 +1,4578 @@ +{ + "type": "FeatureCollection", "features" : [ + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.3944369162, 48.257052006], + [11.3943484033, 48.2569756077], + [11.3940479959, 48.2567234758], + [11.3940184916, 48.2566912756], + [11.3939930106, 48.2566604147], + [11.3939769173, 48.256630949], + [11.3939769173, 48.2566027668], + [11.3939822818, 48.256579942], + [11.3939970339, 48.2565531549], + [11.3940198327, 48.2565356875], + [11.3940547014, 48.2565182759], + [11.3941070045, 48.256503543], + [11.3941673542, 48.2564927724], + [11.3942491616, 48.2564793788], + [11.394305488, 48.2564740214], + [11.3945388401, 48.2564579491], + [11.3946313763, 48.2564485178], + [11.3946890438, 48.2564404817], + [11.3947158659, 48.2564351243], + [11.3947896267, 48.2564150339], + [11.3948915506, 48.256373458] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.3953019286, 48.2558678477], + [11.3952523077, 48.2559295146], + [11.3951932991, 48.2560059702], + [11.3951302672, 48.2560984981], + [11.3950565065, 48.2562058147], + [11.3950135911, 48.2562674812], + [11.3949706758, 48.2563117359], + [11.3949559236, 48.2563264688], + [11.3949411715, 48.2563385789], + [11.3949170316, 48.2563546512], + [11.3948915506, 48.256373458] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4109620059, 48.1293372933], + [11.4107809568, 48.1292930407], + [11.4102297629, 48.1291468558], + [11.4098918045, 48.1290583502], + [11.4097013677, 48.1289993277], + [11.4095243419, 48.128949704], + [11.4093781615, 48.1289081365], + [11.4092078412, 48.1288505125], + [11.4087357725, 48.128692242], + [11.4085359479, 48.1286251629] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4125753547, 48.1383267204], + [11.4126289988, 48.138156397], + [11.4128154124, 48.1375515627], + [11.4128422345, 48.1374603867] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4198025669, 48.1518946711], + [11.4199474061, 48.1515379527], + [11.4200587178, 48.1512617025] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4244065786, 48.2547668166], + [11.4246479774, 48.2545508936], + [11.4247606302, 48.2544542888], + [11.4248585308, 48.2543738684], + [11.4249135161, 48.2543363091] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4278585816, 48.1194640996], + [11.427721789, 48.119590168], + [11.4275581742, 48.119740353], + [11.4273771251, 48.1199120245] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Contraflow" + }, + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4085185135, 48.1284816614], + [11.4085815454, 48.1285031447], + [11.4096074904, 48.1288370855], + [11.4104228819, 48.1290543221], + [11.4108050967, 48.1291683388], + [11.4109660293, 48.1292085634], + [11.4112476612, 48.1292769845], + [11.4116365815, 48.1293668324], + [11.4118551815, 48.1294110849], + [11.4123366381, 48.1295103313], + [11.4126531387, 48.1295706399], + [11.413093021, 48.12966183], + [11.4135074223, 48.1297356211], + [11.4138145352, 48.1297865867], + [11.4145293439, 48.1298979164], + [11.4147197808, 48.1299233711], + [11.4148713256, 48.1299475391], + [11.4150014127, 48.1299635952], + [11.4156169797, 48.1300387285], + [11.4166026915, 48.1301553724], + [11.4177010561, 48.1302411908], + [11.4179518426, 48.1302586454], + [11.4181905592, 48.1302747573], + [11.4185218121, 48.1302908132], + [11.4187940563, 48.1303015545], + [11.4189496244, 48.1303055825], + [11.4192419852, 48.1303149811], + [11.419586649, 48.1303216943], + [11.4199567939, 48.1303284076], + [11.4203470553, 48.1303297503], + [11.4205710197, 48.1303297503], + [11.4208325351, 48.1303297503], + [11.4209921266, 48.1303297503], + [11.4213515426, 48.1303257223], + [11.4216358567, 48.1303082678], + [11.4218638445, 48.1302948412], + [11.4222339893, 48.1302613307], + [11.4226457084, 48.1302264775], + [11.4231472815, 48.1301714843], + [11.4233766104, 48.1301446311], + [11.4236756767, 48.1301030645], + [11.4237427319, 48.1300950085], + [11.4237762595, 48.1300923232], + [11.4245608056, 48.1299435111], + [11.4247284437, 48.1299126298], + [11.4249001051, 48.1298737483], + [11.4253533984, 48.1297651039], + [11.4266784097, 48.1293735458], + [11.4268554355, 48.129317209], + [11.4271370674, 48.129223333], + [11.4275219644, 48.1290878894], + [11.4276265706, 48.129050294], + [11.4278693105, 48.128963131], + [11.4281361903, 48.1288652262], + [11.4284298922, 48.1287552929], + [11.4286391045, 48.1286841858], + [11.4289328063, 48.1285755388], + [11.4291299487, 48.128501802], + [11.4296798016, 48.1283059905], + [11.4302189256, 48.1281074928], + [11.4307204987, 48.1279345061], + [11.4309002067, 48.1278674819], + [11.4310758913, 48.1278084581], + [11.4315265025, 48.1276756962], + [11.4319194461, 48.1275737608], + [11.4320133234, 48.1275495916], + [11.4322413112, 48.1274919661], + [11.4325497652, 48.1273592034], + [11.4326825345, 48.1273296632], + [11.4329601432, 48.1272719815], + [11.4331666733, 48.1272411545], + [11.4334174598, 48.1272116702], + [11.4337446893, 48.1271807872], + [11.4339753593, 48.1271526456], + [11.4343334342, 48.1271191331], + [11.4345600809, 48.1271016774], + [11.4348511005, 48.1270895927], + [11.434908768, 48.12708825], + [11.4352279509, 48.1270815922], + [11.4352453853, 48.1270815922], + [11.4353003705, 48.1270802495], + [11.4357442761, 48.1270869632], + [11.436063459, 48.1271083911], + [11.4366951192, 48.1271566738], + [11.4368775094, 48.1271861582], + [11.437153777, 48.1272277271], + [11.4373442138, 48.1272612956], + [11.4376379157, 48.1273175786], + [11.4377103353, 48.127331006], + [11.4379396642, 48.127376603], + [11.4382856692, 48.1274530829], + [11.4385042692, 48.127502652], + [11.4388113821, 48.1275710753], + [11.4394229258, 48.1277038375], + [11.4398923124, 48.1277950309], + [11.4405883456, 48.1278795105], + [11.4413044954, 48.1279425624], + [11.4414319004, 48.1279546469], + [11.4419965054, 48.1279666754], + [11.4424605275, 48.1279506187], + [11.442723384, 48.1279412197], + [11.4429366196, 48.1279331634], + [11.4431364442, 48.1279171067], + [11.4431793595, 48.1279117358], + [11.4432665313, 48.1279023367] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4463980103, 48.1273913731], + [11.4461928214, 48.1274503974], + [11.44579049, 48.1275670471], + [11.445431074, 48.1276662971], + [11.4449227954, 48.1277856318], + [11.4444064702, 48.1278956231], + [11.4442240799, 48.1279264498], + [11.4440309609, 48.127958675], + [11.4440229143, 48.1279600177], + [11.4437694455, 48.1279935298], + [11.4437064136, 48.1280029288], + [11.4436380173, 48.1280122719], + [11.4435548688, 48.1280230136], + [11.4432839657, 48.1280498679], + [11.4432745779, 48.1280512107], + [11.4429325963, 48.1280806945], + [11.4426268245, 48.1280968071], + [11.4422794784, 48.128111521], + [11.4422204698, 48.1281128637], + [11.4418530072, 48.1281128637], + [11.4416531826, 48.1281074928], + [11.4415016378, 48.1281035206], + [11.4414037372, 48.1281008352], + [11.4413219298, 48.1280954643], + [11.4412977899, 48.1280927789], + [11.44128572, 48.1280927789], + [11.4411998893, 48.1280874081], + [11.4407801236, 48.1280525534], + [11.4405320192, 48.1280324126], + [11.4401605333, 48.127982788], + [11.4399808253, 48.127958675], + [11.4398292805, 48.1279318206], + [11.4397032166, 48.1279117358], + [11.439386716, 48.1278500266], + [11.4390769208, 48.1277842891], + [11.4386263097, 48.1276877248], + [11.438308468, 48.1276153294], + [11.4378712679, 48.1275174221], + [11.437654009, 48.1274745106], + [11.43744882, 48.1274342846], + [11.4371551181, 48.1273819739], + [11.4369392003, 48.1273444333], + [11.4364416505, 48.1272840662], + [11.4360688234, 48.1272572674], + [11.4357670749, 48.127238469], + [11.4353017117, 48.1272357836], + [11.434998622, 48.1272451827], + [11.4346727336, 48.1272599528], + [11.434356233, 48.1272880944], + [11.434266379, 48.1273028645], + [11.43404912, 48.1273216068], + [11.4338023568, 48.127351147], + [11.4335797335, 48.127376603], + [11.4333597923, 48.1274114581], + [11.4324129725, 48.1275858453], + [11.4322949553, 48.1276139867], + [11.4320656265, 48.1276783817], + [11.431995889, 48.1276984666], + [11.4314634706, 48.127852712], + [11.4310879613, 48.1279774171], + [11.4309632386, 48.1280216709], + [11.430802306, 48.1280753236], + [11.4301022495, 48.1283261312], + [11.4297790433, 48.1284347227], + [11.4293351377, 48.1286023929], + [11.4290213192, 48.1287150119], + [11.4287544394, 48.1288156024], + [11.4286122824, 48.128870597], + [11.4282770062, 48.1289926702], + [11.4279001559, 48.129124086], + [11.4277311767, 48.1291857378], + [11.4276265706, 48.1292206476], + [11.4272698368, 48.1293480348], + [11.4269761349, 48.129448624], + [11.4265966023, 48.1295706399], + [11.4264276231, 48.1296216057], + [11.4261392857, 48.1297087676], + [11.4259461666, 48.1297624186], + [11.4257959629, 48.1298039855], + [11.4256551469, 48.1298456082], + [11.4254352058, 48.1298992591] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4580750073, 48.199023763], + [11.458084395, 48.1991163381], + [11.4581165815, 48.1993000353], + [11.4581232871, 48.1993402609], + [11.4581568147, 48.1996165315], + [11.4581796134, 48.2000792325] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4632610584, 48.1426611901], + [11.4619749392, 48.1426156067], + [11.4609731341, 48.1425431764] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4583727325, 48.1504221501], + [11.4585551227, 48.150351073], + [11.4587214197, 48.1502893907], + [11.4588890577, 48.1502303926], + [11.4590124393, 48.1501901285], + [11.4597956444, 48.1499125289], + [11.4604487623, 48.1496966109], + [11.461241355, 48.149455191], + [11.4617469514, 48.1493010105], + [11.4619843269, 48.1492326161], + [11.4621761049, 48.1491735609], + [11.4627125467, 48.1490099844], + [11.4635386671, 48.1487900361], + [11.4642534758, 48.1485888773], + [11.4646598304, 48.1484628241], + [11.4653451348, 48.1482388468] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4659607018, 48.1481476338], + [11.4657622183, 48.1482079765], + [11.465732714, 48.1482160296], + [11.4655610527, 48.1482710034], + [11.4649615789, 48.1484574554], + [11.4645230378, 48.1485929038], + [11.4644626881, 48.1486116384], + [11.4641515518, 48.1487041927], + [11.4639812315, 48.1487497708], + [11.4632396008, 48.1489536692], + [11.4624926055, 48.1491588531], + [11.4622082914, 48.1492446397], + [11.4620178546, 48.1493023526], + [11.4617885257, 48.1493707469], + [11.4612882937, 48.1495222988], + [11.4606700445, 48.1497113746], + [11.4603723193, 48.1498172925], + [11.4601403082, 48.1498923968], + [11.4598895217, 48.1499822645], + [11.4595113302, 48.150117709], + [11.459059378, 48.1502786536], + [11.4588112737, 48.150371205], + [11.4585832859, 48.1504530191], + [11.4583955313, 48.1505147011] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.469145825, 48.1823860165], + [11.4691873992, 48.1824812484], + [11.4691941048, 48.1825550194], + [11.4691726471, 48.1826556162], + [11.4691163207, 48.1828044431], + [11.46879982, 48.1836882302], + [11.4686630274, 48.1840678058], + [11.4681815709, 48.1854128958], + [11.4681332911, 48.185545676], + [11.4680581893, 48.1856234663], + [11.4679093267, 48.1856932092], + [11.4677255953, 48.1857468575], + [11.4675069953, 48.1857790465], + [11.4672495032, 48.185730763], + [11.4671033228, 48.185691868] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4671033228, 48.185691868], + [11.4672495032, 48.185730763], + [11.4675069953, 48.1857790465], + [11.4677255953, 48.1857468575], + [11.4679093267, 48.1856932092], + [11.4680581893, 48.1856234663], + [11.4681332911, 48.185545676], + [11.4681815709, 48.1854128958], + [11.4686630274, 48.1840678058], + [11.46879982, 48.1836882302], + [11.4691163207, 48.1828044431], + [11.4691726471, 48.1826556162], + [11.4691941048, 48.1825550194], + [11.4691873992, 48.1824812484], + [11.469145825, 48.1823860165] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.469581684, 48.1470171049], + [11.4694650079, 48.1470479201], + [11.4690291489, 48.1471699501], + [11.4685329402, 48.1473080864], + [11.4681654776, 48.1474113808], + [11.4680152739, 48.1474583022] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4775625969, 48.292721375], + [11.4772165919, 48.2923834264] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Slow traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4777731503, 48.1622131556], + [11.4772072042, 48.163658838], + [11.4771844054, 48.1636870155], + [11.477140149, 48.1637178765], + [11.4770838226, 48.1637326362], + [11.4770046974, 48.1637447122], + [11.4762107636, 48.1637969858], + [11.4761490727, 48.1640679132], + [11.4761343206, 48.1642221053], + [11.4761530961, 48.164392454] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.478937229, 48.1446915989], + [11.4791008438, 48.1446835452], + [11.4792242254, 48.1446795184], + [11.4796989764, 48.1446594401], + [11.4802434648, 48.144644675], + [11.4810213054, 48.1446125161], + [11.4824388529, 48.144550771] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4824388529, 48.144550771], + [11.4810213054, 48.1446125161], + [11.4802434648, 48.144644675], + [11.4796989764, 48.1446594401], + [11.4792242254, 48.1446795184], + [11.4791008438, 48.1446835452], + [11.478937229, 48.1446915989] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4834111537, 48.1336154068], + [11.4838121439, 48.1344093637], + [11.4840508605, 48.1348572701], + [11.4842091108, 48.135169745] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + }, + { + "description": "Construction work" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.486931553, 48.1366423121], + [11.4866686965, 48.1366127773], + [11.4862878228, 48.1366262022], + [11.4859471823, 48.1366369421] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4912056531, 48.1363217911], + [11.491436323, 48.1370272143] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.491436323, 48.1370272143], + [11.4912056531, 48.1363217911] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4930188264, 48.1371412133], + [11.4928458239, 48.1362171879] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4928458239, 48.1362171879], + [11.4930188264, 48.1371412133] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + }, + { + "description": "Construction work" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4941735173, 48.1360817067], + [11.4928458239, 48.1362171879] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4942660535, 48.1370942824], + [11.4941735173, 48.1360817067] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4941735173, 48.1360817067], + [11.4942660535, 48.1370942824] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + }, + { + "description": "Construction work" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4926848913, 48.1361058719], + [11.4933675135, 48.136050885], + [11.4941748584, 48.1359703904], + [11.4947515334, 48.135916746] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4956956709, 48.1378318581], + [11.4955159629, 48.1363714077], + [11.4954877998, 48.1359677054] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4954877998, 48.1359677054], + [11.4955159629, 48.1363714077], + [11.4956956709, 48.1378318581] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4905015732, 48.1945847092], + [11.4905404652, 48.1945793453], + [11.4906625057, 48.1945686175], + [11.4907832051, 48.1945592306], + [11.4908985401, 48.1945525257], + [11.4909696187, 48.1945525257], + [11.4910930003, 48.1945485028], + [11.4912794138, 48.1945511848], + [11.4915704335, 48.1945578897], + [11.4917474593, 48.1945578897], + [11.4918185378, 48.1945565487], + [11.4919244851, 48.1945485028], + [11.4920143391, 48.194539116], + [11.4920880998, 48.1945283882], + [11.4921873416, 48.1945122964], + [11.4923764373, 48.194473408], + [11.4924434925, 48.1944586573], + [11.4925346876, 48.1944372016], + [11.4926124717, 48.1944157459], + [11.4927224423, 48.1943835624], + [11.492847165, 48.1943419919], + [11.4929625, 48.1942990804], + [11.493052354, 48.1942628739], + [11.4932052399, 48.1941985066], + [11.4933245982, 48.1941435261], + [11.4934855307, 48.1940777618], + [11.4936062301, 48.1940335091], + [11.4936410988, 48.1940214402], + [11.4937604571, 48.1939852334], + [11.4938583578, 48.1939610956], + [11.4939924682, 48.1939356167], + [11.4942057038, 48.1939061148], + [11.494349202, 48.1938927049], + [11.4944216217, 48.1938886819], + [11.4945195223, 48.1938873409], + [11.4946294929, 48.1938913639], + [11.4947247113, 48.1938994099], + [11.4948185886, 48.1939114788], + [11.4949795211, 48.1939409807], + [11.4951149727, 48.1939731645], + [11.4952182377, 48.1939986433], + [11.4953335727, 48.1940348501], + [11.4954126979, 48.1940643519], + [11.495490482, 48.1940965356], + [11.4956017936, 48.194150231], + [11.4956219102, 48.1941609589], + [11.4957640673, 48.1942400771], + [11.4958324636, 48.1942843296], + [11.4958874489, 48.1943178542] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4951337482, 48.1246662223], + [11.4957318808, 48.1248110772], + [11.4958552624, 48.1248392201], + [11.4966666306, 48.1250256452], + [11.4969254638, 48.1250766155], + [11.4970220233, 48.1250981002], + [11.4970931018, 48.1251155006] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4993770028, 48.0869865588], + [11.4983456935, 48.0870214414], + [11.4980157817, 48.0869946216], + [11.4978065694, 48.0869879026], + [11.4976617302, 48.0869637704], + [11.4974525179, 48.0869101307], + [11.4971547927, 48.0868229522], + [11.4967564846, 48.0866995469], + [11.4962589348, 48.0864876744], + [11.4961422588, 48.0864380657], + [11.4960148538, 48.0863978075], + [11.4959129299, 48.0863763626], + [11.4957962538, 48.0863656122], + [11.4956621433, 48.0863576053] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4997712875, 48.1313127337], + [11.4996291305, 48.1310230602] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4996291305, 48.1310230602], + [11.4997712875, 48.1313127337] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5009045209, 48.1026372578], + [11.5008723343, 48.1025688573], + [11.5008321012, 48.1024749883], + [11.5008012558, 48.1023998706], + [11.5007677282, 48.1023556508], + [11.5007328595, 48.1023073448], + [11.5007046963, 48.1022684424] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.4994038249, 48.1120759372], + [11.5018620695, 48.1120316698] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5021074916, 48.1057915314], + [11.5020551885, 48.1056681717], + [11.5019881333, 48.1054388024], + [11.5019277836, 48.1052725119], + [11.5018459762, 48.1050499134] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.49859648, 48.1120839961], + [11.4993984605, 48.1120759372], + [11.5018660928, 48.1120316698], + [11.5022550131, 48.1120330129] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5023006106, 48.107427699], + [11.5023059751, 48.1075886096], + [11.5023140217, 48.1078850196], + [11.502318045, 48.1079802219] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5024266745, 48.11218322], + [11.5022483076, 48.1121779034], + [11.5018540228, 48.1121752172] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Left lane closed" + }, + { + "description": "Carriageway reduced to one lane" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5026801432, 48.1277078657], + [11.5026734377, 48.127482567], + [11.5026627089, 48.1269219735] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + }, + { + "description": "Lane closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5027391518, 48.12977316], + [11.5027109886, 48.1289550748], + [11.5026989187, 48.1284132953], + [11.5026801432, 48.1277078657], + [11.5026734377, 48.127482567], + [11.5026627089, 48.1269219735], + [11.5026600267, 48.1267824956], + [11.5026586856, 48.1265612211], + [11.5026506389, 48.1264042863], + [11.5026439334, 48.126293005], + [11.502638569, 48.1261682958], + [11.5026358868, 48.1260998706], + [11.5026345457, 48.1260703857], + [11.5026332046, 48.1260395579], + [11.5026305224, 48.1259697898], + [11.5026291813, 48.125909421], + [11.5026291813, 48.1258356804], + [11.5026291813, 48.1257511974], + [11.5026197935, 48.1256438871], + [11.5026197935, 48.1255969457] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Left lane closed" + }, + { + "description": "Carriageway reduced to one lane" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5028155948, 48.1322408193], + [11.5028129126, 48.1320999572], + [11.5028048659, 48.131775436] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Left lane closed" + }, + { + "description": "Carriageway reduced to one lane" + }, + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5029108132, 48.1302667013], + [11.5029134954, 48.1303592328], + [11.5029497052, 48.1310203749], + [11.5029564108, 48.1314213748], + [11.5029644574, 48.1317902048] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Left lane closed" + }, + { + "description": "Carriageway reduced to one lane" + }, + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5030181016, 48.1396141678], + [11.503011396, 48.1394599578], + [11.5029832328, 48.1387142949], + [11.5029711629, 48.1383535694], + [11.5029644574, 48.1379284034], + [11.5029523874, 48.1373919766], + [11.5029483641, 48.1372189651], + [11.5029322709, 48.1368756814], + [11.5029255654, 48.1366986408], + [11.5029202009, 48.1364572157], + [11.5029134954, 48.1362171879], + [11.5029014255, 48.1357893751], + [11.5028987433, 48.1355533158], + [11.5028960611, 48.1355184662], + [11.5028920377, 48.1354433408], + [11.5028893555, 48.1353990935], + [11.5028880144, 48.1353642438], + [11.5028866733, 48.1352730638], + [11.50288265, 48.1350638528], + [11.50288265, 48.1349994671], + [11.5028786267, 48.1347097585], + [11.5028611923, 48.1341800108], + [11.5028598512, 48.1341210502], + [11.5028518046, 48.1338393919], + [11.5028491224, 48.1337669493] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5026560033, 48.121427498], + [11.502843758, 48.1214127262], + [11.5029684807, 48.1213966115], + [11.5030851568, 48.121377867] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Left lane closed" + }, + { + "description": "Carriageway reduced to one lane" + }, + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5030905212, 48.1423098328], + [11.5030932034, 48.1422735895], + [11.5030918623, 48.142163629], + [11.5030918623, 48.1421354956], + [11.5030905212, 48.1419772101], + [11.5030891801, 48.1417733959] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Left lane closed" + }, + { + "description": "Carriageway reduced to one lane" + }, + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5030154194, 48.1337736621], + [11.5030181016, 48.1338367068], + [11.5030274893, 48.1341303921], + [11.5030288304, 48.1341773816], + [11.5030328537, 48.1346414006], + [11.503036877, 48.1350396872], + [11.5030422414, 48.1352703788], + [11.5030422414, 48.135349476], + [11.5030422414, 48.1353910383], + [11.5030449237, 48.1354379708], + [11.503048947, 48.1355184662], + [11.5030516292, 48.1355519732], + [11.5030502881, 48.1358041427], + [11.5030610169, 48.1363794627], + [11.503062358, 48.1364317642], + [11.5030851568, 48.13692127], + [11.5030945445, 48.137190829], + [11.5031025911, 48.1374348797], + [11.5031160022, 48.1376011781], + [11.5031253899, 48.138067907], + [11.5031347777, 48.1382596539], + [11.5031508709, 48.138574849], + [11.5031709875, 48.1391354271], + [11.5031937863, 48.1396302768], + [11.5031964685, 48.139689287], + [11.5031978096, 48.139750982], + [11.5032125617, 48.1400943024], + [11.5032206083, 48.1402780434], + [11.5032273139, 48.1404268814], + [11.503228655, 48.1405207929], + [11.5032340194, 48.1407755668], + [11.5032340194, 48.1408386029], + [11.5032514537, 48.1412811956], + [11.503254136, 48.141438085], + [11.5032581593, 48.1416057127], + [11.5032554771, 48.1417063339], + [11.503254136, 48.1417787094], + [11.5032581593, 48.1419798948] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5014436449, 48.1029564217], + [11.501444986, 48.1029443874], + [11.5014516915, 48.1028960819], + [11.5014771725, 48.102775402], + [11.5015308167, 48.1025929822], + [11.5015670265, 48.1025299551], + [11.5015951897, 48.1024817052], + [11.5016153062, 48.1024454898], + [11.5016448105, 48.1023891795], + [11.5016930903, 48.1023180919], + [11.5017950143, 48.1021732295], + [11.5019398535, 48.1020082718], + [11.5020377542, 48.1019090282], + [11.5021611358, 48.1018030674], + [11.5022483076, 48.1017360092], + [11.5023341383, 48.1016729811], + [11.5024521555, 48.1015965748], + [11.5025151874, 48.1015549851], + [11.5028598512, 48.1013591829], + [11.5031589175, 48.1012049698], + [11.5033252145, 48.101119103] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.502997985, 48.1255782027], + [11.5030771102, 48.1255674605], + [11.5032045151, 48.1255553754], + [11.5032876636, 48.1255460319], + [11.5034767593, 48.1255285757], + [11.5038415397, 48.1254789487] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5033453311, 48.149288931], + [11.5034593249, 48.1498723205], + [11.5036873127, 48.1504208079], + [11.5037610735, 48.1505656461], + [11.5039407815, 48.1508875321] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5042626465, 48.1211806854], + [11.503523698, 48.1213080926], + [11.5031937863, 48.1213604094], + [11.5030851568, 48.121377867], + [11.5029684807, 48.1213966115], + [11.502843758, 48.1214127262], + [11.5026560033, 48.121427498] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5062340702, 48.0989371736], + [11.5062380935, 48.098843298], + [11.5062327291, 48.0987842409], + [11.5062112714, 48.0987373309], + [11.5061670149, 48.0986890215], + [11.506116053, 48.098640768], + [11.5060932542, 48.0986179847], + [11.5060717965, 48.0985991759], + [11.506065091, 48.0985777361], + [11.5059913303, 48.0985804231], + [11.5059323217, 48.0985804231], + [11.5056211854, 48.0985790796], + [11.5040225888, 48.0985616702], + [11.5029805506, 48.0985562963] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5071272458, 48.1397308459], + [11.5067611242, 48.1397482972], + [11.5065049733, 48.1397617213], + [11.5053060259, 48.139767091], + [11.5048634614, 48.1397697758], + [11.5044718588, 48.1397711182], + [11.5043605472, 48.1397724606], + [11.5041687692, 48.1397724606], + [11.5039568747, 48.139773803], + [11.5036578084, 48.1397751454], + [11.503357401, 48.1397684334], + [11.5031978096, 48.139750982] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5086708571, 48.1060624293], + [11.5083100999, 48.1059431001], + [11.5076516176, 48.105642649], + [11.5068134273, 48.1052765418], + [11.5065049733, 48.1051357177], + [11.5063936616, 48.105082097], + [11.5061911548, 48.104985546], + [11.5059376861, 48.1048634717], + [11.5055621768, 48.104683802], + [11.5052885915, 48.1045537229], + [11.5050619448, 48.1044370209], + [11.5049291755, 48.1043713095], + [11.5048098172, 48.1043096279], + [11.5046046282, 48.104191582], + [11.5045429374, 48.1041526811], + [11.5044852699, 48.1041151795], + [11.5044262613, 48.1040695618], + [11.5043565239, 48.1040065366], + [11.5043028797, 48.1039528587], + [11.5042210723, 48.1038643657], + [11.5041231717, 48.1037610956], + [11.5040842796, 48.1037128469], + [11.5040427054, 48.1036498212], + [11.5039877201, 48.1035626151], + [11.5039112772, 48.1034258164], + [11.5038656796, 48.1033306056], + [11.5037771667, 48.1031254065], + [11.5037060882, 48.1029390139], + [11.5036792661, 48.1028424588], + [11.5036551262, 48.1027164053], + [11.5036336685, 48.1025634837], + [11.5036175753, 48.1023918103], + [11.5036068464, 48.1022201923], + [11.5036095286, 48.1020418007], + [11.5036229397, 48.10189162], + [11.5036470796, 48.1017091971], + [11.5036739017, 48.1015657324], + [11.5037007238, 48.1014597709], + [11.5037436391, 48.1013310271], + [11.5037583912, 48.1012974977], + [11.5037785078, 48.1012559078], + [11.5038388575, 48.101100351], + [11.5039206649, 48.1009434504], + [11.5040091778, 48.1007865493], + [11.5041164662, 48.1006470564], + [11.5041835214, 48.1005773098], + [11.504268011, 48.1004780634], + [11.5044664944, 48.1002782827], + [11.5048741902, 48.0999148242], + [11.5050243939, 48.0998007986], + [11.5052577461, 48.0996237981], + [11.5058062578, 48.0992214863], + [11.5059537793, 48.0991182069], + [11.5061240996, 48.0990095534], + [11.5062340702, 48.0989371736], + [11.5066967512, 48.0986970824], + [11.5069113279, 48.0986259897], + [11.5069435145, 48.0986152978], + [11.5070508028, 48.0985790796] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5086373294, 48.1531647229], + [11.508823743, 48.1533564693], + [11.5093293394, 48.1539157118] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5089028681, 48.097982288], + [11.5090342964, 48.0979541304], + [11.5092515553, 48.0979098508], + [11.509542575, 48.0978589095], + [11.5095734204, 48.0978535355] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5096485222, 48.1823538254], + [11.5093963946, 48.1824906374], + [11.5090222264, 48.1826945135], + [11.5089296902, 48.1827360934], + [11.5088344718, 48.1827789587], + [11.5086480583, 48.1828634596], + [11.5085474754, 48.1828983329], + [11.5085206534, 48.1829077219], + [11.5084589625, 48.182931865], + [11.5080941821, 48.1830659929], + [11.5079681183, 48.1831129376] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5100508536, 48.1544642678], + [11.5099905039, 48.1544508475], + [11.5098979677, 48.1544334012], + [11.5098242069, 48.1544038766], + [11.5097598339, 48.1543730659], + [11.5096726621, 48.1543180427], + [11.5095465983, 48.1542242123], + [11.5095077063, 48.1541195896], + [11.509413829, 48.1540109406], + [11.5093293394, 48.1539157118], + [11.508823743, 48.1533564693], + [11.5086373294, 48.1531647229], + [11.5085944141, 48.1531338555], + [11.5085582043, 48.1531164087], + [11.5080780889, 48.1528737187], + [11.5077629293, 48.1527623829], + [11.507489344, 48.1526752042], + [11.5068818236, 48.1524927938], + [11.5054428185, 48.1521347374], + [11.5048889423, 48.1519966141], + [11.5047776307, 48.1519483548], + [11.5046837534, 48.1519054078], + [11.504601946, 48.15185178], + [11.5045415963, 48.1518021784], + [11.504500022, 48.1517538629], + [11.504447719, 48.1517029192], + [11.5042760576, 48.1514454034], + [11.5042492355, 48.1514038541], + [11.5041473116, 48.1512294918], + [11.504076233, 48.1511168663], + [11.5040534342, 48.1510792871], + [11.5039823557, 48.1509559242], + [11.5039407815, 48.1508875321], + [11.5037610735, 48.1505656461], + [11.5036873127, 48.1504208079], + [11.5034593249, 48.1498723205], + [11.5033453311, 48.149288931] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5079681183, 48.1831129376], + [11.5080941821, 48.1830659929], + [11.5084589625, 48.182931865], + [11.5085206534, 48.1829077219], + [11.5085474754, 48.1828983329], + [11.5086480583, 48.1828634596], + [11.5088344718, 48.1827789587], + [11.5089296902, 48.1827360934], + [11.5090222264, 48.1826945135], + [11.5093963946, 48.1824906374], + [11.5096485222, 48.1823538254], + [11.5096793677, 48.1823351031], + [11.5097263063, 48.1823082772], + [11.5100320781, 48.1821365908], + [11.5100763346, 48.1821111061], + [11.5101286377, 48.1820789148], + [11.5102667714, 48.1819957539], + [11.5106744672, 48.1817503503] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 7, + "events": [ + { + "description": "Lane closed" + }, + { + "description": "Right lane closed" + }, + { + "description": "Carriageway reduced to two lanes" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.511416098, 48.1249317613], + [11.5110835041, 48.1249813889], + [11.5098537112, 48.1251530428], + [11.5094165112, 48.1252147553], + [11.5091080571, 48.1252522975], + [11.5088612939, 48.125287154], + [11.508733889, 48.1253032675], + [11.5086561049, 48.1253032675], + [11.5085702742, 48.1253166954], + [11.5084053184, 48.1253394668], + [11.5079694594, 48.1253958079], + [11.5077535416, 48.1254252933], + [11.5075604225, 48.1254508062], + [11.5065049733, 48.1255916305], + [11.5062179769, 48.1256238013], + [11.505961826, 48.1256532865], + [11.5054186786, 48.1257136556], + [11.5052711571, 48.125729713], + [11.5052483584, 48.1257323985], + [11.5049171055, 48.1257673107], + [11.5048916246, 48.1257686535], + [11.504820546, 48.1257753114], + [11.5044919754, 48.1258048525], + [11.5039917434, 48.1258410515], + [11.5033050979, 48.1258866499], + [11.5031535531, 48.1258960493], + [11.5030274893, 48.1259027631], + [11.5028786267, 48.1259054487], + [11.5026291813, 48.125909421], + [11.5024762953, 48.125909421], + [11.5019532646, 48.1259080783], + [11.5011714007, 48.1258826215], + [11.5007368828, 48.1258571648], + [11.4998128618, 48.1257726259], + [11.4996344949, 48.1257525402], + [11.4994923378, 48.1257364269], + [11.4993246997, 48.1257109701], + [11.4989156629, 48.125650601], + [11.4988338555, 48.1256372291], + [11.4985803867, 48.1255982885], + [11.4974337424, 48.1253649798], + [11.4970796908, 48.1252925252], + [11.4969254638, 48.1252576686], + [11.4957841838, 48.1249934741], + [11.494913807, 48.1247829343], + [11.4947971309, 48.1247520499], + [11.4946603383, 48.1247145073], + [11.4944806303, 48.1246662223], + [11.4943156744, 48.1246233085], + [11.493810078, 48.1245079949], + [11.4933299626, 48.1244100816], + [11.4930738116, 48.1243604535], + [11.4928900803, 48.1243242535], + [11.4924287404, 48.1242343967], + [11.4919218029, 48.1241552824], + [11.4919003452, 48.1241525968], + [11.4917018617, 48.1241231107], + [11.4914671684, 48.124090883], + [11.4914068187, 48.1240828821] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5175275112, 48.054802749], + [11.5173263456, 48.0548456651], + [11.5169387664, 48.0549033161], + [11.5164814497, 48.0549355311], + [11.5159369613, 48.054939509], + [11.5155145134, 48.0549046607], + [11.5151068176, 48.054849699], + [11.5143276359, 48.0547128828], + [11.5132413412, 48.0545761223] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + }, + { + "description": "New roadworks layout" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5175811554, 48.1118694299], + [11.5175570155, 48.111908325], + [11.5175033713, 48.1120115787], + [11.517421564, 48.1121993376], + [11.5173786486, 48.1122918456], + [11.5173330511, 48.1124139023], + [11.5172311271, 48.1127370908], + [11.5171989406, 48.112865862], + [11.5171613897, 48.1130737084], + [11.5171452964, 48.1131850184] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5178225542, 48.0945624563], + [11.5174550916, 48.0945584256], + [11.5172968413, 48.0945557384] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.512173822, 48.1246796504], + [11.5125131215, 48.1245924799], + [11.5130562688, 48.124499938], + [11.5130777265, 48.1244972524], + [11.5134881045, 48.1244302238], + [11.5136476959, 48.124407396], + [11.5141559745, 48.12430551], + [11.5144523586, 48.1242518534], + [11.514559647, 48.1242276827], + [11.5146454776, 48.1242075964], + [11.5148560311, 48.1241700534], + [11.5149351562, 48.1241539396], + [11.515022328, 48.124136483], + [11.515368333, 48.1240640826], + [11.5157867576, 48.1239916821], + [11.5163030828, 48.1238991391], + [11.5167389418, 48.1238253956], + [11.5170017983, 48.1237797954], + [11.5174322928, 48.1237033101], + [11.5180170144, 48.1236000799], + [11.5183978881, 48.1235397083], + [11.5186674501, 48.1234873937], + [11.5188163127, 48.1234511931], + [11.5189531053, 48.1233988784], + [11.5190858747, 48.1233318483], + [11.5191730465, 48.1232808763], + [11.5192065741, 48.1232513898] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5165659393, 48.0762577411], + [11.5168247725, 48.0762644615], + [11.5170125271, 48.0762658056], + [11.5171332265, 48.0762644615], + [11.5172364916, 48.0762644615], + [11.51731964, 48.0762604293], + [11.5174376572, 48.0762563971], + [11.5175677444, 48.0762510208], + [11.5176978315, 48.0762510208], + [11.5178386475, 48.0762577411], + [11.5179915334, 48.076273814], + [11.5182463432, 48.0763033275], + [11.5184220279, 48.0763234325], + [11.5185802783, 48.076332841], + [11.518718412, 48.0763341851], + [11.5188753213, 48.0763368732], + [11.518884709, 48.0763368732], + [11.519230714, 48.0763475698], + [11.5197456981, 48.0763743951], + [11.5200823153, 48.0763838036], + [11.5202982331, 48.0763878358], + [11.5204672123, 48.0763838036], + [11.5207488443, 48.0763757392] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5206911768, 48.1243068528], + [11.5209647621, 48.1244905383], + [11.5210264529, 48.1245079949] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5221905316, 48.076332841], + [11.5218472089, 48.0763422495], + [11.5208547915, 48.076373051] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5202848221, 48.0763878358], + [11.5202982331, 48.0763878358], + [11.5204672123, 48.0763838036], + [11.5207609142, 48.0763757392], + [11.5208521093, 48.076373051], + [11.5218472089, 48.0763422495], + [11.5221905316, 48.076332841] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5243523921, 48.1779751441], + [11.52274709, 48.1780998952], + [11.5213805045, 48.1781414229] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5246367062, 48.2007953996], + [11.5245803798, 48.2006317642], + [11.5245481933, 48.2005365661], + [11.5244087185, 48.199922299], + [11.524389943, 48.1998284403], + [11.5243497099, 48.1996580976], + [11.5243175234, 48.1995092638], + [11.524300089, 48.1994113818], + [11.5242960657, 48.1993899282], + [11.5242679025, 48.1992437194], + [11.5241968239, 48.198868223], + [11.5241807307, 48.1987904528], + [11.5241659785, 48.198719331], + [11.5240747834, 48.1982258333], + [11.524043938, 48.198058167], + [11.5239956583, 48.197768535], + [11.5239889527, 48.1977014344] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Slow traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5282684172, 48.1301285751], + [11.528252324, 48.1301205191], + [11.5281128491, 48.1300507566], + [11.5277427043, 48.129858979], + [11.5270855631, 48.1295036179], + [11.5262648071, 48.1290570075], + [11.5262366439, 48.1290409511], + [11.5260247494, 48.1289269342], + [11.5258638169, 48.1288330574], + [11.5255137886, 48.1286493315], + [11.5252522732, 48.128501802], + [11.5252334977, 48.1284910604], + [11.5250993873, 48.128414638], + [11.5246742572, 48.1281665163], + [11.5244167651, 48.1280002434], + [11.5242410804, 48.1278942804], + [11.523979565, 48.1277253211], + [11.5235276128, 48.1274074859], + [11.5230930949, 48.1270949637], + [11.5228409673, 48.1269085461], + [11.5225714053, 48.1267087562], + [11.5224627758, 48.1266283029], + [11.5221918727, 48.1264297988], + [11.5220577623, 48.1263318892], + [11.5220443512, 48.1263211471], + [11.5219102408, 48.1262112083] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5283274258, 48.1520234559], + [11.5279908086, 48.1519188287], + [11.5276179815, 48.151823596] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5271016563, 48.1820279452], + [11.5277963484, 48.1820413583], + [11.5286841596, 48.1820386757], + [11.5293976272, 48.1820641604], + [11.5294780935, 48.1820292865], + [11.5295411254, 48.1820212387] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5324432756, 48.2521851686], + [11.5324151124, 48.2520376594], + [11.5324043835, 48.2519893826], + [11.5323869492, 48.2519222973], + [11.5323319639, 48.251819046], + [11.5322742964, 48.2517358867], + [11.5322112645, 48.2516661778], + [11.5321334804, 48.2516205796], + [11.5319926645, 48.2515561728], + [11.5318411196, 48.2515199509], + [11.5316426362, 48.2514998586], + [11.5314682926, 48.251511914], + [11.5313730742, 48.2515307226], + [11.5312791969, 48.2515655492], + [11.5311866606, 48.251609808], + [11.5310981477, 48.2516701963], + [11.5310284103, 48.2517412446], + [11.5309653784, 48.2518217249], + [11.5309372152, 48.2519062236], + [11.5309238042, 48.2520228694], + [11.5309144164, 48.2521275156], + [11.5309197808, 48.2522146927], + [11.5309720839, 48.2525043516] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Queuing traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5276380981, 48.1890781412], + [11.5280551816, 48.1890593655], + [11.5281128491, 48.1890566833], + [11.5282201375, 48.1890499777], + [11.5284373964, 48.1890365665], + [11.528650632, 48.1890285197], + [11.5288263167, 48.1890151085], + [11.5289792026, 48.1890003562], + [11.5291454996, 48.1889735337], + [11.52929168, 48.1889413467], + [11.5294311548, 48.1888877018], + [11.5295344199, 48.1888407624], + [11.5296309794, 48.1887871173], + [11.5297074224, 48.1887334721], + [11.5297986175, 48.1886650745], + [11.5298737193, 48.1885779009], + [11.5299313868, 48.1885081619], + [11.5299729611, 48.1884317171], + [11.5300131942, 48.1883364963], + [11.5300426985, 48.1881903118], + [11.5300507451, 48.1881072167], + [11.5300520862, 48.1880884407], + [11.5300628151, 48.1879663962], + [11.5300668384, 48.1879087268], + [11.5300842727, 48.1877813173], + [11.5301245059, 48.1876700013], + [11.5302022899, 48.1875694144], + [11.5302693452, 48.1875036976], + [11.5303270127, 48.1874473687], + [11.5304141844, 48.1873937222], + [11.5304825808, 48.1873575107], + [11.5305818225, 48.1873078876], + [11.5307078863, 48.1872622879], + [11.530819198, 48.1872341234], + [11.5308808888, 48.1872247352], + [11.5309694017, 48.1872099823], + [11.5310807134, 48.1871952295], + [11.5312577392, 48.1871845001], + [11.531512549, 48.1871657237], + [11.5317499245, 48.1871549944], + [11.5320168043, 48.1871321945], + [11.5323681737, 48.1871093945], + [11.5324499811, 48.1871040299], + [11.5327289308, 48.1870852534], + [11.5329850818, 48.1870705005], + [11.5335443224, 48.1870222183] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Slow traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5350088085, 48.1450724699], + [11.5349712576, 48.144941039], + [11.53492566, 48.1447036794], + [11.5348559226, 48.1443228057], + [11.5348371471, 48.1442235879], + [11.5348291005, 48.1441779499], + [11.5347432698, 48.1435396288], + [11.5347244943, 48.1434162478], + [11.5346990133, 48.1432552816], + [11.5346856023, 48.14318151], + [11.5346735324, 48.1429924101], + [11.5346520747, 48.1429079554], + [11.5346319581, 48.1428341832], + [11.5346198882, 48.1427523569], + [11.534605136, 48.1426611901], + [11.5345984305, 48.1426236047], + [11.5345809962, 48.1425203567], + [11.5345635618, 48.1424211354], + [11.5345313753, 48.1422145823], + [11.5345260109, 48.1421770525], + [11.5345219876, 48.1421394667], + [11.5345099176, 48.1420804593], + [11.5345005299, 48.1420415871], + [11.5344924833, 48.1419892913], + [11.5344710256, 48.1418055565], + [11.5344616379, 48.1417317828], + [11.5344535912, 48.1416821714], + [11.5344227458, 48.141493066], + [11.5344066526, 48.1413938428], + [11.5344053115, 48.1413857886], + [11.5343664194, 48.1409955495], + [11.534335574, 48.1407018475], + [11.5343074108, 48.1404335934], + [11.5343007053, 48.1401117537], + [11.5343033875, 48.1400191838], + [11.5343060697, 48.1399226425], + [11.534322163, 48.1394277956], + [11.5343409384, 48.1391769864], + [11.534347644, 48.1390509101], + [11.5343664194, 48.1387585953], + [11.5344053115, 48.1382959], + [11.534412017, 48.1381953282], + [11.5344160403, 48.138112152], + [11.5344294513, 48.1379096649], + [11.5344240869, 48.1378291732], + [11.5344200636, 48.1377487374], + [11.5344146992, 48.1376092329], + [11.5343972648, 48.1374523318], + [11.5343892182, 48.1373598131], + [11.534373125, 48.137165322], + [11.5343208219, 48.1367790783], + [11.5343033875, 48.1366476821], + [11.5342644955, 48.1363915452], + [11.534220239, 48.1361689137], + [11.5341451372, 48.1358041427], + [11.534116974, 48.1356767156], + [11.5340593065, 48.1354205739], + [11.5340338255, 48.1352971734], + [11.5340070034, 48.135146978], + [11.5339721347, 48.1349927545], + [11.533937266, 48.1348345029], + [11.5339091028, 48.1346789359], + [11.5338822807, 48.1345354514], + [11.5338433887, 48.1343610878], + [11.5337977911, 48.1341773816], + [11.5337535347, 48.1340553207], + [11.533732077, 48.1339922763], + [11.5336596574, 48.1338232811], + [11.5336060132, 48.1337280708], + [11.5335832144, 48.1336851645], + [11.5335228647, 48.1335872687], + [11.5334772671, 48.1335161683], + [11.5334397162, 48.1334638638], + [11.5334021653, 48.1334102167], + [11.5333833898, 48.1333874489], + [11.5333418156, 48.1333378294], + [11.5332801248, 48.1332788119], + [11.5332103873, 48.1331943412], + [11.5330414082, 48.1330280285], + [11.5328241492, 48.1328576876], + [11.5325331296, 48.1326699483], + [11.532307824, 48.1325076617], + [11.5321683491, 48.1324205045], + [11.5321106816, 48.1323802824], + [11.5320261921, 48.1323333472], + [11.5319712068, 48.1322944676], + [11.5318370963, 48.1322126245], + [11.5316962804, 48.132128152], + [11.5316091086, 48.1320731609], + [11.5314803625, 48.1319954013], + [11.5311866606, 48.1318102881], + [11.5310042704, 48.1317003611], + [11.5308165158, 48.1315876927], + [11.5306917931, 48.1315125616], + [11.5305737759, 48.1314334585], + [11.5305281783, 48.1314053192], + [11.5304530765, 48.1313583272] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5363096799, 48.1536193437], + [11.5365135277, 48.1536743117], + [11.5365416909, 48.1536622892], + [11.5365658308, 48.1536542369], + [11.5367374922, 48.1536072652], + [11.5368783082, 48.1535643756] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5368984247, 48.199938389], + [11.5366395916, 48.2007081908], + [11.5362117792, 48.2019245758], + [11.5361500884, 48.2020935702], + [11.5361111964, 48.2022732903], + [11.5360870565, 48.202607198], + [11.5360655988, 48.2028083684], + [11.5360763277, 48.2029277519], + [11.536105832, 48.2029947897], + [11.5361567939, 48.2030725535], + [11.5362184848, 48.2031342841], + [11.5362935866, 48.2031879141], + [11.5366650726, 48.2034507565], + [11.5366932358, 48.2035137715], + [11.5367160345, 48.2035929311], + [11.5367160345, 48.2037578978] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Slow traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5370030309, 48.1534946449], + [11.5369829143, 48.153167407], + [11.5369560922, 48.1527395677], + [11.5369426812, 48.1524176933], + [11.5369198824, 48.1520958728], + [11.5369064714, 48.1518061488], + [11.5369051303, 48.1517578892], + [11.5369037892, 48.1517243927], + [11.5369037892, 48.1516854719], + [11.5369024481, 48.1516090281], + [11.5368930603, 48.1514749297], + [11.5368850137, 48.1513354625], + [11.5368528272, 48.1508929006], + [11.5367884542, 48.150061395], + [11.536785772, 48.1500252131], + [11.5367589499, 48.1496684257], + [11.5367307867, 48.1492755094], + [11.5366610492, 48.1485432432], + [11.5366409327, 48.1484104789], + [11.5366355683, 48.1483689271], + [11.5366315449, 48.1483407412], + [11.5365792419, 48.1478982094], + [11.5365510787, 48.1476983893], + [11.5365470554, 48.1476715452] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5402686204, 48.1262152366], + [11.5401197578, 48.1264861387], + [11.5400795246, 48.1265665922], + [11.540032586, 48.126649731], + [11.5399977173, 48.1267141272], + [11.5399789418, 48.12674764], + [11.5398448313, 48.1269756274], + [11.5395886804, 48.1273242923] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5444877352, 48.176448987], + [11.5444072689, 48.1764543528], + [11.5441296602, 48.1764771575], + [11.5438520516, 48.1764972233], + [11.5435570086, 48.1765173451], + [11.5428851153, 48.1765696615], + [11.5426946784, 48.1765763688], + [11.5423258747, 48.1765938076], + [11.5422105397, 48.1765978319], + [11.5420791115, 48.1765978319], + [11.5419302489, 48.1765924662], + [11.5416767801, 48.1765750273], + [11.5415359641, 48.1765629543], + [11.5413897837, 48.1765401497], + [11.5412610377, 48.1765160036], + [11.5411765481, 48.1765012477], + [11.5408305432, 48.176422158], + [11.5408090855, 48.1764154507], + [11.5407353247, 48.1763953289], + [11.5406669284, 48.1763765486], + [11.5406079198, 48.1763604512], + [11.5405502523, 48.1763295977], + [11.5404456462, 48.1762839883], + [11.5403933431, 48.1762518492], + [11.540237775, 48.1761740447], + [11.54012244, 48.1761123376], + [11.5400138105, 48.1760520278], + [11.5398756767, 48.1759608084], + [11.5397134031, 48.1758387909], + [11.5396114792, 48.1757475711], + [11.5395176018, 48.1756469608], + [11.5394089724, 48.17553165], + [11.5393150951, 48.1754029241], + [11.5392453576, 48.1752942643], + [11.539160868, 48.1751346837], + [11.539134046, 48.1750676094], + [11.5391125883, 48.1750086398], + [11.5390978361, 48.1749657122], + [11.5390683318, 48.1748557099], + [11.5390294398, 48.1747095429], + [11.5390079821, 48.1745875225], + [11.5389610435, 48.1743179363], + [11.5389409269, 48.1741556696], + [11.5389395858, 48.174146279] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Heavy traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5492714549, 48.1122288305], + [11.5491963531, 48.1122234579], + [11.5487873162, 48.1121926219], + [11.5487001444, 48.1121899356], + [11.5486196781, 48.11218322], + [11.5481838192, 48.1121456683], + [11.5476500596, 48.1121001137], + [11.5474421884, 48.1120853392], + [11.5470894779, 48.1120504737], + [11.5469178165, 48.112034356], + [11.5464336778, 48.1119740268], + [11.5463170017, 48.1119632817], + [11.5458409096, 48.1119351318], + [11.5456209685, 48.1119163838], + [11.5455726887, 48.1119123544], + [11.5455150212, 48.1119096681], + [11.5448686088, 48.1118748025], + [11.5447090174, 48.1118627142], + [11.5445252861, 48.1118453094], + [11.5443992223, 48.1118385937], + [11.5442825462, 48.1118278486], + [11.5440277363, 48.1117996986], + [11.5438802148, 48.1117728357], + [11.5436884369, 48.1117326534], + [11.5436294283, 48.1117192219], + [11.543382665, 48.1116588924], + [11.5430554355, 48.1115931342], + [11.5429132785, 48.1115569252], + [11.5426034833, 48.1114442685], + [11.5424412097, 48.1113839386], + [11.5422091986, 48.1112980887], + [11.5420415605, 48.1112391018], + [11.5419007446, 48.1111841443], + [11.5416794623, 48.1111076962], + [11.5415158476, 48.1110593984], + [11.5412623788, 48.1109789206], + [11.5410129334, 48.110917247], + [11.5407487358, 48.1108582037], + [11.5405703689, 48.1108246805], + [11.5404523517, 48.1108059321], + [11.5402713026, 48.1107750952], + [11.5399910117, 48.1107429152], + [11.5397938694, 48.1107200813], + [11.539557835, 48.1107040192], + [11.5393848325, 48.110702676], + [11.5390804018, 48.1106986465], + [11.5386794115, 48.1106838717], + [11.5386432017, 48.1106825285], + [11.5385654176, 48.1106811853], + [11.5384769047, 48.1106825285], + [11.5383280421, 48.1106811853], + [11.537235042, 48.1106745254], + [11.5371049548, 48.1106704959], + [11.5369923021, 48.1106704959], + [11.5368622149, 48.1106651232], + [11.5367173756, 48.1106610937], + [11.5363955106, 48.1106584074], + [11.5362037326, 48.110655721], + [11.5360776688, 48.1106597505], + [11.53583627, 48.1106570642], + [11.5355586613, 48.1106543779], + [11.5350892748, 48.1106409461], + [11.5348545815, 48.1106356294], + [11.5345568563, 48.1106235409], + [11.5343798305, 48.1106181682], + [11.5341116096, 48.1106074228], + [11.5339547003, 48.1105913607], + [11.5326216425, 48.1104478648] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5484600867, 48.1241499111], + [11.5486330892, 48.1242370824], + [11.5487269665, 48.1242893962], + [11.5488543714, 48.1243913382], + [11.5489039923, 48.1244315666], + [11.5489603187, 48.1244744806], + [11.5490260328, 48.1245147089], + [11.5490971113, 48.1245817374], + [11.5491735543, 48.1247038208], + [11.5493908132, 48.1248848193], + [11.5496590341, 48.1250766155] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5497757102, 48.1389651064], + [11.549708655, 48.1389851869], + [11.5496174599, 48.1389999537], + [11.5495812501, 48.1390012961], + [11.5494551862, 48.1390106931], + [11.5492379273, 48.139022775], + [11.5491118635, 48.1390254598], + [11.5490327383, 48.1390308296], + [11.5486317481, 48.1390697041], + [11.5478713418, 48.1391890682], + [11.5472946669, 48.1392815836], + [11.5471337343, 48.1393070896], + [11.5469580497, 48.1393205139], + [11.5468132104, 48.1393352246], + [11.5458516384, 48.1394036321], + [11.5455203856, 48.1394264532] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Queuing traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5456504728, 48.2513000515], + [11.5461212004, 48.2512705269], + [11.5466656889, 48.2512343048], + [11.5475280191, 48.2511820087], + [11.5478029455, 48.2511619163], + [11.5483112241, 48.2511243546], + [11.5483635272, 48.2511203361], + [11.5488865579, 48.2510841139], + [11.5501512195, 48.2510009534], + [11.5506635214, 48.2509741634], + [11.5511557068, 48.2509459781], + [11.5513796712, 48.2509299041], + [11.5517055596, 48.2509084163], + [11.5520757045, 48.2508843052] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Queuing traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5577847863, 48.1865287197], + [11.5571584905, 48.1864697074], + [11.5566166843, 48.1864267894], + [11.5564557518, 48.1864120363], + [11.556317618, 48.1863999656], + [11.5561687554, 48.1863865537], + [11.5560292805, 48.1863758241], + [11.5559126045, 48.1863650946], + [11.5557422842, 48.1863490003], + [11.5555263664, 48.1863275412], + [11.5553895737, 48.1863181529], + [11.5552594866, 48.1863033998], + [11.5549416448, 48.1862779171], + [11.5545513834, 48.1862417049], + [11.554469576, 48.1862363401], + [11.5542804803, 48.1862202457], + [11.5540068949, 48.186194763], + [11.5537480618, 48.1861733039], + [11.5536917354, 48.1861679391], + [11.5536783243, 48.1861665979], + [11.553340366, 48.1861451387], + [11.5530480052, 48.1861277032], + [11.5527382101, 48.1861116088], + [11.552660426, 48.1861075852], + [11.5522969867, 48.1861035616], + [11.5518691744, 48.1860981968], + [11.5516867841, 48.1861035616] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Queuing traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5586243178, 48.1363512702], + [11.5558468903, 48.1363781202] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Slow traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5640008057, 48.1393352246], + [11.5635367836, 48.1393392518], + [11.5631652976, 48.1393567033], + [11.5630217994, 48.139362073], + [11.5629829074, 48.1393634154], + [11.5626449491, 48.139362073], + [11.5624813343, 48.1393661003], + [11.5619314815, 48.139378182], + [11.5613212789, 48.1394049745], + [11.5611362065, 48.139413029] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Queuing traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5644514169, 48.1436830881], + [11.5638345088, 48.1438654739], + [11.563670894, 48.1439111122], + [11.5628970767, 48.1441283409], + [11.5627401675, 48.1441725808], + [11.5626650656, 48.1441967421], + [11.5625899638, 48.1442168765], + [11.5608813967, 48.1447144177], + [11.5603302027, 48.1448900884], + [11.560218891, 48.1449343276], + [11.5595604087, 48.1451167648] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Queuing traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5651246513, 48.136273517], + [11.5650911237, 48.1363083661], + [11.5650522317, 48.1363418727], + [11.5650321151, 48.1363620102], + [11.5650012697, 48.1363834902], + [11.5649610366, 48.1364102842], + [11.5649328734, 48.1364210242], + [11.564915439, 48.1364263942], + [11.5648752059, 48.1364344492], + [11.5648309494, 48.1364371342], + [11.5647652353, 48.1364357917] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5661546196, 48.1378828157], + [11.5659574772, 48.1366905859] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5710724498, 48.2720428888], + [11.5718167628, 48.2718149324] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5704032387, 48.1674608698], + [11.5705923344, 48.1674461113], + [11.5709745492, 48.1674153084], + [11.571973672, 48.1673173651], + [11.57239612, 48.1672758286] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5734690036, 48.2002388472], + [11.5735494698, 48.2004936598], + [11.5735669042, 48.2006760112], + [11.5735736097, 48.2007443928] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5737868453, 48.2712328747], + [11.5725007261, 48.2716083983] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5736902858, 48.1355948779], + [11.5738109852, 48.1355198087], + [11.5739853288, 48.1354473684], + [11.5741315092, 48.1354017785] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5737962331, 48.1341116523], + [11.5739397312, 48.1342001491], + [11.5741945411, 48.1343624303], + [11.5742723252, 48.1344160764], + [11.5743192638, 48.1344455566], + [11.5743782724, 48.1344885181], + [11.5745217706, 48.1345823846], + [11.5745646859, 48.1346158923], + [11.5746008958, 48.1346427432], + [11.5746987964, 48.1347339242], + [11.574744394, 48.1347821998], + [11.5748127903, 48.1348559276], + [11.5748758222, 48.1349511918], + [11.5749187375, 48.1350115499], + [11.5749589707, 48.1350812498], + [11.5749898161, 48.1351483205], + [11.5750126149, 48.1352046508], + [11.5750421192, 48.1352944883], + [11.5749160553, 48.1352985159] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5750206615, 48.1343731707], + [11.5752781535, 48.1341988066], + [11.5754806603, 48.1340714314], + [11.5759715046, 48.1337280708], + [11.5761002506, 48.133648971], + [11.5761351193, 48.1336328602], + [11.5762021745, 48.1336154068], + [11.5762906874, 48.1336033796] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5804266537, 48.2705851443], + [11.5794597174, 48.2706172799] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Slow traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5802603568, 48.1323038099], + [11.5810194219, 48.1330146027], + [11.5812165643, 48.1331970263], + [11.5813345815, 48.1332841822], + [11.5814230944, 48.1333512552], + [11.581507584, 48.1334035598], + [11.5816671754, 48.133485345], + [11.5817503239, 48.1335309366], + [11.5819045509, 48.1336033796], + [11.581931373, 48.1336167494], + [11.5820695068, 48.1336744239], + [11.58253487, 48.133811254], + [11.5827641989, 48.1338742427] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5835044886, 48.1265330792], + [11.5836372579, 48.1266108471], + [11.5841468777, 48.1271539884] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5837820972, 48.1688234457], + [11.5846497918, 48.1686718949] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5851111318, 48.1325371989], + [11.5849287416, 48.1323775972], + [11.5848429109, 48.1322796989], + [11.5846538152, 48.1321160685] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5846538152, 48.1321160685], + [11.5848429109, 48.1322796989], + [11.5849287416, 48.1323775972], + [11.5851111318, 48.1325371989] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5851687993, 48.1426397128], + [11.5851352717, 48.1425780212], + [11.5850910152, 48.1424855118], + [11.5847919489, 48.1416794867], + [11.5847825612, 48.1416231634] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5903065707, 48.1387223495], + [11.5901255215, 48.1388175506], + [11.5899592246, 48.138902068], + [11.5891384686, 48.1393151442] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5907665695, 48.1393070896], + [11.5906633045, 48.1391233452], + [11.5905922259, 48.1390294871], + [11.5905278529, 48.1389516821], + [11.5904044713, 48.1388282901], + [11.5903065707, 48.1387223495], + [11.590246221, 48.1386633381], + [11.5899659301, 48.1383897595], + [11.5899082626, 48.1383334327] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + }, + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5918166543, 48.1417277557], + [11.5917402114, 48.141592345], + [11.5913217868, 48.1408962694], + [11.5912654604, 48.1407863059], + [11.5912399794, 48.1406991627], + [11.5911219622, 48.1402807282], + [11.5910777058, 48.1401211505], + [11.5910455192, 48.1400071581], + [11.590990534, 48.1398019377], + [11.5909301843, 48.1396289344], + [11.5907665695, 48.1393070896], + [11.5906633045, 48.1391233452], + [11.5905922259, 48.1390294871], + [11.5905278529, 48.1389516821], + [11.5904044713, 48.1388282901], + [11.5903065707, 48.1387223495], + [11.590246221, 48.1386633381], + [11.5899659301, 48.1383897595], + [11.5899082626, 48.1383334327], + [11.5897419657, 48.138171164], + [11.5895220245, 48.1379633073], + [11.5894241239, 48.1378707336], + [11.5893637742, 48.1377983525], + [11.5893396343, 48.1377500798], + [11.589296719, 48.1376548208] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5946490671, 48.1306945042], + [11.5953571702, 48.1303552048] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Slow traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.5507788564, 48.1761109962], + [11.5510135497, 48.1761083133], + [11.5514078344, 48.1761056303], + [11.5523694063, 48.176101606], + [11.5536179746, 48.1760922157], + [11.5539022888, 48.1760895328], + [11.5541772152, 48.1760895328], + [11.5552299823, 48.176081484], + [11.5553587283, 48.1760828255], + [11.5555303897, 48.1760828255], + [11.5558401848, 48.1760975816], + [11.5560708548, 48.1760975816], + [11.5568084623, 48.1760922157], + [11.5570525433, 48.1760895328], + [11.5571960415, 48.1760881914], + [11.557690909, 48.176084167], + [11.5579296256, 48.1760801426], + [11.5580583717, 48.1760761182], + [11.5581750478, 48.1760747767], + [11.5583346392, 48.1760761182], + [11.5585518981, 48.1760761182], + [11.5588616933, 48.1760640451], + [11.5590065326, 48.1760600766], + [11.5597159768, 48.1760493449], + [11.560039183, 48.1760412961], + [11.5605729426, 48.1760332473], + [11.5609672273, 48.1760225156], + [11.5611469353, 48.1760184913], + [11.5612233783, 48.1760171498], + [11.561399063, 48.1760131254], + [11.5615693833, 48.1760131254], + [11.561809441, 48.1760050766], + [11.5621715392, 48.1759956864], + [11.562272122, 48.1759943449], + [11.5629735197, 48.1759876376], + [11.5632296706, 48.1759809303], + [11.5634858216, 48.1759782474], + [11.5638103689, 48.1759701986], + [11.5638868119, 48.1759688571], + [11.5639806892, 48.1759621498], + [11.5640490855, 48.1759608084], + [11.5644929911, 48.175956784], + [11.564632466, 48.1759634913], + [11.5647853519, 48.1759661742], + [11.564966401, 48.1759755645], + [11.565081736, 48.1759849547], + [11.5650978292, 48.1759862962], + [11.5652212108, 48.1759983693], + [11.5652533973, 48.1760010523], + [11.5653486158, 48.176011784], + [11.5655122305, 48.1760372717], + [11.5656517054, 48.1760627036], + [11.5658542122, 48.1761069718], + [11.5659507717, 48.1761311181], + [11.5662069227, 48.1761968495], + [11.5664027239, 48.1762478249], + [11.5664791669, 48.1762679467], + [11.5666414405, 48.1763108174], + [11.5669257547, 48.1763953289], + [11.567148378, 48.1764583772], + [11.5675171818, 48.1765508813], + [11.567584237, 48.176571003], + [11.5676727499, 48.1765964905], + [11.5677558984, 48.1766246609], + [11.5686463918, 48.1769089908], + [11.5690809096, 48.1770457615], + [11.5698533858, 48.1772697248], + [11.5708377565, 48.1774842971], + [11.5712253357, 48.1775916109], + [11.5715539063, 48.1776706988], + [11.571690699, 48.1777042343], + [11.5718543137, 48.177741794], + [11.5719844009, 48.1777713051], + [11.5721466745, 48.1777994749], + [11.5723102893, 48.1778249618], + [11.5725490059, 48.1778571557], + [11.572704574, 48.1778745382], + [11.5728547777, 48.177893318], + [11.572935244, 48.177900025], + [11.5730452145, 48.1779053907], + [11.5732812489, 48.1779147806], + [11.5735548343, 48.1779295361], + [11.5741020049, 48.1779416088], + [11.5747403706, 48.1779349018], + [11.5750166382, 48.1779322189], + [11.5751534308, 48.1779268533], + [11.5752553548, 48.1779228291], + [11.5753653253, 48.1779201462], + [11.5757435168, 48.177900025], + [11.5761485304, 48.1778745382], + [11.5771731342, 48.1777887435], + [11.5775701011, 48.1777511839], + [11.5781521405, 48.1776961858], + [11.579005083, 48.1776331391], + [11.5791163946, 48.1776250906], + [11.5792920793, 48.1776144151], + [11.5799975003, 48.177547344], + [11.5806009973, 48.1775057599], + [11.5814029778, 48.1774735658], + [11.5816256012, 48.1774682001], + [11.5817677583, 48.1774668586], + [11.5820681657, 48.1774695415], + [11.5833314861, 48.1774722243], + [11.5839269365, 48.1774896628], + [11.5841468777, 48.17749637], + [11.584305128, 48.1774990528], + [11.5845210458, 48.1775044185], + [11.5848590041, 48.177512467], + [11.5850588287, 48.177512467], + [11.5855201687, 48.1775231984], + [11.5857950951, 48.1775258813], + [11.5860606338, 48.1775299055], + [11.5862752105, 48.1775285641], + [11.5864549185, 48.1775231984], + [11.5869913603, 48.1774789314], + [11.5874339248, 48.177423933], + [11.5878255273, 48.1773622833], + [11.5882224943, 48.1772764319], + [11.5884799863, 48.1772147262], + [11.5885980035, 48.1771838732], + [11.5888273324, 48.1771074675], + [11.5891465153, 48.1769988112], + [11.5893852319, 48.176915698], + [11.5895971264, 48.1768365531], + [11.5897795166, 48.1767654566], + [11.5899042393, 48.1767198476], + [11.5902408565, 48.1766031977], + [11.5903454627, 48.1765602714], + [11.5913472678, 48.1761606302], + [11.5915001537, 48.1760922157], + [11.5916007365, 48.1760493449], + [11.5917013193, 48.1760064181], + [11.5917281414, 48.1759956864], + [11.5918515231, 48.1759433693], + [11.5922350789, 48.1757811078], + [11.592363825, 48.1757247661], + [11.5925234164, 48.175659034], + [11.5926172937, 48.1756201873], + [11.5927929784, 48.1755477477], + [11.5929391588, 48.1754820154], + [11.5931309368, 48.1754002412], + [11.5931805576, 48.175380119], + [11.5936271454, 48.1751816356], + [11.5940911676, 48.174984493], + [11.5941837038, 48.1749442483], + [11.5943714584, 48.1748597344], + [11.5945913996, 48.1747564952], + [11.5947885419, 48.1746652735], + [11.5949333812, 48.1745928885], + [11.5950889493, 48.1745150814], + [11.5953880156, 48.1743635475], + [11.5960920955, 48.174002793], + [11.5966647471, 48.1737104537], + [11.5968726183, 48.1736044734], + [11.596919557, 48.1735776428], + [11.5971153582, 48.173469035], + [11.5972494687, 48.1734046416], + [11.597343346, 48.1733564024], + [11.5974063779, 48.1733268887], + [11.5977201964, 48.1731673019], + [11.5978167559, 48.1731190066], + [11.5980930234, 48.1729956409], + [11.5982780959, 48.1728963667], + [11.5984779204, 48.1727917821], + [11.5986576284, 48.1727018984], + [11.5988279487, 48.1726174366], + [11.5989821757, 48.1725396266], + [11.599101534, 48.1724766295], + [11.5992047991, 48.1724229673], + [11.5993120874, 48.1723599141], + [11.5993885304, 48.1723103323], + [11.5994515623, 48.1722674024], + [11.5995521451, 48.1721949581], + [11.5996567513, 48.1721064708], + [11.5997452642, 48.1720126171], + [11.5998418237, 48.1718757771], + [11.5998820568, 48.1718087544], + [11.5999316777, 48.1717041676], + [11.5999692286, 48.1716022078], + [11.599986663, 48.1715137195], + [11.5999933685, 48.171464081], + [11.5999947096, 48.1714426157], + [11.5999987329, 48.1713635182], + [11.5999973918, 48.1712857063], + [11.5999826397, 48.1711999006], + [11.5999678875, 48.1711314796], + [11.5999491121, 48.1710711639], + [11.5999088789, 48.1709705444], + [11.5998297538, 48.1708270495], + [11.5997895206, 48.1707640503], + [11.5996554102, 48.1705655491], + [11.5996031071, 48.1704890775], + [11.5995038654, 48.1703428981], + [11.5994368101, 48.1702436747], + [11.5993563439, 48.1701256685], + [11.5992731954, 48.1700103453], + [11.5991846825, 48.1698762391], + [11.5990854408, 48.1697340828], + [11.5990532543, 48.1696844426], + [11.5990130211, 48.1696173611], + [11.5988722051, 48.1694242779], + [11.5987139548, 48.1691895472], + [11.5986294652, 48.1690608054], + [11.5985382701, 48.1689307217], + [11.5985329057, 48.1689226718], + [11.5983022357, 48.1685874265], + [11.598292848, 48.1685740099], + [11.5981815363, 48.1684036751], + [11.5980836357, 48.1682655397], + [11.5980259682, 48.1681810706], + [11.59789454, 48.1679839011], + [11.5977738406, 48.1678095952], + [11.5976678933, 48.1676607248], + [11.5974627043, 48.1673629826], + [11.5970509852, 48.1667648655], + [11.5969316269, 48.1665945247], + [11.5968994404, 48.1665449373], + [11.5968645717, 48.1664993192], + [11.5968243386, 48.1664429673], + [11.5968028809, 48.1664094804], + [11.5967559422, 48.1663397112], + [11.5966862048, 48.1662431635], + [11.596560141, 48.1660741627], + [11.5964099373, 48.1658582568], + [11.5962959434, 48.1656906523], + [11.5962355937, 48.1655953892], + [11.5961511041, 48.1654398596], + [11.59607332, 48.165286957], + [11.5960250403, 48.1651823569], + [11.5959861482, 48.1650764148], + [11.5959526206, 48.1649812064], + [11.5959325041, 48.1649060683], + [11.5959123875, 48.164814885], + [11.5959016587, 48.1647143091], + [11.5958962942, 48.1646083661], + [11.5958976354, 48.1645051063], + [11.5959137286, 48.1643079226], + [11.5959365274, 48.1641859334], + [11.5959713961, 48.1640638879], + [11.5960022415, 48.1639405004], + [11.5960263814, 48.163864019], + [11.5960679556, 48.1637500234], + [11.5961457397, 48.1635757031], + [11.5962060894, 48.1634684159], + [11.5962718035, 48.1633651539], + [11.5963361765, 48.1632699424], + [11.5963992084, 48.1631948577], + [11.5964622403, 48.1631170334], + [11.5965145434, 48.1630661009], + [11.5965520944, 48.1630285304], + [11.5965829398, 48.1629923017], + [11.5966446306, 48.1629360019], + [11.5967559422, 48.1628340806], + [11.5968095864, 48.1627898009], + [11.5969007815, 48.1627147155], + [11.5969678367, 48.1626677521], + [11.5970255042, 48.1626262119], + [11.5971220638, 48.162560463], + [11.5972950662, 48.1624518878], + [11.5973513926, 48.1624170005], + [11.5974707509, 48.1623445982], + [11.597574016, 48.1622882418], + [11.5975914503, 48.162278849], + [11.5977698172, 48.1621822937], + [11.5978583301, 48.1621353857], + [11.5980071927, 48.1620521925], + [11.5981694664, 48.1619623459], + [11.5983156468, 48.1618805501], + [11.5984229351, 48.1618215654], + [11.5989513303, 48.1615318403], + [11.5991806592, 48.1614071608], + [11.5992343034, 48.1613776402], + [11.5993040408, 48.1613400685], + [11.5993295218, 48.16132665], + [11.5995199586, 48.1612167303], + [11.5996299292, 48.1611523215], + [11.5997734274, 48.1610664989], + [11.5998927857, 48.1609940947], + [11.600012144, 48.1609190066], + [11.6001221146, 48.1608438626], + [11.6002240385, 48.1607768255], + [11.6002602483, 48.160752672], + [11.6003635134, 48.1606842929], + [11.6004305686, 48.1606413533], + [11.6007524337, 48.1603825405] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Queuing traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6008771564, 48.1079185447], + [11.6006464864, 48.1078608412], + [11.6005150582, 48.1078246295], + [11.6002964581, 48.1077696684], + [11.6000148262, 48.1076985882], + [11.5995923783, 48.1076020421], + [11.5994448568, 48.1075738898], + [11.5992946531, 48.1075456815], + [11.5990344788, 48.1075323049], + [11.5982646848, 48.1073726814], + [11.598087659, 48.1073351262], + [11.5979414786, 48.1073016007], + [11.5978677179, 48.1072841943], + [11.5977014209, 48.1072452957], + [11.5974855031, 48.1072010241], + [11.5973661448, 48.1071742148], + [11.5972829963, 48.1071580956], + [11.5971555914, 48.1071353161], + [11.597112676, 48.1071232268], + [11.5969812478, 48.1070870706], + [11.5969007815, 48.1070548322], + [11.5968189741, 48.1070199633], + [11.5967478956, 48.1069850943], + [11.5967036392, 48.1069623147], + [11.5965494121, 48.1068804872], + [11.5964153017, 48.1068120924] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6004989649, 48.206367686], + [11.6005579735, 48.2063944994], + [11.6005995478, 48.2064454447], + [11.6006438042, 48.2065540944], + [11.6006759907, 48.2067177109], + [11.6007376815, 48.2071066121], + [11.6007966901, 48.2074606538], + [11.6008691098, 48.2078187708], + [11.6009415294, 48.2081754889] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6076430286, 48.0711038698], + [11.6071696187, 48.0711105908], + [11.60713475, 48.0711065582], + [11.606955042, 48.0710797301], + [11.606826296, 48.071046181] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.606826296, 48.071046181], + [11.606955042, 48.0710797301], + [11.60713475, 48.0711065582], + [11.6071696187, 48.0711105908], + [11.6076430286, 48.0711038698] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6125823165, 48.1473376151], + [11.6125581767, 48.1472544538], + [11.6125192846, 48.1471283973], + [11.612472346, 48.1470157627], + [11.6124052907, 48.1468601767], + [11.6123771275, 48.1467917791] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Heavy traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6162703539, 48.1503779156], + [11.6162421907, 48.150471753], + [11.6162059809, 48.1505723567], + [11.6161536778, 48.1507024311], + [11.6161201502, 48.1507694814], + [11.6160893048, 48.1508311631], + [11.6160611416, 48.1508875321], + [11.6160370017, 48.1509344503], + [11.6160115208, 48.1509773981], + [11.6159672643, 48.1510564711], + [11.6158908214, 48.151183916], + [11.6158519293, 48.1512429129], + [11.6157942618, 48.1513233836], + [11.6157151367, 48.1514373508], + [11.615642717, 48.1515258737], + [11.6155515219, 48.1516412385], + [11.615437528, 48.1517713102], + [11.6153584029, 48.1518544642], + [11.6152618433, 48.151951039], + [11.6151813771, 48.152024798], + [11.6150298323, 48.1521454741], + [11.6149225439, 48.1522272854], + [11.6148326899, 48.1522929916], + [11.6147401537, 48.1523694343], + [11.6146637107, 48.1524391666], + [11.6145242359, 48.1525303719], + [11.6144410874, 48.1525853411], + [11.6142426039, 48.1527154663], + [11.6141111757, 48.152801247], + [11.6140172984, 48.1528616401], + [11.6139837707, 48.1528843993], + [11.6138550247, 48.1529715777], + [11.6134379412, 48.1532384802], + [11.6132354344, 48.1533631796], + [11.6129658724, 48.153522772], + [11.6127352024, 48.153658263], + [11.6124656404, 48.1537990659], + [11.6122939791, 48.1538849007], + [11.6121048833, 48.1539801296], + [11.6118031348, 48.1541424042], + [11.6114611532, 48.1542979681], + [11.6113592292, 48.1543475673], + [11.6112304832, 48.1544146128], + [11.6110762562, 48.1544870263], + [11.6107892598, 48.1546184887], + [11.6105706598, 48.1547110322], + [11.6103547419, 48.1547968096], + [11.6102568413, 48.154834386], + [11.6098250057, 48.1550154461], + [11.6096466388, 48.1550892007], + [11.6093127037, 48.1552286577], + [11.60917457, 48.1552836799], + [11.6088969613, 48.1553962964], + [11.6087829675, 48.1554432664], + [11.6085938717, 48.1555210464], + [11.608135214, 48.1557047881], + [11.6080614532, 48.155734256], + [11.6075679268, 48.1559367847], + [11.6072152163, 48.1560802653], + [11.6070770825, 48.1561365727], + [11.6063528861, 48.1564316401], + [11.6062335278, 48.1564798953], + [11.6061235572, 48.1565282063], + [11.6057949866, 48.1566596076], + [11.6054395939, 48.1567937483], + [11.6051297988, 48.1569238069], + [11.6050573791, 48.156954672], + [11.6050158049, 48.1569721175], + [11.6049514319, 48.1570029267], + [11.6048320736, 48.1570472113], + [11.6047529484, 48.1570807603], + [11.6046456601, 48.157122305], + [11.6045946981, 48.1571397505], + [11.6042849029, 48.1572698082], + [11.6039456035, 48.1574240766], + [11.6037256624, 48.1575313765], + [11.6035808231, 48.1576131792], + [11.6035392488, 48.1576386202], + [11.6033273543, 48.1577714164], + [11.6032710279, 48.1578102768], + [11.6032133604, 48.1578532188], + [11.6031503285, 48.1578987887], + [11.6030242647, 48.1579993779], + [11.6028365101, 48.1581482764], + [11.602823099, 48.1581616957], + [11.6026380266, 48.1583360344], + [11.6025749947, 48.1584030746], + [11.6025374438, 48.1584459603], + [11.6022933627, 48.1587356468], + [11.6020921971, 48.1589944679], + [11.6018226351, 48.1593592977], + [11.6013787295, 48.1599332913], + [11.6013438608, 48.1599640987], + [11.6013022865, 48.1600070389], + [11.6012486423, 48.1600579744], + [11.6009321417, 48.1603530194], + [11.6008476521, 48.1604294501], + [11.600512376, 48.1606910022], + [11.6003179158, 48.1608277603], + [11.6002468373, 48.1608774091], + [11.6001864876, 48.1609163229], + [11.5999450888, 48.1610705245], + [11.599640658, 48.1612475369], + [11.5994877721, 48.1613373848], + [11.5992799009, 48.1614513857], + [11.5991431083, 48.1615278148], + [11.5990559365, 48.1615761211], + [11.5988802518, 48.1616726775], + [11.5987743045, 48.1617289788], + [11.5985449756, 48.1618550553], + [11.5982941891, 48.1619972334], + [11.5981453265, 48.1620830545], + [11.5980836357, 48.1621166002], + [11.5978489424, 48.1622479871], + [11.5976652111, 48.1623499096], + [11.5976155902, 48.162376746], + [11.5974264945, 48.1624840355], + [11.5972561742, 48.1625913247], + [11.5970952417, 48.1626999556], + [11.5970509852, 48.1627321591], + [11.5970120932, 48.1627630207], + [11.5969262625, 48.162831397], + [11.5968471373, 48.1628984314], + [11.5967224146, 48.163017796], + [11.596663406, 48.1630781771], + [11.596649995, 48.1630902533], + [11.5965923275, 48.1631559455], + [11.59653466, 48.1632243213], + [11.596458217, 48.1633208747], + [11.5963978673, 48.1634054077], + [11.5963495876, 48.1634818338], + [11.5963026489, 48.1635663106], + [11.596239617, 48.1636950662], + [11.5961980428, 48.1637795426], + [11.5961671974, 48.1638546824], + [11.5961162354, 48.1639847231], + [11.5960813667, 48.1641242118], + [11.5960558857, 48.1642596748], + [11.5960411335, 48.1643629351], + [11.5960317458, 48.1644621699], + [11.5960277225, 48.1645734803], + [11.5960357691, 48.1647183344], + [11.5960572268, 48.1648497706], + [11.5960840489, 48.1649530297], + [11.5961376931, 48.1651005662], + [11.5961926783, 48.1652252927], + [11.5962516869, 48.1653606969], + [11.59631606, 48.165484081], + [11.5963844563, 48.1656020979], + [11.5966419484, 48.1660031073], + [11.5967318024, 48.166130515], + [11.5968565251, 48.1663115352], + [11.5969021226, 48.1663692289], + [11.5969477202, 48.1664295502], + [11.5969919766, 48.1664845604], + [11.597034892, 48.1665476208], + [11.5973567571, 48.1670196769], + [11.5977617706, 48.1675990074], + [11.5980246271, 48.1679771927], + [11.5982941891, 48.1683687919], + [11.5984832848, 48.1686450618], + [11.5986200775, 48.1688449121], + [11.5987313892, 48.1690098788], + [11.598986199, 48.1693706125], + [11.5991109218, 48.1695476522], + [11.5991927291, 48.1696616349], + [11.5992503966, 48.1697501264], + [11.5993429328, 48.1698829472], + [11.5994689967, 48.170067979] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6143619622, 48.0622593062], + [11.6148152555, 48.0622324735], + [11.6154938544, 48.0621855302], + [11.6163454558, 48.0621291758] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6166485454, 48.145795334], + [11.6166901196, 48.1460595334], + [11.6166874374, 48.1460836938], + [11.6166793908, 48.1460917473], + [11.6166632975, 48.1460998007], + [11.6166364755, 48.1461051138], + [11.6166016067, 48.1461024293], + [11.6165721024, 48.146101143], + [11.6165479626, 48.146095774], + [11.6165157761, 48.1460742981], + [11.616437992, 48.1457121702], + [11.6164031233, 48.145566032] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Slow traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6172118093, 48.0721579957], + [11.6171528007, 48.0719326774], + [11.6171286608, 48.071856227], + [11.6171045209, 48.0718213342], + [11.6170052792, 48.0718146692], + [11.6168577577, 48.0718160134], + [11.6167558338, 48.0718320876], + [11.6167156006, 48.0718683246], + [11.6167102362, 48.0719085382], + [11.6167451049, 48.0720654154], + [11.616758516, 48.0722035857] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6237765159, 48.3002543717], + [11.6241050865, 48.3000451647], + [11.6243290509, 48.2998976264], + [11.6245194878, 48.2997742314], + [11.6245369221, 48.2997635256], + [11.6245852019, 48.2997313525], + [11.62474077, 48.2996334392], + [11.6250183786, 48.2994497117], + [11.6251162793, 48.2993907181], + [11.6253174449, 48.2992686601], + [11.6253523137, 48.2992458544], + [11.6256191935, 48.2990742254], + [11.6257747616, 48.2989776491], + [11.6258659567, 48.2989159784], + [11.6260724868, 48.2988127105], + [11.6261422242, 48.2987308544], + [11.6262441482, 48.2986665069], + [11.6263272966, 48.2986182183], + [11.6264627482, 48.2985404324] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6430924441, 48.1949937612], + [11.6428953017, 48.1948824609], + [11.6428282465, 48.194836868], + [11.642205974, 48.1943634476], + [11.6420383359, 48.1942159394], + [11.6419122721, 48.1940938536] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6602532174, 48.0765889974], + [11.6638232376, 48.0758540705] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6701586153, 48.238210877], + [11.6703503932, 48.2381934033], + [11.6705529, 48.2381759854], + [11.6706293429, 48.2381692863], + [11.6708170976, 48.2381532082], + [11.6708694006, 48.2381491887], + [11.6709833945, 48.2381410939], + [11.6710222866, 48.2381384142], + [11.6710799541, 48.2381330549], + [11.6711148228, 48.2381303752], + [11.671695521, 48.238099559], + [11.671759894, 48.2380955394], + [11.6720053162, 48.2380727064], + [11.6721045579, 48.2380753861], + [11.6723459567, 48.2380633275], + [11.6726289298, 48.238027096], + [11.6729481126, 48.2380069985], + [11.6732954587, 48.2379815415], + [11.6734429802, 48.2379694829], + [11.6743562724, 48.2378970199], + [11.6745869423, 48.2378742425], + [11.6752253081, 48.2378138937], + [11.6755042578, 48.2377911164], + [11.6758542861, 48.2377629238], + [11.6762995328, 48.2377266921], + [11.6765087451, 48.2377092741], + [11.676726004, 48.2376905162], + [11.6774206962, 48.237640886], + [11.6779128815, 48.2375925956], + [11.6781287993, 48.2375698181], + [11.6786773111, 48.2375108088] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.6850341465, 48.0710167205], + [11.6852433588, 48.0710676323], + [11.6853077318, 48.0710864512], + [11.6855008508, 48.0711481165], + [11.6855920459, 48.0711789772], + [11.6857020165, 48.0712138145], + [11.6859380509, 48.0712715031], + [11.6864342596, 48.0714270941] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7069638874, 48.1224654854], + [11.7071047033, 48.1224507139], + [11.7072133328, 48.1224158554], + [11.7073407377, 48.122359567], + [11.7074399795, 48.1223032225] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Stationary traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7318681981, 48.1658341057], + [11.7319419588, 48.1656906523], + [11.7320519294, 48.1655229914], + [11.7320787515, 48.1654746889], + [11.732110938, 48.1653848482], + [11.7321028914, 48.1653660639], + [11.7320680227, 48.1653593552], + [11.7319982852, 48.1653526465], + [11.7318936791, 48.165349963], + [11.7318105306, 48.1653687474], + [11.7316254582, 48.1654813975], + [11.7316549625, 48.1655980727], + [11.7316710557, 48.165722798] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 6, + "events": [ + { + "description": "Queuing traffic" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7324851062, 48.1093065996], + [11.7320023085, 48.1082806033], + [11.7319473232, 48.1081505334], + [11.7315476741, 48.1073512453], + [11.7314739134, 48.1072023673], + [11.7314189281, 48.1071098501] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7467222716, 48.3200075239], + [11.7470883931, 48.3205305582] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7474853601, 48.3210978415], + [11.7470883931, 48.3205305582], + [11.7467222716, 48.3200075239], + [11.746688744, 48.3199591998] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7550223674, 48.1679208984], + [11.7550116386, 48.167971826], + [11.7549955453, 48.1680483013], + [11.7549794521, 48.1681274039], + [11.7548413183, 48.1684988771], + [11.7547031845, 48.1688086875], + [11.7546656336, 48.1688905281], + [11.7546468581, 48.1689240134], + [11.7544966544, 48.1691775283], + [11.7542458679, 48.1695503355], + [11.7541493084, 48.1697903751] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 8, + "events": [ + { + "description": "Closed" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7541493084, 48.1697903751], + [11.7542458679, 48.1695503355], + [11.7544966544, 48.1691775283], + [11.7546468581, 48.1689240134], + [11.7546656336, 48.1688905281], + [11.7547031845, 48.1688086875], + [11.7548413183, 48.1684988771], + [11.7549794521, 48.1681274039], + [11.7549955453, 48.1680483013], + [11.7550116386, 48.167971826], + [11.7550223674, 48.1679208984] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7553026582, 48.1086132204], + [11.7554595675, 48.1090544679], + [11.7556097712, 48.1095037148], + [11.7558095958, 48.1100777064], + [11.7558779921, 48.1102681587], + [11.7560429479, 48.110733513], + [11.7561059798, 48.1109346522], + [11.7561488952, 48.1110647711], + [11.7562038805, 48.1112243271], + [11.756223997, 48.1112887426], + [11.7563326265, 48.111618654], + [11.7564358916, 48.1119579092], + [11.756556591, 48.1123468579], + [11.7567604388, 48.1129999494], + [11.7569321002, 48.1135967904], + [11.7570568229, 48.1140232212], + [11.7571681346, 48.1144228989], + [11.7572325076, 48.1146562572], + [11.7573719825, 48.1151658367], + [11.7575570549, 48.1158954453], + [11.7576616611, 48.1163232559], + [11.7578051593, 48.1169200025], + [11.7579084243, 48.1173786935], + [11.7579701151, 48.1176643591], + [11.7580693568, 48.1181310453], + [11.7581699397, 48.1186084711] + ] + } + }, + { + "type": "Feature", + "properties": { + "iconCategory": 9, + "events": [ + { + "description": "Roadworks" + } + ] + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [11.7590255644, 48.1313315305], + [11.7590255644, 48.1307159865], + [11.7590228822, 48.1301473164], + [11.7590175177, 48.1296511445], + [11.75900813, 48.1292340185], + [11.7589987423, 48.1288411136], + [11.7589772846, 48.1282550235], + [11.7589705791, 48.1280833799], + [11.758957168, 48.1277910027], + [11.7589330282, 48.1272907798] + ] + } + } +] +} \ No newline at end of file diff --git a/common/data/src/main/res/values-de/strings.xml b/common/data/src/main/res/values-de/strings.xml index d6b2ee6..2ec7b3a 100644 --- a/common/data/src/main/res/values-de/strings.xml +++ b/common/data/src/main/res/values-de/strings.xml @@ -48,5 +48,6 @@ Ladestation Speed camera Auto GPS verwenden + TomTom\t diff --git a/common/data/src/main/res/values/strings.xml b/common/data/src/main/res/values/strings.xml index e5b0030..91e4c8f 100644 --- a/common/data/src/main/res/values/strings.xml +++ b/common/data/src/main/res/values/strings.xml @@ -34,4 +34,5 @@ Osrm Routing engine Use car location + TomTom\t \ No newline at end of file