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

org.opentripplanner.updater.vehicle_rental.datasources.GbfsVehicleRentalDataSource Maven / Gradle / Ivy

The newest version!
package org.opentripplanner.updater.vehicle_rental.datasources;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.mobilitydata.gbfs.v2_3.free_bike_status.GBFSFreeBikeStatus;
import org.mobilitydata.gbfs.v2_3.geofencing_zones.GBFSGeofencingZones;
import org.mobilitydata.gbfs.v2_3.station_information.GBFSStationInformation;
import org.mobilitydata.gbfs.v2_3.station_status.GBFSStation;
import org.mobilitydata.gbfs.v2_3.station_status.GBFSStationStatus;
import org.mobilitydata.gbfs.v2_3.system_information.GBFSSystemInformation;
import org.mobilitydata.gbfs.v2_3.vehicle_types.GBFSVehicleType;
import org.mobilitydata.gbfs.v2_3.vehicle_types.GBFSVehicleTypes;
import org.opentripplanner.framework.application.OTPFeature;
import org.opentripplanner.framework.io.OtpHttpClient;
import org.opentripplanner.framework.io.OtpHttpClientFactory;
import org.opentripplanner.service.vehiclerental.model.GeofencingZone;
import org.opentripplanner.service.vehiclerental.model.RentalVehicleType;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem;
import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters;
import org.opentripplanner.updater.vehicle_rental.datasources.params.RentalPickupType;
import org.opentripplanner.utils.tostring.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by demory on 2017-03-14.
 * 

* Leaving OTPFeature.FloatingBike turned off both prevents floating bike updaters added to * router-config.json from being used, but more importantly, floating bikes added by a * VehicleRentalServiceDirectoryFetcher endpoint (which may be outside our control) will not be * used. */ class GbfsVehicleRentalDataSource implements VehicleRentalDatasource { private static final Logger LOG = LoggerFactory.getLogger(GbfsVehicleRentalDataSource.class); private final GbfsVehicleRentalDataSourceParameters params; private final OtpHttpClient otpHttpClient; private GbfsFeedLoader loader; private List geofencingZones = List.of(); private boolean logGeofencingZonesDoesNotExistWarning = true; public GbfsVehicleRentalDataSource( GbfsVehicleRentalDataSourceParameters parameters, OtpHttpClientFactory otpHttpClientFactory ) { this.params = parameters; this.otpHttpClient = otpHttpClientFactory.create(LOG); } @Override public boolean update() { if (loader == null) { return false; } return loader.update(); } @Override public List getUpdates() { // Get system information GBFSSystemInformation systemInformation = loader.getFeed(GBFSSystemInformation.class); GbfsSystemInformationMapper systemInformationMapper = new GbfsSystemInformationMapper(); VehicleRentalSystem system = systemInformationMapper.mapSystemInformation( systemInformation.getData(), params.network() ); // Get vehicle types final Map vehicleTypes = getVehicleTypes(system); List stations = new LinkedList<>(); if (params.allowRentalType(RentalPickupType.STATION)) { // Both station information and status are required for all systems using stations GBFSStationInformation stationInformation = loader.getFeed(GBFSStationInformation.class); GBFSStationStatus stationStatus = loader.getFeed(GBFSStationStatus.class); if (stationInformation != null && stationStatus != null) { // Index all the station status entries on their station ID. Map statusLookup = stationStatus .getData() .getStations() .stream() .collect(Collectors.toMap(GBFSStation::getStationId, Function.identity())); GbfsStationStatusMapper stationStatusMapper = new GbfsStationStatusMapper( statusLookup, vehicleTypes ); GbfsStationInformationMapper stationInformationMapper = new GbfsStationInformationMapper( system, vehicleTypes, params.allowKeepingRentedVehicleAtDestination(), params.overloadingAllowed() ); // Iterate over all known stations, and if we have any status information add it to those station objects. stations.addAll( stationInformation .getData() .getStations() .stream() .map(stationInformationMapper::mapStationInformation) .filter(Objects::nonNull) .peek(stationStatusMapper::fillStationStatus) .toList() ); } } // Append the floating bike stations. if (OTPFeature.FloatingBike.isOn() && params.allowRentalType(RentalPickupType.FREE_FLOATING)) { GBFSFreeBikeStatus freeBikeStatus = loader.getFeed(GBFSFreeBikeStatus.class); if (freeBikeStatus != null) { GbfsFreeVehicleStatusMapper freeVehicleStatusMapper = new GbfsFreeVehicleStatusMapper( system, vehicleTypes ); stations.addAll( freeBikeStatus .getData() .getBikes() .stream() .map(freeVehicleStatusMapper::mapFreeVehicleStatus) .filter(Objects::nonNull) .toList() ); } } if (params.geofencingZones()) { var zones = loader.getFeed(GBFSGeofencingZones.class); if (zones != null) { var mapper = new GbfsGeofencingZoneMapper(system.systemId); this.geofencingZones = mapper.mapGeofencingZone(zones); } else { if (logGeofencingZonesDoesNotExistWarning) { LOG.warn( "GeofencingZones is enabled in OTP, but no zones exist for network: {}", params.network() ); } logGeofencingZonesDoesNotExistWarning = false; } } return stations; } @Override public void setup() { loader = new GbfsFeedLoader( params.url(), params.httpHeaders(), params.language(), otpHttpClient ); } @Override public String toString() { return ToStringBuilder.of(GbfsVehicleRentalDataSource.class) .addStr("url", params.url()) .addStr("language", params.language()) .addBoolIfTrue( "allowKeepingRentedVehicleAtDestination", params.allowKeepingRentedVehicleAtDestination() ) .toString(); } @Override public List getGeofencingZones() { return this.geofencingZones; } protected static Map mapVehicleTypes( GbfsVehicleTypeMapper vehicleTypeMapper, List gbfsVehicleTypes ) { return gbfsVehicleTypes .stream() .map(vehicleTypeMapper::mapRentalVehicleType) .distinct() .collect(Collectors.toMap(v -> v.id.getId(), Function.identity())); } private Map getVehicleTypes(VehicleRentalSystem system) { GBFSVehicleTypes rawVehicleTypes = loader.getFeed(GBFSVehicleTypes.class); if (rawVehicleTypes != null) { GbfsVehicleTypeMapper vehicleTypeMapper = new GbfsVehicleTypeMapper(system.systemId); List gbfsVehicleTypes = rawVehicleTypes.getData().getVehicleTypes(); return mapVehicleTypes(vehicleTypeMapper, gbfsVehicleTypes); } return Map.of(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy