refactor: optimisation around stoptimes

- moved stoptime related functionality into new core:data:stoptime module
  - will feature all the different realtime stoptime sources to be
      integrated later
- create proper database schema for future migrations
- deduplicate trips into stoppingpatterns, since many trips share the
  exact same stopping pattern
  - stoptimes are now linked to stoppingpatterns instead
  - stoppingpattern ids are generated from a hash composed of all stoptimes
- stoptimes now use deltas for arrival time to save space
This commit is contained in:
Cilly Leang 2026-05-05 03:23:11 +10:00
parent f1770744db
commit 102c028407
Signed by: cilly
GPG key ID: 6500251E087653C9
39 changed files with 396 additions and 223 deletions

View file

@ -231,30 +231,36 @@ class MapScreenViewModel(
)
}
val departures = stopTimeRepository.getForStop(id)
.filter { !it.headsign.isNullOrBlank() }
.groupBy { it.headsign!! }
.map { (headsign, stopTimes) ->
val now = Clock.System.now()
val times = stopTimes
.map { it.arrivalTime.toInstant(TimeZone.currentSystemDefault()) }
.filter { it >= (now - 1.minutes) }
.joinToString(" | ") {
val diff = (it - now).inWholeMinutes.coerceAtLeast(0)
if (diff >= 65) {
"${((diff + 30.0) / 60.0).toInt()}hr"
} else {
"${diff}mn"
}
stopTimeRepository.getForStop(id)
.onEach { stoptimes ->
val departures = stoptimes
// .filter { !it.headsign.isNullOrBlank() }
// .groupBy { it.headsign!! }
.groupBy { it.stopId } // TODO: Placeholder
.map { (headsign, stopTimes) ->
val now = Clock.System.now()
val times = stopTimes
.map { it.time.arrival.toInstant(TimeZone.currentSystemDefault()) }
.filter { it >= (now - 1.minutes) }
.joinToString(" | ") {
val diff = (it - now).inWholeMinutes.coerceAtLeast(0)
if (diff >= 65) {
"${((diff + 30.0) / 60.0).toInt()}hr"
} else {
"${diff}mn"
}
}
StopInfoPanelState.Departure(headsign, times)
}
StopInfoPanelState.Departure(headsign, times)
iInfoState.update {
if (it !is StopInfoPanelState)
it
else
it.copy(departures = departures)
}
}
iInfoState.update {
if (it !is StopInfoPanelState)
it
else
it.copy(departures = departures)
}
.launchIn(viewModelScope)
}
/*private suspend fun buildPolylines(route: PtvRoute) {