Skip to content

Commit

Permalink
Merge pull request opentripplanner#5909 from HSLdevcom/rentalvehicle-…
Browse files Browse the repository at this point in the history
…details

Add rental system to GraphQL API
  • Loading branch information
optionsome authored Jul 8, 2024
2 parents 9554487 + 87bda74 commit e508838
Show file tree
Hide file tree
Showing 32 changed files with 396 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.opentripplanner.service.vehiclerental.model.RentalVehicleType;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.updater.spi.DataSource;
import org.opentripplanner.updater.spi.GenericJsonDataSource;
Expand All @@ -32,6 +33,7 @@ public class SmooveBikeRentalDataSource

private final String networkName;
private final RentalVehicleType vehicleType;
private final VehicleRentalSystem system;

public SmooveBikeRentalDataSource(SmooveBikeRentalDataSourceParameters config) {
this(config, new OtpHttpClientFactory());
Expand All @@ -45,6 +47,24 @@ public SmooveBikeRentalDataSource(
networkName = config.getNetwork(DEFAULT_NETWORK_NAME);
vehicleType = RentalVehicleType.getDefaultType(networkName);
overloadingAllowed = config.overloadingAllowed();
system =
new VehicleRentalSystem(
networkName,
"fi",
"Helsinki/Espoo",
null,
null,
null,
null,
null,
null,
null,
null,
"Europe/Helsinki",
null,
null,
null
);
}

/**
Expand Down Expand Up @@ -94,6 +114,7 @@ protected VehicleRentalStation parseElement(JsonNode node) {
station.vehicleTypesAvailable = Map.of(vehicleType, station.vehiclesAvailable);
station.vehicleSpacesAvailable = Map.of(vehicleType, station.spacesAvailable);
station.overloadingAllowed = overloadingAllowed;
station.system = system;
return station;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import org.opentripplanner.apis.gtfs.datafetchers.UnknownImpl;
import org.opentripplanner.apis.gtfs.datafetchers.VehicleParkingImpl;
import org.opentripplanner.apis.gtfs.datafetchers.VehiclePositionImpl;
import org.opentripplanner.apis.gtfs.datafetchers.VehicleRentalNetworkImpl;
import org.opentripplanner.apis.gtfs.datafetchers.VehicleRentalStationImpl;
import org.opentripplanner.apis.gtfs.datafetchers.debugOutputImpl;
import org.opentripplanner.apis.gtfs.datafetchers.elevationProfileComponentImpl;
Expand Down Expand Up @@ -166,6 +167,7 @@ protected static GraphQLSchema buildSchema() {
.type(typeWiring.build(BookingTimeImpl.class))
.type(typeWiring.build(BookingInfoImpl.class))
.type(typeWiring.build(VehicleRentalStationImpl.class))
.type(typeWiring.build(VehicleRentalNetworkImpl.class))
.type(typeWiring.build(RentalVehicleImpl.class))
.type(typeWiring.build(RentalVehicleTypeImpl.class))
.type(typeWiring.build(StopOnRouteImpl.class))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ public DataFetcher<Connection<PlaceAtDistance>> nearest() {
List<PlaceType> filterByPlaceTypes = args.getGraphQLFilterByPlaceTypes() != null
? args.getGraphQLFilterByPlaceTypes().stream().map(GraphQLUtils::toModel).toList()
: DEFAULT_PLACE_TYPES;
List<String> filterByNetwork = args.getGraphQLFilterByNetwork();

List<PlaceAtDistance> places;
try {
Expand All @@ -347,6 +348,7 @@ public DataFetcher<Connection<PlaceAtDistance>> nearest() {
filterByStations,
filterByRoutes,
filterByBikeRentalStations,
filterByNetwork,
getTransitService(environment)
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers;
import org.opentripplanner.service.vehiclerental.model.RentalVehicleType;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle;

public class RentalVehicleImpl implements GraphQLDataFetchers.GraphQLRentalVehicle {
Expand Down Expand Up @@ -61,6 +62,11 @@ public DataFetcher<RentalVehicleType> vehicleType() {
return environment -> getSource(environment).vehicleType;
}

@Override
public DataFetcher<VehicleRentalSystem> rentalNetwork() {
return environment -> getSource(environment).getVehicleRentalSystem();
}

private VehicleRentalVehicle getSource(DataFetchingEnvironment environment) {
return environment.getSource();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.opentripplanner.apis.gtfs.datafetchers;

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem;

public class VehicleRentalNetworkImpl implements GraphQLDataFetchers.GraphQLVehicleRentalNetwork {

@Override
public DataFetcher<String> networkId() {
return environment -> getSource(environment).systemId;
}

@Override
public DataFetcher<String> url() {
return environment -> getSource(environment).url;
}

private VehicleRentalSystem getSource(DataFetchingEnvironment environment) {
return environment.getSource();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.opentripplanner.service.vehiclerental.model.RentalVehicleEntityCounts;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem;

public class VehicleRentalStationImpl implements GraphQLDataFetchers.GraphQLVehicleRentalStation {

Expand Down Expand Up @@ -107,6 +108,11 @@ public DataFetcher<RentalVehicleEntityCounts> availableSpaces() {
return environment -> getSource(environment).getVehicleSpaceCounts();
}

@Override
public DataFetcher<VehicleRentalSystem> rentalNetwork() {
return environment -> getSource(environment).getVehicleRentalSystem();
}

private VehicleRentalStation getSource(DataFetchingEnvironment environment) {
return environment.getSource();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem;
import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle;
import org.opentripplanner.transit.model.basic.Money;
import org.opentripplanner.transit.model.network.Route;
Expand Down Expand Up @@ -852,6 +853,8 @@ public interface GraphQLRentalVehicle {

public DataFetcher<Boolean> operative();

public DataFetcher<VehicleRentalSystem> rentalNetwork();

public DataFetcher<VehicleRentalStationUris> rentalUris();

public DataFetcher<String> vehicleId();
Expand Down Expand Up @@ -1266,6 +1269,17 @@ public interface GraphQLVehiclePosition {
public DataFetcher<String> vehicleId();
}

/**
* Vehicle rental network, which is referred as system in the GBFS terminology. Note, the same operator can operate in multiple
* regions either with the same network/system or with a different one. This can contain information about either the rental brand
* or about the operator.
*/
public interface GraphQLVehicleRentalNetwork {
public DataFetcher<String> networkId();

public DataFetcher<String> url();
}

/** Vehicle rental station represents a location where users can rent bicycles etc. for a fee. */
public interface GraphQLVehicleRentalStation {
public DataFetcher<Boolean> allowDropoff();
Expand Down Expand Up @@ -1298,6 +1312,8 @@ public interface GraphQLVehicleRentalStation {

public DataFetcher<Boolean> realtime();

public DataFetcher<VehicleRentalSystem> rentalNetwork();

public DataFetcher<VehicleRentalStationUris> rentalUris();

public DataFetcher<Integer> spacesAvailable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2409,6 +2409,7 @@ public static class GraphQLQueryTypeNearestArgs {
private String before;
private GraphQLInputFiltersInput filterByIds;
private List<GraphQLMode> filterByModes;
private List<String> filterByNetwork;
private List<GraphQLFilterPlaceType> filterByPlaceTypes;
private Integer first;
private Integer last;
Expand All @@ -2430,6 +2431,7 @@ public GraphQLQueryTypeNearestArgs(Map<String, Object> args) {
.map(GraphQLMode.class::cast)
.collect(Collectors.toList());
}
this.filterByNetwork = (List<String>) args.get("filterByNetwork");
if (args.get("filterByPlaceTypes") != null) {
this.filterByPlaceTypes =
((List<Object>) args.get("filterByPlaceTypes")).stream()
Expand Down Expand Up @@ -2466,6 +2468,10 @@ public List<GraphQLMode> getGraphQLFilterByModes() {
return this.filterByModes;
}

public List<String> getGraphQLFilterByNetwork() {
return this.filterByNetwork;
}

public List<GraphQLFilterPlaceType> getGraphQLFilterByPlaceTypes() {
return this.filterByPlaceTypes;
}
Expand Down Expand Up @@ -2510,6 +2516,10 @@ public void setGraphQLFilterByModes(List<GraphQLMode> filterByModes) {
this.filterByModes = filterByModes;
}

public void setGraphQLFilterByNetwork(List<String> filterByNetwork) {
this.filterByNetwork = filterByNetwork;
}

public void setGraphQLFilterByPlaceTypes(List<GraphQLFilterPlaceType> filterByPlaceTypes) {
this.filterByPlaceTypes = filterByPlaceTypes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ config:
BikeRentalStation: org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace#VehicleRentalPlace
BikeRentalStationUris: org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris#VehicleRentalStationUris
VehicleRentalStation: org.opentripplanner.service.vehiclerental.model.VehicleRentalStation#VehicleRentalStation
VehicleRentalNetwork: org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem#VehicleRentalSystem
RentalVehicleEntityCounts: org.opentripplanner.service.vehiclerental.model.RentalVehicleEntityCounts#RentalVehicleEntityCounts
RentalVehicleTypeCount: org.opentripplanner.service.vehiclerental.model.RentalVehicleTypeCount#RentalVehicleTypeCount
RentalVehicle: org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle#VehicleRentalVehicle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ private GraphQLSchema create() {
List<String> filterByBikeRentalStations = null;
List<String> filterByBikeParks = null;
List<String> filterByCarParks = null;
List<String> filterByNetwork = null;
@SuppressWarnings("rawtypes")
Map filterByIds = environment.getArgument("filterByIds");
if (filterByIds != null) {
Expand Down Expand Up @@ -960,6 +961,7 @@ private GraphQLSchema create() {
filterByStations,
filterByRoutes,
filterByBikeRentalStations,
filterByNetwork,
GqlUtil.getTransitService(environment)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ public interface LayerParameters<T extends Enum<T>> {
int MAX_ZOOM = 20;
int CACHE_MAX_SECONDS = -1;
double EXPANSION_FACTOR = 0.25d;

/**
* User-visible name of the layer
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public List<PlaceAtDistance> findClosestPlaces(
List<FeedScopedId> filterByStations,
List<FeedScopedId> filterByRoutes,
List<String> filterByBikeRentalStations,
List<String> filterByNetwork,
TransitService transitService
) {
throw new UnsupportedOperationException("Not implemented");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ List<PlaceAtDistance> findClosestPlaces(
List<FeedScopedId> filterByStations,
List<FeedScopedId> filterByRoutes,
List<String> filterByBikeRentalStations,
List<String> filterByNetwork,
TransitService transitService
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class PlaceFinderTraverseVisitor implements TraverseVisitor<State, Edge>
private final Set<FeedScopedId> filterByStops;
private final Set<FeedScopedId> filterByStations;
private final Set<FeedScopedId> filterByRoutes;
private final Set<String> filterByNetwork;
private final Set<String> filterByVehicleRental;
private final Set<String> seenPatternAtStops = new HashSet<>();
private final Set<FeedScopedId> seenStops = new HashSet<>();
Expand Down Expand Up @@ -69,6 +70,7 @@ public PlaceFinderTraverseVisitor(
List<FeedScopedId> filterByStations,
List<FeedScopedId> filterByRoutes,
List<String> filterByBikeRentalStations,
List<String> filterByNetwork,
int maxResults,
double radiusMeters
) {
Expand All @@ -82,6 +84,7 @@ public PlaceFinderTraverseVisitor(
this.filterByStations = toSet(filterByStations);
this.filterByRoutes = toSet(filterByRoutes);
this.filterByVehicleRental = toSet(filterByBikeRentalStations);
this.filterByNetwork = toSet(filterByNetwork);
includeStops = shouldInclude(filterByPlaceTypes, PlaceType.STOP);

includePatternAtStops = shouldInclude(filterByPlaceTypes, PlaceType.PATTERN_AT_STOP);
Expand Down Expand Up @@ -264,6 +267,9 @@ private void handleVehicleRental(VehicleRentalPlace station, double distance) {
if (seenVehicleRentalPlaces.contains(station.getId())) {
return;
}
if (!filterByNetwork.isEmpty() && !filterByNetwork.contains(station.getNetwork())) {
return;
}
seenVehicleRentalPlaces.add(station.getId());
placesFound.add(new PlaceAtDistance(station, distance));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public List<PlaceAtDistance> findClosestPlaces(
List<FeedScopedId> filterByStations,
List<FeedScopedId> filterByRoutes,
List<String> filterByBikeRentalStations,
List<String> filterByNetwork,
TransitService transitService
) {
PlaceFinderTraverseVisitor visitor = new PlaceFinderTraverseVisitor(
Expand All @@ -66,6 +67,7 @@ public List<PlaceAtDistance> findClosestPlaces(
filterByStations,
filterByRoutes,
filterByBikeRentalStations,
filterByNetwork,
maxResults,
radiusMeters
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ public interface VehicleRentalPlace {
/** Deep links for this rental station or individual vehicle */
VehicleRentalStationUris getRentalUris();

/** System information for the vehicle rental provider */
VehicleRentalSystem getVehicleRentalSystem();

default boolean networkIsNotAllowed(VehicleRentalPreferences preferences) {
if (
getNetwork() == null &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ public VehicleRentalStationUris getRentalUris() {
return rentalUris;
}

@Override
public VehicleRentalSystem getVehicleRentalSystem() {
return system;
}

@Override
public String toString() {
return String.format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,9 @@ public boolean isRealTimeData() {
public VehicleRentalStationUris getRentalUris() {
return rentalUris;
}

@Override
public VehicleRentalSystem getVehicleRentalSystem() {
return system;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.mobilitydata.gbfs.v2_3.geofencing_zones.GBFSGeofencingZones;
import org.opentripplanner.framework.geometry.GeometryUtils;
import org.opentripplanner.framework.geometry.UnsupportedGeometryException;
import org.opentripplanner.framework.lang.StringUtils;
import org.opentripplanner.service.vehiclerental.model.GeofencingZone;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.slf4j.Logger;
Expand Down Expand Up @@ -52,6 +53,9 @@ private GeofencingZone toInternalModel(GBFSFeature f) {
return null;
}
var name = Objects.requireNonNullElseGet(f.getProperties().getName(), () -> fallbackId(g));
if (!StringUtils.hasValue(name)) {
name = fallbackId(g);
}
var dropOffBanned = !f.getProperties().getRules().get(0).getRideAllowed();
var passThroughBanned = !f.getProperties().getRules().get(0).getRideThroughAllowed();
return new GeofencingZone(
Expand Down
Loading

0 comments on commit e508838

Please sign in to comment.