Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions detekt-baseline.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/main/java/org/mtransit/commons/CloseableUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ object CloseableUtils {
fun closeQuietly(closeable: Closeable?) {
try {
closeable?.close()
} catch (ioe: IOException) {
} catch (_: IOException) {
// ignore
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ data class GCalendarDate(
val startDateToCheck = max(startDate, gCalendar.startDate)
val endDateToCheck = min(endDate, gCalendar.endDate)
val gCalendarDateServiceId = gCalendarDates?.filter { it.isServiceIdInt(gCalendar.serviceIdInt) } ?: return false // NOT entirely removed
(startDateToCheck..endDateToCheck).forEach { date ->
for (date in startDateToCheck..endDateToCheck) {
if (gCalendarDateServiceId.none { it.isDate(date) && it.exceptionType == GCalendarDatesExceptionType.SERVICE_REMOVED }) {
return false // NOT entirely removed
}
Expand Down
20 changes: 8 additions & 12 deletions src/main/java/org/mtransit/parser/gtfs/data/GFrequency.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import java.util.concurrent.TimeUnit
// https://gtfs.org/reference/static/#frequenciestxt
data class GFrequency(
val tripIdInt: Int,
private val _startTime: Int,
private val _endTime: Int,
val startTime: Int,
val endTime: Int,
val headwaySecs: Int,
val exactTimes: Int?,
) {
Expand All @@ -38,23 +38,19 @@ data class GFrequency(
private val _tripId: String
get() = GIDs.getString(tripIdInt)

val startTime: Int = _startTime

@Suppress("unused")
val startTimeDate: Date
get() = GTime.toDate(_startTime)
get() = GTime.toDate(startTime)

val startTimeMs: Long
get() = GTime.toMs(_startTime)

val endTime: Int = _endTime
get() = GTime.toMs(startTime)

@Suppress("unused")
val endTimeDate: Date
get() = GTime.toDate(_endTime)
get() = GTime.toDate(endTime)

val endTimeMs: Long
get() = GTime.toMs(_endTime)
get() = GTime.toMs(endTime)

val headwayMs: Long
get() = TimeUnit.SECONDS.toMillis(headwaySecs.toLong())
Expand All @@ -67,8 +63,8 @@ data class GFrequency(

fun to() = Frequency(
tripId = _tripId,
startTime = GTime.toString(_startTime),
endTime = GTime.toString(_endTime),
startTime = GTime.toString(startTime),
endTime = GTime.toString(endTime),
headwaySecs = headwaySecs,
exactTimes = exactTimes
)
Expand Down
36 changes: 31 additions & 5 deletions src/main/java/org/mtransit/parser/gtfs/data/GLocationType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,37 @@ package org.mtransit.parser.gtfs.data
// https://gtfs.org/schedule/reference/#stopstxt
enum class GLocationType(val id: Int) {

STOP_PLATFORM(0), // Stop (or Platform). A location where passengers board or disembark from a transit vehicle. Is called a platform when defined within a parent_station.
STATION(1), // Station. A physical structure or area that contains one or more platform.
ENTRANCE_EXIT(2), // Entrance/Exit. A location where passengers can enter or exit a station from the street. If an entrance/exit belongs to multiple stations, it may be linked by pathways to both, but the data provider must pick one of them as parent.
GENERIC_NODE(3), // Generic Node. A location within a station, not matching any other location_type, that may be used to link together pathways define in pathways.txt.
BOARDING_AREA(4) // Boarding Area. A specific location on a platform, where passengers can board and/or alight vehicles.
/**
* Stop (or Platform).
* A location where passengers board or disembark from a transit vehicle.
* Is called a platform when defined within a parent_station.
*/
STOP_PLATFORM(0),

/**
* Station.
* A physical structure or area that contains one or more platforms.
*/
STATION(1),

/**
* Entrance/Exit.
* A location where passengers can enter or exit a station from the street.
* If an entrance/exit belongs to multiple stations, it may be linked by pathways to both, but the data provider must pick one of them as parent.
*/
ENTRANCE_EXIT(2),

/**
* Generic Node.
* A location within a station, not matching any other location_type, that may be used to link together pathways define in pathways.txt.
*/
GENERIC_NODE(3),

/**
* Boarding Area.
* A specific location on a platform, where passengers can board and/or alight vehicles.
*/
BOARDING_AREA(4)
;

companion object {
Expand Down
44 changes: 20 additions & 24 deletions src/main/java/org/mtransit/parser/gtfs/data/GStopTime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import java.util.Date
// https://gtfs.org/schedule/reference/#stop_timestxt
data class GStopTime(
val tripIdInt: Int,
private val _arrivalTime: Int, // HHmmss
private val _departureTime: Int, // HHmmss
val arrivalTime: Int, // HHmmss
val departureTime: Int, // HHmmss
val stopIdInt: Int,
val stopSequence: Int,
val stopHeadsign: String?,
Expand All @@ -33,8 +33,8 @@ data class GStopTime(
timePointInt: Int,
) : this(
tripIdInt = tripIdInt,
_arrivalTime = arrivalTime,
_departureTime = departureTime,
arrivalTime = arrivalTime,
departureTime = departureTime,
stopIdInt = stopIdInt,
stopSequence = stopSequence,
stopHeadsign = stopHeadsign,
Expand All @@ -55,8 +55,8 @@ data class GStopTime(
timePoint: GTimePoint,
) : this(
tripIdInt = GIDs.getInt(tripId),
_arrivalTime = arrivalTime,
_departureTime = departureTime,
arrivalTime = arrivalTime,
departureTime = departureTime,
stopIdInt = stopIdInt,
stopSequence = stopSequence,
stopHeadsign = stopHeadsign,
Expand All @@ -77,8 +77,8 @@ data class GStopTime(
timePoint: GTimePoint,
) : this(
tripIdInt = GIDs.getInt(tripId),
_arrivalTime = GTime.fromString(arrivalTime),
_departureTime = GTime.fromString(departureTime),
arrivalTime = GTime.fromString(arrivalTime),
departureTime = GTime.fromString(departureTime),
stopIdInt = GIDs.getInt(stopId),
stopSequence = stopSequence,
stopHeadsign = stopHeadsign,
Expand All @@ -101,28 +101,24 @@ data class GStopTime(
private val _stopId: String
get() = GIDs.getString(stopIdInt)

val arrivalTime: Int = _arrivalTime

fun hasArrivalTime() = _arrivalTime >= 0
fun hasArrivalTime() = arrivalTime >= 0

@Suppress("unused")
val arrivalTimeMs: Long
get() = GTime.toMs(_arrivalTime)
get() = GTime.toMs(arrivalTime)

@Suppress("unused")
val arrivalTimeDate: Date
get() = GTime.toDate(_arrivalTime)

val departureTime: Int = _departureTime
get() = GTime.toDate(arrivalTime)

fun hasDepartureTime() = _departureTime >= 0
fun hasDepartureTime() = departureTime >= 0

val departureTimeMs: Long
get() = GTime.toMs(_departureTime)
get() = GTime.toMs(departureTime)

@Suppress("unused")
val departureTimeDate: Date
get() = GTime.toDate(_departureTime)
get() = GTime.toDate(departureTime)

val uID by lazy { getNewUID(tripIdInt, stopIdInt, stopSequence) }

Expand All @@ -149,8 +145,8 @@ data class GStopTime(
if (this.stopSequence != other.stopSequence) {
return this.stopSequence.compareTo(other.stopSequence)
}
if (this._departureTime != other._departureTime) {
return this._departureTime.compareTo(other._departureTime)
if (this.departureTime != other.departureTime) {
return this.departureTime.compareTo(other.departureTime)
}
throw MTLog.Fatal("Unexpected stop times to compare: '$this' & '$other'!")
}
Expand All @@ -167,9 +163,9 @@ data class GStopTime(
add("s:$_stopId")
add("#:$stopSequence")
if (hasDepartureTime()) {
add("d:${GTime.toString(_departureTime)}")
add("d:${GTime.toString(departureTime)}")
} else if (hasArrivalTime()) {
add("a:${GTime.toString(_arrivalTime)}")
add("a:${GTime.toString(arrivalTime)}")
}
if (pickupType != GPickupType.REGULAR) {
add("$pickupType")
Expand All @@ -184,8 +180,8 @@ data class GStopTime(
tripId = _tripId,
stopId = _stopId,
stopSequence = stopSequence,
arrivalTime = GTime.toString(_arrivalTime),
departureTime = GTime.toString(_departureTime),
arrivalTime = GTime.toString(arrivalTime),
departureTime = GTime.toString(departureTime),
stopHeadsign = stopHeadsign,
pickupType = pickupType.id,
dropOffType = dropOffType.id,
Expand Down
19 changes: 15 additions & 4 deletions src/main/java/org/mtransit/parser/mt/MDataChangedManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ object MDataChangedManager {
if (gCalendarDateToAdd.date in lastStartDate..lastEndDate) {
return false // same date range
}
val diffInMs = DefaultAgencyTools.diffInMs(GFieldTypes.makeDateFormat(), Calendar.getInstance(), p.todayStringInt, gCalendarDateToAdd.date).absoluteValue
val diffInMs = DefaultAgencyTools.diffInMs(
GFieldTypes.makeDateFormat(), Calendar.getInstance(), p.todayStringInt, gCalendarDateToAdd.date
).absoluteValue
if (diffInMs < MIN_NOT_IGNORED_IN_DAYS.days.inWholeMilliseconds) {
return false // too soon to ignore
}
Expand Down Expand Up @@ -203,7 +205,10 @@ object MDataChangedManager {
}
val updatedCalendar = originalCalendar.copy(startDate = removedServiceDate.calendarDate)
if (updatedCalendar.dates.size - originalCalendar.dates.size != 1) {
MTLog.log("> Cannot re-add removed dates because of wrong number of added dates (${updatedCalendar.dates.size} vs ${originalCalendar.dates.size})")
MTLog.log(
"> Cannot re-add removed dates because of wrong number of added dates " +
"(${updatedCalendar.dates.size} vs ${originalCalendar.dates.size})"
)
return
}
newGCalendars.remove(originalCalendar)
Expand Down Expand Up @@ -263,7 +268,10 @@ object MDataChangedManager {
}
val updatedCalendar = originalCalendar.copy(startDate = dayAfterRemovedDate)
if (originalCalendar.dates.size - updatedCalendar.dates.size != 1) {
MTLog.log("> Cannot remove added dates because of wrong number of added dates (${updatedCalendar.dates.size} vs ${originalCalendar.dates.size})")
MTLog.log(
"> Cannot remove added dates because of wrong number of added dates " +
"(${updatedCalendar.dates.size} vs ${originalCalendar.dates.size})"
)
return
}
newGCalendars.remove(originalCalendar)
Expand Down Expand Up @@ -304,7 +312,10 @@ object MDataChangedManager {
}
val updatedCalendar = originalCalendar.copy(endDate = dayBeforeRemovedDate)
if (originalCalendar.dates.size - updatedCalendar.dates.size != 1) {
MTLog.log("> Cannot remove added dates because of wrong number of added dates (${updatedCalendar.dates.size} vs ${originalCalendar.dates.size})")
MTLog.log(
"> Cannot remove added dates because of wrong number of added dates " +
"(${updatedCalendar.dates.size} vs ${originalCalendar.dates.size})"
)
return
}
newGCalendars.remove(originalCalendar)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ object MDirectionHeadSignFinder {

private const val MIN_HEAD_SIGN_COUNT_PERCENT = .67f

@Suppress("DestructuringDeclarationWithTooManyEntries")
@JvmStatic
fun findDirectionHeadSigns(routeId: Long, gRouteTrips: List<GTrip>, routeGTFS: GSpec, agencyTools: GAgencyTools): Map<Int, String> {
val directionHeadSigns = mutableMapOf<Int, String>()
Expand Down Expand Up @@ -1034,11 +1035,11 @@ object MDirectionHeadSignFinder {
// cheating, just changing first arrival time / last departure time for AM/PM
val firstIdx = 0
if (mergedStopTimes[firstIdx].departureTime < otherStopTimesList.first().departureTime) {
mergedStopTimes[firstIdx] = mergedStopTimes[firstIdx].copy(_departureTime = otherStopTimesList.first().departureTime)
mergedStopTimes[firstIdx] = mergedStopTimes[firstIdx].copy(departureTime = otherStopTimesList.first().departureTime)
}
val lastIdx = mergedStopTimes.size - 1
if (mergedStopTimes[lastIdx].arrivalTime > otherStopTimesList.last().arrivalTime) {
mergedStopTimes[lastIdx] = mergedStopTimes[lastIdx].copy(_arrivalTime = otherStopTimesList.last().arrivalTime)
mergedStopTimes[lastIdx] = mergedStopTimes[lastIdx].copy(arrivalTime = otherStopTimesList.last().arrivalTime)
}
return mergedStopTimes
}
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/org/mtransit/parser/mt/MReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,17 @@ object MReader {

// region first/last departures

private fun makeFirstDepartureRegex(fileBase: String) =
Regex(any(WHITESPACE_CAR) + "<integer name=\"$fileBase${MGenerator.GTFS_RDS_FIRST_DEPARTURE_IN_SEC}\">${group(oneOrMore(DIGIT_CAR))}</integer>" + any(ANY))
private fun makeFirstDepartureRegex(fileBase: String) = Regex(
any(WHITESPACE_CAR) + "<integer name=\"$fileBase${MGenerator.GTFS_RDS_FIRST_DEPARTURE_IN_SEC}\">${group(oneOrMore(DIGIT_CAR))}</integer>" + any(ANY)
)

private fun makeLastDepartureRegex(fileBase: String) =
Regex(any(WHITESPACE_CAR) + "<integer name=\"$fileBase${MGenerator.GTFS_RDS_LAST_DEPARTURE_IN_SEC}\">${group(oneOrMore(DIGIT_CAR))}</integer>" + any(ANY))
private fun makeLastDepartureRegex(fileBase: String) = Regex(
any(WHITESPACE_CAR) + "<integer name=\"$fileBase${MGenerator.GTFS_RDS_LAST_DEPARTURE_IN_SEC}\">${group(oneOrMore(DIGIT_CAR))}</integer>" + any(ANY)
)

private fun makeTimeZoneRegex() =
Regex(any(WHITESPACE_CAR) + "<string name=\"${MGenerator.GTFS_RDS_TIMEZONE}\">${group(oneOrMore(ALPHA_NUM_CAR) + "/" + oneOrMore(ALPHA_NUM_CAR))}</string>")
private fun makeTimeZoneRegex() = Regex(
any(WHITESPACE_CAR) + "<string name=\"${MGenerator.GTFS_RDS_TIMEZONE}\">${group(oneOrMore(ALPHA_NUM_CAR) + "/" + oneOrMore(ALPHA_NUM_CAR))}</string>"
)

@Suppress("unused") // TODO removed
@JvmStatic
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/mtransit/parser/mt/data/MSchedule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ data class MSchedule( // MStopTime
}
if (FeatureFlags.F_EXPORT_TRIP_ID) {
if (FeatureFlags.F_EXPORT_ARRIVAL_W_TRIP_ID) {
var arrivalDiff = (departure - arrival).takeIf { it > MIN_ARRIVAL_DIFF_IN_HH_MM_SS }
var departureArrivalDiff = (departure - arrival).takeIf { it > MIN_ARRIVAL_DIFF_IN_HH_MM_SS }
if (FeatureFlags.F_SCHEDULE_IN_MINUTES) {
arrivalDiff = arrivalDiff?.div(100) // truncates the time to a minute that is closer to 0
departureArrivalDiff = departureArrivalDiff?.div(100) // truncates the time to a minute that is closer to 0
}
add(arrivalDiff?.toString().orEmpty())
add(departureArrivalDiff?.toString().orEmpty())
}
add(_tripId.convertTripId(quotesString = true))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,8 +453,11 @@ class MDirectionHeadSignFinderTest {
assertEquals("foo foo/trip head-sign", result?.headSign)
}

/**
* should be same head-sign for same last stop, probably wrong data, use most popular / last stops
*/
@Test
fun testFindDirectionHeadSign_TripsWithMoreStopsMultipleHeadSignInclShorterTrips() { // should be same head-sign for same last stop, probably wrong data, use most popular / last stops
fun testFindDirectionHeadSign_TripsWithMoreStopsMultipleHeadSignInclShorterTrips() {
// Arrange
val directionId = GDirectionId.NONE.id
val tripId1 = "trip_id_1"
Expand Down