From eb6d6a01311615827cfd655b7e265109d5b425b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Tue, 10 Mar 2026 09:56:39 -0400 Subject: [PATCH] JSON config > Add `use_stop_id_for_stop_code` & "is_word" FR cleaner --- .../mtransit/parser/DefaultAgencyTools.java | 20 ++++++----- .../parser/config/gtfs/data/RouteConfig.kt | 33 ++++++++++++------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/mtransit/parser/DefaultAgencyTools.java b/src/main/java/org/mtransit/parser/DefaultAgencyTools.java index 0c0640e..9827516 100644 --- a/src/main/java/org/mtransit/parser/DefaultAgencyTools.java +++ b/src/main/java/org/mtransit/parser/DefaultAgencyTools.java @@ -547,7 +547,7 @@ public String cleanRouteShortName(@NotNull String routeShortName) { if (org.mtransit.commons.StringUtils.isEmpty(routeShortName)) { throw new MTLog.Fatal("No default route short name for '%s'!", routeShortName); } - routeShortName = Configs.getRouteConfig().cleanRouteShortName(routeShortName); + routeShortName = Configs.getRouteConfig().cleanRouteShortName(getFirstLanguageNN(), routeShortName); return routeShortName.trim(); } @@ -605,7 +605,7 @@ public String cleanRouteLongName(@NotNull String routeLongName) { if (org.mtransit.commons.StringUtils.isEmpty(routeLongName)) { throw new MTLog.Fatal("No default route long name for %s!", routeLongName); } - routeLongName = Configs.getRouteConfig().cleanRouteLongName(routeLongName); + routeLongName = Configs.getRouteConfig().cleanRouteLongName(getFirstLanguageNN(), routeLongName); if (defaultStringsCleanerEnabled()) { return StringsCleaner.cleanRouteLongName(routeLongName, getSupportedLanguages(), getAgencyRouteType(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords()); } @@ -753,7 +753,7 @@ public void setDirectionHeadsign(@NotNull MRoute mRoute, @NotNull MDirection mDi @NotNull @Override public String cleanTripHeadsign(@NotNull String tripHeadsign) { - tripHeadsign = Configs.getRouteConfig().cleanTripHeadsign(tripHeadsign); + tripHeadsign = Configs.getRouteConfig().cleanTripHeadsign(getFirstLanguageNN(), tripHeadsign); if (defaultStringsCleanerEnabled()) { return StringsCleaner.cleanTripHeadsign(tripHeadsign, getSupportedLanguages(), getAgencyRouteType(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords(), Configs.getRouteConfig().getTripHeadsignRemoveVia()); } @@ -867,7 +867,7 @@ public boolean removeRouteDescFromDirectionHeadsign() { @NotNull @Override public String cleanDirectionHeadsign(int directionId, boolean fromStopName, @NotNull String directionHeadSign) { - directionHeadSign = Configs.getRouteConfig().cleanDirectionHeadsign(directionHeadSign); + directionHeadSign = Configs.getRouteConfig().cleanDirectionHeadsign(getFirstLanguageNN(), directionHeadSign); //noinspection deprecation return cleanDirectionHeadsign(fromStopName, directionHeadSign); } @@ -1154,7 +1154,7 @@ public boolean excludeCalendar(@NotNull GCalendar gCalendar) { @NotNull @Override public String cleanStopName(@NotNull String gStopName) { - gStopName = Configs.getRouteConfig().cleanStopName(gStopName); + gStopName = Configs.getRouteConfig().cleanStopName(getFirstLanguageNN(), gStopName); if (defaultStringsCleanerEnabled()) { return StringsCleaner.cleanStopName(gStopName, getSupportedLanguages(), getAgencyRouteType(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords()); } @@ -1206,10 +1206,14 @@ public String cleanStopHeadSign(@NotNull String stopHeadsign) { @Override public String getStopCode(@NotNull GStop gStop) { final String prepend = getStopCodePrependIfMissing(); - if (prepend != null && !gStop.getStopCode().startsWith(prepend)) { - return prepend + gStop.getStopCode(); + //noinspection DiscouragedApi + final String stopCode = + Configs.getRouteConfig().getUseStopIdForStopCode() ? gStop.getStopId() : + gStop.getStopCode(); + if (prepend != null && !stopCode.startsWith(prepend)) { + return prepend + stopCode; } - return gStop.getStopCode(); + return stopCode; } @Deprecated 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 88fafed..0cb0300 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 @@ -7,6 +7,7 @@ import org.mtransit.commons.StringUtils.EMPTY import org.mtransit.parser.gtfs.data.GRoute import org.mtransit.parser.gtfs.data.GStopTime import org.mtransit.parser.gtfs.data.GTrip +import java.util.Locale @Serializable data class RouteConfig( @@ -95,6 +96,8 @@ data class RouteConfig( val stopIdNotUniqueAllowed: Boolean = false, // OPT-IN feature @SerialName("use_stop_code_for_stop_id") val useStopCodeForStopId: Boolean = false, // OPT-IN feature + @SerialName("use_stop_id_for_stop_code") + val useStopIdForStopCode: Boolean = false, // OPT-IN feature @SerialName("stop_code_to_stop_id_configs") val stopCodeToStopIdConfigs: List = emptyList(), @SerialName("stop_code_prepend_if_missing") @@ -246,17 +249,17 @@ data class RouteConfig( fun isRouteColorIgnored(routeColor: String) = this.routeColorsIgnored.any { it.equals(routeColor, ignoreCase = true) } - fun cleanRouteShortName(routeShortName: String) = - cleanString(routeShortName, this.routeShortNameCleaners) + fun cleanRouteShortName(lang: Locale, routeShortName: String) = + cleanString(lang, routeShortName, this.routeShortNameCleaners) - fun cleanRouteLongName(routeLongName: String) = - cleanString(routeLongName, this.routeLongNameCleaners) + fun cleanRouteLongName(lang: Locale, routeLongName: String) = + cleanString(lang, routeLongName, this.routeLongNameCleaners) - fun cleanTripHeadsign(tripHeadsign: String) = - cleanString(tripHeadsign, this.tripHeadsignCleaners) + fun cleanTripHeadsign(lang: Locale, tripHeadsign: String) = + cleanString(lang, tripHeadsign, this.tripHeadsignCleaners) - fun cleanStopName(stopName: String) = - cleanString(stopName, this.stopNameCleaners) + fun cleanStopName(lang: Locale, stopName: String) = + cleanString(lang, stopName, this.stopNameCleaners) fun cleanStopHeadsign(gRoute: GRoute, gTrip: GTrip, @Suppress("unused") gStopTime: GStopTime, stopHeadsign: String): String { if (stopHeadsign.isEmpty()) return stopHeadsign @@ -318,14 +321,14 @@ data class RouteConfig( return false // KEEP } - fun cleanDirectionHeadsign(directionHeadsign: String) = - cleanString(directionHeadsign, this.directionHeadsignCleaners) + fun cleanDirectionHeadsign(lang: Locale, directionHeadsign: String) = + cleanString(lang, directionHeadsign, this.directionHeadsignCleaners) fun convertStopIdFromCodeNotSupported(stopCode: String) = this.stopCodeToStopIdConfigs .singleOrNull { it.stopCode == stopCode }?.stopId - private fun cleanString(originalString: String, cleaners: List): String { + private fun cleanString(lang: Locale, originalString: String, cleaners: List): String { if (cleaners.isEmpty()) return originalString var string = originalString cleaners.forEach { @@ -335,7 +338,13 @@ data class RouteConfig( regexOptions.add(RegexOption.IGNORE_CASE) } string = when { - it.isWord -> CleanUtils.cleanWord(it.regex).matcher(string).replaceAll(CleanUtils.cleanWordsReplacement(it.replacement)) + it.isWord -> { + val pattern = + if (lang.language == Locale.FRENCH.language) CleanUtils.cleanWordsFR(it.regex) + else CleanUtils.cleanWords(it.regex) + pattern.matcher(string).replaceAll(CleanUtils.cleanWordsReplacement(it.replacement)) + } + else -> it.regex.toRegex(regexOptions).replace(string, it.replacement) } }