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
18 changes: 13 additions & 5 deletions src/main/java/org/mtransit/parser/gtfs/GReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.nio.file.Files;
import java.sql.PreparedStatement;
import java.text.DateFormat;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
Expand Down Expand Up @@ -175,8 +176,11 @@ public static GSpec readGtfsZipFile(
}
// STOPS (after stop times)
if (!calendarsOnly && !routeTripCalendarsOnly) {
final GAgency singleAgency = gSpec.getSingleAgency();
//noinspection DiscouragedApi
final String agencyTimezone = singleAgency == null ? null : singleAgency.getAgencyTimezone();
readFile(gtfsDir, GStop.FILENAME, true, line ->
processStop(agencyTools, gSpec, line, skipDataCleanup)
processStop(agencyTools, gSpec, line, skipDataCleanup, agencyTimezone)
);
}
// TODO OTHER FILES TYPE
Expand Down Expand Up @@ -412,9 +416,11 @@ private static void processFrequency(
}
}

private static final Set<String> AVAILABLE_TIME_ZONE_IDS = ZoneId.getAvailableZoneIds(); // cache because it returns new set copy every time

private static void processAgency(GAgencyTools agencyTools, GSpec gSpec, HashMap<String, String> line) {
try {
final GAgency gAgency = GAgency.fromLine(line);
final GAgency gAgency = GAgency.fromLine(line, AVAILABLE_TIME_ZONE_IDS);
if (agencyTools.excludeAgency(gAgency)) {
MTLog.logDebug("processAgency() > SKIP (exclude agency)");
return;
Expand Down Expand Up @@ -546,14 +552,15 @@ private static void processTrip(
}
}

private static void processStop(GAgencyTools agencyTools, GSpec gSpec, Map<String, String> line, boolean skipDataCleanup) {
private static void processStop(GAgencyTools agencyTools, GSpec gSpec, Map<String, String> line, boolean skipDataCleanup, @Nullable String agencyTimezone) {
try {
final GLocationType stopLocationType = GLocationType.parse(line.get(GStop.LOCATION_TYPE));
if (stopLocationType == GLocationType.GENERIC_NODE) {
MTLog.log("Generic node stop ignored (%s).", line); // not lat/lng?
return;
}
final GStop gStop = skipDataCleanup ? GStop.fromLine(line) : GStop.fromLine(line, agencyTools);
final GStop gStop = skipDataCleanup ? GStop.fromLine(line, agencyTimezone, AVAILABLE_TIME_ZONE_IDS)
: GStop.fromLine(line, agencyTimezone, AVAILABLE_TIME_ZONE_IDS, agencyTools);
if (agencyTools.excludeStop(gStop)) {
//noinspection DiscouragedApi
logExclude("Exclude stop: %s.", line.get(GStop.STOP_ID));
Expand All @@ -575,8 +582,9 @@ private static void processStop(GAgencyTools agencyTools, GSpec gSpec, Map<Strin
if (previousStop != null && previousStop.equalsExceptMergeable(gStop)) {
final double mergedLat = GStop.mergeLocation(previousStop.getStopLat(), gStop.getStopLat());
final double mergedLng = GStop.mergeLocation(previousStop.getStopLong(), gStop.getStopLong());
final String mergedTimeZoneId = GStop.mergeTimezone(previousStop.getStopTimezone(), gStop.getStopTimezone());
final GWheelchairBoardingType mergedWheelchairBoarding = GWheelchairBoardingType.merge(previousStop.getWheelchairBoarding(), gStop.getWheelchairBoarding());
gSpec.addStop(previousStop.clone(mergedLat, mergedLng, mergedWheelchairBoarding), true);
gSpec.addStop(previousStop.clone(mergedLat, mergedLng, mergedTimeZoneId, mergedWheelchairBoarding), true);
return;
}
if (previousStop != null) {
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/org/mtransit/parser/gtfs/data/GAgency.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,13 @@ data class GAgency(
private const val AGENCY_EMAIL = "agency_email" // Optional

@JvmStatic
fun fromLine(line: Map<String, String>) = GAgency(
fun fromLine(line: Map<String, String>, availableZoneIds: Set<String>) = GAgency(
agencyId = line[AGENCY_ID].orEmpty(),
agencyName = line[AGENCY_NAME] ?: throw MTLog.Fatal("Invalid GAgency from $line!"),
agencyUrl = line[AGENCY_URL] ?: throw MTLog.Fatal("Invalid GAgency from $line!"),
agencyTimezone = line[AGENCY_TIMEZONE] ?: throw MTLog.Fatal("Invalid GAgency from $line!"),
agencyTimezone = line[AGENCY_TIMEZONE]?.trim()
?.takeIf { availableZoneIds.contains(it) }
?: throw MTLog.Fatal("Invalid GAgency from $line!"),
agencyLang = line[AGENCY_LANG],
agencyPhone = line[AGENCY_PHONE],
agencyFareUrl = line[AGENCY_FARE_URL],
Expand Down
26 changes: 24 additions & 2 deletions src/main/java/org/mtransit/parser/gtfs/data/GStop.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ data class GStop(
val stopCode: String,
val locationType: GLocationType,
val parentStationIdInt: Int?,
val stopTimezone: String?,
Comment thread
mmathieum marked this conversation as resolved.
var wheelchairBoarding: GWheelchairBoardingType,
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
) {

Expand All @@ -29,6 +30,7 @@ data class GStop(
stopCode: String,
locationType: Int?,
parentStationId: StopId?,
stopTimezone: String?,
wheelchairBoarding: Int?,
) : this(
GIDs.getInt(stopId),
Expand All @@ -38,6 +40,7 @@ data class GStop(
stopCode,
GLocationType.parse(locationType),
parentStationId?.let { GIDs.getInt(it) },
stopTimezone,
GWheelchairBoardingType.parse(wheelchairBoarding),
)

Expand Down Expand Up @@ -92,16 +95,19 @@ data class GStop(
stopUrl = null, // TODO
locationType = locationType.id,
parentStationId = _parentStationId,
stopTimezone = stopTimezone,
wheelchairBoarding = wheelchairBoarding.id,
)

fun clone(
stopLat: Double,
stopLong: Double,
stopTimezone: String?,
wheelchairBoarding: GWheelchairBoardingType,
) = this.copy(
stopLat = stopLat,
stopLong = stopLong,
stopTimezone = stopTimezone,
wheelchairBoarding = wheelchairBoarding,
)

Expand All @@ -115,11 +121,12 @@ data class GStop(
private const val STOP_CODE = "stop_code"
internal const val LOCATION_TYPE = "location_type"
private const val PARENT_STATION = "parent_station"
private const val STOP_TIMEZONE = "stop_timezone"
private const val WHEELCHAIR_BOARDING = "wheelchair_boarding"

@JvmOverloads
@JvmStatic
fun fromLine(line: Map<String, String>, agencyTools: GAgencyTools? = null) = GStop(
fun fromLine(line: Map<String, String>, agencyTimezone: String?, availableZoneIds: Set<String>, agencyTools: GAgencyTools? = null) = GStop(
stopId = line[STOP_ID]?.trim()
?.let { agencyTools?.cleanStopOriginalId(it) ?: it }
?: throw MTLog.Fatal("Invalid GStop from $line!"),
Expand All @@ -130,6 +137,14 @@ data class GStop(
locationType = line[LOCATION_TYPE]?.takeIf { it.isNotBlank() }?.toInt(),
parentStationId = line[PARENT_STATION]?.takeIf { it.isNotBlank() }?.trim()
?.let { agencyTools?.cleanStopOriginalId(it) ?: it },
stopTimezone = line[STOP_TIMEZONE]?.trim()
?.takeIf { it.isNotBlank() }
?.also { gStopTimezone ->
if (!availableZoneIds.contains(gStopTimezone)) {
throw MTLog.Fatal("Invalid stop timezone in $line!")
}
}
?.takeIf { it != agencyTimezone },
wheelchairBoarding = line[WHEELCHAIR_BOARDING]?.takeIf { it.isNotBlank() }?.toInt(),
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
)

Expand All @@ -146,6 +161,7 @@ data class GStop(
stopCode = it.stopCode ?: EMPTY,
locationType = it.locationType,
parentStationId = it.parentStationId,
stopTimezone = it.stopTimezone,
wheelchairBoarding = it.wheelchairBoarding,
)
}
Expand All @@ -154,5 +170,11 @@ data class GStop(
fun mergeLocation(loc1: Double, loc2: Double): Double {
return floor((loc1 + loc2) / 2.00)
}

@JvmStatic
fun mergeTimezone(tz1: String?, tz2: String?): String? {
if (tz1 == tz2) return tz1 // only kept if same
return null // will use agency TZ
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ private HashMap<Long, String> parseGTripStops(
gStop.getStopLong(),
gStop.getWheelchairBoarding().getId(),
gStop.getStopId(),
gStop.getStopTimezone(),
this.agencyTools
));
}
Expand Down
25 changes: 16 additions & 9 deletions src/main/java/org/mtransit/parser/mt/data/MStop.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.mtransit.commons.FeatureFlags
import org.mtransit.commons.GTFSCommons
import org.mtransit.commons.sql.SQLUtils
import org.mtransit.parser.db.SQLUtils.quotesEscape
import org.mtransit.parser.db.SQLUtils.quotesEscapeId
import org.mtransit.parser.gtfs.GAgencyTools
import org.mtransit.parser.mt.MDataChangedManager

Expand All @@ -15,6 +16,7 @@ data class MStop(
val lng: Double,
val accessible: Int,
private val originalIdHash: Int,
val timeZoneId: String?,
) : Comparable<MStop> {
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.

constructor(
Expand All @@ -25,6 +27,7 @@ data class MStop(
lng: Double,
accessible: Int,
originalId: String,
timeZoneId: String?,
agencyTools: GAgencyTools? = null,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
) : this(
id,
Expand All @@ -34,21 +37,25 @@ data class MStop(
lng,
accessible,
GTFSCommons.stringIdToHash(originalId),
timeZoneId
)

fun hasLat() = lat != 0.0

fun hasLng() = lng != 0.0

fun toFile() = listOf(
id.toString(), // ID
code.quotesEscape(), // code
name.toStringIds(FeatureFlags.F_EXPORT_STRINGS).quotesEscape(), // name
MDataChangedManager.avoidLatLngChanged(lat), // latitude
MDataChangedManager.avoidLatLngChanged(lng), // longitude
accessible.toString(),
originalIdHash.toString(), // original ID hash
).joinToString(SQLUtils.COLUMN_SEPARATOR)
fun toFile() = buildList {
add(id.toString()) // ID
add(code.quotesEscape()) // code
add(name.toStringIds(FeatureFlags.F_EXPORT_STRINGS).quotesEscape()) // name
add(MDataChangedManager.avoidLatLngChanged(lat)) // latitude
add(MDataChangedManager.avoidLatLngChanged(lng)) // longitude
add(accessible.toString())
add(originalIdHash.toString()) // original ID hash
if (FeatureFlags.F_EXPORT_STOP_TIMEZONE_ID) {
add(timeZoneId.orEmpty().quotesEscapeId()) // time zone ID (can contain "_")
}
}.joinToString(SQLUtils.COLUMN_SEPARATOR)

override fun compareTo(other: MStop): Int {
return id - other.id
Expand Down
Loading