Skip to content

Commit

Permalink
Merge pull request #2929 from entur/otp2_raptor_code_cleanup
Browse files Browse the repository at this point in the history
Otp2 raptor code cleanup
  • Loading branch information
abyrd committed Jan 24, 2020
2 parents a570533 + 1ac51d4 commit d042ccb
Show file tree
Hide file tree
Showing 110 changed files with 811 additions and 834 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,159 +12,149 @@
import org.opentripplanner.routing.algorithm.raptor.transit.request.RaptorRoutingRequestTransitData;
import org.opentripplanner.routing.core.RoutingRequest;
import org.opentripplanner.routing.services.FareService;
import org.opentripplanner.transit.raptor.RangeRaptorService;
import org.opentripplanner.transit.raptor.RaptorService;
import org.opentripplanner.transit.raptor.api.path.Path;
import org.opentripplanner.transit.raptor.api.request.RangeRaptorProfile;
import org.opentripplanner.transit.raptor.api.request.RangeRaptorRequest;
import org.opentripplanner.transit.raptor.api.request.RequestBuilder;
import org.opentripplanner.transit.raptor.api.request.TuningParameters;
import org.opentripplanner.transit.raptor.api.request.RaptorProfile;
import org.opentripplanner.transit.raptor.api.request.RaptorRequest;
import org.opentripplanner.transit.raptor.api.request.RaptorRequestBuilder;
import org.opentripplanner.transit.raptor.api.request.RaptorTuningParameters;
import org.opentripplanner.transit.raptor.api.transit.TransferLeg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
* Does a complete transit search, including access and egress legs.
* <p>
* TODO OTP2 - Rename to better reflect scope, does more than Raptor routing. This is - THE
* router...
*/
public class RaptorRouter {

private static final int TRANSIT_SEARCH_RANGE_IN_DAYS = 2;
private static final Logger LOG = LoggerFactory.getLogger(RaptorRouter.class);
private static final RangeRaptorService<TripSchedule> rangeRaptorService = new RangeRaptorService<>(
// TODO OTP2 - Load turning parameters from config file
new TuningParameters() {}
);

private final RaptorRoutingRequestTransitData requestTransitDataProvider;
private final TransitLayer transitLayer;
private final RoutingRequest request;

//TODO Naming
public RaptorRouter(RoutingRequest request, TransitLayer transitLayer) {
double startTime = System.currentTimeMillis();

ZonedDateTime startOfTime = calculateStartOfTime(request);

this.requestTransitDataProvider = new RaptorRoutingRequestTransitData(
transitLayer,
request.getDateTime().toInstant(),
TRANSIT_SEARCH_RANGE_IN_DAYS,
request.modes,
request.walkSpeed
private static final int TRANSIT_SEARCH_RANGE_IN_DAYS = 2;
private static final Logger LOG = LoggerFactory.getLogger(RaptorRouter.class);
private static final RaptorService<TripSchedule> raptorService = new RaptorService<>(
// TODO OTP2 - Load turning parameters from config file
new RaptorTuningParameters() {}
);
LOG.info("Filtering tripPatterns took {} ms", System.currentTimeMillis() - startTime);
this.transitLayer = transitLayer;
this.request = request;
}

private ZonedDateTime calculateStartOfTime(RoutingRequest request) {
ZoneId zoneId = request.getRoutingContext().graph.getTimeZone().toZoneId();
ZonedDateTime zdt = request.getDateTime().toInstant().atZone(zoneId);
return DateMapper.asStartOfService(zdt);
}

public Collection<Itinerary> route() {

/* Prepare access/egress transfers */

double startTimeAccessEgress = System.currentTimeMillis();

Map<Stop, Transfer> accessTransfers = AccessEgressRouter.streetSearch(request, false, 2000);
Map<Stop, Transfer> egressTransfers = AccessEgressRouter.streetSearch(request, true, 2000);

TransferToAccessEgressLegMapper accessEgressLegMapper = new TransferToAccessEgressLegMapper(
transitLayer);

Collection<TransferLeg> accessTimes = accessEgressLegMapper.map(
accessTransfers,
request.walkSpeed
);
Collection<TransferLeg> egressTimes = accessEgressLegMapper.map(
egressTransfers,
request.walkSpeed
);

LOG.info(
"Access/egress routing took {} ms",
System.currentTimeMillis() - startTimeAccessEgress
);

/* Prepare transit search */

double startTimeRouting = System.currentTimeMillis();

int departureTime = DateMapper.secondsSinceStartOfTime(
requestTransitDataProvider.getStartOfTime(), request.getDateTime().toInstant()
);

// TODO Expose parameters
// TODO Remove parameters from API
RequestBuilder builder = new RequestBuilder();
builder
.profile(RangeRaptorProfile.STANDARD)
.searchParams()
.earliestDepartureTime(departureTime)
.searchWindowInSeconds(request.raptorSearchWindow)
.addAccessStops(accessTimes)
.addEgressStops(egressTimes)
.boardSlackInSeconds(request.boardSlack)
.timetableEnabled(true);

//TODO Check in combination with timetableEnabled
//builder.enableOptimization(Optimization.PARETO_CHECK_AGAINST_DESTINATION);

RangeRaptorRequest rangeRaptorRequest = builder.build();

/* Route transit */

// We know this cast is correct because we have instantiated rangeRaptorService as RangeRaptorService<TripSchedule>
@SuppressWarnings("unchecked") Collection<Path<TripSchedule>> paths = rangeRaptorService.route(
rangeRaptorRequest,
this.requestTransitDataProvider
);

LOG.info("Found {} itineraries", paths.size());

LOG.info("Main routing took {} ms", System.currentTimeMillis() - startTimeRouting);

/* Create itineraries */

double startItineraries = System.currentTimeMillis();

ItineraryMapper itineraryMapper = new ItineraryMapper(
transitLayer,
requestTransitDataProvider.getStartOfTime(),
request,
accessTransfers,
egressTransfers
);
FareService fareService = request.getRoutingContext().graph.getService(FareService.class);

List<Itinerary> itineraries = new ArrayList<>();
for (Path path : paths) {
// Convert the Raptor/Astar paths to OTP API Itineraries
Itinerary itinerary = itineraryMapper.createItinerary(path);
// Decorate the Itineraries with fare information.
// Itinerary and Leg are API model classes, lacking internal object references needed for effective
// fare calculation. We derive the fares from the internal Path objects and add them to the itinerary.
if (fareService != null) {
itinerary.fare = fareService.getCost(path, transitLayer);
}
itineraries.add(itinerary);
}

LOG.info(
"Creating {} itineraries took {} ms",
itineraries.size(),
System.currentTimeMillis() - startItineraries
);

return itineraries;
}
private final RaptorRoutingRequestTransitData requestTransitDataProvider;
private final TransitLayer transitLayer;
private final RoutingRequest request;

//TODO Naming
public RaptorRouter(RoutingRequest request, TransitLayer transitLayer) {
double startTime = System.currentTimeMillis();

this.requestTransitDataProvider = new RaptorRoutingRequestTransitData(
transitLayer,
request.getDateTime().toInstant(),
TRANSIT_SEARCH_RANGE_IN_DAYS,
request.modes,
request.walkSpeed
);
LOG.info("Filtering tripPatterns took {} ms", System.currentTimeMillis() - startTime);
this.transitLayer = transitLayer;
this.request = request;
}

public Collection<Itinerary> route() {

/* Prepare access/egress transfers */

double startTimeAccessEgress = System.currentTimeMillis();

Map<Stop, Transfer> accessTransfers = AccessEgressRouter.streetSearch(request, false, 2000);
Map<Stop, Transfer> egressTransfers = AccessEgressRouter.streetSearch(request, true, 2000);

TransferToAccessEgressLegMapper accessEgressLegMapper = new TransferToAccessEgressLegMapper(
transitLayer
);

Collection<TransferLeg> accessTimes = accessEgressLegMapper.map(
accessTransfers,
request.walkSpeed
);
Collection<TransferLeg> egressTimes = accessEgressLegMapper.map(
egressTransfers,
request.walkSpeed
);

LOG.info(
"Access/egress routing took {} ms",
System.currentTimeMillis() - startTimeAccessEgress
);

/* Prepare transit search */

double startTimeRouting = System.currentTimeMillis();

int departureTime = DateMapper.secondsSinceStartOfTime(
requestTransitDataProvider.getStartOfTime(),
request.getDateTime().toInstant()
);

// TODO Expose parameters
// TODO Remove parameters from API
RaptorRequest<TripSchedule> raptorRequest = new RaptorRequestBuilder<TripSchedule>()
.profile(RaptorProfile.STANDARD)
//TODO Check in combination with timetableEnabled
//.enableOptimization(Optimization.PARETO_CHECK_AGAINST_DESTINATION)
.searchParams()
.earliestDepartureTime(departureTime)
.searchWindowInSeconds(request.raptorSearchWindow)
.addAccessStops(accessTimes)
.addEgressStops(egressTimes)
.boardSlackInSeconds(request.boardSlack)
.timetableEnabled(true)
.build();

/* Route transit */

Collection<Path<TripSchedule>> paths = raptorService.route(
raptorRequest,
this.requestTransitDataProvider
);

LOG.info("Found {} itineraries", paths.size());

LOG.info("Main routing took {} ms", System.currentTimeMillis() - startTimeRouting);

/* Create itineraries */

double startItineraries = System.currentTimeMillis();

ItineraryMapper itineraryMapper = new ItineraryMapper(
transitLayer,
requestTransitDataProvider.getStartOfTime(),
request,
accessTransfers,
egressTransfers
);
FareService fareService = request.getRoutingContext().graph.getService(FareService.class);

List<Itinerary> itineraries = new ArrayList<>();
for (Path<TripSchedule> path : paths) {
// Convert the Raptor/Astar paths to OTP API Itineraries
Itinerary itinerary = itineraryMapper.createItinerary(path);
// Decorate the Itineraries with fare information.
// Itinerary and Leg are API model classes, lacking internal object references needed for effective
// fare calculation. We derive the fares from the internal Path objects and add them to the itinerary.
if (fareService != null) {
itinerary.fare = fareService.getCost(path, transitLayer);
}
itineraries.add(itinerary);
}

LOG.info("Creating {} itineraries took {} ms",
itineraries.size(),
System.currentTimeMillis() - startItineraries
);

return itineraries;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import org.opentripplanner.model.TripPattern;
import org.opentripplanner.routing.trippattern.TripTimes;
import org.opentripplanner.transit.raptor.api.transit.TripScheduleInfo;
import org.opentripplanner.transit.raptor.api.transit.RaptorTripSchedule;

/**
* Extension of TripScheduleInfo passed through Range Raptor searches to be able to retrieve the
* Extension of RaptorTripSchedule passed through Raptor searches to be able to retrieve the
* original trip from the path when creating itineraries.
*/
public interface TripSchedule extends TripScheduleInfo {
public interface TripSchedule extends RaptorTripSchedule {

/**
* TODO OTP2 - Add JavaDoc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

Expand Down Expand Up @@ -465,10 +464,7 @@ public class RoutingRequest implements Cloneable, Serializable {

/**
* Invariant: boardSlack + alightSlack ≤ transferSlack.
*
* @deprecated TODO OTP2 - Regression. Not currently working in OTP2.
*/
@Deprecated
public int boardSlack = 0;

/**
Expand Down

0 comments on commit d042ccb

Please sign in to comment.