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

Not allowed transfers and support for GTFS transfer points #3792

Merged
merged 26 commits into from
Jan 26, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4a931a5
feat: Extend internal model to allow implementing not-allowed transfers.
t2gran Nov 15, 2021
e472a11
feat: Extend Raptor with support for not-allowed transfers.
t2gran Nov 15, 2021
4f44616
feat: Extend Raptor and optimized transfers with support for not-allo…
t2gran Nov 16, 2021
cca1168
feat: Extend ConstrainedBoardingSearch with support for not-allowed t…
t2gran Nov 15, 2021
ad6c2cc
refactor: Make transfer constraint none null.
t2gran Dec 20, 2021
268b079
test: Add test on ConstrainedBoardingSearch
t2gran Dec 20, 2021
072731f
refactor: remove unused method in ConstrainedBoardingSearchStrategy
t2gran Dec 20, 2021
ddaa114
refactor: Improve TransferPoints toString()
t2gran Dec 20, 2021
2be63f4
refactor: Cleanup T2 equals() and add test
t2gran Nov 29, 2021
539bf9a
refactor: cleanup TripPattern
t2gran Dec 17, 2021
29be403
refactor: StopTransferPriorityMapper renamed from TransferPriorityMapper
t2gran Dec 20, 2021
c706ecf
refactor: rename local variable in RangeRaptorWorker
t2gran Dec 20, 2021
0a0cf45
refactor: improve encapsulation in StopIndexForRaptor
t2gran Dec 20, 2021
5ce3d16
feat: Support for GTFS Trip, Route, Stop & Station Transfers
t2gran Dec 18, 2021
d1cbca0
refactor: Update otp.serialization.version.id
t2gran Dec 20, 2021
594f8f4
refactor: Encapsulate StopPattern in TripPattern
t2gran Jan 7, 2022
1390922
feat: Support for GTFS Trip, Route, Stop & Station Transfers
t2gran Jan 6, 2022
4950704
fix: NPE in TransferIndexGenerator
t2gran Jan 13, 2022
4e4339a
Apply suggestions from code review
t2gran Jan 13, 2022
2a08080
refactor: Review
t2gran Jan 13, 2022
768117c
Merge remote-tracking branch 'otp/dev-2.x' into otp2_not_allowed_tran…
t2gran Jan 14, 2022
0ccdf70
Merge remote-tracking branch 'otp/dev-2.x' into otp2_not_allowed_tran…
t2gran Jan 14, 2022
1e82238
review: Update src/main/java/org/opentripplanner/model/transfer/Trans…
t2gran Jan 25, 2022
6028793
Merge remote-tracking branch 'otp/dev-2.x' into otp2_not_allowed_tran…
t2gran Jan 26, 2022
244b30e
review: Cleanup AccessEgressMapper
t2gran Jan 26, 2022
3e447f4
feat: Abort constrained transfer search after 5 normal boardings found
t2gran Jan 26, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public void shouldNotInterpolateFlexTimes() {
var feedId = graph.getFeedIds().iterator().next();
var pattern = graph.tripPatternForId.get(new FeedScopedId(feedId, "090z:0:01"));

assertEquals(3, pattern.getStops().size());
assertEquals(3, pattern.numberOfStops());

var tripTimes = pattern.getScheduledTimetable().getTripTimes(0);
var arrivalTime = tripTimes.getArrivalTime(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private static void addLocation(
Trip trip,
boolean arrival
) {
if(pattern == null || stopPosition >= pattern.getStopPattern().getSize()) {
if(pattern == null || stopPosition >= pattern.numberOfStops()) {
r.loc += "[Stop position not found: " + stopPosition + "]";
return;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package org.opentripplanner.ext.siri;

import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.opentripplanner.model.FeedScopedId;
import org.opentripplanner.model.Route;
import org.opentripplanner.model.Station;
import org.opentripplanner.model.Stop;
import org.opentripplanner.model.Trip;
import org.opentripplanner.model.TripPattern;
import org.opentripplanner.routing.RoutingService;
Expand All @@ -18,14 +23,6 @@
import uk.org.siri.siri20.VehicleActivityStructure;
import uk.org.siri.siri20.VehicleModesEnumeration;

import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* This class is used for matching TripDescriptors without trip_ids to scheduled GTFS data and to
* feed back that information into a new TripDescriptor with proper trip_id.
Expand Down Expand Up @@ -237,7 +234,7 @@ private static void initCache(RoutingService index) {
}
}
}
String lastStopId = tripPattern.getStops().get(tripPattern.getStops().size()-1).getId().getId();
String lastStopId = tripPattern.lastStop().getId().getId();

TripTimes tripTimes = tripPattern.getScheduledTimetable().getTripTimes(trip);
if (tripTimes != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
package org.opentripplanner.ext.siri;

import static org.opentripplanner.ext.siri.TimetableHelper.createModifiedStopTimes;
import static org.opentripplanner.ext.siri.TimetableHelper.createModifiedStops;
import static org.opentripplanner.ext.siri.TimetableHelper.createUpdatedTripTimes;
import static org.opentripplanner.model.PickDrop.NONE;
import static org.opentripplanner.model.PickDrop.SCHEDULED;

import com.google.common.base.Preconditions;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.locks.ReentrantLock;
import org.opentripplanner.model.Agency;
import org.opentripplanner.model.FeedScopedId;
import org.opentripplanner.model.Operator;
import org.opentripplanner.model.Route;
import org.opentripplanner.model.Stop;
import org.opentripplanner.model.StopLocation;
import org.opentripplanner.model.StopPattern;
import org.opentripplanner.model.StopTime;
Expand Down Expand Up @@ -36,22 +50,6 @@
import uk.org.siri.siri20.VehicleModesEnumeration;
import uk.org.siri.siri20.VehicleMonitoringDeliveryStructure;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.locks.ReentrantLock;

import static org.opentripplanner.ext.siri.TimetableHelper.createModifiedStopTimes;
import static org.opentripplanner.ext.siri.TimetableHelper.createModifiedStops;
import static org.opentripplanner.ext.siri.TimetableHelper.createUpdatedTripTimes;
import static org.opentripplanner.model.PickDrop.NONE;
import static org.opentripplanner.model.PickDrop.SCHEDULED;

/**
* This class should be used to create snapshots of lookup tables of realtime data. This is
* necessary to provide planning threads a consistent constant view of a graph with realtime data at
Expand Down Expand Up @@ -778,7 +776,7 @@ private boolean handleModifiedTrip(Graph graph, String feedId, EstimatedVehicleJ
for (TripTimes tripTimes : times) {
Trip trip = tripTimes.getTrip();
for (TripPattern pattern : patterns) {
if (tripTimes.getNumStops() == pattern.getStopPattern().getStops().length) {
if (tripTimes.getNumStops() == pattern.numberOfStops()) {
if (!tripTimes.isCanceled()) {
/*
UPDATED and MODIFIED tripTimes should be handled the same way to always allow latest realtime-update
Expand Down Expand Up @@ -1009,7 +1007,7 @@ private Set<TripPattern> getPatternsForTrip(Set<Trip> matches, VehicleActivitySt
}

var firstStop = tripPattern.getStop(0);
var lastStop = tripPattern.getStop(tripPattern.getStops().size() - 1);
var lastStop = tripPattern.lastStop();

String siriOriginRef = monitoredVehicleJourney.getOriginRef().getValue();

Expand Down Expand Up @@ -1124,8 +1122,8 @@ private TripPattern getPatternForTrip(Trip trip, EstimatedVehicleJourney journey
}


var firstStop = tripPattern.getStop(0);
var lastStop = tripPattern.getStop(tripPattern.getStops().size() - 1);
var firstStop = tripPattern.firstStop();
var lastStop = tripPattern.lastStop();

if (serviceDates.contains(journeyDate)) {
boolean firstStopIsMatch = firstStop.getId().getId().equals(journeyFirstStopId);
Expand Down Expand Up @@ -1250,9 +1248,9 @@ private Set<Trip> getTripForJourney(Set<Trip> trips, EstimatedVehicleJourney jou

TripPattern pattern = routingService.getPatternForTrip().get(trip);

if (stopNumber < pattern.getStopPattern().getStops().length) {
if (stopNumber < pattern.numberOfStops()) {
boolean firstReportedStopIsFound = false;
var stop = pattern.getStopPattern().getStops()[stopNumber - 1];
var stop = pattern.getStop(stopNumber - 1);
if (firstStopId.equals(stop.getId().getId())) {
firstReportedStopIsFound = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimaps;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import org.opentripplanner.model.Stop;
import org.opentripplanner.model.StopLocation;
import org.opentripplanner.model.StopPattern;
Expand All @@ -13,12 +18,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* A synchronized cache of trip patterns that are added to the graph due to GTFS-realtime messages.
*/
Expand Down Expand Up @@ -129,9 +128,10 @@ public synchronized TripPattern getOrCreateTripPattern(
* Remove previously added TripPatterns for the trip currently being updated - if the stopPattern does not match
*/
TripPattern cachedTripPattern = updatedTripPatternsForTripCache.get(tripServiceDateKey);
if (cachedTripPattern != null && !tripPattern
.getStopPattern()
.equals(cachedTripPattern.getStopPattern())) {
if (
cachedTripPattern != null &&
!tripPattern.stopPatternIsEqual(cachedTripPattern)
) {
int sizeBefore = patternsForStop.values().size();
long t1 = System.currentTimeMillis();
patternsForStop.values().removeAll(Arrays.asList(cachedTripPattern));
Expand Down
52 changes: 24 additions & 28 deletions src/ext/java/org/opentripplanner/ext/siri/TimetableHelper.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
package org.opentripplanner.ext.siri;

import static java.util.Collections.EMPTY_LIST;
import static org.opentripplanner.model.PickDrop.NONE;
import static org.opentripplanner.model.PickDrop.SCHEDULED;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import javax.xml.datatype.Duration;
import lombok.val;
import org.opentripplanner.model.FeedScopedId;
import org.opentripplanner.model.Stop;
import org.opentripplanner.model.StopLocation;
import org.opentripplanner.model.StopTime;
import org.opentripplanner.model.Timetable;
import org.opentripplanner.model.TimetableSnapshot;
import org.opentripplanner.model.Trip;
import org.opentripplanner.routing.RoutingService;
import org.opentripplanner.routing.algorithm.raptor.transit.mappers.DateMapper;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.RoutingService;
import org.opentripplanner.routing.trippattern.RealTimeState;
import org.opentripplanner.routing.trippattern.TripTimes;
import org.slf4j.Logger;
Expand All @@ -25,19 +37,6 @@
import uk.org.siri.siri20.RecordedCall;
import uk.org.siri.siri20.VehicleActivityStructure;

import javax.xml.datatype.Duration;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;

import static java.util.Collections.EMPTY_LIST;
import static org.opentripplanner.model.PickDrop.NONE;
import static org.opentripplanner.model.PickDrop.SCHEDULED;

public class TimetableHelper {

private static final Logger LOG = LoggerFactory.getLogger(TimetableHelper.class);
Expand Down Expand Up @@ -95,8 +94,6 @@ public static TripTimes createUpdatedTripTimes(final Graph graph, Timetable time

boolean stopPatternChanged = false;

var modifiedStops = timetable.getPattern().getStopPattern().getStops();

Trip trip = getTrip(tripId, timetable);

List<StopTime> modifiedStopTimes = createModifiedStopTimes(timetable, oldTimes, journey, trip, new RoutingService(graph));
Expand All @@ -119,7 +116,7 @@ public static TripTimes createUpdatedTripTimes(final Graph graph, Timetable time
int departureFromPreviousStop = 0;
int lastArrivalDelay = 0;
int lastDepartureDelay = 0;
for (var stop : modifiedStops) {
for (var stop : timetable.getPattern().getStops()) {
boolean foundMatch = false;

for (RecordedCall recordedCall : recordedCalls) {
Expand Down Expand Up @@ -286,8 +283,7 @@ public static TripTimes createUpdatedTripTimes(final Graph graph, Timetable time
}
if (!foundMatch) {

if (timetable.getPattern().getStopPattern().getPickup(callCounter) == NONE &&
timetable.getPattern().getStopPattern().getDropoff(callCounter) == NONE) {
if (timetable.getPattern().isBoardAndAlightAt(callCounter, NONE)) {
// When newTimes contains stops without pickup/dropoff - set both arrival/departure to previous stop's departure
// This necessary to accommodate the case when delay is reduced/eliminated between to stops with pickup/dropoff, and
// multiple non-pickup/dropoff stops are in between.
Expand Down Expand Up @@ -331,7 +327,7 @@ public static TripTimes createUpdatedTripTimes(final Graph graph, Timetable time
return null;
}

if (newTimes.getNumStops() != timetable.getPattern().getStopPattern().getStops().length) {
if (newTimes.getNumStops() != timetable.getPattern().numberOfStops()) {
return null;
}

Expand Down Expand Up @@ -372,15 +368,15 @@ public static List<StopLocation> createModifiedStops(Timetable timetable, Estima
}

//Get all scheduled stops
var stops = timetable.getPattern().getStopPattern().getStops();
val pattern = timetable.getPattern();

// Keeping track of visited stop-objects to allow multiple visits to a stop.
List<Object> alreadyVisited = new ArrayList<>();

List<StopLocation> modifiedStops = new ArrayList<>();

for (int i = 0; i < stops.length; i++) {
StopLocation stop = stops[i];
for (int i = 0; i < pattern.numberOfStops(); i++) {
StopLocation stop = pattern.getStop(i);

boolean foundMatch = false;
if (i < recordedCalls.size()) {
Expand Down Expand Up @@ -481,8 +477,8 @@ public static List<StopTime> createModifiedStopTimes(Timetable timetable, TripTi
stopTime.setStop(stop);
stopTime.setTrip(trip);
stopTime.setStopSequence(i);
stopTime.setDropOffType(timetable.getPattern().getStopPattern().getDropoff(i));
stopTime.setPickupType(timetable.getPattern().getStopPattern().getPickup(i));
stopTime.setDropOffType(timetable.getPattern().getAlightType(i));
stopTime.setPickupType(timetable.getPattern().getBoardType(i));
stopTime.setArrivalTime(oldTimes.getScheduledArrivalTime(i));
stopTime.setDepartureTime(oldTimes.getScheduledDepartureTime(i));
stopTime.setStopHeadsign(oldTimes.getHeadsign(i));
Expand Down Expand Up @@ -597,7 +593,6 @@ public static TripTimes createUpdatedTripTimes(Timetable timetable, Graph graph,
if (update == null) {
return null;
}
final List<StopLocation> stops = timetable.getPattern().getStops();

VehicleActivityStructure.MonitoredVehicleJourney monitoredVehicleJourney = activity.getMonitoredVehicleJourney();

Expand All @@ -615,11 +610,12 @@ public static TripTimes createUpdatedTripTimes(Timetable timetable, Graph graph,

int arrivalDelay = 0;
int departureDelay = 0;
val pattern = timetable.getPattern();

for (int index = 0; index < newTimes.getNumStops(); ++index) {
if (!matchFound) {
// Delay is set on a single stop at a time. When match is found - propagate delay on all following stops
final var stop = stops.get(index);
final var stop = pattern.getStop(index);

matchFound = stop.getId().getId().equals(monitoredCall.getStopPointRef().getValue());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package org.opentripplanner.ext.vectortiles.layers.stops;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.val;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.opentripplanner.common.model.T2;
Expand All @@ -9,12 +15,6 @@
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.vertextype.TransitStopVertex;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class DigitransitStopPropertyMapper extends PropertyMapper<TransitStopVertex> {
private final Graph graph;

Expand All @@ -41,11 +41,14 @@ public Collection<T2<String, Object>> map(TransitStopVertex input) {
.orElse(null);

String patterns = JSONArray.toJSONString(patternsForStop.stream().map(tripPattern -> {
JSONObject pattern = new JSONObject();
pattern.put("headsign", tripPattern.getScheduledTimetable().getTripTimes().get(0).getHeadsign(tripPattern.getStopIndex(stop)));
pattern.put("type", tripPattern.getRoute().getMode().name());
pattern.put("shortName", tripPattern.getRoute().getShortName());
return pattern;
int stopPos = tripPattern.findStopPosition(stop);
val headsign = stopPos < 0 ? "Not Available" :
tripPattern.getScheduledTimetable().getTripTimes().get(0).getHeadsign(stopPos);
t2gran marked this conversation as resolved.
Show resolved Hide resolved
return new JSONObject(Map.of(
"headsign", headsign,
"type", tripPattern.getRoute().getMode().name(),
"shortName", tripPattern.getRoute().getShortName()
));
}).collect(Collectors.toList()));

return List.of(
Expand Down
Loading