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
92 changes: 60 additions & 32 deletions src/main/java/org/mtransit/parser/DefaultAgencyTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -591,11 +591,36 @@ public String cleanRouteLongName(@NotNull String routeLongName) {
}
routeLongName = Configs.getRouteConfig().cleanRouteLongName(routeLongName);
if (defaultStringsCleanerEnabled()) {
return StringsCleaner.cleanRouteLongName(routeLongName, getSupportedLanguages());
return StringsCleaner.cleanRouteLongName(routeLongName, getSupportedLanguages(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords());
}
return org.mtransit.commons.CleanUtils.cleanLabel(getFirstLanguageNN(), routeLongName);
}

@Override
public boolean lowerUCWords() {
if (Configs.getAgencyConfig() != null) {
return Configs.getAgencyConfig().getToLowerUpperCaseWords();
}
return false; // OPT-IN feature
Comment thread
mmathieum marked this conversation as resolved.
}

@Override
public boolean lowerUCStrings() {
if (Configs.getAgencyConfig() != null) {
return Configs.getAgencyConfig().getToLowerUpperCaseStrings();
}
return false; // OPT-IN feature
Comment thread
mmathieum marked this conversation as resolved.
}


@Override
public @NotNull String[] getIgnoreUCWords() {
if (Configs.getAgencyConfig() != null) {
return Configs.getAgencyConfig().getIgnoreUpperCaseWords().toArray(new String[0]);
}
return new String[0];
Comment thread
mmathieum marked this conversation as resolved.
}

