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

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

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.entur.gbfs.v2_2.free_bike_status.GBFSFreeBikeStatus;
import org.entur.gbfs.v2_2.station_information.GBFSStationInformation;
import org.entur.gbfs.v2_2.station_status.GBFSStation;
import org.entur.gbfs.v2_2.station_status.GBFSStationStatus;
import org.entur.gbfs.v2_2.system_information.GBFSSystemInformation;
import org.entur.gbfs.v2_2.vehicle_types.GBFSVehicleTypes;
import org.opentripplanner.model.base.ToStringBuilder;
import org.opentripplanner.routing.vehicle_rental.RentalVehicleType;
import org.opentripplanner.routing.vehicle_rental.VehicleRentalPlace;
import org.opentripplanner.routing.vehicle_rental.VehicleRentalSystem;
import org.opentripplanner.updater.DataSource;
import org.opentripplanner.updater.vehicle_rental.datasources.params.GbfsVehicleRentalDataSourceParameters;
import org.opentripplanner.util.OTPFeature;
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 DataSource {

    private static final Logger LOG = LoggerFactory.getLogger(GbfsVehicleRentalDataSource.class);

    private final String url;

    private final String language;

    private final Map httpHeaders;

    /** Is it possible to arrive at the destination with a rented bicycle, without dropping it off */
    private final boolean allowKeepingRentedVehicleAtDestination;

    private GbfsFeedLoader loader;

    public GbfsVehicleRentalDataSource(GbfsVehicleRentalDataSourceParameters parameters) {
        url = parameters.getUrl();
        language = parameters.language();
        httpHeaders = parameters.getHttpHeaders();
        allowKeepingRentedVehicleAtDestination = parameters.allowKeepingRentedVehicleAtDestination();
    }

    @Override
    public void setup() {
        loader = new GbfsFeedLoader(url, httpHeaders, language);
    }

    @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());

        // Get vehicle types
        Map vehicleTypes = null;
        GBFSVehicleTypes rawVehicleTypes = loader.getFeed(GBFSVehicleTypes.class);
        if (rawVehicleTypes != null) {
            GbfsVehicleTypeMapper vehicleTypeMapper = new GbfsVehicleTypeMapper(system.systemId);
            vehicleTypes = rawVehicleTypes.getData().getVehicleTypes().stream()
                    .map(vehicleTypeMapper::mapRentalVehicleType)
                    .collect(Collectors.toMap(v -> v.id.getId(), Function.identity()));
        }

        List stations = new LinkedList<>();

        // 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, allowKeepingRentedVehicleAtDestination);

            // 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)
                    .peek(stationStatusMapper::fillStationStatus)
                    .collect(Collectors.toList())
            );
        }

        // Append the floating bike stations.
        if (OTPFeature.FloatingBike.isOn()) {
            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)
                        .collect(Collectors.toList())
                );
            }
        }

        return stations;
    }

    @Override
    public String toString() {
        return ToStringBuilder.of(GbfsVehicleRentalDataSource.class)
                .addStr("url", url)
                .addStr("language", language)
                .addBoolIfTrue("allowKeepingRentedVehicleAtDestination", allowKeepingRentedVehicleAtDestination)
                .toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy