listNextStopTimeForRoute method

Future<List<({Date date, StopTime time})>> listNextStopTimeForRoute(
  1. GtfsDataset dataset,
  2. Route route,
  3. Stop stop, {
  4. LoadCriterion? tripCriterion,
  5. LoadCriterion? stopTimesCriterion,
})

Implementation

Future<List<({StopTime time, Date date})>> listNextStopTimeForRoute(
  GtfsDataset dataset,
  Route route,
  Stop stop, {
  LoadCriterion? tripCriterion,
  LoadCriterion? stopTimesCriterion,
}) async {
  late BaseCSVFile trips;
  final now = DateTime.now();
  final today = Date.fromDatetime(now);
  final next24Hours = now.add(Duration(days: 1));
  final tomorrow = Date.fromDatetime(next24Hours);
  Date currentTestingDay = today;

  final List<({StopTime time, Date date})> foundStopTimes = [];

  final defaultTripCriterion = LoadCriterion([
    'route_id',
  ], (requestedFields) => requestedFields[0] == route.id);
  if (tripCriterion == null) {
    tripCriterion = defaultTripCriterion;
  } else {
    tripCriterion = LoadCriterion.and(defaultTripCriterion, tripCriterion);
  }

  late List<Map<String, String>> currentTrips;

  final defaultStopTimesCriterion = LoadCriterion(
    ['trip_id', 'departure_time', 'stop_id'],
    (requestedFields) {
      if (!currentTrips.any(
            (element) => element['trip_id'] == requestedFields[0],
          ) ||
          requestedFields[2] != stop.id) {
        return false;
      }
      final time = Time.parse(
        requestedFields[1]!,
      ).relativeToDate(currentTestingDay);

      return time.isAfter(now) && time.isBefore(next24Hours);
    },
  );

  if (stopTimesCriterion == null) {
    stopTimesCriterion = defaultStopTimesCriterion;
  } else {
    stopTimesCriterion = LoadCriterion.and(
      defaultStopTimesCriterion,
      stopTimesCriterion,
    );
  }

  trips = await dataset.trips.listRawResource(criteria: tripCriterion);

  final totalActiveServices = await dataset.calendar.listServicesForDateRange(
    now,
    next24Hours,
  );

  for (final dayToTest in [today, tomorrow]) {
    currentTestingDay = dayToTest;
    currentTrips = trips
        .where(
          (element) =>
              totalActiveServices[dayToTest]!.contains(element['service_id']),
        )
        .toList(growable: false);

    await for (final stopTime in dataset.stopTimes.streamResource(
      stopTimesCriterion,
    )) {
      foundStopTimes.add((time: stopTime, date: currentTestingDay));
    }
  }

  return foundStopTimes;
}