org.opentripplanner.updater.bike_rental.datasources.GbfsBikeRentalDataSource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.updater.bike_rental.datasources;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Sets;
import org.opentripplanner.routing.bike_rental.BikeRentalStation;
import org.opentripplanner.updater.bike_rental.BikeRentalDataSource;
import org.opentripplanner.updater.bike_rental.datasources.params.GbfsBikeRentalDataSourceParameters;
import org.opentripplanner.util.NonLocalizedString;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Created by demory on 2017-03-14.
*/
class GbfsBikeRentalDataSource implements BikeRentalDataSource {
// station_information.json required by GBFS spec
private final GbfsStationDataSource stationInformationSource;
// station_status.json required by GBFS spec
private final GbfsStationStatusDataSource stationStatusSource;
// free_bike_status.json declared OPTIONAL by GBFS spec
private final GbfsFloatingBikeDataSource floatingBikeSource;
private final String networkName;
/** Some car rental systems and flex transit systems work exactly like bike rental, but with cars. */
private final boolean routeAsCar;
public GbfsBikeRentalDataSource (GbfsBikeRentalDataSourceParameters parameters) {
routeAsCar = parameters.routeAsCar();
stationInformationSource = new GbfsStationDataSource(parameters);
stationStatusSource = new GbfsStationStatusDataSource(parameters);
floatingBikeSource = new GbfsFloatingBikeDataSource(parameters);
setBaseUrl(parameters.getUrl());
this.networkName = parameters.getNetwork("GBFS");
}
// TODO This should be updated to fetch the endpoints defined in gbfs.json
private void setBaseUrl (String url) {
String baseUrl = url;
if (!baseUrl.endsWith("/")) baseUrl += "/";
stationInformationSource.setUrl(baseUrl + "station_information.json");
stationStatusSource.setUrl(baseUrl + "station_status.json");
floatingBikeSource.setUrl(baseUrl + "free_bike_status.json");
}
@Override
public boolean update() {
// These first two GBFS files are required.
boolean updatesFound = stationInformationSource.update();
updatesFound |= stationStatusSource.update();
// This floating-bikes file is optional, and does not appear in all GBFS feeds.
updatesFound |= floatingBikeSource.update();
// Return true if ANY of the sub-updaters found any updates.
return updatesFound;
}
@Override
public List getStations() {
// Index all the station status entries on their station ID.
Map statusLookup = new HashMap<>();
for (BikeRentalStation station : stationStatusSource.getStations()) {
statusLookup.put(station.id, station);
}
// Iterate over all known stations, and if we have any status information add it to those station objects.
for (BikeRentalStation station : stationInformationSource.getStations()) {
if (!statusLookup.containsKey(station.id)) continue;
BikeRentalStation status = statusLookup.get(station.id);
station.bikesAvailable = status.bikesAvailable;
station.spacesAvailable = status.spacesAvailable;
}
// Copy the full list of station objects (with status updates) into a List, appending the floating bike stations.
List stations = new LinkedList<>(stationInformationSource.getStations());
stations.addAll(floatingBikeSource.getStations());
// Set identical network ID on all stations
Set networkIdSet = Sets.newHashSet(this.networkName);
for (BikeRentalStation station : stations) station.networks = networkIdSet;
return stations;
}
class GbfsStationDataSource extends GenericJsonBikeRentalDataSource {
public GbfsStationDataSource (GbfsBikeRentalDataSourceParameters config) {
super(config, "data/stations");
}
@Override
public BikeRentalStation makeStation(JsonNode stationNode) {
BikeRentalStation brstation = new BikeRentalStation();
brstation.id = stationNode.path("station_id").asText();
brstation.x = stationNode.path("lon").asDouble();
brstation.y = stationNode.path("lat").asDouble();
brstation.name = new NonLocalizedString(stationNode.path("name").asText());
brstation.isCarStation = routeAsCar;
return brstation;
}
}
class GbfsStationStatusDataSource extends GenericJsonBikeRentalDataSource {
public GbfsStationStatusDataSource (GbfsBikeRentalDataSourceParameters config) {
super(config, "data/stations");
}
@Override
public BikeRentalStation makeStation(JsonNode stationNode) {
BikeRentalStation brstation = new BikeRentalStation();
brstation.id = stationNode.path("station_id").asText();
brstation.bikesAvailable = stationNode.path("num_bikes_available").asInt();
brstation.spacesAvailable = stationNode.path("num_docks_available").asInt();
brstation.isCarStation = routeAsCar;
return brstation;
}
}
class GbfsFloatingBikeDataSource extends GenericJsonBikeRentalDataSource {
public GbfsFloatingBikeDataSource (GbfsBikeRentalDataSourceParameters config) {
super(config, "data/bikes");
}
@Override
public BikeRentalStation makeStation(JsonNode stationNode) {
BikeRentalStation brstation = new BikeRentalStation();
brstation.id = stationNode.path("bike_id").asText();
brstation.name = new NonLocalizedString(stationNode.path("name").asText());
brstation.x = stationNode.path("lon").asDouble();
brstation.y = stationNode.path("lat").asDouble();
brstation.bikesAvailable = 1;
brstation.spacesAvailable = 0;
brstation.allowDropoff = false;
brstation.isFloatingBike = true;
brstation.isCarStation = routeAsCar;
return brstation;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy