Skip to content

Commit

Permalink
ENH: NAV-131 - Add trip masking based on gtfs schedule and query config.
Browse files Browse the repository at this point in the history
  • Loading branch information
clukas1 committed Aug 17, 2024
1 parent d65a4fe commit 216098f
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 36 deletions.
33 changes: 0 additions & 33 deletions src/main/java/ch/naviqore/service/gtfs/raptor/TypeMapper.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ch.naviqore.service.gtfs.raptor;

import ch.naviqore.gtfs.schedule.model.GtfsSchedule;
import ch.naviqore.gtfs.schedule.type.DefaultRouteType;
import ch.naviqore.raptor.QueryConfig;
import ch.naviqore.service.*;
import ch.naviqore.service.config.ConnectionQueryConfig;
Expand Down Expand Up @@ -133,38 +132,6 @@ public static EnumSet<ch.naviqore.raptor.TravelMode> map(EnumSet<TravelMode> tra
return raptorTravelModes;
}

public static EnumSet<DefaultRouteType> mapToRouteTypes(EnumSet<ch.naviqore.raptor.TravelMode> travelModes) {
if (travelModes == null || travelModes.isEmpty()) {
return EnumSet.allOf(DefaultRouteType.class);
}
EnumSet<DefaultRouteType> routeTypes = EnumSet.noneOf(DefaultRouteType.class);
for (ch.naviqore.raptor.TravelMode travelMode : travelModes) {
routeTypes.addAll(map(travelMode));
}
return routeTypes;
}

public static EnumSet<DefaultRouteType> map(ch.naviqore.raptor.TravelMode travelMode) {
if (travelMode.equals(ch.naviqore.raptor.TravelMode.BUS)) {
return EnumSet.of(DefaultRouteType.BUS, DefaultRouteType.TROLLEYBUS);
} else if (travelMode.equals(ch.naviqore.raptor.TravelMode.TRAM)) {
return EnumSet.of(DefaultRouteType.TRAM, DefaultRouteType.CABLE_TRAM);
} else if (travelMode.equals(ch.naviqore.raptor.TravelMode.RAIL)) {
return EnumSet.of(DefaultRouteType.RAIL, DefaultRouteType.MONORAIL);
} else if (travelMode.equals(ch.naviqore.raptor.TravelMode.SHIP)) {
return EnumSet.of(DefaultRouteType.FERRY);
} else if (travelMode.equals(ch.naviqore.raptor.TravelMode.SUBWAY)) {
return EnumSet.of(DefaultRouteType.SUBWAY);
} else if (travelMode.equals(ch.naviqore.raptor.TravelMode.AERIAL_LIFT)) {
return EnumSet.of(DefaultRouteType.AERIAL_LIFT);
} else if (travelMode.equals(ch.naviqore.raptor.TravelMode.FUNICULAR)) {
return EnumSet.of(DefaultRouteType.FUNICULAR);
} else {
// should never happen
throw new IllegalArgumentException("Travel mode not supported");
}
}

private static Leg createPublicTransitLeg(ch.naviqore.raptor.Leg leg, GtfsSchedule schedule, int distance) {
ch.naviqore.gtfs.schedule.model.Trip gtfsTrip = schedule.getTrips().get(leg.getTripId());
LocalDate serviceDay = getServiceDay(leg, gtfsTrip);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package ch.naviqore.service.gtfs.raptor.convert;

import ch.naviqore.gtfs.schedule.model.GtfsSchedule;
import ch.naviqore.gtfs.schedule.model.Route;
import ch.naviqore.gtfs.schedule.model.Trip;
import ch.naviqore.gtfs.schedule.type.AccessibilityInformation;
import ch.naviqore.gtfs.schedule.type.BikeInformation;
import ch.naviqore.gtfs.schedule.type.DefaultRouteType;
import ch.naviqore.gtfs.schedule.type.RouteTypeMapper;
import ch.naviqore.raptor.QueryConfig;
import ch.naviqore.raptor.TravelMode;
import ch.naviqore.raptor.router.RaptorTripMaskProvider;
import ch.naviqore.service.config.ServiceConfig;
import ch.naviqore.utils.cache.EvictionCache;
import lombok.Setter;

import java.time.LocalDate;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
Expand All @@ -29,6 +37,38 @@ public GtfsTripMaskProvider(GtfsSchedule schedule, int cacheSize, EvictionCache.
this.cache = new GtfsTripMaskProvider.MaskCache(cacheSize, strategy);
}

private static EnumSet<DefaultRouteType> mapToRouteTypes(EnumSet<TravelMode> travelModes) {
if (travelModes == null || travelModes.isEmpty()) {
return EnumSet.allOf(DefaultRouteType.class);
}
EnumSet<DefaultRouteType> routeTypes = EnumSet.noneOf(DefaultRouteType.class);
for (TravelMode travelMode : travelModes) {
routeTypes.addAll(map(travelMode));
}
return routeTypes;
}

private static EnumSet<DefaultRouteType> map(TravelMode travelMode) {
if (travelMode.equals(TravelMode.BUS)) {
return EnumSet.of(DefaultRouteType.BUS, DefaultRouteType.TROLLEYBUS);
} else if (travelMode.equals(TravelMode.TRAM)) {
return EnumSet.of(DefaultRouteType.TRAM, DefaultRouteType.CABLE_TRAM);
} else if (travelMode.equals(TravelMode.RAIL)) {
return EnumSet.of(DefaultRouteType.RAIL, DefaultRouteType.MONORAIL);
} else if (travelMode.equals(TravelMode.SHIP)) {
return EnumSet.of(DefaultRouteType.FERRY);
} else if (travelMode.equals(TravelMode.SUBWAY)) {
return EnumSet.of(DefaultRouteType.SUBWAY);
} else if (travelMode.equals(TravelMode.AERIAL_LIFT)) {
return EnumSet.of(DefaultRouteType.AERIAL_LIFT);
} else if (travelMode.equals(TravelMode.FUNICULAR)) {
return EnumSet.of(DefaultRouteType.FUNICULAR);
} else {
// should never happen
throw new IllegalArgumentException("Travel mode not supported");
}
}

public void clearCache() {
cache.clear();
}
Expand All @@ -43,18 +83,55 @@ public DayTripMask getDayTripMask(LocalDate date, QueryConfig queryConfig) {
if (tripIds == null) {
throw new IllegalStateException("Trip ids not set");
}
return buildTripMask(date, cache.getActiveServices(date));
return buildTripMask(date, cache.getActiveServices(date), queryConfig);
}

private DayTripMask buildTripMask(LocalDate date, String serviceId) {
private DayTripMask buildTripMask(LocalDate date, String serviceId, QueryConfig queryConfig) {
Map<String, RouteTripMask> tripMasks = new HashMap<>();

boolean hasNonDefaultTravelModeFilter = queryConfig.getAllowedTravelModes()
.size() != TravelMode.values().length;
EnumSet<DefaultRouteType> allowedRouteTypes = mapToRouteTypes(queryConfig.getAllowedTravelModes());

for (Map.Entry<String, String[]> entry : tripIds.entrySet()) {
String routeId = entry.getKey();
String[] tripIds = entry.getValue();

boolean[] tripMask = new boolean[tripIds.length];

// only check route type if there is a non-default travel mode filter
if (hasNonDefaultTravelModeFilter) {
Route route = schedule.getRoutes().get(routeId);
DefaultRouteType routeType = RouteTypeMapper.map(route.getType());
if (!allowedRouteTypes.contains(routeType)) {
// no need for further checks if route type is not allowed
tripMasks.put(routeId, new RouteTripMask(tripMask));
continue;
}
}

for (int i = 0; i < tripIds.length; i++) {
tripMask[i] = schedule.getTrips().get(tripIds[i]).getCalendar().isServiceAvailable(date);
Trip trip = schedule.getTrips().get(tripIds[i]);
if (!trip.getCalendar().isServiceAvailable(date)) {
tripMask[i] = false;
continue;
}

if (queryConfig.isWheelchairAccessible()) {
if (trip.getWheelchairAccessible() != AccessibilityInformation.ACCESSIBLE) {
tripMask[i] = false;
continue;
}
}

if (queryConfig.isBikeAccessible()) {
if (trip.getBikesAllowed() != BikeInformation.ALLOWED) {
tripMask[i] = false;
continue;
}
}

tripMask[i] = true;
}

tripMasks.put(routeId, new RouteTripMask(tripMask));
Expand Down

0 comments on commit 216098f

Please sign in to comment.