diff --git a/src/main/java/org/mtransit/parser/config/gtfs/data/RouteConfig.kt b/src/main/java/org/mtransit/parser/config/gtfs/data/RouteConfig.kt index 79ebe80..335a836 100644 --- a/src/main/java/org/mtransit/parser/config/gtfs/data/RouteConfig.kt +++ b/src/main/java/org/mtransit/parser/config/gtfs/data/RouteConfig.kt @@ -209,12 +209,20 @@ data class RouteConfig( @SerialName("route_id") val routeId: String? = null, @SerialName("route_short_name") - val routeShortName: String?, + val routeShortName: String? = null, + @SerialName("route_short_name_regex") + val routeShortNameRegex: String? = null, @SerialName("route_long_name") val routeLongName: String? = null, + @SerialName("original_route_color") + val originalRouteColor: String? = null, @SerialName("color") val color: String, - ) + ) { + internal val parsedRouteShortNameRegex by lazy { + routeShortNameRegex?.toRegex(RegexOption.IGNORE_CASE) + } + } @Serializable data class StopIdConfig( @@ -303,10 +311,13 @@ data class RouteConfig( fun getRouteColor(gRoute: GRoute) = //noinspection DiscouragedApi - (this.routeColors.singleOrNull { gRoute.routeId == it.routeId } - ?: this.routeColors.singleOrNull { gRoute.routeShortName == it.routeShortName } - ?: this.routeColors.singleOrNull { gRoute.routeLongNameOrDefault == it.routeLongName }) - ?.color + this.routeColors.firstOrNull { // order is important, 1st config match found wins + it.routeId == gRoute.routeId + || it.routeShortName == gRoute.routeShortName + || it.routeLongName == gRoute.routeLongNameOrDefault + || it.originalRouteColor?.let { originalRouteColor -> originalRouteColor == gRoute.routeColor } == true + || it.parsedRouteShortNameRegex?.containsMatchIn(gRoute.routeShortName) == true + }?.color fun isRouteColorIgnored(routeColor: String) = this.routeColorsIgnored.any { it.equals(routeColor, ignoreCase = true) } diff --git a/src/main/java/org/mtransit/parser/mt/GenerateMObjectsTask.java b/src/main/java/org/mtransit/parser/mt/GenerateMObjectsTask.java index a2dd8b1..4ec2409 100644 --- a/src/main/java/org/mtransit/parser/mt/GenerateMObjectsTask.java +++ b/src/main/java/org/mtransit/parser/mt/GenerateMObjectsTask.java @@ -281,17 +281,19 @@ private MSpec doCall() { return mRouteSpec; } - private void parseRDS(HashMap mSchedules, - HashMap mFrequencies, - HashMap mAgencies, - HashMap mRoutes, - HashMap mDirections, - HashMap mTrips, - HashMap mStops, - HashMap allMDirectionStops, - HashSet directionStopIds, - HashSet serviceIdInts, - GSpec routeGTFS) { + private void parseRDS( + HashMap mSchedules, + HashMap mFrequencies, + HashMap mAgencies, + HashMap mRoutes, + HashMap mDirections, + HashMap mTrips, + HashMap mStops, + HashMap allMDirectionStops, + HashSet directionStopIds, + HashSet serviceIdInts, + GSpec routeGTFS + ) { boolean mergeSuccessful; HashMap mDirectionStopTimesHeadsign; HashMap> directionIdToMDirectionStops = new HashMap<>(); @@ -431,7 +433,7 @@ private void fixRouteLongName(HashMap mRoutes, HashMap supportedLanguages = this.agencyTools.getSupportedLanguages(); - if (supportedLanguages != null && supportedLanguages.size() >= 1) { + if (supportedLanguages != null && !supportedLanguages.isEmpty()) { final Locale supportedLanguage = supportedLanguages.get(0); if (Locale.ENGLISH.equals(supportedLanguage)) { sb.append("Route ").append(mRoute.getShortNameOrDefault()); @@ -450,18 +452,20 @@ private void fixRouteLongName(HashMap mRoutes, HashMap mSchedules, - HashMap mFrequencies, - HashMap mDirections, - HashMap mTrips, - HashMap mStops, - HashSet serviceIdInts, - MRoute mRoute, - HashMap mDirectionStopTimesHeadsign, - HashMap> directionIdToMDirectionStops, - GRoute gRoute, - Map gDirectionHeadSigns, - GSpec routeGTFS) { + private void parseGTrips( + HashMap mSchedules, + HashMap mFrequencies, + HashMap mDirections, + HashMap mTrips, + HashMap mStops, + HashSet serviceIdInts, + MRoute mRoute, + HashMap mDirectionStopTimesHeadsign, + HashMap> directionIdToMDirectionStops, + GRoute gRoute, + Map gDirectionHeadSigns, + GSpec routeGTFS + ) { boolean mergeSuccessful; HashMap> mergedDirectionIdToMDirectionStops = new HashMap<>(); HashMap> originalDirectionHeadsign; @@ -614,16 +618,18 @@ private void parseGTrips(HashMap mSchedules, MTLog.log("%s: parsing %d trips for route ID '%s'... DONE", this.routeId, routeGTrips.size(), gRouteId); } - private HashMap parseGTripStops(HashMap mSchedules, - HashSet serviceIdInts, - HashMap mStops, - GRoute gRoute, - GTrip gTrip, - HashMap> originalDirectionHeadsign, - ArrayList splitDirections, - Integer serviceIdInt, - HashMap> splitDirectionStops, - GSpec routeGTFS) { + private HashMap parseGTripStops( + HashMap mSchedules, + HashSet serviceIdInts, + HashMap mStops, + GRoute gRoute, + GTrip gTrip, + HashMap> originalDirectionHeadsign, + ArrayList splitDirections, + Integer serviceIdInt, + HashMap> splitDirectionStops, + GSpec routeGTFS + ) { HashMap splitDirectionStopTimesHeadSign = new HashMap<>(); int mStopId; GStop gStop; @@ -716,17 +722,19 @@ private HashMap parseGTripStops(HashMap mSchedu private final DateFormat DATE_TIME_FORMAT = GFieldTypes.makeDateAndTimeFormat(); private final DateFormat DATE_FORMAT = GFieldTypes.makeDateFormat(); - private String parseGStopTimes(HashMap mSchedules, - long mDirectionId, - Integer serviceIdInt, - int originalDirectionHeadsignType, - @Nullable String originalDirectionHeadsignValue, - String directionStopTimesHeadsign, - @NotNull GRoute gRoute, - @NotNull GTrip gTrip, - @NotNull GTripStop gTripStop, - int mStopId, - HashMap addedMDirectionIdAndGStopIds) { + private String parseGStopTimes( + HashMap mSchedules, + long mDirectionId, + Integer serviceIdInt, + int originalDirectionHeadsignType, + @Nullable String originalDirectionHeadsignValue, + String directionStopTimesHeadsign, + @NotNull GRoute gRoute, + @NotNull GTrip gTrip, + @NotNull GTripStop gTripStop, + int mStopId, + HashMap addedMDirectionIdAndGStopIds + ) { MSchedule mSchedule; String stopHeadsign; boolean noPickup; @@ -804,11 +812,13 @@ private String parseGStopTimes(HashMap mSchedules, return directionStopTimesHeadsign; } - private void parseFrequencies(HashMap mFrequencies, - GTrip gTrip, - ArrayList splitDirections, - Integer serviceIdInt, - GSpec routeGTFS) { + private void parseFrequencies( + HashMap mFrequencies, + GTrip gTrip, + ArrayList splitDirections, + Integer serviceIdInt, + GSpec routeGTFS + ) { MFrequency mFrequency; for (GFrequency gFrequency : routeGTFS.getFrequencies(gTrip.getTripIdInt())) { if (gFrequency.getTripIdInt() != gTrip.getTripIdInt()) { @@ -842,8 +852,10 @@ private static String setDirectionStopTimesHeadsign(String directionStopTimesHea return directionStopTimesHeadsign; } - private void setDirectionStopNoPickup(@NotNull ArrayList mDirectionStopsList, - @NotNull Collection mSchedules) { + private void setDirectionStopNoPickup( + @NotNull ArrayList mDirectionStopsList, + @NotNull Collection mSchedules + ) { for (MDirectionStop directionStop : mDirectionStopsList) { boolean noPickup = false; for (MSchedule schedule : mSchedules) { diff --git a/src/test/java/org/mtransit/parser/config/gtfs/data/RouteConfigTest.kt b/src/test/java/org/mtransit/parser/config/gtfs/data/RouteConfigTest.kt index bb28808..7d7721b 100644 --- a/src/test/java/org/mtransit/parser/config/gtfs/data/RouteConfigTest.kt +++ b/src/test/java/org/mtransit/parser/config/gtfs/data/RouteConfigTest.kt @@ -1,6 +1,9 @@ package org.mtransit.parser.config.gtfs.data +import org.mtransit.parser.config.gtfs.data.RouteConfig.RouteColor +import org.mtransit.parser.mt.data.makeGRoute import kotlin.test.Test +import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -10,6 +13,48 @@ class RouteConfigTest { private const val TODAY_DATE = 20260528 } + @Test + fun test_getRouteColor() { + with( + RouteConfig( + routeColors = listOf( + RouteColor( + routeShortNameRegex = "^3\\d{2}$", + color = "000000", + ), + RouteColor( + routeShortNameRegex = "^4\\d{2}$", + color = "007339", + ), + RouteColor( + originalRouteColor = "009EE0", + color = "0060AA", + ), + RouteColor( + originalRouteColor = "", + color = "0060AA", + ), + ) + ) + ) { + getRouteColor(makeGRoute(shortName = "10", color = "009EE0")).let { result -> + assertEquals("0060AA", result) + } + getRouteColor(makeGRoute(shortName = "31", color = "009EE0")).let { result -> + assertEquals("0060AA", result) + } + getRouteColor(makeGRoute(shortName = "350", color = "009EE0")).let { result -> + assertEquals("000000", result) + } + getRouteColor(makeGRoute(shortName = "350", color = null)).let { result -> + assertEquals("000000", result) + } + getRouteColor(makeGRoute(shortName = "427", color = "009EE0")).let { result -> + assertEquals("007339", result) + } + } + } + @Test fun test_directionFinderEnabled() { RouteConfig() diff --git a/src/test/java/org/mtransit/parser/mt/data/GTestsFixtures.kt b/src/test/java/org/mtransit/parser/mt/data/GTestsFixtures.kt index c198fe4..597096a 100644 --- a/src/test/java/org/mtransit/parser/mt/data/GTestsFixtures.kt +++ b/src/test/java/org/mtransit/parser/mt/data/GTestsFixtures.kt @@ -6,14 +6,16 @@ import org.mtransit.parser.gtfs.data.GRoute fun makeGRoute( agencyId: String = "agency_id", id: String = "1", + shortName: String = "RSN$id", + longName: String = "Long Name $id", routeType: Int = 0, - color: String = "000000", + color: String? = "000000", ) = GRoute( agencyIdInt = GIDs.getInt(agencyId), routeIdInt = GIDs.getInt(id), originalRouteIdInt = GIDs.getInt(id), - routeShortName = "RSN$id", - routeLongName = "Long Name $id", + routeShortName = shortName, + routeLongName = longName, routeDesc = null, routeType = routeType, routeColor = color,