ref: c10e9e44bcd05997920b2b8bc94f7817535773da
app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
package ml.adamsprogs.bimba.models import ml.adamsprogs.bimba.models.gtfs.AgencyAndId import ml.adamsprogs.bimba.safeSplit import ml.adamsprogs.bimba.secondsAfterMidnight import java.io.Serializable import java.util.* import kotlin.collections.ArrayList import kotlin.collections.HashMap data class Departure(val line: AgencyAndId, val mode: List<Int>, val time: Int, val lowFloor: Boolean, //time in seconds since midnight val modification: List<String>, val headsign: String, val vm: Boolean = false, var tomorrow: Boolean = false, val onStop: Boolean = false) { val isModified: Boolean get() { return modification.isNotEmpty() } override fun toString(): String { return "$line|${mode.joinToString(";")}|$time|$lowFloor|${modification.joinToString(";")}|$headsign|$vm|$tomorrow|$onStop" } fun copy(): Departure { return Departure.fromString(this.toString()) } companion object { private fun filterDepartures(departures: List<Departure>, relativeTo: Int = Calendar.getInstance().secondsAfterMidnight()): Array<Serializable> { val filtered = ArrayList<Departure>() val lines = HashMap<AgencyAndId, Int>() val sortedDepartures = departures.sortedBy { it.timeTill(relativeTo) } for (departure in sortedDepartures) { val timeTill = departure.timeTill(relativeTo) var lineExistedTimes = lines[departure.line] if (timeTill >= 0 && lineExistedTimes ?: 0 < 3) { lineExistedTimes = (lineExistedTimes ?: 0) + 1 lines[departure.line] = lineExistedTimes filtered.add(departure) } } return arrayOf(filtered, lines.all { it.value >= 3 }) } fun createDepartures(stopId: AgencyAndId): Map<AgencyAndId, List<Departure>> { val timetable = Timetable.getTimetable() val departures = timetable.getStopDepartures(stopId) return rollDepartures(departures) } fun rollDepartures(departures: Map<AgencyAndId, List<Departure>>): Map<AgencyAndId, List<Departure>> { //todo<p:2> it'd be nice to roll from tomorrow's real mode (Fri->Sat, Sat->Sun, Sun->Mon) val rolledDepartures = HashMap<AgencyAndId, List<Departure>>() departures.keys.forEach { val (filtered, isFull) = filterDepartures(departures[it]!!) if (isFull as Boolean) { @Suppress("UNCHECKED_CAST") rolledDepartures[it] = filtered as List<Departure> } else { val (filteredTomorrow, _) = filterDepartures(departures[it]!!, 0) val departuresTomorrow = ArrayList<Departure>() @Suppress("UNCHECKED_CAST") (filteredTomorrow as List<Departure>).forEach { val departure = it.copy() departure.tomorrow = true departuresTomorrow.add(departure) } val (result, _) = @Suppress("UNCHECKED_CAST") filterDepartures((filtered as List<Departure>) + departuresTomorrow) val now = Calendar.getInstance().secondsAfterMidnight() @Suppress("UNCHECKED_CAST") rolledDepartures[it] = (result as List<Departure>).sortedBy { it.timeTill(now) } } } return rolledDepartures } fun fromString(string: String): Departure { val array = string.split("|") if (array.size != 9) throw IllegalArgumentException() val modification = array[4].safeSplit(";") return Departure(AgencyAndId.convertFromString(array[0]), array[1].safeSplit(";").map { Integer.parseInt(it) }, Integer.parseInt(array[2]), array[3] == "true", modification, array[5], array[6] == "true", array[7] == "true", array[8] == "true") } } fun timeTill(relativeTo: Int): Int { var time = this.time if (this.tomorrow) time += 24 * 60 * 60 return (time - relativeTo) / 60 } val lineText: String = line.id } |