From a8bac9fac553ff869b802f7d3f8f77246d11140d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Sun, 1 Mar 2026 15:11:31 -0500 Subject: [PATCH 1/2] JSON configs > add `stop_name_cleaners` & compat w/ mtransitapps/commons-java#22 --- src/main/java/org/mtransit/parser/DefaultAgencyTools.java | 7 ++++--- .../org/mtransit/parser/config/gtfs/data/RouteConfig.kt | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/mtransit/parser/DefaultAgencyTools.java b/src/main/java/org/mtransit/parser/DefaultAgencyTools.java index 89d7a7a..5bc202a 100644 --- a/src/main/java/org/mtransit/parser/DefaultAgencyTools.java +++ b/src/main/java/org/mtransit/parser/DefaultAgencyTools.java @@ -604,7 +604,7 @@ public String cleanRouteLongName(@NotNull String routeLongName) { } routeLongName = Configs.getRouteConfig().cleanRouteLongName(routeLongName); if (defaultStringsCleanerEnabled()) { - return StringsCleaner.cleanRouteLongName(routeLongName, getSupportedLanguages(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords()); + return StringsCleaner.cleanRouteLongName(routeLongName, getSupportedLanguages(), getAgencyRouteType(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords()); } return org.mtransit.commons.CleanUtils.cleanLabel(getFirstLanguageNN(), routeLongName); } @@ -746,7 +746,7 @@ public void setDirectionHeadsign(@NotNull MRoute mRoute, @NotNull MDirection mDi public String cleanTripHeadsign(@NotNull String tripHeadsign) { tripHeadsign = Configs.getRouteConfig().cleanTripHeadsign(tripHeadsign); if (defaultStringsCleanerEnabled()) { - return StringsCleaner.cleanTripHeadsign(tripHeadsign, getSupportedLanguages(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords(), Configs.getRouteConfig().getTripHeadsignRemoveVia()); + return StringsCleaner.cleanTripHeadsign(tripHeadsign, getSupportedLanguages(), getAgencyRouteType(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords(), Configs.getRouteConfig().getTripHeadsignRemoveVia()); } return tripHeadsign; } @@ -1142,8 +1142,9 @@ public boolean excludeCalendar(@NotNull GCalendar gCalendar) { @NotNull @Override public String cleanStopName(@NotNull String gStopName) { + gStopName = Configs.getRouteConfig().cleanStopName(gStopName); if (defaultStringsCleanerEnabled()) { - return StringsCleaner.cleanStopName(gStopName, getSupportedLanguages(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords()); + return StringsCleaner.cleanStopName(gStopName, getSupportedLanguages(), getAgencyRouteType(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords()); } return org.mtransit.commons.CleanUtils.cleanLabel(getFirstLanguageNN(), gStopName); } 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 14bf191..4914def 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 @@ -91,6 +91,8 @@ data class RouteConfig( val stopCodePrependIfMissing: String? = null, // optional @SerialName("use_stop_id_hash_code") val useStopIdHashCode: Boolean = false, // OPT-IN feature + @SerialName("stop_name_cleaners") + val stopNameCleaners: List = emptyList(), @SerialName("stop_headsign_remove_trip_headsign") val stopHeadsignRemoveTripHeadsign: Boolean = false, // OPT-IN feature @SerialName("stop_headsign_remove_route_long_name") @@ -209,6 +211,9 @@ data class RouteConfig( fun cleanTripHeadsign(tripHeadsign: String) = cleanString(tripHeadsign, this.tripHeadsignCleaners) + fun cleanStopName(stopName: String) = + cleanString(stopName, this.stopNameCleaners) + private val _tripExcludes: List by lazy { this.tripExcludes.mapNotNull { if (it.tripHeadsignRegex.isNullOrEmpty()) return@mapNotNull null From 31028170d64f755256698d8cc0de7ffbc6eaa1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Sun, 1 Mar 2026 15:28:31 -0500 Subject: [PATCH 2/2] add `(exclude|keep)_routes` --- .../mtransit/parser/DefaultAgencyTools.java | 6 +++++ .../parser/config/gtfs/data/RouteConfig.kt | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/main/java/org/mtransit/parser/DefaultAgencyTools.java b/src/main/java/org/mtransit/parser/DefaultAgencyTools.java index 5bc202a..97370ed 100644 --- a/src/main/java/org/mtransit/parser/DefaultAgencyTools.java +++ b/src/main/java/org/mtransit/parser/DefaultAgencyTools.java @@ -692,6 +692,12 @@ public boolean excludeRouteNullable(@Nullable GRoute gRoute) { @Override public boolean excludeRoute(@NotNull GRoute gRoute) { + if (Configs.getRouteConfig().keepRoutes(gRoute)) { + return KEEP; + } + if (Configs.getRouteConfig().excludeRoutes(gRoute)) { + return EXCLUDE; + } //noinspection ConstantConditions if (getOriginalAgencyRouteType() == null) { throw new MTLog.Fatal("ERROR: unspecified agency route type '%s'!", getOriginalAgencyRouteType()); 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 4914def..cb077c8 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 @@ -8,6 +8,10 @@ import org.mtransit.parser.gtfs.data.GTrip @Serializable data class RouteConfig( + @SerialName("keep_routes") + val keepRoutes: List = emptyList(), // force additional routes to be included (different types...) + @SerialName("exclude_routes") + val excludeRoutes: List = emptyList(), // force additional routes to be excluded // ID @SerialName("default_route_id_enabled") val defaultRouteIdEnabled: Boolean = false, // OPT-IN feature @@ -106,6 +110,14 @@ data class RouteConfig( val allowInvalidStopTimesUntil: String? = null, // OPT-IN feature ) { + @Serializable + data class RouteDef( + @SerialName("route_id") + val routeId: String? = null, + @SerialName("route_short_name") + val routeShortName: String? = null, + ) + @Serializable data class RouteShortNameToRouteIdConfig( @SerialName("route_short_name") @@ -170,6 +182,20 @@ data class RouteConfig( val ignoreCase: Boolean = false, ) + fun keepRoutes(gRoute: GRoute) = + this.keepRoutes.any { + //noinspection DiscouragedApi + it.routeId != null && gRoute.routeId == it.routeId + || it.routeShortName != null && gRoute.routeShortName == it.routeShortName + } + + fun excludeRoutes(gRoute: GRoute) = + this.excludeRoutes.any { + //noinspection DiscouragedApi + it.routeId != null && gRoute.routeId == it.routeId + || it.routeShortName != null && gRoute.routeShortName == it.routeShortName + } + fun convertRouteIdFromShortNameNotSupported(routeShortName: String) = this.routeShortNameToRouteIdConfigs .singleOrNull { it.routeShortName == routeShortName }?.routeId