Skip to content

Commit

Permalink
feature: Map OTP request to Raptor request - last step to make the vi…
Browse files Browse the repository at this point in the history
…a-search work!
  • Loading branch information
t2gran committed Sep 22, 2024
1 parent 0be98db commit 3a3724f
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,18 @@ private Duration searchWindowUsed() {
: Duration.ofSeconds(raptorSearchParamsUsed.searchWindowInSeconds());
}

private Void routeDirectStreet(
private List<Itinerary> routeDirectStreet(
List<Itinerary> itineraries,
Collection<RoutingError> routingErrors
) {
// TODO: Add support for via search to the direct-street search and remove this.
// The direct search is used to prune away silly transit results and it
// would be nice to also support via as a feature in the direct-street
// search.
if (request.isViaSearch()) {
return null;
}

debugTimingAggregator.startedDirectStreetRouter();
try {
itineraries.addAll(DirectStreetRouter.route(serverContext, request));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class FilterTransitWhenDirectModeIsEmpty {
private final StreetMode originalDirectMode;

public FilterTransitWhenDirectModeIsEmpty(RequestModes modes) {
this.originalDirectMode = modes.directMode;
this(modes.directMode);
}

public FilterTransitWhenDirectModeIsEmpty(StreetMode originalDirectMode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.time.ZonedDateTime;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
import org.opentripplanner.framework.application.OTPFeature;
import org.opentripplanner.raptor.api.model.GeneralizedCostRelaxFunction;
import org.opentripplanner.raptor.api.model.RaptorAccessEgress;
Expand All @@ -18,6 +19,7 @@
import org.opentripplanner.raptor.api.request.PassThroughPoint;
import org.opentripplanner.raptor.api.request.RaptorRequest;
import org.opentripplanner.raptor.api.request.RaptorRequestBuilder;
import org.opentripplanner.raptor.api.request.RaptorViaLocation;
import org.opentripplanner.raptor.rangeraptor.SystemErrDebugLogger;
import org.opentripplanner.routing.algorithm.raptoradapter.router.performance.PerformanceTimersForRaptor;
import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.RaptorCostConverter;
Expand Down Expand Up @@ -82,6 +84,13 @@ private RaptorRequest<T> doMap() {

var preferences = request.preferences();

// TODO Fix the Raptor search so pass-through and via search can be used together.
if (hasViaLocationsAndPassThroughLocations()) {
throw new IllegalArgumentException(
"A mix of via-locations and pass-through is not allowed in this versionP."
);
}

if (request.pageCursor() == null) {
int time = relativeTime(request.dateTime());

Expand Down Expand Up @@ -122,7 +131,7 @@ private RaptorRequest<T> doMap() {
// Note! If a pass-through-point exists, then the transit-group-priority feature is disabled

// TODO - We need handle via locations that are not pass-through-points here
if (request.getViaLocations().stream().allMatch(ViaLocation::isPassThroughLocation)) {
if (hasPassThroughOnly()) {
mcBuilder.withPassThroughPoints(mapPassThroughPoints());
r.relaxGeneralizedCostAtDestination().ifPresent(mcBuilder::withRelaxCostAtDestination);
} else if (!pt.relaxTransitGroupPriority().isNormal()) {
Expand Down Expand Up @@ -151,6 +160,10 @@ private RaptorRequest<T> doMap() {
.addAccessPaths(accessPaths)
.addEgressPaths(egressPaths);

if (hasViaLocationsOnly()) {
builder.searchParams().addViaLocations(mapViaLocations());
}

var raptorDebugging = request.journey().transit().raptorDebugging();

if (raptorDebugging.isEnabled()) {
Expand Down Expand Up @@ -182,10 +195,48 @@ private RaptorRequest<T> doMap() {
)
);
}

return builder.build();
}

private boolean hasPassThroughOnly() {
return request.getViaLocations().stream().allMatch(ViaLocation::isPassThroughLocation);
}

private boolean hasViaLocationsOnly() {
return request.getViaLocations().stream().noneMatch(ViaLocation::isPassThroughLocation);
}

private boolean hasViaLocationsAndPassThroughLocations() {
var c = request.getViaLocations();
return (
request.isViaSearch() &&
c.stream().anyMatch(ViaLocation::isPassThroughLocation) &&
c.stream().anyMatch(Predicate.not(ViaLocation::isPassThroughLocation))
);
}

private List<RaptorViaLocation> mapViaLocations() {
return request.getViaLocations().stream().map(this::mapViaLocation).toList();
}

private RaptorViaLocation mapViaLocation(ViaLocation input) {
if (input.isPassThroughLocation()) {
var builder = RaptorViaLocation.allowPassThrough(input.label());
for (int stopIndex : lookUpStopIndex.lookupStopLocationIndexes(input.stopLocationIds())) {
builder.addViaStop(stopIndex);
}
return builder.build();
}
// Visit Via location
else {
var builder = RaptorViaLocation.via(input.label(), input.minimumWaitTime());
for (int stopIndex : lookUpStopIndex.lookupStopLocationIndexes(input.stopLocationIds())) {
builder.addViaStop(stopIndex);
}
return builder.build();
}
}

private List<PassThroughPoint> mapPassThroughPoints() {
return request.getViaLocations().stream().map(this::mapPassThroughPoints).toList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,13 @@ public void setTo(GenericLocation to) {
this.to = to;
}

/**
* Return {@code true} if at least one via location is set!
*/
public boolean isViaSearch() {
return !via.isEmpty();
}

public List<ViaLocation> getViaLocations() {
return via;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Map;
Expand All @@ -18,6 +19,7 @@
import org.opentripplanner.routing.api.request.RouteRequest;
import org.opentripplanner.routing.api.request.framework.CostLinearFunction;
import org.opentripplanner.routing.api.request.via.PassThroughViaLocation;
import org.opentripplanner.routing.api.request.via.VisitViaLocation;
import org.opentripplanner.transit.model._data.TransitModelForTest;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.site.StopLocation;
Expand Down Expand Up @@ -55,6 +57,24 @@ void mapRelaxCost(CostLinearFunction input, int cost, int expected) {
assertEquals(expected, calcCost.relax(cost));
}

@Test
void testViaLocation() {
var req = new RouteRequest();
var minWaitTime = Duration.ofMinutes(13);

req.setViaLocations(
List.of(new VisitViaLocation("Via A", minWaitTime, List.of(STOP_A.getId()), List.of()))
);

var result = map(req);

assertTrue(result.searchParams().hasViaLocations());
assertEquals(
"[Via{label: Via A, minWaitTime: 13m, connections: [0 13m]}]",
result.searchParams().viaLocations().toString()
);
}

@Test
void testPassThroughPoints() {
var req = new RouteRequest();
Expand Down

0 comments on commit 3a3724f

Please sign in to comment.