Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alerts filter by mode #154

Open
wants to merge 4 commits into
base: dev-1.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/main/java/org/opentripplanner/api/resource/AlertPatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ the License, or (at your option) any later version.
import static org.opentripplanner.api.resource.ServerInfo.Q;

import java.util.Collection;
import java.util.List;

import javax.annotation.security.RolesAllowed;
import javax.ws.rs.Consumes;
Expand All @@ -35,6 +36,8 @@ the License, or (at your option) any later version.
import org.opentripplanner.routing.alertpatch.AlertPatch;
import org.opentripplanner.routing.services.AlertPatchService;



@Path("/patch")
@XmlRootElement
public class AlertPatcher {
Expand Down Expand Up @@ -95,11 +98,12 @@ public AlertPatchCreationResponse createPatches(AlertPatchSet alertPatches) {
return response;
}

final AgencyAndId route = alertPatch.getRoute();
if (route != null && route.getId().equals("")) {
response.status = "Every route patch must have a route id";
return response;
}
final List<AgencyAndId> routes = alertPatch.getRoute();
for(AgencyAndId route : routes)
if (route != null && route.getId().equals("")) {
response.status = "Every route patch must have a route id";
return response;
}
}
for (AlertPatch alertPatch : alertPatches.alertPatches) {
alertPatchService.apply(alertPatch);
Expand Down
149 changes: 126 additions & 23 deletions src/main/java/org/opentripplanner/index/IndexGraphQLSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,10 @@

import static java.util.Collections.emptyList;

import java.util.*;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -184,6 +175,8 @@ public static String experimental(String message) {
.build();

private final GtfsRealtimeFuzzyTripMatcher fuzzyTripMatcher;

public GraphQLOutputType routeHeadsignMapType = new GraphQLTypeReference("RouteHeadsignMapType");

public GraphQLOutputType agencyType = new GraphQLTypeReference("Agency");

Expand Down Expand Up @@ -693,8 +686,15 @@ public IndexGraphQLSchema(GraphIndex index) {
.build())
.field(GraphQLFieldDefinition.newFieldDefinition()
.name("route")
.type(routeType)
.dataFetcher(environment -> index.routeForId.get(((AlertPatch) environment.getSource()).getRoute()))
.type(new GraphQLList(routeType))
.dataFetcher(environment -> {
List<AgencyAndId> rts = ((AlertPatch) environment.getSource()).getRoute();
List<Route> routes = null;
routes = rts.stream()
.map(route -> index.routeForId.get(route))
.collect(Collectors.toList());
return routes;
})
.build())
.field(GraphQLFieldDefinition.newFieldDefinition()
.name("trip")
Expand Down Expand Up @@ -961,6 +961,23 @@ public IndexGraphQLSchema(GraphIndex index) {
.dataFetcher(environment -> ((StopCluster) environment.getSource()).children)
.build())
.build();

routeHeadsignMapType = GraphQLObjectType.newObject()
.name("RouteHeadsignMapType")
.description("Route mapped with its most popular headsign")
.field(GraphQLFieldDefinition.newFieldDefinition()
.name("route")
.description("Route")
.type(routeType)
.dataFetcher(environment -> ((Map.Entry<Route,String>) environment.getSource()).getKey())
.build())
.field(GraphQLFieldDefinition.newFieldDefinition()
.name("headsign")
.description("The most popular headsign for a route")
.type(Scalars.GraphQLString)
.dataFetcher(environment -> ((Map.Entry<Route,String>) environment.getSource()).getValue())
.build())
.build();

stopType = GraphQLObjectType.newObject()
.name("Stop")
Expand Down Expand Up @@ -1098,6 +1115,69 @@ public IndexGraphQLSchema(GraphIndex index) {
.dataFetcher(environment -> index.patternsForStop.get(environment.getSource()))
.build())
.field(GraphQLFieldDefinition.newFieldDefinition()
.name("topDestinationsForToday")
.type(new GraphQLList(routeHeadsignMapType))
.argument(GraphQLArgument.newArgument()
.name("serviceDay")
.type(Scalars.GraphQLString)
.defaultValue(null)
.build())
.dataFetcher(environment -> {
try {
BitSet services = index.servicesRunning(
ServiceDate.parseString(environment.getArgument("serviceDay"))
);

List<Map.Entry<Route, String>> routeHeadsignList = new ArrayList<Map.Entry<Route, String>>();
Map<Route, Long> routeTripCount = new HashMap<Route, Long>();
index.routesForStop(((Stop)environment
.getSource()))
.stream()
.forEach((route) -> {
Map<TripPattern, Long> tripCountMap = new HashMap<TripPattern, Long>();

if(!routeTripCount.containsValue(route))
routeTripCount.put(route, new Long(0));
index.patternsForStop.get((Stop)environment.getSource())
.stream()
.filter(pattern -> index.patternsForRoute.get(route).contains(pattern))
.forEach((pattern) -> {
long count = pattern.scheduledTimetable.tripTimes
.stream()
.filter(times -> services.get(times.serviceCode))
.map(times -> times.trip).count();

tripCountMap.put(pattern, count);
routeTripCount.put(route, routeTripCount.get(route)+ count);
});

String headsignForRoute = tripCountMap
.entrySet()
.stream()
.max(Map.Entry.comparingByValue())
.get()
.getKey()
.getDirection();

routeHeadsignList.add(new AbstractMap.SimpleEntry<Route, String>(route, headsignForRoute));
});

if(routeHeadsignList != null) {

routeHeadsignList.sort((Map.Entry<Route, String> e1, Map.Entry<Route, String> e2) ->
(int) (routeTripCount.get(e2.getKey()) - routeTripCount.get(e1.getKey())));
return routeHeadsignList;
}


return null;

} catch (ParseException e) {
return null; // Invalid date format
}
})
.build())
.field(GraphQLFieldDefinition.newFieldDefinition()
.name("transfers") //TODO: add max distance as parameter?
.type(new GraphQLList(stopAtDistanceType))
.dataFetcher(environment -> index.stopVertexForStop
Expand Down Expand Up @@ -2435,16 +2515,39 @@ private Object getObject(String idString) {
.name("feeds")
.type(new GraphQLList(new GraphQLNonNull(Scalars.GraphQLString)))
.build())
.dataFetcher(environment -> environment.getArgument("feeds") != null
? index.getAlerts()
.stream()
.filter(alertPatch ->
((List) environment.getArgument("feeds"))
.contains(alertPatch.getFeedId())
)
.collect(Collectors.toList())
: index.getAlerts()
)
.argument(GraphQLArgument.newArgument()
.name("modes")
.type(Scalars.GraphQLString)
.build())
.dataFetcher(environment -> {
List <AlertPatch> alerts = index.getAlerts();
if(alerts != null) {
if(environment.getArgument("feeds") != null)
alerts = alerts
.stream()
.filter(alertPatch ->
((List) environment.getArgument("feeds"))
.contains(alertPatch.getFeedId())
)
.collect(Collectors.toList());
if(environment.getArgument("modes") != null) {
Set<TraverseMode> modes = new QualifiedModeSet(
environment.getArgument("modes")).qModes
.stream()
.map(qualifiedMode -> qualifiedMode.mode)
.filter(TraverseMode::isTransit)
.collect(Collectors.toSet());
alerts = alerts
.stream()
.filter(alertPatch ->
modes.contains(GtfsLibrary.getTraverseMode(
index.routeForId.get(alertPatch.getRoute() instanceof AgencyAndId ? alertPatch.getRoute() : alertPatch.getRoute().get(0)))))
.collect(Collectors.toList());
}
}

return alerts;
})
.build())
.field(GraphQLFieldDefinition.newFieldDefinition()
.name("serviceTimeRange")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public class AlertPatch implements Serializable {

private String agency;

private AgencyAndId route;
private List<AgencyAndId> route = new LinkedList();

private AgencyAndId trip;

Expand Down Expand Up @@ -120,7 +120,7 @@ public void apply(Graph graph) {
Map<String, Agency> agencies = graph.index.agenciesForFeedId.get(feedId);
agency = this.agency != null ? agencies.get(this.agency) : null;
}
Route route = this.route != null ? graph.index.routeForId.get(this.route) : null;
Route route = (this.route != null && this.route.size() != 0) ? graph.index.routeForId.get(this.route.get(this.route.size()-1)) : null;
Stop stop = this.stop != null ? graph.index.stopForId.get(this.stop) : null;
Trip trip = this.trip != null ? graph.index.tripForId.get(this.trip) : null;

Expand Down Expand Up @@ -204,7 +204,7 @@ public void remove(Graph graph) {
Map<String, Agency> agencies = graph.index.agenciesForFeedId.get(feedId);
agency = this.agency != null ? agencies.get(this.agency) : null;
}
Route route = this.route != null ? graph.index.routeForId.get(this.route) : null;
Route route = (this.route != null && this.route.size() != 0) ? graph.index.routeForId.get(this.route.get(this.route.size()-1)) : null;
Stop stop = this.stop != null ? graph.index.stopForId.get(this.stop) : null;
Trip trip = this.trip != null ? graph.index.tripForId.get(this.trip) : null;

Expand Down Expand Up @@ -279,7 +279,10 @@ public String getAgency() {
}

@XmlJavaTypeAdapter(AgencyAndIdAdapter.class)
public AgencyAndId getRoute() {
public List<AgencyAndId> getRoute() {
// if(route.size() > 0)
// return route.get(route.size()-1);
// return null;
return route;
}

Expand All @@ -298,7 +301,7 @@ public void setAgencyId(String agency) {
}

public void setRoute(AgencyAndId route) {
this.route = route;
this.route.add(route);
}

public void setTrip(AgencyAndId trip) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1079,8 +1079,13 @@ public List<AlertPatch> getAlerts() {

public List<AlertPatch> getAlertsForRoute(Route route) {
return getAlertPatchStream()
.filter(alertPatch -> alertPatch.getRoute() != null)
.filter(alertPatch -> route.getId().equals(alertPatch.getRoute()))
.filter(alertPatch -> {
for(AgencyAndId routeInAlerts: alertPatch.getRoute())
if(routeInAlerts != null && route.getId().equals(routeInAlerts))
return true;

return false;
})
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ public synchronized void apply(AlertPatch alertPatch) {
if (stop != null) {
patchesByStop.put(stop, alertPatch);
}
AgencyAndId route = alertPatch.getRoute();
if (route != null) {

List<AgencyAndId> routes = alertPatch.getRoute();
for( AgencyAndId route: routes) {
patchesByRoute.put(route, alertPatch);
}
}
Expand Down Expand Up @@ -128,8 +129,8 @@ private void expire(AlertPatch alertPatch) {
if (stop != null) {
patchesByStop.remove(stop, alertPatch);
}
AgencyAndId route = alertPatch.getRoute();
if (route != null) {
List<AgencyAndId> routes = alertPatch.getRoute();
for( AgencyAndId route: routes) {
patchesByRoute.remove(route, alertPatch);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ private void handleAlert(String id, GtfsRealtime.Alert alert) {
// Per the GTFS-rt spec, if an alert has no TimeRanges, than it should always be shown.
periods.add(new TimePeriod(0, Long.MAX_VALUE));
}

AlertPatch patch = new AlertPatch();

for (EntitySelector informed : alert.getInformedEntityList()) {
if (fuzzyTripMatcher != null && informed.hasTrip()) {
TripDescriptor trip = fuzzyTripMatcher.match(feedId, informed.getTrip());
Expand All @@ -108,6 +111,9 @@ private void handleAlert(String id, GtfsRealtime.Alert alert) {
String routeId = null;
if (informed.hasRouteId()) {
routeId = informed.getRouteId();
} else if (informed.hasTrip() && informed.getTrip().hasRouteId()) {
String tempRouteId = informed.getTrip().getRouteId();
routeId = tempRouteId.substring(tempRouteId.indexOf("_")+1);
}

int direction;
Expand All @@ -130,10 +136,12 @@ private void handleAlert(String id, GtfsRealtime.Alert alert) {
String agencyId = informed.getAgencyId();
if (informed.hasAgencyId()) {
agencyId = informed.getAgencyId().intern();
} else if (informed.hasTrip() && informed.getTrip().hasRouteId()) {
agencyId = informed.getTrip().getRouteId().substring(0, informed.getTrip().getRouteId().indexOf("_"));
}

AlertPatch patch = new AlertPatch();
patch.setFeedId(feedId);

if (routeId != null) {
patch.setRoute(new AgencyAndId(feedId, routeId));
// Makes no sense to set direction if we don't have a route
Expand All @@ -150,6 +158,7 @@ private void handleAlert(String id, GtfsRealtime.Alert alert) {
if (agencyId != null && routeId == null && tripId == null && stopId == null) {
patch.setAgencyId(agencyId);
}

patch.setTimePeriods(periods);
patch.setAlert(alertText);

Expand Down