diff --git a/README.md b/README.md index e20a5f2..9926b22 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Coming soon: - [TripInfo Request](https://opentransportdata.swiss/en/cookbook/ojptripinforequest/) ## Requirements -Compatible with Android 6+ +Compatible with Android 7+ ## Integration To integrate the SDK you have to add following dependency: diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 019aed2..17bc907 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,7 +13,7 @@ android { defaultConfig { applicationId = "ch.opentransportdata" - minSdk = 23 + minSdk = 25 targetSdk = 35 versionCode = 1 versionName = "1.0" @@ -77,4 +77,6 @@ dependencies { testImplementation(libs.junit) debugImplementation(libs.ui.tooling) + //for displaying the map we use Ramani-Maps without modifying the SKD (Source: https://github.com/ramani-maps/ramani-maps) + implementation("org.ramani-maps:ramani-maplibre:0.9.2") } \ No newline at end of file diff --git a/app/src/main/java/ch/opentransportdata/domain/MapLibreData.kt b/app/src/main/java/ch/opentransportdata/domain/MapLibreData.kt new file mode 100644 index 0000000..254d9fa --- /dev/null +++ b/app/src/main/java/ch/opentransportdata/domain/MapLibreData.kt @@ -0,0 +1,12 @@ +package ch.opentransportdata.domain + +import ch.opentransportdata.ojp.data.dto.response.GeoPositionDto + +/** + * Created by Nico Brandenberger on 05.11.2025 + */ + +data class MapLibreData( + val id: String, + val positions: List, +) \ No newline at end of file diff --git a/app/src/main/java/ch/opentransportdata/presentation/MainActivity.kt b/app/src/main/java/ch/opentransportdata/presentation/MainActivity.kt index 45893ef..225251a 100644 --- a/app/src/main/java/ch/opentransportdata/presentation/MainActivity.kt +++ b/app/src/main/java/ch/opentransportdata/presentation/MainActivity.kt @@ -23,15 +23,19 @@ import androidx.navigation.compose.rememberNavController import androidx.navigation.toRoute import ch.opentransportdata.ojp.BuildConfig import ch.opentransportdata.ojp.OjpSdk +import ch.opentransportdata.ojp.data.dto.response.GeoPositionDto import ch.opentransportdata.ojp.data.dto.response.PlaceResultDto import ch.opentransportdata.presentation.lir.LirScreenComposable import ch.opentransportdata.presentation.navigation.BottomNavItem import ch.opentransportdata.presentation.navigation.LocationSearchMask +import ch.opentransportdata.presentation.navigation.TripMap import ch.opentransportdata.presentation.navigation.TripResults import ch.opentransportdata.presentation.navigation.TripSearchMask import ch.opentransportdata.presentation.navigation.navtypes.PlaceResultType +import ch.opentransportdata.presentation.navigation.navtypes.jsonNavType import ch.opentransportdata.presentation.theme.OJPAndroidSDKTheme import ch.opentransportdata.presentation.tir.TirScreenComposable +import ch.opentransportdata.presentation.tir.map.MapScreen import ch.opentransportdata.presentation.tir.result.TripResultScreen import kotlin.reflect.typeOf @@ -48,8 +52,6 @@ class MainActivity : ComponentActivity() { val bottomNavigationItems = listOf(BottomNavItem.Lir, BottomNavItem.Tir) OJPAndroidSDKTheme { val navController = rememberNavController() -// val navBackStackEntry by navController.currentBackStackEntryAsState() -// val currentDestination = navBackStackEntry?.destination var selectedBottomNavItem by remember { mutableIntStateOf(0) } Scaffold( @@ -111,12 +113,19 @@ class MainActivity : ComponentActivity() { typeOf() to PlaceResultType, ) ) { navBackstackEntry -> - val parameters = navBackstackEntry.toRoute() TripResultScreen( navHostController = navController, -// originName = parameters.origin.place.placeType?.name() ?: "-", -// viaName = parameters.via?.place?.placeType?.name(), -// destinationName = parameters.destination.place.placeType?.name() ?: "-" + ) + } + composable( + typeMap = mapOf( + typeOf>() to jsonNavType>() + ) + ) { navBackstackEntry -> + val parameters = navBackstackEntry.toRoute() + MapScreen( + coordinates = parameters.coordinates.toList(), + zoom = parameters.zoom ) } } diff --git a/app/src/main/java/ch/opentransportdata/presentation/navigation/TirNavigation.kt b/app/src/main/java/ch/opentransportdata/presentation/navigation/TirNavigation.kt index 5549d0e..ef87fd2 100644 --- a/app/src/main/java/ch/opentransportdata/presentation/navigation/TirNavigation.kt +++ b/app/src/main/java/ch/opentransportdata/presentation/navigation/TirNavigation.kt @@ -1,5 +1,6 @@ package ch.opentransportdata.presentation.navigation +import ch.opentransportdata.ojp.data.dto.response.GeoPositionDto import ch.opentransportdata.ojp.data.dto.response.PlaceResultDto import kotlinx.serialization.Serializable @@ -15,3 +16,9 @@ data class TripResults( val via: PlaceResultDto? = null, val destination: PlaceResultDto ) + +@Serializable +data class TripMap( + val coordinates: List, + val zoom: Double, +) diff --git a/app/src/main/java/ch/opentransportdata/presentation/navigation/navtypes/jsonNavType.kt b/app/src/main/java/ch/opentransportdata/presentation/navigation/navtypes/jsonNavType.kt new file mode 100644 index 0000000..5f7a315 --- /dev/null +++ b/app/src/main/java/ch/opentransportdata/presentation/navigation/navtypes/jsonNavType.kt @@ -0,0 +1,23 @@ +package ch.opentransportdata.presentation.navigation.navtypes + +import android.net.Uri +import android.os.Bundle +import androidx.navigation.NavType +import kotlinx.serialization.json.Json + +inline fun jsonNavType( + isNullableAllowed: Boolean = false, + json: Json = Json +) = object : NavType(isNullableAllowed) { + override fun get(bundle: Bundle, key: String): T? = + bundle.getString(key)?.let { json.decodeFromString(it) } + + override fun parseValue(value: String): T = + json.decodeFromString(Uri.decode(value)) + + override fun serializeAsValue(value: T): String = + Uri.encode(json.encodeToString(value)) + + override fun put(bundle: Bundle, key: String, value: T) = + bundle.putString(key, json.encodeToString(value)) +} \ No newline at end of file diff --git a/app/src/main/java/ch/opentransportdata/presentation/tir/PreviewData.kt b/app/src/main/java/ch/opentransportdata/presentation/tir/PreviewData.kt index 76d9fbb..7c9975a 100644 --- a/app/src/main/java/ch/opentransportdata/presentation/tir/PreviewData.kt +++ b/app/src/main/java/ch/opentransportdata/presentation/tir/PreviewData.kt @@ -119,7 +119,8 @@ object PreviewData { name = NameDto(text = "Olten"), geoPosition = null ), - duration = Duration.parse("PT5M") + duration = Duration.parse("PT5M"), + pathGuidance = null ) ) diff --git a/app/src/main/java/ch/opentransportdata/presentation/tir/detail/TripDetailScreen.kt b/app/src/main/java/ch/opentransportdata/presentation/tir/detail/TripDetailScreen.kt index a68efab..b919896 100644 --- a/app/src/main/java/ch/opentransportdata/presentation/tir/detail/TripDetailScreen.kt +++ b/app/src/main/java/ch/opentransportdata/presentation/tir/detail/TripDetailScreen.kt @@ -1,16 +1,41 @@ package ch.opentransportdata.presentation.tir.detail import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.DirectionsWalk -import androidx.compose.material.icons.outlined.* +import androidx.compose.material.icons.outlined.Cancel +import androidx.compose.material.icons.outlined.ChevronRight +import androidx.compose.material.icons.outlined.FlashOn +import androidx.compose.material.icons.outlined.HideSource +import androidx.compose.material.icons.outlined.Info +import androidx.compose.material.icons.outlined.Shuffle +import androidx.compose.material.icons.outlined.WarningAmber import androidx.compose.material.icons.rounded.WarningAmber -import androidx.compose.material3.* +import androidx.compose.material3.Button +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -19,7 +44,12 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.PreviewFontScale import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp -import ch.opentransportdata.ojp.data.dto.response.tir.leg.* +import ch.opentransportdata.ojp.data.dto.response.tir.leg.AttributeDto +import ch.opentransportdata.ojp.data.dto.response.tir.leg.ContinuousLegDto +import ch.opentransportdata.ojp.data.dto.response.tir.leg.LegAlightDto +import ch.opentransportdata.ojp.data.dto.response.tir.leg.LegBoardDto +import ch.opentransportdata.ojp.data.dto.response.tir.leg.TimedLegDto +import ch.opentransportdata.ojp.data.dto.response.tir.leg.TransferLegDto import ch.opentransportdata.ojp.data.dto.response.tir.situations.PtSituationDto import ch.opentransportdata.ojp.data.dto.response.tir.situations.PublishingActionDto import ch.opentransportdata.ojp.data.dto.response.tir.trips.TripDto @@ -44,6 +74,8 @@ fun TripDetailScreen( showSituation: (PublishingActionDto) -> Unit, requestTripUpdate: (TripDto) -> Unit, refineTrip: (String) -> Unit, + showMapText: String, + showMap: (String, Boolean) -> Unit ) { val scrollState = rememberScrollState() val timedLegs = trip.legs.mapNotNull { it.legType as? TimedLegDto } @@ -56,10 +88,10 @@ fun TripDetailScreen( ) { val consideredSituations = situations?.let { trip.getPtSituationsForTrip(it) } ?: emptyList() Row { - Button(onClick = {requestTripUpdate(trip)}) { + Button(onClick = { requestTripUpdate(trip) }) { Text("Update Trip") } - Button(onClick = {refineTrip(trip.id)}) { + Button(onClick = { refineTrip(trip.id) }) { Text("Refine Trip") } } @@ -109,21 +141,41 @@ fun TripDetailScreen( HorizontalDivider(modifier = Modifier.padding(bottom = 8.dp)) } trip.legs.forEach { leg -> - when (val legType = leg.legType) { - is TransferLegDto -> TransferLeg(modifier = Modifier.padding(all = 16.dp), leg = legType) - is ContinuousLegDto -> ContinuousLeg( - modifier = Modifier.padding(all = 16.dp), - leg = legType, - isStartLeg = leg == trip.legs.first(), - isLastLeg = leg == trip.legs.last(), - ) + var isZoomed = false + Column ( + modifier = Modifier.fillMaxWidth(), + ) { + when (val legType = leg.legType) { + is TransferLegDto -> { + isZoomed = true + TransferLeg(modifier = Modifier.padding(all = 16.dp), leg = legType) + } + is ContinuousLegDto -> { + isZoomed = true + ContinuousLeg( + modifier = Modifier.padding(all = 16.dp), + leg = legType, + isStartLeg = leg == trip.legs.first(), + isLastLeg = leg == trip.legs.last(), + ) + } - is TimedLegDto -> TimedLeg( - leg = legType, - duration = leg.duration, - situations = legType.getPtSituationsForLeg(consideredSituations), - showSituation = showSituation - ) + is TimedLegDto -> { + isZoomed = false + TimedLeg( + leg = legType, + duration = leg.duration, + situations = legType.getPtSituationsForLeg(consideredSituations), + showSituation = showSituation, + ) + } + } + Button( + modifier = Modifier.padding(vertical = 4.dp).align(alignment = Alignment.CenterHorizontally), + enabled = showMapText == "Show way on map", + onClick = { showMap(leg.id, isZoomed) }) { + Text(text = showMapText) + } } } @@ -513,7 +565,9 @@ private fun TripDetailScreenPreview() { situations = emptyList(), showSituation = {}, requestTripUpdate = {}, - refineTrip = {} + refineTrip = {}, + showMapText = "Show way on map", + showMap = {_ , _ ->} ) } } \ No newline at end of file diff --git a/app/src/main/java/ch/opentransportdata/presentation/tir/map/MapScreen.kt b/app/src/main/java/ch/opentransportdata/presentation/tir/map/MapScreen.kt new file mode 100644 index 0000000..40c39a0 --- /dev/null +++ b/app/src/main/java/ch/opentransportdata/presentation/tir/map/MapScreen.kt @@ -0,0 +1,48 @@ +package ch.opentransportdata.presentation.tir.map + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import ch.opentransportdata.ojp.data.dto.response.GeoPositionDto +import org.maplibre.android.geometry.LatLng +import org.maplibre.android.maps.Style +import org.ramani.compose.CameraPosition +import org.ramani.compose.MapLibre +import org.ramani.compose.Polyline + +/** + * Created by Nico Brandenberger on 04.11.2025 + */ + +@Composable +fun MapScreen( + coordinates: List, + zoom: Double = 7.5 +) { + val styleUrl = "https://vectortiles.geo.admin.ch/styles/ch.swisstopo.basemap.vt/style.json" + val mapLibrePoints = coordinates.map { LatLng(it.latitude, it.longitude) } + val cameraPosition = rememberSaveable { + mutableStateOf( + CameraPosition( + target = mapLibrePoints.first() , + zoom = zoom, + ) + ) + } + Surface( + modifier = Modifier.fillMaxSize(), + color = Color.Red + ) { + MapLibre( + modifier = Modifier.fillMaxSize(), + styleBuilder = Style.Builder().fromUri(styleUrl), + cameraPosition = cameraPosition.value + ) { + Polyline(points = mapLibrePoints, color = "Red", lineWidth = 1.0F) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ch/opentransportdata/presentation/tir/result/TripResultScreen.kt b/app/src/main/java/ch/opentransportdata/presentation/tir/result/TripResultScreen.kt index 89af082..d107b7d 100644 --- a/app/src/main/java/ch/opentransportdata/presentation/tir/result/TripResultScreen.kt +++ b/app/src/main/java/ch/opentransportdata/presentation/tir/result/TripResultScreen.kt @@ -25,6 +25,7 @@ import ch.opentransportdata.ojp.data.dto.response.tir.situations.PublishingActio import ch.opentransportdata.ojp.data.dto.response.tir.trips.TripDto import ch.opentransportdata.presentation.components.TripResultHeader import ch.opentransportdata.presentation.lir.name +import ch.opentransportdata.presentation.navigation.TripMap import ch.opentransportdata.presentation.tir.detail.TripDetailScreen import ch.opentransportdata.presentation.utils.FileReader import kotlinx.coroutines.delay @@ -49,12 +50,14 @@ fun TripResultScreen( val detailBottomSheet = rememberModalBottomSheetState(skipPartiallyExpanded = true) var selectedTrip by remember { mutableStateOf(null) } var selectedAction by remember { mutableStateOf(null) } + val showMapText = if (viewModel.state.collectAsState().value.mapData.isEmpty()) "Refine Trip first" else "Show way on map" if (selectedTrip != null) { ModalBottomSheet( onDismissRequest = { coroutineScope.launch { selectedTrip = null + viewModel.resetMapData() } }, sheetState = detailBottomSheet, @@ -65,7 +68,19 @@ fun TripResultScreen( situations = state.value.tripDelivery?.responseContext?.situation?.ptSituation?.filter { it.publishingActions != null }, showSituation = { selectedAction = it }, requestTripUpdate = { viewModel.requestTripUpdate(it) }, - refineTrip = { id -> viewModel.refineTrip(id) } + refineTrip = { id -> viewModel.refineTrip(id) }, + showMapText = showMapText, + showMap = { id, isZoomed -> + val coordinates = viewModel.state.value.mapData.find { it.id == id } + if (coordinates != null) { + navHostController.navigate( + TripMap( + coordinates = coordinates.positions, + zoom = if (isZoomed) 17.0 else 7.5 + ) + ) + } + } ) } } diff --git a/app/src/main/java/ch/opentransportdata/presentation/tir/result/TripResultViewModel.kt b/app/src/main/java/ch/opentransportdata/presentation/tir/result/TripResultViewModel.kt index 2345e89..de235e8 100644 --- a/app/src/main/java/ch/opentransportdata/presentation/tir/result/TripResultViewModel.kt +++ b/app/src/main/java/ch/opentransportdata/presentation/tir/result/TripResultViewModel.kt @@ -9,8 +9,12 @@ import ch.opentransportdata.ojp.data.dto.request.tir.PlaceReferenceDto import ch.opentransportdata.ojp.data.dto.response.PlaceResultDto import ch.opentransportdata.ojp.data.dto.response.delivery.TripDeliveryDto import ch.opentransportdata.ojp.data.dto.response.place.StopPlaceDto +import ch.opentransportdata.ojp.data.dto.response.tir.leg.ContinuousLegDto +import ch.opentransportdata.ojp.data.dto.response.tir.leg.TimedLegDto +import ch.opentransportdata.ojp.data.dto.response.tir.leg.TransferLegDto import ch.opentransportdata.ojp.data.dto.response.tir.trips.TripDto import ch.opentransportdata.ojp.domain.model.LanguageCode +import ch.opentransportdata.domain.MapLibreData import ch.opentransportdata.ojp.domain.model.ModeAndModeOfOperationFilter import ch.opentransportdata.ojp.domain.model.PtMode import ch.opentransportdata.ojp.domain.model.RealtimeData @@ -277,6 +281,41 @@ class TripResultViewModel( when (response) { is Result.Success -> { Log.d("TripResultViewModel", "Refinement was successful ${response.data}") + val mapData = mutableListOf() + response.data.tripResults?.forEach { result -> + result.trip?.legs?.forEach { leg -> + when(leg.legType) { + is ContinuousLegDto -> { + val positions = leg.continuousLeg?.legTrack?.trackSection?.first()?.linkProjection?.positions + if (!positions.isNullOrEmpty()) { + mapData.add(MapLibreData( + id = leg.id, + positions = positions + )) + } + } + is TransferLegDto -> { + val positions = leg.transferLeg?.pathGuidance?.pathGuidanceSection?.first()?.trackSection?.first()?.linkProjection?.positions + if (!positions.isNullOrEmpty()) { + mapData.add(MapLibreData( + id = leg.id, + positions = positions + )) + } + } + is TimedLegDto -> { + val positions = leg.timedLeg?.legTrack?.trackSection?.first()?.linkProjection?.positions + if (!positions.isNullOrEmpty()) { + mapData.add(MapLibreData( + id = leg.id, + positions = positions + )) + } + } + } + } + state.update { it.copy(mapData = mapData) } + } postEvent(Event.ScrollToFirstTripItem(0)) } @@ -290,6 +329,10 @@ class TripResultViewModel( } } + fun resetMapData() { + state.update { it.copy(mapData = emptyList()) } + } + sealed class Event(val id: Long = UUID.randomUUID().mostSignificantBits) { data class ShowSnackBar(val message: String) : Event() data class ScrollToFirstTripItem(val offset: Int) : Event() @@ -301,6 +344,7 @@ class TripResultViewModel( val events: List = emptyList(), val isLoadingPrevious: Boolean = false, val isLoading: Boolean = false, - val isLoadingNext: Boolean = false + val isLoadingNext: Boolean = false, + val mapData: List = emptyList() ) } \ No newline at end of file diff --git a/sdk/build.gradle.kts b/sdk/build.gradle.kts index fec1f2c..caa8247 100644 --- a/sdk/build.gradle.kts +++ b/sdk/build.gradle.kts @@ -20,7 +20,7 @@ android { compileSdk = 35 defaultConfig { - minSdk = 23 + minSdk = 25 lint.targetSdk = 35 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/ContinuousLegDto.kt b/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/ContinuousLegDto.kt index 9f24c86..eee5e30 100644 --- a/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/ContinuousLegDto.kt +++ b/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/ContinuousLegDto.kt @@ -32,7 +32,11 @@ data class ContinuousLegDto( @XmlElement(true) @XmlSerialName("Duration", OJP_NAME_SPACE, "") @Serializable(with = DurationSerializer::class) - val duration: Duration + val duration: Duration, + + @XmlElement(true) + @XmlSerialName("LegTrack", OJP_NAME_SPACE, "") + val legTrack: LegTrackDto? = null ) : AbstractLegType(), Parcelable fun ContinuousLegDto.minimalCopy(): ContinuousLegDto { diff --git a/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/PathGuidanceDto.kt b/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/PathGuidanceDto.kt new file mode 100644 index 0000000..7244190 --- /dev/null +++ b/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/PathGuidanceDto.kt @@ -0,0 +1,20 @@ +package ch.opentransportdata.ojp.data.dto.response.tir.leg + +import android.os.Parcelable +import ch.opentransportdata.ojp.data.dto.OJP_NAME_SPACE +import kotlinx.parcelize.Parcelize +import kotlinx.serialization.Serializable +import nl.adaptivity.xmlutil.serialization.XmlElement +import nl.adaptivity.xmlutil.serialization.XmlSerialName + +/** + * Created by Nico Brandenberger on 04.11.2025 + */ + +@Parcelize +@Serializable +data class PathGuidanceDto( + @XmlElement(true) + @XmlSerialName("PathGuidanceSection", OJP_NAME_SPACE, "") + val pathGuidanceSection: List +) : Parcelable \ No newline at end of file diff --git a/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/PathGuidanceSectionDto.kt b/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/PathGuidanceSectionDto.kt new file mode 100644 index 0000000..4cef150 --- /dev/null +++ b/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/PathGuidanceSectionDto.kt @@ -0,0 +1,20 @@ +package ch.opentransportdata.ojp.data.dto.response.tir.leg + +import android.os.Parcelable +import ch.opentransportdata.ojp.data.dto.OJP_NAME_SPACE +import kotlinx.parcelize.Parcelize +import kotlinx.serialization.Serializable +import nl.adaptivity.xmlutil.serialization.XmlElement +import nl.adaptivity.xmlutil.serialization.XmlSerialName + +/** + * Created by Nico Brandenberger on 04.11.2025 + */ + +@Parcelize +@Serializable +data class PathGuidanceSectionDto( + @XmlElement(true) + @XmlSerialName("TrackSection", OJP_NAME_SPACE, "") + val trackSection: List +) : Parcelable \ No newline at end of file diff --git a/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/TransferLegDto.kt b/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/TransferLegDto.kt index f1d3f17..a6a5b1a 100644 --- a/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/TransferLegDto.kt +++ b/sdk/src/main/java/ch/opentransportdata/ojp/data/dto/response/tir/leg/TransferLegDto.kt @@ -32,5 +32,9 @@ data class TransferLegDto( @XmlElement(true) @XmlSerialName("Duration", OJP_NAME_SPACE, "") @Serializable(with = DurationSerializer::class) - val duration: Duration + val duration: Duration, + + @XmlElement(true) + @XmlSerialName("PathGuidance", OJP_NAME_SPACE, "") + val pathGuidance: PathGuidanceDto? ) : AbstractLegType(), Parcelable \ No newline at end of file