All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentripplanner.service.realtimevehicles.internal.DefaultRealtimeVehicleService Maven / Gradle / Ivy

The newest version!
package org.opentripplanner.service.realtimevehicles.internal;

import static org.opentripplanner.transit.model.timetable.OccupancyStatus.NO_DATA_AVAILABLE;

import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import java.time.Instant;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.opentripplanner.service.realtimevehicles.RealtimeVehicleRepository;
import org.opentripplanner.service.realtimevehicles.RealtimeVehicleService;
import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.network.TripPattern;
import org.opentripplanner.transit.model.timetable.OccupancyStatus;
import org.opentripplanner.transit.model.timetable.Trip;
import org.opentripplanner.transit.service.TransitService;

@Singleton
public class DefaultRealtimeVehicleService
  implements RealtimeVehicleService, RealtimeVehicleRepository {

  private final Map> vehicles = new ConcurrentHashMap<>();

  private final TransitService transitService;

  @Inject
  public DefaultRealtimeVehicleService(TransitService transitService) {
    this.transitService = transitService;
  }

  /**
   * Stores the relationship between a list of realtime vehicles with a pattern. If the pattern is
   * a realtime-added one, then the original (scheduled) one is used as the key for the map storing
   * the information.
   */
  @Override
  public void setRealtimeVehicles(TripPattern pattern, List updates) {
    if (pattern.getOriginalTripPattern() != null) {
      pattern = pattern.getOriginalTripPattern();
    }
    vehicles.put(pattern, List.copyOf(updates));
  }

  @Override
  public void clearRealtimeVehicles(TripPattern pattern) {
    vehicles.remove(pattern);
  }

  /**
   * Gets the realtime vehicles for a given pattern. If the pattern is a realtime-added one
   * then the original (scheduled) one is used for the lookup instead, so you receive the correct
   * result no matter if you use the realtime or static information.
   *
   * @see DefaultRealtimeVehicleService#setRealtimeVehicles(TripPattern, List)
   */
  @Override
  public List getRealtimeVehicles(TripPattern pattern) {
    if (pattern.getOriginalTripPattern() != null) {
      pattern = pattern.getOriginalTripPattern();
    }
    // the list is made immutable during insertion, so we can safely return them
    return vehicles.getOrDefault(pattern, List.of());
  }

  @Override
  public OccupancyStatus getVehicleOccupancyStatus(Trip trip) {
    return getOccupancyStatus(trip.getId(), transitService.findPattern(trip));
  }

  /**
   * Get the latest occupancy status for a certain trip. Service contains all the vehicles that
   * exist in input feeds but doesn't store any historical data. This method is an alternative to
   * {@link #getVehicleOccupancyStatus(Trip)} and works even when {@link TransitService} is not
   * provided to the service.
   */
  public OccupancyStatus getOccupancyStatus(FeedScopedId tripId, TripPattern pattern) {
    return vehicles
      .getOrDefault(pattern, List.of())
      .stream()
      .filter(vehicle -> tripId.equals(vehicle.trip().getId()))
      .max(Comparator.comparing(vehicle -> vehicle.time().orElse(Instant.MIN)))
      .flatMap(RealtimeVehicle::occupancyStatus)
      .orElse(NO_DATA_AVAILABLE);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy