use of org.opentripplanner.common.model.T2 in project OpenTripPlanner by opentripplanner.
the class ProfileRouter method findClosestPatterns.
/**
* @param stopClusters a multimap from stop clusters to one or more StopAtDistance objects at the corresponding cluster.
* @return for each TripPattern that passes through any of the supplied stop clusters, the stop cluster that is
* closest to the origin or destination point according to the distances in the StopAtDistance objects.
*
* In short, take a bunch of stop clusters near the origin or destination and return the quickest way to reach each
* pattern that passes through them.
* We want stop cluster references rather than indexes within the patterns because when a stop cluster appears more
* than once in a pattern, we want to consider boarding or alighting from that pattern at every index where the
* cluster occurs.
*/
public Multimap<TripPattern, StopAtDistance> findClosestPatterns(Multimap<StopCluster, StopAtDistance> stopClusters) {
SimpleIsochrone.MinMap<T2<TripPattern, QualifiedMode>, StopAtDistance> closest = new SimpleIsochrone.MinMap<>();
// Iterate over all StopAtDistance for all Stops. The fastest mode will win at each stop.
for (StopAtDistance stopDist : stopClusters.values()) {
for (Stop stop : stopDist.stopCluster.children) {
for (TripPattern pattern : graph.index.patternsForStop.get(stop)) {
closest.putMin(new T2(pattern, stopDist.qmode), stopDist);
}
}
}
/* Remove the QualifiedModes from the keys. Maybe it would be better to just return the result including them. */
Multimap<TripPattern, StopAtDistance> result = ArrayListMultimap.create();
for (Entry<T2<TripPattern, QualifiedMode>, StopAtDistance> entry : closest.entrySet()) {
result.put(entry.getKey().first, entry.getValue());
}
// We used to truncate long lists to include a mix of nearby bus and train patterns
// but this gives crazy results. Now we just warn on this condition.
final int MAX_PATTERNS = 1000;
if (result.size() > MAX_PATTERNS) {
LOG.warn("Excessively long list of patterns. {} patterns, max allowed is {}.", closest.size(), MAX_PATTERNS);
}
return result;
}
use of org.opentripplanner.common.model.T2 in project OpenTripPlanner by opentripplanner.
the class RouteMatcher method parse.
/**
* Build a new RouteMatcher from a string representation.
*
* @param routeSpecList A comma-separated list of route spec, each of the format
* [agencyId]_[routeName]_[routeId] Please note that this format is not really intuitive
* as it does not follow the OBA-gtfslib AgencyAndId standard ('agencyID_routeId'). This
* was kept for backward-compatibility purposes. If the original routeName contains some
* "_" each *must* be replaced by a space. If the agency or route ID contains a "_" they
* must be escaped using a backslash.
* TODO why do we want to accept route name strings when we have IDs? Break backward compatibility.
* FIXME this is the only place we are still using underscores as scope separators. Rethink this from scratch.
* @return A RouteMatcher
* @throws IllegalArgumentException If the string representation is invalid.
*/
public static RouteMatcher parse(String routeSpecList) {
if (routeSpecList == null)
return emptyMatcher();
RouteMatcher retval = new RouteMatcher();
int n = 0;
for (String element : routeSpecList.split(",")) {
if (element.length() == 0)
continue;
n++;
// FIXME regexes with no comments
String[] routeSpec = element.split("(?<!\\\\)_", 3);
if (routeSpec.length != 2 && routeSpec.length != 3) {
throw new IllegalArgumentException("Wrong route spec format: " + element);
}
routeSpec[0] = routeSpec[0].replace("\\_", "_");
routeSpec[1] = routeSpec[1].replace("\\_", " ");
if (routeSpec.length >= 3)
routeSpec[2] = routeSpec[2].replace("\\_", "_");
String agencyId = routeSpec[0];
if (agencyId.length() == 0)
agencyId = null;
String routeName = routeSpec[1];
if (routeName.length() == 0)
routeName = null;
String routeId = routeSpec.length > 2 ? routeSpec[2] : null;
if (routeId != null && routeId.length() == 0)
routeId = null;
if (agencyId != null && routeId != null && routeName == null) {
// Case 1: specified agency ID and route ID but no route name
retval.agencyAndRouteIds.add(new AgencyAndId(agencyId, routeId));
} else if (agencyId != null && routeName != null && routeId == null) {
// Case 2: specified agency ID and route name but no route ID
retval.agencyIdAndRouteNames.add(new T2<String, String>(agencyId, routeName));
} else if (agencyId == null && routeName != null && routeId == null) {
// Case 3: specified route name only
retval.routeNames.add(routeName);
} else {
throw new IllegalArgumentException("Wrong route spec format: " + element);
}
}
if (n == 0)
return emptyMatcher();
return retval;
}
use of org.opentripplanner.common.model.T2 in project OpenTripPlanner by opentripplanner.
the class NoteProperties method generateNote.
public T2<Alert, NoteMatcher> generateNote(OSMWithTags way) {
Alert note = new Alert();
// TODO: this could probably be made without patternMatch for {} since all notes (at least currently) have {note} as notePattern
if (patternMatcher.matcher(notePattern).matches()) {
// This gets language -> translation of notePattern and all tags (which can have translations name:en for example)
Map<String, String> noteText = TemplateLibrary.generateI18N(notePattern, way);
note.alertHeaderText = TranslatedString.getI18NString(noteText);
} else {
note.alertHeaderText = new LocalizedString(notePattern, way);
}
return new T2<>(note, noteMatcher);
}
use of org.opentripplanner.common.model.T2 in project OpenTripPlanner by opentripplanner.
the class WFSNotePollingGraphUpdater method buildMatcherAndAlert.
/**
* Create a MatcherAndAlert, interning it if the note and matcher pair is already created. Note:
* we use the default Object.equals() for matchers, as they are mostly already singleton
* instances.
*/
private MatcherAndAlert buildMatcherAndAlert(NoteMatcher noteMatcher, Alert note) {
T2<NoteMatcher, Alert> key = new T2<>(noteMatcher, note);
MatcherAndAlert interned = uniqueMatchers.get(key);
if (interned != null) {
return interned;
}
MatcherAndAlert ret = new MatcherAndAlert(noteMatcher, note);
uniqueMatchers.put(key, ret);
return ret;
}
use of org.opentripplanner.common.model.T2 in project OpenTripPlanner by opentripplanner.
the class TestBanning method doTestBannedTrips.
/**
* Test trip banning. We compute a set of shortest routes between two random stops in the Portland graph. We then ban, for each route, up to a
* certain amount of trips used in this route, one by one, and recompute the path. The banned trips must not appear in the new computed route.
*
* This is using a seeded random generator to easily make a reproducible and arbitrary list
* of start/end points and trip to ban. It allow for a (bit) more coverage than doing a
* single hand-picked test only.
*
* @param partial True to test partial trip banning, false for complete trip
* @param seed Value to use for random generator seed -- Keep the same value for consistency.
*/
public void doTestBannedTrips(boolean partial, int seed) {
Graph graph = ConstantsForTests.getInstance().getPortlandGraph();
String feedId = graph.getFeedIds().iterator().next();
Random rand = new Random(seed);
for (int i = 0; i < 20; i++) {
RoutingRequest options = new RoutingRequest();
options.dateTime = TestUtils.dateInSeconds("America/Los_Angeles", 2009, 11, 1, 12, 34, 25);
// Pick two random locations
Vertex start = null;
Vertex end = null;
while (start == null) start = graph.getVertex(feedId + ":" + rand.nextInt(10000));
while (end == null) end = graph.getVertex(feedId + ":" + rand.nextInt(10000));
options.setRoutingContext(graph, start, end);
ShortestPathTree spt = null;
int n = rand.nextInt(5) + 3;
for (int j = 0; j < n; j++) {
spt = aStar.getShortestPathTree(options);
GraphPath path = spt.getPath(end, true);
if (path == null || spt == null)
// No path found
break;
// List of used [trip,stop index] in the path
Set<T2<AgencyAndId, BannedStopSet>> usedTripDefs = new HashSet<T2<AgencyAndId, BannedStopSet>>();
for (State s : path.states) {
if (s.getBackEdge() instanceof TransitBoardAlight) {
TransitBoardAlight tbae = (TransitBoardAlight) s.getBackEdge();
int boardingStopIndex = tbae.getStopIndex();
AgencyAndId tripId = s.getTripId();
BannedStopSet stopSet;
if (partial) {
stopSet = new BannedStopSet();
stopSet.add(boardingStopIndex);
} else {
stopSet = BannedStopSet.ALL;
}
if (tripId != null)
usedTripDefs.add(new T2<AgencyAndId, BannedStopSet>(tripId, stopSet));
}
}
// Used trips should not contains a banned trip
for (T2<AgencyAndId, BannedStopSet> usedTripDef : usedTripDefs) {
BannedStopSet bannedStopSet = options.bannedTrips.get(usedTripDef.first);
if (bannedStopSet != null) {
for (Integer stopIndex : usedTripDef.second) {
assertFalse(bannedStopSet.contains(stopIndex));
}
}
}
if (usedTripDefs.size() == 0)
// Not a transit trip, no sense to ban trip any longer
break;
// Pick a random used trip + stop set to ban
List<T2<AgencyAndId, BannedStopSet>> usedTripDefsList = new ArrayList<T2<AgencyAndId, BannedStopSet>>(usedTripDefs);
T2<AgencyAndId, BannedStopSet> tripDefToBan = usedTripDefsList.get(rand.nextInt(usedTripDefs.size()));
options.bannedTrips.put(tripDefToBan.first, tripDefToBan.second);
}
options.bannedTrips.clear();
}
}
Aggregations