@Deprecated
@Override
public boolean allowGTFSIdOverride() {
Expand Down Expand Up @@ -709,7 +734,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(), Configs.getRouteConfig().getTripHeadsignRemoveVia());
return StringsCleaner.cleanTripHeadsign(tripHeadsign, getSupportedLanguages(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords(), Configs.getRouteConfig().getTripHeadsignRemoveVia());
}
return tripHeadsign;
}
Expand Down Expand Up @@ -1058,6 +1083,9 @@ public boolean excludeTripNullable(@Nullable GTrip gTrip) {

@Override
public boolean excludeTrip(@NotNull GTrip gTrip) {
if (Configs.getRouteConfig().excludeTrip(gTrip)) {
return EXCLUDE;
}
if (this.serviceIdInts != null) {
return excludeUselessTripInt(gTrip, this.serviceIdInts);
}
Expand All @@ -1084,7 +1112,7 @@ public boolean excludeCalendar(@NotNull GCalendar gCalendar) {
@Override
public String cleanStopName(@NotNull String gStopName) {
if (defaultStringsCleanerEnabled()) {
return StringsCleaner.cleanStopName(gStopName, getSupportedLanguages());
return StringsCleaner.cleanStopName(gStopName, getSupportedLanguages(), lowerUCStrings(), lowerUCWords(), getIgnoreUCWords());
}
return org.mtransit.commons.CleanUtils.cleanLabel(getFirstLanguageNN(), gStopName);
}
Expand Down Expand Up @@ -1300,7 +1328,7 @@ private static Pair<Integer, Integer> extractTimes(GStopTime gStopTime,

@NotNull
public static Pair<Long, Long> extractTimeInMs(@NotNull GStopTime gStopTime,
@NotNull List<GStopTime> tripStopTimes) {
@NotNull List<GStopTime> tripGStopTimes) {
int previousArrivalTime = -1;
int previousArrivalTimeStopSequence = -1;
int previousDepartureTime = -1;
Expand All @@ -1309,59 +1337,59 @@ public static Pair<Long, Long> extractTimeInMs(@NotNull GStopTime gStopTime,
int nextArrivalTimeStopSequence = -1;
int nextDepartureTime = -1;
int nextDepartureTimeStopSequence = -1;
for (GStopTime aStopTime : tripStopTimes) {
if (gStopTime.getTripIdInt() != aStopTime.getTripIdInt()) {
for (GStopTime tripGStopTime : tripGStopTimes) {
if (gStopTime.getTripIdInt() != tripGStopTime.getTripIdInt()) {
continue;
}
if (aStopTime.getStopSequence() == gStopTime.getStopSequence()
&& aStopTime.getStopIdInt() == gStopTime.getStopIdInt()
&& aStopTime.hasArrivalTime()
&& aStopTime.hasDepartureTime()) {
if (tripGStopTime.getStopSequence() == gStopTime.getStopSequence()
&& tripGStopTime.getStopIdInt() == gStopTime.getStopIdInt()
&& tripGStopTime.hasArrivalTime()
&& tripGStopTime.hasDepartureTime()) {
return new Pair<>( // re-use provided stop times from another trip #frequencies
aStopTime.getArrivalTimeMs(),
aStopTime.getDepartureTimeMs()
tripGStopTime.getArrivalTimeMs(),
tripGStopTime.getDepartureTimeMs()
);
}
if (aStopTime.getStopSequence() < gStopTime.getStopSequence()) {
if (aStopTime.hasDepartureTime()) {
if (tripGStopTime.getStopSequence() < gStopTime.getStopSequence()) {
if (tripGStopTime.hasDepartureTime()) {
if (previousDepartureTime < 0
|| previousDepartureTimeStopSequence < 0
|| previousDepartureTimeStopSequence < aStopTime.getStopSequence()) {
previousDepartureTime = aStopTime.getDepartureTime();
previousDepartureTimeStopSequence = aStopTime.getStopSequence();
|| previousDepartureTimeStopSequence < tripGStopTime.getStopSequence()) {
previousDepartureTime = tripGStopTime.getDepartureTime();
previousDepartureTimeStopSequence = tripGStopTime.getStopSequence();
}
}
if (aStopTime.hasArrivalTime()) {
if (tripGStopTime.hasArrivalTime()) {
if (previousArrivalTime < 0
|| previousArrivalTimeStopSequence < 0
|| previousArrivalTimeStopSequence < aStopTime.getStopSequence()) {
previousArrivalTime = aStopTime.getArrivalTime();
previousArrivalTimeStopSequence = aStopTime.getStopSequence();
|| previousArrivalTimeStopSequence < tripGStopTime.getStopSequence()) {
previousArrivalTime = tripGStopTime.getArrivalTime();
previousArrivalTimeStopSequence = tripGStopTime.getStopSequence();
}
}
} else if (aStopTime.getStopSequence() > gStopTime.getStopSequence()) {
if (aStopTime.hasDepartureTime()) {
} else if (tripGStopTime.getStopSequence() > gStopTime.getStopSequence()) {
if (tripGStopTime.hasDepartureTime()) {
if (nextDepartureTime < 0
|| nextDepartureTimeStopSequence < 0
|| nextDepartureTimeStopSequence > aStopTime.getStopSequence()) {
nextDepartureTime = aStopTime.getDepartureTime();
nextDepartureTimeStopSequence = aStopTime.getStopSequence();
|| nextDepartureTimeStopSequence > tripGStopTime.getStopSequence()) {
nextDepartureTime = tripGStopTime.getDepartureTime();
nextDepartureTimeStopSequence = tripGStopTime.getStopSequence();
}
}
if (aStopTime.hasArrivalTime()) {
if (tripGStopTime.hasArrivalTime()) {
if (nextArrivalTime < 0
|| nextArrivalTimeStopSequence < 0
|| nextArrivalTimeStopSequence > aStopTime.getStopSequence()) {
nextArrivalTime = aStopTime.getArrivalTime();
nextArrivalTimeStopSequence = aStopTime.getStopSequence();
|| nextArrivalTimeStopSequence > tripGStopTime.getStopSequence()) {
nextArrivalTime = tripGStopTime.getArrivalTime();
nextArrivalTimeStopSequence = tripGStopTime.getStopSequence();
}
}
}
}
if (previousArrivalTime == -1 || previousDepartureTime == -1) {
//noinspection DiscouragedApi
MTLog.log("Trip ID '%s' stops: ", gStopTime.getTripId());
for (GStopTime aStopTime : tripStopTimes) {
for (GStopTime aStopTime : tripGStopTimes) {
MTLog.log("- %s", aStopTime.toStringPlus(true));
}
//noinspection DiscouragedApi
Expand All @@ -1372,7 +1400,7 @@ public static Pair<Long, Long> extractTimeInMs(@NotNull GStopTime gStopTime,
if (nextArrivalTime == -1 || nextDepartureTime == -1) {
//noinspection DiscouragedApi
MTLog.log("Trip ID '%s' stops: ", gStopTime.getTripId());
for (GStopTime aStopTime : tripStopTimes) {
for (GStopTime aStopTime : tripGStopTimes) {
MTLog.log("- %s", aStopTime.toStringPlus(true));
}
//noinspection DiscouragedApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,19 @@ data class AgencyConfig(
*/
@SerialName("target_route_type_id")
val targetRouteTypeId: Int, // REQUIRED
// STRINGS
/**
* (Optional) Default string cleaner enabled/disabled (based on language/country/field)
*/
@SerialName("default_strings_cleaner_enabled")
val defaultStringsCleanerEnabled: Boolean = false, // OPT-IN feature
@SerialName("to_lower_upper_case_strings")
val toLowerUpperCaseStrings: Boolean = false, // OPT-IN feature
@SerialName("to_lower_upper_case_words")
val toLowerUpperCaseWords: Boolean = false, // OPT-IN feature
@SerialName("ignore_upper_case_words")
val ignoreUpperCaseWords: List<String> = emptyList(), // OPT-IN feature
// COLOR
/**
* (Optional) Default color enabled/disabled for agency (based on routes colors)
*/
Expand All @@ -32,6 +40,7 @@ data class AgencyConfig(
*/
@SerialName("default_color")
val defaultColor: String, // REQUIRED
// SERVICE
@SerialName("service_id_cleanup_regex")
val serviceIdCleanupRegex: String? = null, // optional
@SerialName("service_id_clean_merged")
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/org/mtransit/parser/config/gtfs/data/RouteConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.mtransit.commons.CleanUtils
import org.mtransit.parser.gtfs.data.GRoute
import org.mtransit.parser.gtfs.data.GTrip

@Serializable
data class RouteConfig(
Expand Down Expand Up @@ -40,6 +41,8 @@ data class RouteConfig(
@SerialName("route_colors_ignored")
val routeColorsIgnored: List<String> = emptyList(), // optional
// TRIP
@SerialName("trip_excludes")
val tripExcludes: List<TripFilter> = emptyList(), // optional
@SerialName("trip_headsign_cleaners")
val tripHeadsignCleaners: List<Cleaner> = emptyList(),
@SerialName("trip_headsign_remove_via")
Expand Down Expand Up @@ -127,6 +130,14 @@ data class RouteConfig(
val replacement: String = "",
)

@Serializable
data class TripFilter(
@SerialName("trip_headsign_regex")
val tripHeadsignRegex: String? = null,
@SerialName("ignore_case")
val ignoreCase: Boolean = false,
)

fun convertRouteIdFromShortNameNotSupported(routeShortName: String) =
this.routeShortNameToRouteIdConfigs
.singleOrNull { it.routeShortName == routeShortName }?.routeId
Expand Down Expand Up @@ -160,6 +171,27 @@ data class RouteConfig(
fun cleanTripHeadsign(tripHeadsign: String) =
cleanString(tripHeadsign, this.tripHeadsignCleaners)

private val _tripExcludes: List<Regex> by lazy {
this.tripExcludes.mapNotNull {
if (it.tripHeadsignRegex.isNullOrEmpty()) return@mapNotNull null
val regexOptions = mutableSetOf<RegexOption>()
if (it.ignoreCase) {
regexOptions.add(RegexOption.IGNORE_CASE)
}
Comment thread
mmathieum marked this conversation as resolved.
it.tripHeadsignRegex.toRegex(regexOptions)
}
}

fun excludeTrip(gTrip: GTrip): Boolean {
this._tripExcludes.forEach {
val gTripHeadsign = gTrip.tripHeadsign ?: return@forEach
if (it.matches(gTripHeadsign)) {
return true // EXCLUDE
}
}
return false // KEEP
}

fun cleanDirectionHeadsign(directionHeadsign: String) =
cleanString(directionHeadsign, this.directionHeadsignCleaners)

Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/mtransit/parser/gtfs/GAgencyTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,12 @@ public interface GAgencyTools {
@NotNull
String cleanRouteLongName(@NotNull String routeLongName);

boolean lowerUCWords();

boolean lowerUCStrings();

@NotNull String[] getIgnoreUCWords();

@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
boolean allowGTFSIdOverride();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ private void parseGTrips(HashMap<String, MSchedule> mSchedules,
if (cDirectionStopsList != null) {
if (!CollectionUtils.equalsList(mDirectionStopsList, cDirectionStopsList)) {
if (MDirectionStop.containsStopIds(cDirectionStopsList, mDirectionStopsList)) {
MTLog.logDebug("%s: Skip merge because current direction stops list contains other list.", this.routeId, MDirectionStop.printDirectionStops(cDirectionStopsList));
MTLog.logDebug("%s: Skip merge because current direction stops list contains new stops list.", this.routeId);
} else {
MTLog.log("%s: Need to merge direction ID '%s' stops lists (sizes: %d in %d).", this.routeId, mDirection.getId(), mDirectionStopsList.size(), cDirectionStopsList.size());
if (Constants.DEBUG) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/mtransit/parser/mt/MGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,7 @@ private static String getCommentedDateTime(int timestampInSec, @NotNull MSpec mS
private static final String RESOURCE_INTEGER_AND_NAME_VALUE = RESOURCE_TAB + "<integer name=\"%s\">%s</integer>";
private static final String RESOURCE_BOOL_AND_NAME_VALUE = RESOURCE_TAB + "<bool name=\"%s\">%s</bool>";
private static final String RESOURCE_STRING_AND_NAME_VALUE = RESOURCE_TAB + "<string name=\"%s\">%s</string>";
private static final String RESOURCE_STRING_WITHOUT_VALUE = RESOURCE_TAB + "<string name=\"%s\" />";
private static final String RESOURCES_END = "</resources>";

private static String getRESOURCES_INTEGER(String resName, Integer resValue) {
Expand All @@ -1251,6 +1252,7 @@ private static String getRESOURCES_BOOL(String resName, boolean resValue) {
}

private static String getRESOURCES_STRING(@NotNull String resName, @Nullable Object resValue) {
if (resValue == null || resValue.toString().isEmpty()) return String.format(RESOURCE_STRING_WITHOUT_VALUE, resName);
return String.format(RESOURCE_STRING_AND_NAME_VALUE, resName, resValue);
}

Expand Down