From e3f82e8345b8ff38d8dac0deca1cf99f09e23d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Mon, 4 May 2026 11:18:40 -0400 Subject: [PATCH 1/3] Reapply "Route long name merging improvement" This reverts commit f221343fb7b9b5c9758b20ab13f3fd85fa5009ff. --- .../mtransit/parser/DefaultAgencyTools.java | 12 ++++- .../mtransit/parser/gtfs/GAgencyTools.java | 3 ++ .../org/mtransit/parser/gtfs/GReader.java | 2 +- .../org/mtransit/parser/gtfs/data/GRoute.kt | 15 +++--- .../org/mtransit/parser/mt/data/MRoute.kt | 46 +------------------ 5 files changed, 23 insertions(+), 55 deletions(-) diff --git a/src/main/java/org/mtransit/parser/DefaultAgencyTools.java b/src/main/java/org/mtransit/parser/DefaultAgencyTools.java index c3c31684..d860e654 100644 --- a/src/main/java/org/mtransit/parser/DefaultAgencyTools.java +++ b/src/main/java/org/mtransit/parser/DefaultAgencyTools.java @@ -695,7 +695,17 @@ public boolean allowGTFSIdOverride() { @Override public boolean mergeRouteLongName(@NotNull MRoute mRoute, @NotNull MRoute mRouteToMerge) { - return mRoute.mergeLongName(mRouteToMerge); + final String mergedRouteLongName = mergeRouteLongNamesOrNull(mRoute.getLongName(), mRouteToMerge.getLongName()); + if (mergedRouteLongName != null) { + mRoute.setLongName(mergedRouteLongName); + } + return mergedRouteLongName != null; + } + + @Nullable + @Override + public String mergeRouteLongNamesOrNull(@Nullable String routeLongName1, @Nullable String routeLongName2) { + return GRoute.mergeRouteLongNames(routeLongName1, routeLongName2); } @Nullable diff --git a/src/main/java/org/mtransit/parser/gtfs/GAgencyTools.java b/src/main/java/org/mtransit/parser/gtfs/GAgencyTools.java index 3859ab59..ac9d288d 100644 --- a/src/main/java/org/mtransit/parser/gtfs/GAgencyTools.java +++ b/src/main/java/org/mtransit/parser/gtfs/GAgencyTools.java @@ -167,6 +167,9 @@ public interface GAgencyTools { boolean mergeRouteLongName(@NotNull MRoute mRoute, @NotNull MRoute mRouteToMerge); + @Nullable + String mergeRouteLongNamesOrNull(@Nullable String routeLongName1, @Nullable String routeLongName2); + @Nullable String getRouteColor(@NotNull GRoute gRoute); diff --git a/src/main/java/org/mtransit/parser/gtfs/GReader.java b/src/main/java/org/mtransit/parser/gtfs/GReader.java index 46d1623d..1cc585e6 100644 --- a/src/main/java/org/mtransit/parser/gtfs/GReader.java +++ b/src/main/java/org/mtransit/parser/gtfs/GReader.java @@ -533,7 +533,7 @@ private static void processRoute(GAgencyTools agencyTools, GSpec gSpec, HashMap< return; // ignore if route already exists with same values } if (previousGRoute != null && previousGRoute.equalsExceptMergeable(gRoute)) { - final String mergedRouteLongName = GRoute.mergeRouteLongNames(previousGRoute.getRouteLongName(), gRoute.getRouteLongName()); + final String mergedRouteLongName = agencyTools.mergeRouteLongNamesOrNull(previousGRoute.getRouteLongName(), gRoute.getRouteLongName()); final String mergedRouteColor = GRoute.mergeRouteColors(previousGRoute.getRouteColor(), gRoute.getRouteColor()); final Integer mergedRouteSortOrder = GRoute.mergeRouteSortOrders(previousGRoute.getRouteSortOrder(), gRoute.getRouteSortOrder()); if (mergedRouteLongName != null) { // merge successful diff --git a/src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt b/src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt index 70178cc3..36e0c118 100644 --- a/src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt +++ b/src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt @@ -181,7 +181,7 @@ data class GRoute( ?: throw MTLog.Fatal("Invalid GRoute.$ROUTE_ID from $line!"), originalRouteId = line[ROUTE_ID] ?: throw MTLog.Fatal("Invalid GRoute.$ROUTE_ID from $line!"), routeShortName = line[ROUTE_SHORT_NAME]?.trim() - ?.let { it.takeIf { it.isNotEmpty() }?.let { agencyTools?.cleanRouteShortName(it) } ?: it } + ?.let { rsn -> rsn.takeIf { it.isNotEmpty() }?.let { agencyTools?.cleanRouteShortName(it) } ?: rsn } ?.takeUnless { agencyTools?.useRouteIdForRouteShortName() == true } ?: line[ROUTE_ID]?.trim()?.let { agencyTools?.cleanRouteOriginalId(it) ?: it } ?: EMPTY, @@ -214,7 +214,7 @@ data class GRoute( ) } - private const val SLASH_: String = " / " + private const val SLASH_ = " / " @JvmStatic fun mergeRouteLongNames(routeLongName1: String?, routeLongName2: String?): String? { @@ -242,11 +242,10 @@ data class GRoute( routeLongName2.dropLast(suffix.length) + suffix } - return if (routeLongName1 > routeLongName2) { - routeLongName2 + SLASH_ + routeLongName1 - } else { - routeLongName1 + SLASH_ + routeLongName2 - } + val routeLongName1Split = routeLongName1.split(SLASH_) + val routeLongName2Split = routeLongName2.split(SLASH_) + val routeLongNamesSplit = (routeLongName1Split + routeLongName2Split).distinct().sorted() + return routeLongNamesSplit.joinToString(SLASH_) } @JvmStatic @@ -278,4 +277,4 @@ data class GRoute( return null // -1 // not merged < route sort order not used at the moment } } -} \ No newline at end of file +} diff --git a/src/main/java/org/mtransit/parser/mt/data/MRoute.kt b/src/main/java/org/mtransit/parser/mt/data/MRoute.kt index 2f7c2761..aa1d55eb 100644 --- a/src/main/java/org/mtransit/parser/mt/data/MRoute.kt +++ b/src/main/java/org/mtransit/parser/mt/data/MRoute.kt @@ -6,7 +6,6 @@ import org.mtransit.commons.sql.SQLUtils import org.mtransit.parser.db.SQLUtils.quotes import org.mtransit.parser.db.SQLUtils.quotesEscape import org.mtransit.parser.gtfs.GAgencyTools -import kotlin.math.max data class MRoute( val id: Long, @@ -60,45 +59,6 @@ data class MRoute( } } - @Suppress("SameReturnValue") - fun mergeLongName(mRouteToMerge: MRoute?): Boolean { - if (mRouteToMerge == null || mRouteToMerge.longName.isEmpty()) { - return true - } else if (longName.isEmpty()) { - longName = mRouteToMerge.longName - return true - } else if (mRouteToMerge.longName.contains(longName)) { - longName = mRouteToMerge.longName - return true - } else if (longName.contains(mRouteToMerge.longName)) { - return true - } - val prefix = longName.commonPrefixWith(mRouteToMerge.longName) - val maxLength = max(longName.length, mRouteToMerge.longName.length) - if (prefix.length > maxLength / 2) { - longName = prefix + - longName.substring(prefix.length) + - SLASH + - mRouteToMerge.longName.substring(prefix.length) - return true - } - val suffix = longName.commonSuffixWith(mRouteToMerge.longName) - if (suffix.length > maxLength / 2) { - longName = longName.substring(0, longName.length - suffix.length) + - SLASH + - mRouteToMerge.longName.substring(0, mRouteToMerge.longName.length - suffix.length) + - suffix - return true - } - return if (longName > mRouteToMerge.longName) { - longName = mRouteToMerge.longName + SLASH + longName - true - } else { - longName = longName + SLASH + mRouteToMerge.longName - true - } - } - @Suppress("unused") fun simpleMergeLongName(mRouteToMerge: MRoute?): Boolean { @Suppress("RedundantIf") @@ -114,8 +74,4 @@ data class MRoute( false // not simple } } - - companion object { - private const val SLASH = " / " - } -} \ No newline at end of file +} From 258ab1f4d0ea02bcd75109e1868c09cc29ae2124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Mon, 4 May 2026 11:32:07 -0400 Subject: [PATCH 2/3] fix --- .../org/mtransit/parser/mt/data/MRouteTest.kt | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/test/java/org/mtransit/parser/mt/data/MRouteTest.kt b/src/test/java/org/mtransit/parser/mt/data/MRouteTest.kt index b501a987..7535e799 100644 --- a/src/test/java/org/mtransit/parser/mt/data/MRouteTest.kt +++ b/src/test/java/org/mtransit/parser/mt/data/MRouteTest.kt @@ -1,7 +1,11 @@ package org.mtransit.parser.mt.data -import org.junit.Assert.assertEquals -import org.junit.Test +import org.mtransit.commons.CommonsApp +import org.mtransit.parser.gtfs.data.GRoute +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull class MRouteTest { @@ -9,27 +13,30 @@ class MRouteTest { private const val ROUTE_TYPE: Int = 0 } + @BeforeTest + fun setUp() { + CommonsApp.setup(false) + } + @Test fun testMergeLongName_CommonPrefix() { - // Arrange val route1 = MRoute(1L, "RSN", "Jasper Pl - CN Tower", "000000", "1", ROUTE_TYPE) val route2 = MRoute(1L, "RSN", "Jasper Pl - Downtown", "000000", "1", ROUTE_TYPE) - // Act - val result = route1.mergeLongName(route2) - // Assert - assertEquals(true, result) - assertEquals("Jasper Pl - CN Tower / Downtown", route1.longName) + + val result = GRoute.mergeRouteLongNames(route1.longName, route2.longName) + + assertNotNull(result) + assertEquals("Jasper Pl - CN Tower / Downtown", result) } @Test fun testMergeLongName_CommonSuffix() { - // Arrange val route1 = MRoute(1L, "RSN", "CN Tower - Jasper Pl", "000000", "1", ROUTE_TYPE) val route2 = MRoute(1L, "RSN", "Downtown - Jasper Pl", "000000", "1", ROUTE_TYPE) - // Act - val result = route1.mergeLongName(route2) - // Assert - assertEquals(true, result) - assertEquals("CN Tower / Downtown - Jasper Pl", route1.longName) + + val result = GRoute.mergeRouteLongNames(route1.longName, route2.longName) + + assertNotNull(result) + assertEquals("CN Tower / Downtown - Jasper Pl", result) } -} \ No newline at end of file +} From 7770e8332ffc2d583d85625f6b650f9510339ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20M=C3=A9a?= Date: Mon, 4 May 2026 13:16:37 -0400 Subject: [PATCH 3/3] PR comments --- src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt b/src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt index 36e0c118..d1b59a2c 100644 --- a/src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt +++ b/src/main/java/org/mtransit/parser/gtfs/data/GRoute.kt @@ -215,6 +215,7 @@ data class GRoute( } private const val SLASH_ = " / " + private const val SLASH= "/" @JvmStatic fun mergeRouteLongNames(routeLongName1: String?, routeLongName2: String?): String? { @@ -242,9 +243,10 @@ data class GRoute( routeLongName2.dropLast(suffix.length) + suffix } - val routeLongName1Split = routeLongName1.split(SLASH_) - val routeLongName2Split = routeLongName2.split(SLASH_) - val routeLongNamesSplit = (routeLongName1Split + routeLongName2Split).distinct().sorted() + val routeLongName1Split = routeLongName1.split(SLASH) + val routeLongName2Split = routeLongName2.split(SLASH) + val routeLongNamesSplit = (routeLongName1Split + routeLongName2Split) + .map { it.trim() }.filter { it.isNotBlank() }.distinct().sorted() return routeLongNamesSplit.joinToString(SLASH_) }